~midori/midori/trunk

« back to all changes in this revision

Viewing changes to midori/midori-bookmarks-db.c

  • Committer: André Auzi
  • Date: 2013-08-05 12:50:34 UTC
  • mto: This revision was merged to the branch mainline in revision 6388.
  • Revision ID: aauzi@free.fr-20130805125034-tyywj27asg4egh3b
prepare to KatzeItem derivation for update-item signals
as a result, all db operations are centralized in midori-bookmarks-db 

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
 See the file COPYING for the full license text.
11
11
*/
12
12
 
13
 
#include "midori-bookmarks.h"
14
 
#include "panels/midori-bookmarks.h"
 
13
#include "midori-bookmarks-db.h"
 
14
 
15
15
#include "midori-app.h"
16
16
#include "midori-array.h"
17
17
#include "sokoke.h"
25
25
    #include <unistd.h>
26
26
#endif
27
27
 
 
28
static gint64
 
29
midori_bookmarks_insert_item_db (sqlite3*   db,
 
30
                                 KatzeItem* item,
 
31
                                 gint64     parentid);
 
32
 
 
33
static gboolean
 
34
midori_bookmarks_update_item_db (sqlite3*   db,
 
35
                                 KatzeItem* item);
 
36
 
 
37
gint64
 
38
midori_bookmarks_insert_item_db (sqlite3*   db,
 
39
                                 KatzeItem* item,
 
40
                                 gint64     parentid)
 
41
{
 
42
    gchar* sqlcmd;
 
43
    char* errmsg = NULL;
 
44
    KatzeItem* old_parent;
 
45
    gchar* new_parentid;
 
46
    gchar* id = NULL;
 
47
    const gchar* uri = NULL;
 
48
    const gchar* desc = NULL;
 
49
    gint64 seq = 0;
 
50
 
 
51
    /* Bookmarks must have a name, import may produce invalid items */
 
52
    g_return_val_if_fail (katze_item_get_name (item), seq);
 
53
 
 
54
    if (!db)
 
55
        return seq;
 
56
 
 
57
    if (katze_item_get_meta_integer (item, "id") > 0)
 
58
        id = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer(item, "id"));
 
59
    else
 
60
        id = g_strdup_printf ("NULL");
 
61
 
 
62
    if (KATZE_ITEM_IS_BOOKMARK (item))
 
63
        uri = katze_item_get_uri (item);
 
64
 
 
65
    if (katze_item_get_text (item))
 
66
        desc = katze_item_get_text (item);
 
67
 
 
68
    /* Use folder, otherwise fallback to parent folder */
 
69
    old_parent = katze_item_get_parent (item);
 
70
    if (parentid > 0)
 
71
        new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, parentid);
 
72
    else if (old_parent && katze_item_get_meta_integer (old_parent, "id") > 0)
 
73
        new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer (old_parent, "id"));
 
74
    else
 
75
        new_parentid = g_strdup_printf ("NULL");
 
76
 
 
77
    sqlcmd = sqlite3_mprintf (
 
78
            "INSERT INTO bookmarks (id, parentid, title, uri, desc, toolbar, app) "
 
79
            "VALUES (%q, %q, '%q', '%q', '%q', %d, %d)",
 
80
            id,
 
81
            new_parentid,
 
82
            katze_item_get_name (item),
 
83
            katze_str_non_null (uri),
 
84
            katze_str_non_null (desc),
 
85
            katze_item_get_meta_boolean (item, "toolbar"),
 
86
            katze_item_get_meta_boolean (item, "app"));
 
87
 
 
88
    if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) == SQLITE_OK)
 
89
    {
 
90
        /* Get insert id */
 
91
        if (g_str_equal (id, "NULL"))
 
92
        {
 
93
            KatzeArray* seq_array;
 
94
 
 
95
            sqlite3_free (sqlcmd);
 
96
            sqlcmd = sqlite3_mprintf (
 
97
                    "SELECT seq FROM sqlite_sequence WHERE name = 'bookmarks'");
 
98
 
 
99
            seq_array = katze_array_from_sqlite (db, sqlcmd);
 
100
            if (katze_array_get_nth_item (seq_array, 0))
 
101
            {
 
102
                KatzeItem* seq_item = katze_array_get_nth_item (seq_array, 0);
 
103
 
 
104
                seq = katze_item_get_meta_integer (seq_item, "seq");
 
105
                katze_item_set_meta_integer (item, "id", seq);
 
106
            }
 
107
            g_object_unref (seq_array);
 
108
        }
 
109
    }
 
110
    else
 
111
    {
 
112
        g_printerr (_("Failed to add bookmark item: %s\n"), errmsg);
 
113
        sqlite3_free (errmsg);
 
114
    }
 
115
 
 
116
    sqlite3_free (sqlcmd);
 
117
    g_free (new_parentid);
 
118
    g_free (id);
 
119
 
 
120
    return seq;
 
121
}
 
122
 
 
123
gboolean
 
124
midori_bookmarks_update_item_db (sqlite3*   db,
 
125
                                 KatzeItem* item)
 
126
{
 
127
    gchar* sqlcmd;
 
128
    char* errmsg = NULL;
 
129
    gchar* parentid;
 
130
    gboolean updated;
 
131
    gchar* id;
 
132
 
 
133
    id = g_strdup_printf ("%" G_GINT64_FORMAT,
 
134
            katze_item_get_meta_integer (item, "id"));
 
135
 
 
136
    if (katze_item_get_meta_integer (item, "parentid") > 0)
 
137
        parentid = g_strdup_printf ("%" G_GINT64_FORMAT,
 
138
                                    katze_item_get_meta_integer (item, "parentid"));
 
139
    else
 
140
        parentid = g_strdup_printf ("NULL");
 
141
 
 
142
    sqlcmd = sqlite3_mprintf (
 
143
            "UPDATE bookmarks SET "
 
144
            "parentid=%q, title='%q', uri='%q', desc='%q', toolbar=%d, app=%d "
 
145
            "WHERE id = %q ;",
 
146
            parentid,
 
147
            katze_item_get_name (item),
 
148
            katze_str_non_null (katze_item_get_uri (item)),
 
149
            katze_str_non_null (katze_item_get_meta_string (item, "desc")),
 
150
            katze_item_get_meta_boolean (item, "toolbar"),
 
151
            katze_item_get_meta_boolean (item, "app"),
 
152
            id);
 
153
 
 
154
    updated = TRUE;
 
155
    if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
 
156
    {
 
157
        updated = FALSE;
 
158
        g_printerr (_("Failed to update bookmark: %s\n"), errmsg);
 
159
        sqlite3_free (errmsg);
 
160
    }
 
161
 
 
162
    sqlite3_free (sqlcmd);
 
163
    g_free (parentid);
 
164
    g_free (id);
 
165
 
 
166
    return updated;
 
167
}
 
168
 
 
169
/**
 
170
 * midori_bookmarks_db_update_item:
 
171
 * @bookmarks: the main bookmark array
 
172
 * @item: #KatzeItem the item to update
 
173
 *
 
174
 * Updates the @item in the bookmark data base.
 
175
 *
 
176
 * Since: 0.5.5
 
177
 **/
 
178
void
 
179
midori_array_update_item (KatzeArray* bookmarks,
 
180
                          KatzeItem* item)
 
181
{
 
182
    g_return_if_fail (KATZE_IS_ARRAY (bookmarks));
 
183
    g_return_if_fail (KATZE_IS_ITEM (item));
 
184
    g_return_if_fail (katze_item_get_meta_string (item, "id"));
 
185
    g_return_if_fail (0 != katze_item_get_meta_integer (item, "id"));
 
186
 
 
187
    sqlite3* db = g_object_get_data (G_OBJECT (bookmarks), "db");
 
188
 
 
189
    g_return_if_fail (db);
 
190
 
 
191
    midori_bookmarks_update_item_db (db, item);
 
192
}
 
193
 
28
194
void
29
195
midori_bookmarks_dbtracer (void*       dummy,
30
196
                           const char* query)
32
198
    g_printerr ("%s\n", query);
33
199
}
34
200
 
35
 
void
 
201
static void
36
202
midori_bookmarks_add_item_cb (KatzeArray* array,
37
203
                              KatzeItem*  item,
38
204
                              sqlite3*    db)
41
207
        katze_item_get_meta_integer (item, "parentid"));
42
208
}
43
209
 
44
 
void
 
210
static void
45
211
midori_bookmarks_remove_item_cb (KatzeArray* array,
46
212
                                 KatzeItem*  item,
47
213
                                 sqlite3*    db)
319
485
    sqlite3_close (db);
320
486
}
321
487
 
 
488
void
 
489
midori_bookmarks_import_array (KatzeArray* bookmarks,
 
490
                               KatzeArray* array,
 
491
                               gint64      parentid)
 
492
{
 
493
    GList* list;
 
494
    KatzeItem* item;
 
495
 
 
496
    if (!bookmarks)
 
497
        return;
 
498
 
 
499
    KATZE_ARRAY_FOREACH_ITEM_L (item, array, list)
 
500
    {
 
501
        katze_item_set_meta_integer (item, "parentid", parentid);
 
502
        katze_array_add_item (bookmarks, item);
 
503
        if (KATZE_IS_ARRAY (item))
 
504
          midori_bookmarks_import_array (bookmarks, KATZE_ARRAY (item),
 
505
                                         katze_item_get_meta_integer(item, "id"));
 
506
    }
 
507
    g_list_free (list);
 
508
}
 
509
 
 
510
/**
 
511
 * midori_array_query_recursive:
 
512
 * @array: the main bookmark array
 
513
 * @fields: comma separated list of fields
 
514
 * @condition: condition, like "folder = '%q'"
 
515
 * @value: a value to be inserted if @condition contains %q
 
516
 * @recursive: if %TRUE include children
 
517
 *
 
518
 * Stores the result in a #KatzeArray.
 
519
 *
 
520
 * Return value: a #KatzeArray on success, %NULL otherwise
 
521
 *
 
522
 * Since: 0.4.4
 
523
 **/
 
524
KatzeArray*
 
525
midori_array_query_recursive (KatzeArray*  bookmarks,
 
526
                              const gchar* fields,
 
527
                              const gchar* condition,
 
528
                              const gchar* value,
 
529
                              gboolean     recursive)
 
530
{
 
531
    sqlite3* db;
 
532
    gchar* sqlcmd;
 
533
    char* sqlcmd_value;
 
534
    KatzeArray* array;
 
535
    KatzeItem* item;
 
536
    GList* list;
 
537
 
 
538
    g_return_val_if_fail (KATZE_IS_ARRAY (bookmarks), NULL);
 
539
    g_return_val_if_fail (fields, NULL);
 
540
    g_return_val_if_fail (condition, NULL);
 
541
    db = g_object_get_data (G_OBJECT (bookmarks), "db");
 
542
    g_return_val_if_fail (db != NULL, NULL);
 
543
 
 
544
    sqlcmd = g_strdup_printf ("SELECT %s FROM bookmarks WHERE %s "
 
545
                              "ORDER BY (uri='') ASC, title DESC", fields, condition);
 
546
    if (strstr (condition, "%q"))
 
547
    {
 
548
        sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : "");
 
549
        array = katze_array_from_sqlite (db, sqlcmd_value);
 
550
        sqlite3_free (sqlcmd_value);
 
551
    }
 
552
    else
 
553
        array = katze_array_from_sqlite (db, sqlcmd);
 
554
    g_free (sqlcmd);
 
555
 
 
556
    if (!recursive)
 
557
        return array;
 
558
 
 
559
    KATZE_ARRAY_FOREACH_ITEM_L (item, array, list)
 
560
    {
 
561
        if (KATZE_ITEM_IS_FOLDER (item))
 
562
        {
 
563
            gchar* parentid = g_strdup_printf ("%" G_GINT64_FORMAT,
 
564
                                               katze_item_get_meta_integer (item, "id"));
 
565
            KatzeArray* subarray = midori_array_query_recursive (bookmarks,
 
566
                                                                 fields, "parentid=%q", parentid, TRUE);
 
567
            KatzeItem* subitem;
 
568
            GList* sublist;
 
569
 
 
570
            KATZE_ARRAY_FOREACH_ITEM_L (subitem, subarray, sublist)
 
571
            {
 
572
                katze_array_add_item (KATZE_ARRAY (item), subitem);
 
573
            }
 
574
 
 
575
            g_object_unref (subarray);
 
576
            g_free (parentid);
 
577
        }
 
578
    }
 
579
    g_list_free (list);
 
580
    return array;
 
581
}
 
582
 
 
583
static gint64
 
584
count_from_sqlite (sqlite3*     db,
 
585
                   const gchar* sqlcmd)
 
586
{
 
587
    gint64 count = -1;
 
588
    sqlite3_stmt* stmt;
 
589
    gint result;
 
590
    
 
591
    result = sqlite3_prepare_v2 (db, sqlcmd, -1, &stmt, NULL);
 
592
    if (result != SQLITE_OK)
 
593
        return -1;
 
594
 
 
595
    g_assert (sqlite3_column_count (stmt) == 1);
 
596
    
 
597
    if ((result = sqlite3_step (stmt)) == SQLITE_ROW)
 
598
        count = sqlite3_column_int64(stmt, 0);
 
599
 
 
600
    sqlite3_clear_bindings (stmt);
 
601
    sqlite3_reset (stmt);
 
602
 
 
603
    return count;
 
604
}
 
605
 
 
606
static gint64
 
607
midori_array_count_recursive_by_id (KatzeArray*  bookmarks,
 
608
                                    const gchar* condition,
 
609
                                    const gchar* value,
 
610
                                    gint64       id,
 
611
                                    gboolean     recursive)
 
612
{
 
613
    gint64 count = -1;
 
614
    sqlite3* db;
 
615
    gchar* sqlcmd;
 
616
    char* sqlcmd_value;
 
617
    sqlite3_stmt* stmt;
 
618
    gint result;
 
619
    GList* ids;
 
620
    GList* iter_ids;
 
621
 
 
622
    g_return_val_if_fail (condition, -1);
 
623
    g_return_val_if_fail (KATZE_IS_ARRAY (bookmarks), -1);
 
624
    db = g_object_get_data (G_OBJECT (bookmarks), "db");
 
625
    g_return_val_if_fail (db != NULL, -1);
 
626
 
 
627
    g_assert(!strstr("parentid", condition));
 
628
 
 
629
    if (id > 0)
 
630
        sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks "
 
631
                                  "WHERE parentid = %" G_GINT64_FORMAT " AND %s",
 
632
                                  id,
 
633
                                  condition);
 
634
    else
 
635
        sqlcmd = g_strdup_printf ("SELECT COUNT(*) FROM bookmarks "
 
636
                                  "WHERE parentid IS NULL AND %s ",
 
637
                                  condition);
 
638
 
 
639
    if (strstr (condition, "%q"))
 
640
    {
 
641
        sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : "");
 
642
        count = count_from_sqlite (db, sqlcmd_value);
 
643
        sqlite3_free (sqlcmd_value);
 
644
    }
 
645
    else
 
646
        count = count_from_sqlite (db, sqlcmd);
 
647
 
 
648
    g_free (sqlcmd);
 
649
 
 
650
    if (!recursive || (count < 0))
 
651
        return count;
 
652
 
 
653
    ids = NULL;
 
654
 
 
655
    if (id > 0)
 
656
        sqlcmd_value = sqlite3_mprintf (
 
657
            "SELECT id FROM bookmarks "
 
658
            "WHERE parentid = %" G_GINT64_FORMAT " AND uri = ''", id);
 
659
    else
 
660
        sqlcmd_value = sqlite3_mprintf (
 
661
            "SELECT id FROM bookmarks "
 
662
            "WHERE parentid IS NULL AND uri = ''");
 
663
 
 
664
    if (sqlite3_prepare_v2 (db, sqlcmd_value, -1, &stmt, NULL) == SQLITE_OK)
 
665
    {
 
666
        g_assert (sqlite3_column_count (stmt) == 1);
 
667
    
 
668
        if ((result = sqlite3_step (stmt)) == SQLITE_ROW)
 
669
        {
 
670
            gint64* pid = g_new (gint64, 1);
 
671
            
 
672
            *pid = sqlite3_column_int64(stmt, 0);
 
673
            ids = g_list_append (ids, pid);
 
674
        }
 
675
        
 
676
        sqlite3_clear_bindings (stmt);
 
677
        sqlite3_reset (stmt);
 
678
    }
 
679
 
 
680
    sqlite3_free (sqlcmd_value);
 
681
 
 
682
    iter_ids = ids;
 
683
    while (iter_ids)
 
684
    {
 
685
        gint64 sub_count = midori_array_count_recursive_by_id (bookmarks,
 
686
                                                               condition,
 
687
                                                               value,
 
688
                                                               *(gint64*)(iter_ids->data),
 
689
                                                               recursive);
 
690
        
 
691
        if (sub_count < 0)
 
692
        {
 
693
            g_list_free_full (ids, g_free);
 
694
            return -1;
 
695
        }
 
696
        
 
697
        count += sub_count;
 
698
        iter_ids = g_list_next (iter_ids);
 
699
    }
 
700
        
 
701
    g_list_free_full (ids, g_free);
 
702
    return count;
 
703
}
 
704
 
 
705
/**
 
706
 * midori_array_count_recursive:
 
707
 * @array: the main bookmark array
 
708
 * @condition: condition, like "folder = '%q'"
 
709
 * @value: a value to be inserted if @condition contains %q
 
710
 * @recursive: if %TRUE include children
 
711
 *
 
712
 * Return value: the number of elements on success, -1 otherwise
 
713
 *
 
714
 * Since: 0.5.2
 
715
 **/
 
716
gint64
 
717
midori_array_count_recursive (KatzeArray*  bookmarks,
 
718
                              const gchar* condition,
 
719
                              const gchar* value,
 
720
                              KatzeItem*   folder,
 
721
                              gboolean     recursive)
 
722
{
 
723
    gint64 id = -1;
 
724
 
 
725
    g_return_val_if_fail (!folder || KATZE_ITEM_IS_FOLDER (folder), -1);
 
726
    
 
727
    id = folder ? katze_item_get_meta_integer (folder, "id") : 0;
 
728
 
 
729
    return midori_array_count_recursive_by_id (bookmarks, condition,
 
730
                                               value, id,
 
731
                                               recursive);
 
732
}