11 static const char db_engine_
[] = "sqlite3";
13 struct prepared_statement
{
14 const char *statement_name
;
15 const char *arguments
;
17 sqlite3_stmt
*statement
;
18 } prepared_statements
[] = {
19 { "begin_transaction", "", "BEGIN TRANSACTION", NULL
},
20 { "end_transaction", "", "END TRANSACTION", NULL
},
21 { "vacuum", "", "VACUUM", NULL
},
22 { "uid_from_name", "s", "SELECT uid FROM uid_name WHERE name = ?", NULL
},
23 { NULL
, NULL
, NULL
, NULL
}
26 enum prepared_statement_enums
{
35 * pre-prepare all queries used
38 db_init_all_statements_(sqlite3
*db
)
40 struct prepared_statement
*s
;
43 for (s
= prepared_statements
; s
->statement_name
; s
++) {
44 r
= sqlite3_prepare_v2(db
, s
->query
, -1, &s
->statement
, NULL
);
46 NOTIFY_ERROR("%s('%s'):%d:%s", "sqlite3_prepare_v2", s
->statement_name
, r
, sqlite3_errmsg(db
));
55 * finalize all queries used
58 db_finalize_all_statements_(sqlite3
*db
)
60 struct prepared_statement
*s
;
63 for (s
= prepared_statements
; s
->statement_name
; s
++) {
65 r
= sqlite3_finalize(s
->statement
);
67 NOTIFY_ERROR("%s('%s'):%d:%s", "sqlite3_finalize", s
->statement_name
, r
, sqlite3_errmsg(db
));
83 return sqlite3_libversion();
91 db_init(struct database
*db
, struct database_options
*db_opts
)
95 /* Ensure sqlite header matches library. */
96 assert(sqlite3_libversion_number() == SQLITE_VERSION_NUMBER
);
97 assert(strncmp(sqlite3_sourceid(), SQLITE_SOURCE_ID
, 80) == 0);
98 assert(strcmp(sqlite3_libversion(), SQLITE_VERSION
) == 0);
100 r
= sqlite3_open_v2(db_opts
->db_file
, &db
->db
, SQLITE_OPEN_READWRITE
, NULL
);
101 if (r
!= SQLITE_OK
) {
102 NOTIFY_ERROR("error opening %s '%s': %s", "db_file", db_opts
->db_file
, sqlite3_errmsg(db
->db
));
106 if (db_init_all_statements_(db
->db
)) {
107 NOTIFY_ERROR("%s:%s", "db_init_all_statements", "failed");
118 db_fini(struct database
*db
)
122 db_finalize_all_statements_(db
->db
);
123 r
= sqlite3_close(db
->db
);
124 if (r
!= SQLITE_OK
) {
125 NOTIFY_ERROR("%s:%s", "sqlite3_close", sqlite3_errmsg(db
->db
));
131 * given a string, returns the uid which matches
134 db_uid_from_name(struct database
*db
, unsigned char *name
, int *uid
)
136 struct prepared_statement
*ps
= &prepared_statements
[PS_UID_FROM_NAME
];
140 r
= sqlite3_bind_text(ps
->statement
, 1, (char *)name
, -1, SQLITE_TRANSIENT
);
141 if (r
!= SQLITE_OK
) {
142 NOTIFY_ERROR("%s('%s'):%d:%s", "sqlite3_bind_text", name
, r
, sqlite3_errmsg(db
->db
));
147 r
= sqlite3_step(ps
->statement
);
148 if (r
== SQLITE_ROW
) {
150 NOTIFY_ERROR("%s:%s", "internal db error", "multiple uids for name");
152 *uid
= sqlite3_column_int(ps
->statement
, 0);
156 if (SQLITE_INTEGER
!= sqlite3_column_type(ps
->statement
, 0)) {
157 NOTIFY_ERROR("%s:%s", "internal db error", "uid is not an integer");
162 } while (r
== SQLITE_ROW
|| r
== SQLITE_BUSY
);
164 if (r
!= SQLITE_DONE
) {
165 NOTIFY_ERROR("%s('%s'):%d:%s", "sqlite3_step", name
, r
, sqlite3_errmsg(db
->db
));
169 r
= sqlite3_reset(ps
->statement
);
170 if (r
!= SQLITE_OK
) {
171 NOTIFY_ERROR("%s('%s'):%d:%s", "sqlite3_reset", name
, r
, sqlite3_errmsg(db
->db
));
173 r
= sqlite3_clear_bindings(ps
->statement
);
174 if (r
!= SQLITE_OK
) {
175 NOTIFY_ERROR("%s('%s'):%d:%s", "sqlite3_clear_bindings", name
, r
, sqlite3_errmsg(db
->db
));