forked from WiseLibs/better-sqlite3
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmeta.c
More file actions
125 lines (104 loc) · 3.84 KB
/
Copy pathmeta.c
File metadata and controls
125 lines (104 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "meta.h"
#include "debug.h"
#include <sqlite3.h>
#include <stddef.h>
#include <string.h>
#define META_DEFAULT_TABLE_NAME "TableMeta"
// if last updated time < database update time, return nDate, otherwise 0
int meta_needs_update(sqlite3 *pDb, const char *zName, int nLastUpdate,
int *pnDate, const char *zTableName) {
int rc = SQLITE_OK;
sqlite3_stmt *pStmt;
int nRet = 0;
if (zTableName == NULL) {
zTableName = (const char *)META_DEFAULT_TABLE_NAME;
}
const char *zStatementTemplate = "SELECT ? < date AS needs_update, date "
"FROM %s "
"WHERE name = ?;";
// Add +1 for null terminator, -2 for removing %s replacement.
const size_t nStatementLength =
strlen(zStatementTemplate) + strlen(zTableName) - 1;
char *zStatementSql = (char *)sqlite3_malloc((int)nStatementLength);
if (zStatementSql == NULL) {
rc = SQLITE_NOMEM;
log_error("[meta] Unable to allocate prepared statement string\n");
} else {
sqlite3_snprintf((int)nStatementLength, zStatementSql, zStatementTemplate,
zTableName);
log_debug("[meta] Running SQL \"%s\"\n", zStatementSql);
rc = sqlite3_prepare_v2(pDb, zStatementSql, (int)nStatementLength, &pStmt,
NULL);
if (rc != SQLITE_OK) {
log_error("[meta] Failed to prepare statement: %s\n",
sqlite3_errmsg(pDb));
sqlite3_free(zStatementSql);
return rc;
}
rc = sqlite3_bind_int(pStmt, 1, nLastUpdate);
if (rc != SQLITE_OK) {
log_error("[meta] Failed to bind date value to prepared statement: %s\n",
sqlite3_errmsg(pDb));
sqlite3_finalize(pStmt);
sqlite3_free(zStatementSql);
return rc;
}
rc = sqlite3_bind_text(pStmt, 2, zName, -1, SQLITE_STATIC);
if (rc != SQLITE_OK) {
log_error("[meta] Failed to bind name value to prepared statement: %s\n",
sqlite3_errmsg(pDb));
sqlite3_finalize(pStmt);
sqlite3_free(zStatementSql);
return rc;
}
rc = sqlite3_step(pStmt);
if (rc == SQLITE_ROW) {
int bNeedsUpdate = sqlite3_column_int(pStmt, 0);
if (bNeedsUpdate == 1) {
nRet = sqlite3_column_int(pStmt, 1);
log_debug("[meta] Got new timestamp %d from database for %s\n", nRet,
zName);
}
}
rc = sqlite3_finalize(pStmt);
if (rc != SQLITE_OK) {
log_error("[meta] Failed to run prepared statement: %s\n",
sqlite3_errmsg(pDb));
sqlite3_free(zStatementSql);
return rc;
}
sqlite3_free(zStatementSql);
}
*pnDate = nRet;
return rc;
}
int meta_create_table(sqlite3 *pDb, const char *zTableName) {
int rc = SQLITE_OK;
if (zTableName == NULL) {
zTableName = (const char *)META_DEFAULT_TABLE_NAME;
}
const char *zStatementTemplate = "CREATE TABLE IF NOT EXISTS %s ("
" name TEXT NOT NULL, "
" date INTEGER NOT NULL, "
" PRIMARY KEY (name)"
");";
// Add +1 for null terminator, -2 for removing %s replacement.
const size_t nStatementLength =
strlen(zStatementTemplate) + strlen(zTableName) - 1;
char *zStatementSql = (char *)sqlite3_malloc((int)nStatementLength);
if (zStatementSql == NULL) {
rc = SQLITE_NOMEM;
} else {
sqlite3_snprintf((int)nStatementLength, zStatementSql, zStatementTemplate,
zTableName);
log_debug("[meta] Running SQL \"%s\"\n", zStatementSql);
rc = sqlite3_exec(pDb, zStatementSql, NULL, NULL, NULL);
sqlite3_free(zStatementSql);
}
if (rc != SQLITE_OK) {
log_error("[meta] Failed to execute statement: %s\n", sqlite3_errmsg(pDb));
} else {
log_debug("[meta] Created table \"%s\"\n", zTableName);
}
return rc;
}