~mrqtros/ubuntu-rssreader-app/ubuntu-rssreader-app-to-tabs

« back to all changes in this revision

Viewing changes to shorts/qml/utils/databasemodule_v2.js

  • Committer: Roman Shchekin
  • Date: 2015-07-04 08:38:18 UTC
  • Revision ID: mrqtros@gmail.com-20150704083818-ecojm3nmy5bpkxrb
Merge with the Reboot project.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
.pragma library // I hope this will prevent the waste of memory.
 
2
.import QtQuick.LocalStorage 2.0 as SQL
 
3
 
 
4
/* For internal usage in module.
 
5
 */
 
6
var gDbCache = undefined
 
7
function openStdDataBase() {
 
8
    if (gDbCache === undefined) {
 
9
        gDbCache = SQL.LocalStorage.openDatabaseSync("Shorts", "1.1", "Shorts DB", 1000000)
 
10
 
 
11
        // We can check table existance only once.
 
12
        gDbCache.transaction(function(tx) {
 
13
            checkTableExists(tx/*, opts*/);
 
14
        })
 
15
    }
 
16
 
 
17
    return gDbCache
 
18
}
 
19
 
 
20
function checkTableExists(transaction /* and additional string keys */) {
 
21
    transaction.executeSql('PRAGMA foreign_keys = ON;')   // enable foreign key support
 
22
    transaction.executeSql("CREATE TABLE IF NOT EXISTS feed  (id  INTEGER  NOT NULL PRIMARY KEY AUTOINCREMENT,source  TEXT  NULL,title  TEXT  NULL,link  TEXT  NULL, description  TEXT  NULL, status  char(1)  NULL DEFAULT '0', pubdate  INTEGER  NULL,image  TEXT  NULL, count INTEGER NULL DEFAULT 0);")
 
23
    transaction.executeSql("CREATE TABLE IF NOT EXISTS tag  (id  INTEGER  NOT NULL PRIMARY KEY AUTOINCREMENT,name  TEXT  NOT NULL UNIQUE );")
 
24
    transaction.executeSql("CREATE TABLE IF NOT EXISTS feed_tag  (id  INTEGER  NOT NULL PRIMARY KEY AUTOINCREMENT,feed_id  INTEGER  NULL,tag_id  INTEGER  NULL,FOREIGN KEY(feed_id) REFERENCES feed(id) on delete cascade);")
 
25
    transaction.executeSql("CREATE TABLE IF NOT EXISTS article ( id  INTEGER  PRIMARY KEY AUTOINCREMENT NOT NULL, title  TEXT  NULL, content TEXT NULL, link  TEXT  NULL, description  TEXT  NULL, pubdate  INTEGER  NULL, status  char(1)  NULL DEFAULT '0', favourite  char(1)  NULL DEFAULT '0', image  TEXT  NULL, guid TEXT NULL, feed_id  INTEGER  NULL,count INTEGER NULL DEFAULT 0, media_groups TEXT NULL, author TEXT NULL);")
 
26
    transaction.executeSql("CREATE TABLE IF NOT EXISTS settings  ( id INTEGER, current_database_version TEXT NULL, database_last_updated  TEXT  NULL, view_mode char(1) NULL DEFAULT '0', update_interval INTEGER NULL DEFAULT 0, network_mode char(1) NULL DEFAULT '0');")
 
27
}
 
28
 
 
29
function adjustDb(dbParams) {
 
30
 
 
31
    var db = openStdDataBase()
 
32
    var dbResult
 
33
 
 
34
    // Update scheme mechanism - step by step updating DB to the latest version.
 
35
    // WARNING: Don't add 'break' statement.
 
36
    switch (dbParams.oldDbVersion) {
 
37
        case 1.1:
 
38
            // Add new column - author.
 
39
            db.transaction(function(tx) {
 
40
                dbResult = tx.executeSql("alter table article add author text")
 
41
                console.log("Database updated: ", JSON.stringify(dbResult))
 
42
            })
 
43
            dbParams.newDbVersion = 1.1
 
44
        case 1.2:
 
45
            dbParams.newDbVersion = 1.2
 
46
    }
 
47
 
 
48
    var tagCount = 0
 
49
    db.transaction(function(tx) {
 
50
        dbResult = tx.executeSql("SELECT count(*) AS tagCount FROM feed_tag")
 
51
        tagCount = dbResult.rows.item(0).tagCount
 
52
    })
 
53
 
 
54
    if (tagCount === 0) {
 
55
        addTag("Ubuntu")
 
56
        addFeed("Developer" , "http://developer.ubuntu.com/feed/")
 
57
        addFeed("Design" , "http://design.canonical.com/feed/")
 
58
        addFeedTag(1, 1)
 
59
        addFeedTag(2, 1)
 
60
        addTag("Canonical")
 
61
        addFeed("Voices" , "http://voices.canonical.com/feed/atom/")
 
62
        addFeed("Insights" , "http://insights.ubuntu.com/feed/")
 
63
        addFeed("Blog" , "http://blog.canonical.com/feed/")
 
64
        addFeedTag(3, 2)
 
65
        addFeedTag(4, 2)
 
66
        addFeedTag(5, 2)
 
67
 
 
68
        // MainView must refresh articles.
 
69
        dbParams.isRefreshRequired = true
 
70
    }
 
71
}
 
72
 
 
73
/* feed operations
 
74
 * include select, insert, update and delete operations
 
75
 */
 
76
// select
 
77
function loadFeeds()
 
78
{
 
79
    var db = openStdDataBase()
 
80
    var dbResult
 
81
//    var feeds
 
82
    db.transaction(function(tx) {
 
83
        dbResult = tx.executeSql("SELECT * FROM feed")
 
84
        console.log("feed SELECTED: ", dbResult.rows.length)
 
85
    })
 
86
    return dbResult;  // I suggest that return the whole result in order to know if error occurs
 
87
}
 
88
 
 
89
// insert
 
90
function addFeed(title, source)  // from user input
 
91
{
 
92
    var dbResult
 
93
    var db = openStdDataBase()
 
94
    db.transaction(function (tx) {
 
95
        /* Check uniqueness.
 
96
         */
 
97
        dbResult = tx.executeSql("SELECT 1 FROM feed WHERE source=?", [source])
 
98
        if (dbResult.rows.length > 0) {
 
99
            console.log("Database, addFeed: already exist feed with source: ", source, "ID", dbResult.rows.item(0).id)
 
100
            dbResult = {"error": true, "exist": true}
 
101
            return
 
102
        }
 
103
 
 
104
        dbResult = tx.executeSql('INSERT INTO feed (title, source) VALUES(?, ?)',
 
105
                                 [title , source])
 
106
        console.log("feed INSERT ID: ", dbResult.insertId)
 
107
 
 
108
        dbResult.feedId = tx.executeSql("SELECT * FROM feed WHERE source=?", [source]).rows.item(0).id
 
109
        console.log("dbResult.feedId", dbResult.feedId)
 
110
    })
 
111
    return dbResult;
 
112
}
 
113
 
 
114
// change confirmed
 
115
/* Update feed status.
 
116
 * 0 - default, 1 - good, 2 - bad url.
 
117
 */
 
118
function setFeedStatus(id, status)  // from user input
 
119
{
 
120
    var db = openStdDataBase()
 
121
    var dbResult
 
122
    db.transaction(function (tx) {
 
123
        dbResult = tx.executeSql('UPDATE feed SET status=? WHERE id=?',
 
124
                                 [status, id])
 
125
        console.log("feed setFeedStatus, AFFECTED ROWS: ", dbResult.rowsAffected)
 
126
    })
 
127
    return dbResult
 
128
}
 
129
 
 
130
// update
 
131
function updateFeedByUser(id, title, source)  // from user input
 
132
{
 
133
    var db = openStdDataBase()
 
134
    var dbResult
 
135
    db.transaction(function (tx) {
 
136
        dbResult = tx.executeSql('UPDATE feed SET title=?, source=? WHERE id=?',
 
137
                                 [title, source, id])
 
138
        console.log("feed updateFeedByUser, AFFECTED ROWS: ", dbResult.rowsAffected)
 
139
    })
 
140
    return dbResult
 
141
}
 
142
 
 
143
function updateFeedByXml(id, link, description, title)   // from xml file
 
144
{
 
145
    var db = openStdDataBase()
 
146
    var dbResult
 
147
    db.transaction(function (tx) {
 
148
        dbResult = tx.executeSql('UPDATE feed SET link=?, description=?, title=? WHERE id=?',
 
149
                                 [link, description, title, id])
 
150
        //console.log("feed updateFeedByXml, AFFECTED ROWS: ", dbResult.rowsAffected)
 
151
    }
 
152
    )
 
153
    return dbResult
 
154
}
 
155
 
 
156
function updateFeedImage(id, image)  //  offline image path
 
157
{
 
158
    var db = openStdDataBase()
 
159
    var dbResult
 
160
    db.transaction(function (tx) {
 
161
        dbResult = tx.executeSql('UPDATE feed SET image=? WHERE id=?',
 
162
                                 [image, id])
 
163
        console.log("feed UPDATE, AFFECTED ROWS: ", dbResult.rowsAffected)
 
164
    })
 
165
    return dbResult
 
166
}
 
167
 
 
168
function updateFeedCount(id, count)  //
 
169
{
 
170
    var db = openStdDataBase()
 
171
    var dbResult
 
172
    db.transaction(function (tx) {
 
173
        dbResult = tx.executeSql('UPDATE feed SET count=? WHERE id=?',
 
174
                                 [count, id])
 
175
        console.log("feed UPDATE, AFFECTED ROWS: ", dbResult.rowsAffected)
 
176
    })
 
177
    return dbResult
 
178
}
 
179
 
 
180
// delete
 
181
function deleteFeed(id)
 
182
{
 
183
    var db = openStdDataBase()
 
184
    var dbResult
 
185
    db.transaction(function (tx) {
 
186
        dbResult = tx.executeSql('delete from feed where id=?', [id])
 
187
        console.log("feed delete, AFFECTED ROWS: ", dbResult.rowsAffected)
 
188
    })
 
189
    return dbResult
 
190
}
 
191
 
 
192
function deleteFeedByTagId(tagId)
 
193
{
 
194
    var db = openStdDataBase()
 
195
    var dbResult
 
196
    db.transaction(function (tx) {
 
197
        dbResult = tx.executeSql('delete from feed where exists (select 1 from feed_tag where feed_tag.feed_id = feed.id and feed_tag.tag_id = ?)',
 
198
                                 [tagId])
 
199
        console.log("feed delete by tag id, AFFECTED ROWS: ", dbResult.rowsAffected)
 
200
    })
 
201
    return dbResult
 
202
}
 
203
 
 
204
// select feeds without of topic (tag).
 
205
function loadFeedsWithoutTopic()
 
206
{
 
207
    var db = openStdDataBase()
 
208
    var dbResult
 
209
 
 
210
    db.transaction(function(tx) {
 
211
        dbResult = tx.executeSql("SELECT * FROM feed WHERE id NOT IN (SELECT feed_id FROM feed_tag)")
 
212
        console.log("loadFeedsWithoutTopic SELECTED: ", dbResult.rows.length)
 
213
    })
 
214
    return dbResult;  // I suggest that return the whole result in order to know if error occurs
 
215
}
 
216
 
 
217
/* article operations
 
218
 * include select, insert, update and delete operations
 
219
 *
 
220
 *
 
221
 */
 
222
// select
 
223
function loadArticles(params)   // params = {"isAll": true/false, "feedId": id | "tagId" : id}
 
224
{
 
225
    var db = openStdDataBase()
 
226
    var dbResult
 
227
 
 
228
    console.log("loadArticles", JSON.stringify(params))
 
229
 
 
230
    db.transaction(function(tx) {
 
231
        if (params == undefined || params.isAll) // miss params
 
232
            dbResult = tx.executeSql('SELECT article.*, feed.title as feed_name FROM article inner join feed on article.feed_id = feed.id ORDER BY article.pubdate DESC')
 
233
        else if (params.feedId)
 
234
            dbResult = tx.executeSql('SELECT article.*, feed.title as feed_name FROM article inner join feed on article.feed_id = feed.id WHERE article.feed_id = ? ORDER BY article.pubdate DESC', [params.feedId])
 
235
        else if (params.tagId)
 
236
            dbResult = tx.executeSql('SELECT article.*, feed.title as feed_name FROM article INNER JOIN feed on article.feed_id = feed.id INNER JOIN feed_tag on feed_tag.feed_id = feed.id WHERE tag_id = ? ORDER BY article.pubdate DESC', [params.tagId])
 
237
            //dbResult = tx.executeSql('SELECT article.*, feed.title as feed_name FROM article inner join feed on article.feed_id = feed.id WHERE article.feed_id IN (SELECT feed_id FROM feed_tag WHERE tag_id = ?) ORDER BY article.pubdate DESC', [params.tagId])
 
238
    })
 
239
    return dbResult;
 
240
}
 
241
 
 
242
// load all favourite articles
 
243
function loadFavouriteArticles()
 
244
{
 
245
    var db = openStdDataBase()
 
246
    var dbResult
 
247
 
 
248
    db.transaction(function(tx) {
 
249
        dbResult = tx.executeSql('  select article.*, \
 
250
                                    feed.title as feed_name, \
 
251
                                    feed_tag.tag_id \
 
252
                                    from article inner join feed on article.feed_id = feed.id \
 
253
                                    join feed_tag on feed_tag.feed_id = feed.id \
 
254
                                    where article.favourite = "1" order by article.pubdate desc')
 
255
    })
 
256
    //console.log("loadFavouriteArticles", dbResult.rows.length)
 
257
    //console.assert(dbResult.rows.length !== 0,  "ERROR: There are no saved articles")
 
258
    return dbResult;
 
259
}
 
260
 
 
261
// Load top for tag.
 
262
function loadTagHighlights(size) {
 
263
    var db = openStdDataBase()
 
264
    var dbResult
 
265
 
 
266
    db.transaction(function(tx) {
 
267
        dbResult = tx.executeSql(  'select a.id, f.id as feed_id, ft.tag_id \
 
268
                                    from article a \
 
269
                                    inner join feed f on f.id = a.feed_id \
 
270
                                    inner join feed_tag ft on ft.feed_id = f.id \
 
271
                                    order by ft.tag_id, a.pubdate desc' )
 
272
 
 
273
        var idArray = []
 
274
 
 
275
        var curTagId = -1
 
276
        var count = 0
 
277
        for (var i = 0; i < dbResult.rows.length; i++) {
 
278
            var c = dbResult.rows.item(i).tag_id
 
279
 
 
280
            if (c != curTagId) {
 
281
                count = 0
 
282
                curTagId = c
 
283
            }
 
284
 
 
285
            if (count < size) {
 
286
                idArray.push(dbResult.rows.item(i).id)
 
287
                count++
 
288
            }
 
289
        }
 
290
 
 
291
        var param = idArray.length ? idArray.join() : "-1" // Empty array guard.
 
292
        dbResult = tx.executeSql('select a.*, f.id as feed_id, f.title as feed_name, t.id as tag_id, t.name as tag_name \
 
293
                                 from article a \
 
294
                                 inner join feed f on a.feed_id = f.id \
 
295
                                 inner join feed_tag ft on ft.feed_id = f.id \
 
296
                                 inner join tag t on t.id = ft.tag_id
 
297
                                 where a.id in (%1) \
 
298
                                 order by t.id, a.pubdate desc'.arg(param)) // Don't know why, but it doesn't work with commas in param
 
299
 
 
300
        //.console.log(idArray.length, idArray)
 
301
    })
 
302
    console.log("loadTagHighlights", dbResult.rows.length)
 
303
    return dbResult
 
304
}
 
305
 
 
306
/*
 
307
  this function is for avoiding hard drive performance issue,
 
308
  pass model (plain JS array) and feed id as parameters to this function,
 
309
  it will automaticly insert all the articles into database
 
310
  add third pamams which is for restoring articles' properties
 
311
 */
 
312
function addArticles(model, feed_id, restoreArray)
 
313
{
 
314
    var dbResult
 
315
 
 
316
    var db = openStdDataBase()
 
317
    db.transaction(function (tx) {
 
318
 
 
319
        var article;
 
320
        for (var i = 0; i < model.length; i++) {
 
321
 
 
322
            article = model[i]
 
323
            var title =  article.title ? article.title : ""
 
324
            var guid =  article.guid ? article.guid : Qt.md5(title)
 
325
            var link =  article.link ? article.link : ""
 
326
            var pubDate =  article.pubDate ? article.pubDate : ""
 
327
            var description =  article.description ? article.description : ""
 
328
            var content =  article.content ? article.content : ""
 
329
            var image =  article.image ? article.image : ""
 
330
            var media_groups = article.media_groups ? JSON.stringify(article.media_groups) : ""
 
331
            var author = article.author ? JSON.stringify(article.author) : ""
 
332
 
 
333
            /* Check uniqueness.
 
334
             */
 
335
            dbResult = tx.executeSql("SELECT 1 FROM article WHERE guid=? AND feed_id=?", [guid, feed_id])
 
336
            if (dbResult.rows.length > 0) {
 
337
                // console.log("Database, add article: already exist article with guid: ", guid)
 
338
                continue;
 
339
            }
 
340
            dbResult = tx.executeSql('INSERT INTO article (title, content, link, description, pubdate, guid, feed_id, image, media_groups, author) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
 
341
                                     [title, content, link, description, pubDate, guid, feed_id, image, media_groups, author])
 
342
        }
 
343
 
 
344
        //console.time("restoreArrayCycle")
 
345
        if (restoreArray) {
 
346
            var BASE_HEURISTIC_CHUNK = 512
 
347
            var arrayLength = restoreArray.length
 
348
 
 
349
            var queryGetFunction = function(paramSize) {
 
350
                var baseQuery = 'UPDATE article SET status="1" WHERE guid IN ('
 
351
                for (var i = 0; i < paramSize; i++)
 
352
                    baseQuery += '?,'
 
353
                baseQuery = baseQuery.substring(0, baseQuery.length - 1) + ') AND status="0"'
 
354
                return baseQuery
 
355
            }
 
356
 
 
357
            var chunkOfData = restoreArray.length > BASE_HEURISTIC_CHUNK ? BASE_HEURISTIC_CHUNK : restoreArray.length
 
358
            var fullQuery = queryGetFunction(chunkOfData)
 
359
 
 
360
            for (var j = 0; j < restoreArray.length; j += chunkOfData) {
 
361
 
 
362
                var limit = Math.min(chunkOfData, restoreArray.length - j)
 
363
                var queryToUse = limit == chunkOfData ? fullQuery : queryGetFunction(limit)
 
364
 
 
365
                var queryData = []
 
366
                for (var k = 0; k < limit; k++)
 
367
                    queryData.push(restoreArray[j + k].guid)
 
368
 
 
369
                dbResult = tx.executeSql(queryToUse, queryData)
 
370
                // console.log("CONSUMED", limit, "Rows affected:", dbResult.rowsAffected)
 
371
            }
 
372
        } // if restore array
 
373
        //console.timeEnd("restoreArrayCycle")
 
374
    })
 
375
    return dbResult;
 
376
}
 
377
 
 
378
function addArticlesEx(entries, feedId)
 
379
{
 
380
    var dbResult
 
381
 
 
382
    var db = openStdDataBase()
 
383
    db.transaction(function (tx) {
 
384
 
 
385
        // 1. Preload details.
 
386
        //.console.time("Preload")
 
387
        var articlePropertiesDb = dbResult = tx.executeSql("select guid, status \
 
388
                                                            from article \
 
389
                                                            where feed_id = ?", [feedId]) //  and status = '1'", [feedId])
 
390
        var feedArticles = []
 
391
        for (var j = 0; j < articlePropertiesDb.rows.length; j++) {
 
392
            var itm = articlePropertiesDb.rows.item(j)
 
393
            feedArticles.push({ "guid" : itm.guid, "status" : itm.status })
 
394
        }
 
395
        console.log("feedArticles.length", feedArticles.length)
 
396
        //.console.timeEnd("Preload")
 
397
 
 
398
        // 2. CleanUp old.
 
399
        //.console.time("DeleteOld")
 
400
        tx.executeSql("delete from article where feed_id = ? and favourite = '0'", [feedId])
 
401
        //.console.timeEnd("DeleteOld")
 
402
 
 
403
        // 3. Insert new objects.
 
404
        //.console.time("InsertArticle")
 
405
        var emptyStr = ""
 
406
        for (var i = 0; i < entries.length; i++) {
 
407
            var e = entries[i]
 
408
 
 
409
            var title =  e.title ? e.title : emptyStr
 
410
            var content =  e.content ? e.content : emptyStr
 
411
            var link =  e.link ? e.link : emptyStr
 
412
            var author = e.author ? JSON.stringify(e.author) : emptyStr
 
413
            var description =  e.description ? e.description : emptyStr
 
414
            var pubDate =  e.pubDate ? e.pubDate : 0
 
415
            var guid =  e.guid ? e.guid : Qt.md5(title)
 
416
            var image =  e.image ? e.image : emptyStr
 
417
            var media_groups = e.media_groups ? JSON.stringify(e.media_groups) : emptyStr
 
418
 
 
419
            //  Check uniqueness.
 
420
            //if (feedArticles.some(function(v) { return v.guid == guid } ))
 
421
            //    continue
 
422
 
 
423
            dbResult = tx.executeSql('insert into article (title, content, link, description, pubdate, guid, feed_id, image, media_groups, author) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
 
424
                                     [title, content, link, description, pubDate, guid, feedId, image, media_groups, author])
 
425
        }
 
426
        //.console.timeEnd("InsertArticle")
 
427
 
 
428
        // 4. Update statuses.
 
429
        //.console.time("UpdateStatuses")
 
430
        var readArticles = feedArticles.filter(function(e) { return e.status == "1" } )
 
431
        if (readArticles.length) {
 
432
            var BASE_HEURISTIC_CHUNK = 512
 
433
            var arrayLength = readArticles.length
 
434
 
 
435
            var queryGetFunction = function(paramSize) {
 
436
                var baseQuery = 'update article set status="1" where guid in ('
 
437
                for (var i = 0; i < paramSize; i++)
 
438
                    baseQuery += '?,'
 
439
                baseQuery = baseQuery.substring(0, baseQuery.length - 1) + ') AND status="0"'
 
440
                return baseQuery
 
441
            }
 
442
 
 
443
            var chunkOfData = readArticles.length > BASE_HEURISTIC_CHUNK ? BASE_HEURISTIC_CHUNK : readArticles.length
 
444
            var fullQuery = queryGetFunction(chunkOfData)
 
445
 
 
446
            for (var j = 0; j < readArticles.length; j += chunkOfData) {
 
447
 
 
448
                var limit = Math.min(chunkOfData, readArticles.length - j)
 
449
                var queryToUse = limit == chunkOfData ? fullQuery : queryGetFunction(limit)
 
450
 
 
451
                var queryData = []
 
452
                for (var k = 0; k < limit; k++)
 
453
                    queryData.push(readArticles[j + k].guid)
 
454
 
 
455
                dbResult = tx.executeSql(queryToUse, queryData)
 
456
                // console.log("CONSUMED", limit, "Rows affected:", dbResult.rowsAffected)
 
457
            }
 
458
        } // if restore array
 
459
        //.console.timeEnd("UpdateStatuses")
 
460
    })
 
461
    return dbResult;
 
462
}
 
463
 
 
464
// update
 
465
function updateArticleStatus(id, status)
 
466
{
 
467
    var db = openStdDataBase()
 
468
    var dbResult
 
469
    db.transaction(function (tx) {
 
470
        dbResult = tx.executeSql('update article set status=? WHERE id=?',
 
471
                                 [status, id])
 
472
        console.log("article status UPDATE, AFFECTED ROWS: ", dbResult.rowsAffected)
 
473
    })
 
474
    return dbResult
 
475
}
 
476
 
 
477
function updateArticleFavourite(id, favourite) {
 
478
    var db = openStdDataBase()
 
479
    var dbResult
 
480
    db.transaction(function (tx) {
 
481
//        ensureFeedTableExists(tx)
 
482
        dbResult = tx.executeSql('UPDATE article SET favourite=? WHERE id=?',
 
483
                                 [favourite, id])
 
484
        console.log("article favourite UPDATE, AFFECTED ROWS: ", dbResult.rowsAffected)
 
485
    })
 
486
    return dbResult
 
487
}
 
488
 
 
489
 
 
490
// delete
 
491
function deleteArticle(id)
 
492
{
 
493
    var db = openStdDataBase()
 
494
    var dbResult
 
495
    db.transaction(function (tx) {
 
496
//        ensureFeedTableExists(tx)
 
497
        dbResult = tx.executeSql('delete from article WHERE id=?',
 
498
                                 [id])
 
499
        console.log("article delete, AFFECTED ROWS: ", dbResult.rowsAffected)
 
500
    })
 
501
    return dbResult
 
502
}
 
503
 
 
504
// clear article table, only status='2' and favourite='1' remain
 
505
function clearArticles(feed_id)
 
506
{
 
507
    var db = openStdDataBase()
 
508
    var dbResult
 
509
    db.transaction(function (tx) {
 
510
//        ensureFeedTableExists(tx)
 
511
        dbResult = tx.executeSql("delete from article WHERE (status='0' OR status='1') AND favourite='0' AND feed_id=?", [feed_id])
 
512
        console.log("article delete, AFFECTED ROWS: ", dbResult.rowsAffected)
 
513
    })
 
514
    return dbResult
 
515
}
 
516
 
 
517
 
 
518
/* tag operations
 
519
 * include select, insert, update and delete operations
 
520
 *
 
521
 *
 
522
 */
 
523
// select
 
524
function loadTags()
 
525
{
 
526
    var db = openStdDataBase()
 
527
    var dbResult
 
528
 
 
529
    db.transaction(function(tx) {
 
530
        dbResult = tx.executeSql("SELECT * FROM tag")
 
531
        console.assert(dbResult.rows.length !== 0, "ERROR: NO TAGS DATABASE")
 
532
    })
 
533
    return dbResult;
 
534
}
 
535
 
 
536
// insert
 
537
function addTag(name)
 
538
{
 
539
    var dbResult
 
540
    var db = openStdDataBase()
 
541
    db.transaction(function (tx) {
 
542
//        ensureFeedTableExists(tx)
 
543
 
 
544
        /* Check uniqueness.
 
545
         */
 
546
        dbResult = tx.executeSql("SELECT 1 FROM tag WHERE name=?", [name])
 
547
        if (dbResult.rows.length > 0) {
 
548
            console.log("Database, add tag: already exist tag with source: ", name)
 
549
            dbResult = {"error": true, "exist": true}
 
550
            return
 
551
        }
 
552
 
 
553
        dbResult = tx.executeSql('INSERT INTO tag (name) VALUES(?)',
 
554
                                 [name])
 
555
        console.log("tag INSERT ID: ", dbResult.insertId)
 
556
 
 
557
        dbResult.tagId = tx.executeSql("SELECT * FROM tag WHERE name=?", [name]).rows.item(0).id
 
558
        console.log("dbResult.tagId", dbResult.tagId)
 
559
    })
 
560
    return dbResult;
 
561
}
 
562
 
 
563
// update
 
564
function updateTag(id, name) {
 
565
    var db = openStdDataBase()
 
566
    var dbResult
 
567
    db.transaction(function (tx) {
 
568
        dbResult = tx.executeSql('UPDATE tag SET name=? WHERE id=?',
 
569
                                 [name, id])
 
570
        console.log("tag UPDATE, AFFECTED ROWS: ", dbResult.rowsAffected)
 
571
    })
 
572
    return dbResult
 
573
}
 
574
 
 
575
// delete
 
576
function deleteTag(id)
 
577
{
 
578
    var db = openStdDataBase()
 
579
    var dbResult
 
580
    db.transaction(function (tx) {
 
581
        dbResult = tx.executeSql('delete from tag WHERE id=?',
 
582
                                 [id])
 
583
        console.log("tag delete, AFFECTED ROWS: ", dbResult.rowsAffected)
 
584
    })
 
585
    return dbResult
 
586
}
 
587
 
 
588
 
 
589
/* feed_tag operations
 
590
 * include select, insert and delete operations
 
591
 *
 
592
 *
 
593
 */
 
594
// select
 
595
function loadFeedTags()
 
596
{
 
597
    var db = openStdDataBase()
 
598
    var dbResult
 
599
 
 
600
    db.transaction(function(tx) {
 
601
        dbResult = tx.executeSql("SELECT * FROM feed_tag")
 
602
    })
 
603
    return dbResult;
 
604
}
 
605
 
 
606
function loadFeedsFromTag(tag_id)
 
607
{
 
608
    var db = openStdDataBase()
 
609
    var dbResult
 
610
 
 
611
    db.transaction(function(tx) {
 
612
        dbResult = tx.executeSql("SELECT t1.* FROM feed t1 INNER JOIN feed_tag t2 ON t1.id = t2.feed_id WHERE tag_id =?", [tag_id])
 
613
        // console.log("loadFeedsFromTag:", tag_id, "SELECTED: ", dbResult.rows.length)
 
614
    })
 
615
    return dbResult;
 
616
}
 
617
 
 
618
// insert
 
619
function addFeedTag(feed_id, tag_id)
 
620
{
 
621
    var dbResult
 
622
    var db = openStdDataBase()
 
623
    db.transaction(function (tx) {
 
624
 
 
625
        /* Check uniqueness.
 
626
         */
 
627
        dbResult = tx.executeSql("SELECT 1 FROM feed_tag WHERE feed_id=? AND tag_id=? ", [feed_id, tag_id])
 
628
        if (dbResult.rows.length > 0) {
 
629
            console.log("Database, add feed_tag: already exist feed_tag with source: ", feed_id, tag_id)
 
630
            return {"error": true, "exist": true};
 
631
        }
 
632
 
 
633
        dbResult = tx.executeSql('INSERT INTO feed_tag (feed_id, tag_id) VALUES(?, ?)',
 
634
                                 [feed_id, tag_id])
 
635
        console.log("feed_tag INSERT ID: ", dbResult.insertId)
 
636
    })
 
637
    return dbResult
 
638
}
 
639
 
 
640
// delete
 
641
function deleteFeedTag(id) {
 
642
    var db = openStdDataBase()
 
643
    var dbResult
 
644
    db.transaction(function (tx) {
 
645
        dbResult = tx.executeSql('delete from feed_tag WHERE id=?',
 
646
                                 [id])
 
647
        console.log("feed_tag delete, AFFECTED ROWS: ", dbResult.rowsAffected)
 
648
    })
 
649
    return dbResult
 
650
}
 
651
 
 
652
// delete
 
653
function deleteFeedTagsByTagId(tagId) {
 
654
    var db = openStdDataBase()
 
655
    var dbResult
 
656
    db.transaction(function (tx) {
 
657
        dbResult = tx.executeSql('delete from feed_tag WHERE tag_id=?',
 
658
                                 [tagId])
 
659
        console.log("feed_tag delete, AFFECTED ROWS: ", dbResult.rowsAffected)
 
660
    })
 
661
    return dbResult
 
662
}
 
663
 
 
664
function deleteFeedTag(feedId, tagId)
 
665
{
 
666
    var db = openStdDataBase()
 
667
    var dbResult
 
668
 
 
669
    db.transaction(function(tx) {
 
670
        dbResult = tx.executeSql("DELETE FROM feed_tag WHERE feed_id = ? AND tag_id = ?", [feedId, tagId])
 
671
        console.log("feed_tag delete by feedId and tagId: ", dbResult.rowsAffected)
 
672
    })
 
673
    return dbResult;
 
674
}
 
675
 
 
676
/* operations for testing
 
677
 * include clear and drop operations
 
678
 * not completed yet
 
679
 *
 
680
 */
 
681
// clear
 
682
function clearData(table)
 
683
{
 
684
    var db = openStdDataBase()
 
685
 
 
686
    switch(table)
 
687
    {
 
688
    case "feed":
 
689
        db.transaction(function(tx) {
 
690
            tx.executeSql("delete from feed")
 
691
            console.log("feed clear")
 
692
        })
 
693
        break;
 
694
    case "article":
 
695
        db.transaction(function(tx) {
 
696
            tx.executeSql("delete from article")
 
697
            console.log("article clear")
 
698
        })
 
699
        break;
 
700
    case "tag":
 
701
        db.transaction(function(tx) {
 
702
            tx.executeSql("delete from tag")
 
703
            console.log("tag clear")
 
704
        })
 
705
        break;
 
706
    case "feed_tag":
 
707
        db.transaction(function(tx) {
 
708
            tx.executeSql("delete from feed_tag")
 
709
            console.log("feed_tag clear")
 
710
        })
 
711
        break;
 
712
    case "settings":
 
713
        db.transaction(function(tx) {
 
714
            tx.executeSql("delete from settings")
 
715
            console.log("settings clear")
 
716
        })
 
717
        break;
 
718
    default:
 
719
        db.transaction(function(tx) {
 
720
            tx.executeSql("delete from feed_tag")
 
721
            tx.executeSql("delete from feed")
 
722
            tx.executeSql("delete from tag")
 
723
            tx.executeSql("delete from article")
 
724
            tx.executeSql("delete from settings")
 
725
            console.log("DATABASE clear")
 
726
        })
 
727
    }
 
728
}
 
729
 
 
730
// drop
 
731
function dropTable(table)
 
732
{
 
733
    var db = openStdDataBase()
 
734
 
 
735
    switch(table)
 
736
    {
 
737
    case "feed":
 
738
        db.transaction(function(tx) {
 
739
            tx.executeSql("DROP TABLE IF EXISTS feed")
 
740
            console.log("feed deleted")
 
741
        })
 
742
        break;
 
743
    case "article":
 
744
        db.transaction(function(tx) {
 
745
            tx.executeSql("DROP TABLE IF EXISTS article")
 
746
            console.log("article deleted")
 
747
        })
 
748
        break;
 
749
    case "tag":
 
750
        db.transaction(function(tx) {
 
751
            tx.executeSql("DROP TABLE IF EXISTS tag")
 
752
            console.log("tag deleted")
 
753
        })
 
754
        break;
 
755
    case "feed_tag":
 
756
        db.transaction(function(tx) {
 
757
            tx.executeSql("DROP TABLE IF EXISTS feed_tag")
 
758
            console.log("feed_tag deleted")
 
759
        })
 
760
        break;
 
761
    case "settings":
 
762
        db.transaction(function(tx) {
 
763
            tx.executeSql("DROP TABLE IF EXISTS settings")
 
764
            console.log("settings deleted")
 
765
        })
 
766
        break;
 
767
    default:
 
768
        db.transaction(function(tx) {
 
769
            tx.executeSql("DROP TABLE IF EXISTS feed")
 
770
            tx.executeSql("DROP TABLE IF EXISTS article")
 
771
            tx.executeSql("DROP TABLE IF EXISTS tag")
 
772
            tx.executeSql("DROP TABLE IF EXISTS feed_tag")
 
773
            tx.executeSql("DROP TABLE IF EXISTS settings")
 
774
            console.log("DATABASE deleted")
 
775
        })
 
776
    }
 
777
}