#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <unistd.h>
#include <sqlite3.h>
#include "config.h"
#include "util.h"
#include "logging.h"
#include "watch_database.h"
#include "path_utils.h"
Go to the source code of this file.
Classes | |
struct | path_info_iter_context_t |
Private internal context used to iterate over the set of lwatch_path_info_t structs returned by a watch database query. More... | |
Defines | |
#define | _GNU_SOURCE |
Turn on GNU extensions. | |
#define | COLUMNS_STRING "path, original_path, flags, version, reap_time, reap_position, dev, inode, mode, uid, gid, size, access_time, modification_time, change_time" |
The column names for lwatch_event_t persistent storage. | |
Column indices for lwatch_event_t persistent storage. | |
#define | PATH_COLUMN 0 |
lwatch_event_t column index for "path" | |
#define | ORIGINAL_PATH_COLUMN 1 |
lwatch_event_t column index for "original_path" | |
#define | FLAGS_COLUMN 2 |
lwatch_event_t column index for "flags" | |
#define | VERSION_COLUMN 3 |
lwatch_event_t column index for "version" | |
#define | REAP_TIME_COLUMN 4 |
lwatch_event_t column index for "reap_time" | |
#define | REAP_POSITION_COLUMN 5 |
lwatch_event_t column index for "reap_position" | |
#define | DEV_COLUMN 6 |
lwatch_event_t column index for "dev" | |
#define | INODE_COLUMN 7 |
lwatch_event_t column index for "inode" | |
#define | MODE_COLUMN 8 |
lwatch_event_t column index for "mode" | |
#define | UID_COLUMN 9 |
lwatch_event_t column index for "uid" | |
#define | GID_COLUMN 10 |
lwatch_event_t column index for "gid" | |
#define | SIZE_COLUMN 11 |
lwatch_event_t column index for "size" | |
#define | ACCESS_TIME_COLUMN 12 |
lwatch_event_t column index for "access_time" | |
#define | MODIFICATION_TIME_COLUMN 13 |
lwatch_event_t column index for "modification_time" | |
#define | CHANGE_TIME_COLUMN 14 |
lwatch_event_t column index for "change_time" | |
Functions | |
static const char * | sqlite3_result_string (int result) |
Translate a SQLite result code to a string. | |
static int | table_exists (const char *table_name, bool *exists) |
Set variable to true if specified table exists in SQLite database. | |
static int | create_table (const char *table_name, const char *table_schema) |
Create a new SQLite table in the database using supplied schema. | |
static int | populate_path_info (struct lwatch_path_info_t *path_info, sqlite3_stmt *stmt) |
Copy the data from a SQLite query result into a lwatch_path_info_t struct. | |
static struct lwatch_path_info_t * | path_info_iter_next (struct path_info_iter_context_t *iter) |
Used to iterate through SQLite query result of lwatch_path_info_t structs. | |
static int | new_path_info_iter_context (struct path_info_iter_context_t **iter_arg) |
Allocate and initialize a new path_info iteration context. | |
static int | init_statement (struct sqlite3_stmt **stmt_arg, const char *fmt,...) |
Create a SQLite prepared statement from printf style arguments. | |
static int | destroy_statement (sqlite3_stmt **stmt_arg) |
Destroy a SQLite prepared statement. | |
static int | reset_statement (sqlite3_stmt *stmt) |
Resets a prepared statement readying it for parameter binding and execution. | |
int | database_write_path_info (struct lwatch_path_info_t *path_info) |
Write the supplied lwatch_path_info_t struct into the database. | |
int | init_path_info (struct lwatch_path_info_t *path_info, const char *path) |
Initialize a lwatch_path_info_t struct. | |
int | new_path_info (const char *path, struct lwatch_path_info_t **path_info_arg) |
Allocate and initialize a new lwatch_path_info_t struct. | |
char * | path_info_flags_string (unsigned long flag, const char *separator) |
Render the lwatch_path_info_t flag bitset as a string. | |
char * | path_info_string (struct lwatch_path_info_t *path_info, const char *prefix) |
Render a lwatch_path_info_t struct as a string. | |
const char * | watch_database_error_string (int error) |
Render a database error code as a string. | |
int | watch_database_init () |
Initialize the watch database subsystem. | |
int | watch_database_fini () |
Close the watch database subsystem, release all resources, close database. | |
int | database_lookup_path_info (const char *path, struct lwatch_path_info_t *path_info) |
Given a path name lookup the matching lwatch_path_info_t in the database. | |
int | database_query_all_paths_iter (struct database_iter_context_t **iter_arg, const char *path_filter_arg) |
Get an iterator to every lwatch_path_info_t row in the database. | |
int | database_query_backups_iter (struct database_iter_context_t **iter_arg) |
Get an iterator to every lwatch_path_info_t row in the database which is a backup to a primary file. | |
int | database_query_backups_of_target_iter (struct database_iter_context_t **iter_arg, const char *path) |
Get an iterator to each lwatch_path_info_t row in the database which is a backup to the specified primary file. | |
int | database_query_pending_reaps_iter (struct database_iter_context_t **iter_arg) |
Get an iterator to every lwatch_path_info_t row which has a reap pending. | |
int | database_query_targets_iter (struct database_iter_context_t **iter_arg) |
Get an iterator to every lwatch_path_info_t row which is a primary watch file, i.e. | |
Variables | |
static const char * | lwatch_table_schema |
SQLSchema used to store lwatch_path_info_t persistently. | |
static char | watch_database_pathname [PATH_MAX] = WATCH_DATABASE_PATHNAME |
The pathname of the SQLite database. | |
static sqlite3 * | database_handle = NULL |
The handle to the open SQLite database. | |
SQLite Prepared Statements | |
All of these variable are handles to prepared statements which are compiled at initialization time and can be invoked more efficiently due to their precompilation. | |
sqlite3_stmt * | table_exists_stmt = NULL |
test if a table exists in the database | |
sqlite3_stmt * | lookup_path_stmt = NULL |
lookup single lwatch_path_info_t using the path field as key | |
sqlite3_stmt * | insert_path_stmt = NULL |
insert lwatch_path_info_t into database | |
sqlite3_stmt * | query_all_stmt = NULL |
lookup multiple lwatch_path_info_t by matching path field with wildcards | |
sqlite3_stmt * | query_backups_stmt = NULL |
lookup multiple lwatch_path_info_t which have the BACKUP_FLAG set | |
sqlite3_stmt * | query_backups_of_target_stmt = NULL |
lookup multiple lwatch_path_info_t which are backups of a primary target | |
sqlite3_stmt * | query_pending_reaps_stmt = NULL |
lookup multiple lwatch_path_info_t which have the NEEDS_REAPING_FLAG set, i.e. | |
sqlite3_stmt * | query_targets_stmt = NULL |
lookup multiple lwatch_path_info_t which have the TARGET_FLAG set, i.e. |
Definition in file watch_database.c.
static int create_table | ( | const char * | table_name, | |
const char * | table_schema | |||
) | [static] |
Create a new SQLite table in the database using supplied schema.
[in] | table_name | The name of the table to create. |
[in] | table_schema | String containing the SQLite schema for the table. |
Definition at line 390 of file watch_database.c.
Referenced by watch_database_init().
00391 { 00392 int result, sql_result; 00393 char *statement; 00394 char *err_msg; 00395 00396 result = SUCCESS; 00397 00398 if (asprintf(&statement, "create table %s (%s);", table_name, table_schema) < 0) { 00399 log_msg(LOG_ERROR, _("cannot create statement string\n")); 00400 return ENOMEM; 00401 } 00402 00403 if ((sql_result = sqlite3_exec(database_handle, statement, NULL, NULL, &err_msg)) != SQLITE_OK) { 00404 log_msg(LOG_ERROR, _("sqlite3_exec \"%s\", failed with error %d (%s)\n"), statement, sql_result, err_msg); 00405 sqlite3_free(err_msg); 00406 result = WATCH_DATABASE_ERROR_CANNOT_CREATE_TABLE; 00407 } 00408 00409 free(statement); 00410 00411 return result; 00412 }
int database_lookup_path_info | ( | const char * | path, | |
struct lwatch_path_info_t * | path_info | |||
) |
Given a path name lookup the matching lwatch_path_info_t in the database.
[in] | path | Path Name whose lwatch_path_info_t we seek |
[out] | path_info | Pointer to lwatch_path_info_t which will be initialized from the database upon success. |
Definition at line 968 of file watch_database.c.
Referenced by get_create_path_info(), process_file_close(), process_file_create(), process_file_delete(), process_file_modification(), and process_file_rename().
00969 { 00970 int error, result, step_result; 00971 int n_rows; 00972 00973 result = SUCCESS; 00974 00975 if ((error = reset_statement(lookup_path_stmt)) != SUCCESS) { 00976 result = WATCH_DATABASE_ERROR_CANNOT_QUERY; 00977 goto exit; 00978 } 00979 00980 if ((error = sqlite3_bind_text(lookup_path_stmt, 1, path, -1, SQLITE_TRANSIENT)) != SQLITE_OK) { 00981 const char *err_msg = sqlite3_errmsg(database_handle); 00982 log_msg(LOG_ERROR, _("sqlite3_bind_text \"%s\", (%s)\n"), sqlite3_sql(lookup_path_stmt), err_msg); 00983 result = WATCH_DATABASE_ERROR_CANNOT_QUERY; 00984 goto exit; 00985 } 00986 00987 n_rows = 0; 00988 while(true) { 00989 step_result = sqlite3_step(lookup_path_stmt); 00990 if (step_result == SQLITE_DONE) { 00991 break; 00992 } else if (step_result == SQLITE_ROW) { 00993 if (n_rows == 0) { 00994 if ((error = populate_path_info(path_info, lookup_path_stmt)) != SUCCESS) { 00995 log_msg(LOG_ERROR, _("populate_path_info() failed for path \"%s\" (%s)"), 00996 path, error_string(error)); 00997 result = error; 00998 } 00999 } 01000 n_rows++; 01001 } else { 01002 const char *err_msg = sqlite3_errmsg(database_handle); 01003 log_msg(LOG_ERROR, _("sqlite3_step \"%s\", unexpected result %s (%s)\n"), 01004 sqlite3_sql(lookup_path_stmt), sqlite3_result_string(step_result), err_msg); 01005 } 01006 } 01007 01008 exit: 01009 if (result == SUCCESS) { 01010 if (n_rows == 0) 01011 result = WATCH_DATABASE_ERROR_NOT_FOUND; 01012 else if (n_rows > 1) 01013 result = WATCH_DATABASE_ERROR_FOUND_MULTIPLE; 01014 } 01015 return result; 01016 }
int database_query_all_paths_iter | ( | struct database_iter_context_t ** | iter_arg, | |
const char * | path_filter_arg | |||
) |
Get an iterator to every lwatch_path_info_t row in the database.
[out] | iter_arg | Iterator context returned here, NULL if failure |
[in] | path_filter_arg | SQL "like" wildcard pattern, path must match this pattern to be included in result set. If NULL then no filtering is performed, all paths will match. |
Definition at line 1028 of file watch_database.c.
Referenced by dump_database().
01029 { 01030 int error; 01031 struct path_info_iter_context_t *iter; 01032 const char *path_filter; 01033 01034 *iter_arg = NULL; 01035 if ((error = new_path_info_iter_context(&iter)) != SUCCESS) { 01036 log_msg(LOG_ERROR, _("cannot allocate new iteration context (%s)\n"), error_string(error)); 01037 return error; 01038 } 01039 01040 iter->stmt = query_all_stmt; 01041 01042 if ((iter->iter.error = reset_statement(iter->stmt)) != SQLITE_OK) { 01043 free(iter); 01044 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 01045 } 01046 01047 if (path_filter_arg == NULL) 01048 path_filter = "%"; 01049 else 01050 path_filter = path_filter_arg; 01051 01052 if ((iter->iter.error = sqlite3_bind_text(iter->stmt, 1, path_filter, -1, SQLITE_TRANSIENT)) != SQLITE_OK) { 01053 const char *err_msg = sqlite3_errmsg(database_handle); 01054 log_msg(LOG_ERROR, _("sqlite3_bind_text \"%s\", (%s)\n"), sqlite3_sql(iter->stmt), err_msg); 01055 free(iter); 01056 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 01057 } 01058 01059 *iter_arg = (struct database_iter_context_t *)iter; 01060 return SUCCESS; 01061 }
int database_query_backups_iter | ( | struct database_iter_context_t ** | iter_arg | ) |
Get an iterator to every lwatch_path_info_t row in the database which is a backup to a primary file.
[out] | iter_arg | Iterator context returned here, NULL if failure |
Definition at line 1070 of file watch_database.c.
Referenced by validate_backups_in_database().
01071 { 01072 int error; 01073 struct path_info_iter_context_t *iter; 01074 01075 *iter_arg = NULL; 01076 if ((error = new_path_info_iter_context(&iter)) != SUCCESS) { 01077 log_msg(LOG_ERROR, _("cannot allocate new iteration context (%s)\n"), error_string(error)); 01078 return error; 01079 } 01080 01081 iter->stmt = query_backups_stmt; 01082 01083 if ((iter->iter.error = reset_statement(iter->stmt)) != SQLITE_OK) { 01084 free(iter); 01085 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 01086 } 01087 01088 *iter_arg = (struct database_iter_context_t *)iter; 01089 return SUCCESS; 01090 }
int database_query_backups_of_target_iter | ( | struct database_iter_context_t ** | iter_arg, | |
const char * | path | |||
) |
Get an iterator to each lwatch_path_info_t row in the database which is a backup to the specified primary file.
[out] | iter_arg | Iterator context returned here, NULL if failure |
[in] | path | The path name of the primary file whose backup's are sought |
Definition at line 1100 of file watch_database.c.
Referenced by dump_database().
01101 { 01102 int error; 01103 struct path_info_iter_context_t *iter; 01104 01105 *iter_arg = NULL; 01106 if ((error = new_path_info_iter_context(&iter)) != SUCCESS) { 01107 log_msg(LOG_ERROR, _("cannot allocate new iteration context (%s)\n"), error_string(error)); 01108 return error; 01109 } 01110 01111 iter->stmt = query_backups_of_target_stmt; 01112 01113 if ((iter->iter.error = reset_statement(iter->stmt)) != SQLITE_OK) { 01114 free(iter); 01115 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 01116 } 01117 01118 if ((iter->iter.error = sqlite3_bind_text(iter->stmt, 1, path, -1, SQLITE_TRANSIENT)) != SQLITE_OK) { 01119 const char *err_msg = sqlite3_errmsg(database_handle); 01120 log_msg(LOG_ERROR, _("sqlite3_bind_text \"%s\", (%s)\n"), sqlite3_sql(iter->stmt), err_msg); 01121 free(iter); 01122 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 01123 } 01124 01125 *iter_arg = (struct database_iter_context_t *)iter; 01126 return SUCCESS; 01127 }
int database_query_pending_reaps_iter | ( | struct database_iter_context_t ** | iter_arg | ) |
Get an iterator to every lwatch_path_info_t row which has a reap pending.
[out] | iter_arg | Iterator context returned here, NULL if failure |
Definition at line 1135 of file watch_database.c.
Referenced by process_pending_reaps().
01136 { 01137 int error; 01138 struct path_info_iter_context_t *iter; 01139 01140 *iter_arg = NULL; 01141 if ((error = new_path_info_iter_context(&iter)) != SUCCESS) { 01142 log_msg(LOG_ERROR, _("cannot allocate new iteration context (%s)\n"), error_string(error)); 01143 return error; 01144 } 01145 01146 iter->stmt = query_pending_reaps_stmt; 01147 01148 if ((iter->iter.error = reset_statement(iter->stmt)) != SQLITE_OK) { 01149 free(iter); 01150 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 01151 } 01152 01153 *iter_arg = (struct database_iter_context_t *)iter; 01154 return SUCCESS; 01155 }
int database_query_targets_iter | ( | struct database_iter_context_t ** | iter_arg | ) |
Get an iterator to every lwatch_path_info_t row which is a primary watch file, i.e.
a "target".
[out] | iter_arg | Iterator context returned here, NULL if failure |
Definition at line 1164 of file watch_database.c.
01165 { 01166 int error; 01167 struct path_info_iter_context_t *iter; 01168 01169 *iter_arg = NULL; 01170 if ((error = new_path_info_iter_context(&iter)) != SUCCESS) { 01171 log_msg(LOG_ERROR, _("cannot allocate new iteration context (%s)\n"), error_string(error)); 01172 return error; 01173 } 01174 01175 iter->stmt = query_targets_stmt; 01176 01177 if ((iter->iter.error = reset_statement(iter->stmt)) != SQLITE_OK) { 01178 free(iter); 01179 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 01180 } 01181 01182 *iter_arg = (struct database_iter_context_t *)iter; 01183 return SUCCESS; 01184 }
int database_write_path_info | ( | struct lwatch_path_info_t * | path_info | ) |
Write the supplied lwatch_path_info_t struct into the database.
[in] | path_info | The lwatch_path_info_t to write into the database |
Definition at line 523 of file watch_database.c.
Referenced by get_create_path_info(), process_file_close(), process_file_delete(), process_file_modification(), process_file_rename(), reap_file_data(), start_monitoring(), update_stat_info_and_write(), and validate_backups_in_database().
00524 { 00525 int error, result, step_result; 00526 00527 result = SUCCESS; 00528 00529 if ((error = reset_statement(insert_path_stmt)) != SUCCESS) { 00530 result = WATCH_DATABASE_ERROR_CANNOT_QUERY; 00531 goto exit; 00532 } 00533 00534 00535 if ((error = sqlite3_bind_text(insert_path_stmt, PATH_COLUMN + 1, path_info->path, -1, SQLITE_TRANSIENT)) 00536 != SQLITE_OK) goto bind_error; 00537 if ((error = sqlite3_bind_text(insert_path_stmt, ORIGINAL_PATH_COLUMN + 1, path_info->original_path, -1, SQLITE_TRANSIENT)) 00538 != SQLITE_OK) goto bind_error; 00539 if ((error = sqlite3_bind_int64(insert_path_stmt, FLAGS_COLUMN + 1, path_info->flags)) 00540 != SQLITE_OK) goto bind_error; 00541 if ((error = sqlite3_bind_int64(insert_path_stmt, VERSION_COLUMN + 1, path_info->version)) 00542 != SQLITE_OK) goto bind_error; 00543 if ((error = sqlite3_bind_int64(insert_path_stmt, REAP_TIME_COLUMN + 1, path_info->reap_time)) 00544 != SQLITE_OK) goto bind_error; 00545 if ((error = sqlite3_bind_int64(insert_path_stmt, REAP_POSITION_COLUMN + 1, path_info->reap_position)) 00546 != SQLITE_OK) goto bind_error; 00547 if ((error = sqlite3_bind_int64(insert_path_stmt, DEV_COLUMN + 1, path_info->dev)) 00548 != SQLITE_OK) goto bind_error; 00549 if ((error = sqlite3_bind_int64(insert_path_stmt, INODE_COLUMN + 1, path_info->inode)) 00550 != SQLITE_OK) goto bind_error; 00551 if ((error = sqlite3_bind_int64(insert_path_stmt, MODE_COLUMN + 1, path_info->mode)) 00552 != SQLITE_OK) goto bind_error; 00553 if ((error = sqlite3_bind_int64(insert_path_stmt, UID_COLUMN + 1, path_info->uid)) 00554 != SQLITE_OK) goto bind_error; 00555 if ((error = sqlite3_bind_int64(insert_path_stmt, GID_COLUMN + 1, path_info->gid)) 00556 != SQLITE_OK) goto bind_error; 00557 if ((error = sqlite3_bind_int64(insert_path_stmt, SIZE_COLUMN + 1, path_info->size)) 00558 != SQLITE_OK) goto bind_error; 00559 if ((error = sqlite3_bind_int64(insert_path_stmt, ACCESS_TIME_COLUMN + 1, path_info->access_time)) 00560 != SQLITE_OK) goto bind_error; 00561 if ((error = sqlite3_bind_int64(insert_path_stmt, MODIFICATION_TIME_COLUMN + 1, path_info->modification_time)) 00562 != SQLITE_OK) goto bind_error; 00563 if ((error = sqlite3_bind_int64(insert_path_stmt, CHANGE_TIME_COLUMN + 1, path_info->change_time)) 00564 != SQLITE_OK) goto bind_error; 00565 00566 if ((step_result = sqlite3_step(insert_path_stmt)) != SQLITE_DONE) { 00567 const char *err_msg = sqlite3_errmsg(database_handle); 00568 log_msg(LOG_ERROR, _("sqlite3_step \"%s\", unexpected result %s (%s)\n"), 00569 sqlite3_sql(insert_path_stmt), sqlite3_result_string(step_result), err_msg); 00570 result = WATCH_DATABASE_ERROR_CANNOT_INSERT; 00571 goto exit; 00572 } 00573 00574 exit: 00575 return result; 00576 00577 bind_error: { 00578 const char *err_msg = sqlite3_errmsg(database_handle); 00579 log_msg(LOG_ERROR, _("sqlite3_bind_text \"%s\", (%s)\n"), sqlite3_sql(insert_path_stmt), err_msg); 00580 result = WATCH_DATABASE_ERROR_CANNOT_QUERY; 00581 return result; 00582 } 00583 }
static int destroy_statement | ( | sqlite3_stmt ** | stmt_arg | ) | [static] |
Destroy a SQLite prepared statement.
[out] | stmt_arg | Pointer to new SQLite statement assigned here. |
Definition at line 236 of file watch_database.c.
Referenced by watch_database_fini().
00237 { 00238 int error; 00239 sqlite3_stmt *stmt; 00240 00241 if ((stmt = *stmt_arg) == NULL) return SUCCESS; 00242 00243 if ((error = sqlite3_finalize(stmt)) != SQLITE_OK) { 00244 const char *err_msg = sqlite3_errmsg(database_handle); 00245 log_msg(LOG_ERROR, _("sqlite3_finalize (%s)\n"), err_msg); 00246 return error; 00247 } 00248 *stmt_arg = NULL; 00249 return SUCCESS; 00250 }
int init_path_info | ( | struct lwatch_path_info_t * | path_info, | |
const char * | path | |||
) |
Initialize a lwatch_path_info_t struct.
[in] | path_info | The lwatch_path_info_t to initialize |
[in] | path | The path name bound to the lwatch_path_info_t |
Definition at line 596 of file watch_database.c.
Referenced by get_create_path_info(), and new_path_info().
00597 { 00598 int error; 00599 00600 memset(path_info, 0, sizeof(struct lwatch_path_info_t)); 00601 00602 if (path) { 00603 if ((error = copy_path(path_info->path, path, sizeof(path_info->path))) != SUCCESS) { 00604 log_msg(LOG_ERROR, _("failed to copy path \"%s\" (%s)\n"), path, error_string(error)); 00605 return error; 00606 } 00607 } 00608 00609 path_info->flags = INC_VERSION_FLAG; 00610 return SUCCESS; 00611 }
static int init_statement | ( | struct sqlite3_stmt ** | stmt_arg, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Create a SQLite prepared statement from printf style arguments.
[out] | stmt_arg | Pointer to new SQLite statement assigned here. |
[in] | fmt | Printf style format string |
[in] | ... | Optional printf variable arguments |
Definition at line 203 of file watch_database.c.
Referenced by watch_database_init().
00204 { 00205 va_list ap; 00206 int error; 00207 sqlite3_stmt *stmt; 00208 char *sql; 00209 00210 va_start(ap, fmt); 00211 vasprintf(&sql, fmt, ap); 00212 00213 if ((error = sqlite3_prepare_v2(database_handle, sql, -1, &stmt, NULL)) != SQLITE_OK) { 00214 const char *err_msg = sqlite3_errmsg(database_handle); 00215 log_msg(LOG_ERROR, _("could not prepare statement \"%s\", (%s)\n"), sql, err_msg); 00216 free(sql); 00217 *stmt_arg = NULL; 00218 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 00219 } 00220 00221 free(sql); 00222 *stmt_arg = stmt; 00223 return SUCCESS; 00224 }
int new_path_info | ( | const char * | path, | |
struct lwatch_path_info_t ** | path_info_arg | |||
) |
Allocate and initialize a new lwatch_path_info_t struct.
[in] | path | The path name which will be bound to the lwatch_path_info_t |
[in] | path_info_arg | Pointer to variable to receive pointer to new path_info |
Definition at line 622 of file watch_database.c.
00623 { 00624 int error; 00625 struct lwatch_path_info_t *path_info; 00626 00627 if ((path_info = malloc(sizeof(struct lwatch_path_info_t))) == NULL) { 00628 return ENOMEM; 00629 } 00630 00631 if ((error = init_path_info(path_info, path)) != SUCCESS) { 00632 log_msg(LOG_ERROR, _("could not initialize path_info for path \"%s\" (%s)\n"), 00633 path, error_string(error)); 00634 free(path_info); 00635 return error; 00636 } 00637 00638 *path_info_arg = path_info; 00639 return SUCCESS; 00640 }
static int new_path_info_iter_context | ( | struct path_info_iter_context_t ** | iter_arg | ) | [static] |
Allocate and initialize a new path_info iteration context.
[out] | iter_arg | Pointer to variable to receive new iteration context |
Definition at line 494 of file watch_database.c.
Referenced by database_query_all_paths_iter(), database_query_backups_iter(), database_query_backups_of_target_iter(), database_query_pending_reaps_iter(), and database_query_targets_iter().
00495 { 00496 struct path_info_iter_context_t *iter; 00497 00498 *iter_arg = NULL; 00499 if ((iter = malloc(sizeof(struct path_info_iter_context_t))) == NULL) { 00500 return ENOMEM; 00501 } 00502 00503 iter->iter.next = (database_iter_next_t) path_info_iter_next; 00504 iter->iter.error = SUCCESS; 00505 00506 iter->stmt = NULL; 00507 iter->step_result = SQLITE_OK; 00508 00509 *iter_arg = iter; 00510 return SUCCESS; 00511 }
char* path_info_flags_string | ( | unsigned long | flag, | |
const char * | separator | |||
) |
Render the lwatch_path_info_t flag bitset as a string.
[in] | flag | The bitset whose boolean flags will be converted to strings |
[in] | separator | The string used to separate adjacent flags |
Definition at line 652 of file watch_database.c.
Referenced by path_info_string().
00653 { 00654 static __thread char buf[1024]; /* thread local static buffer */ 00655 char *p, *buf_end; 00656 int separator_len; 00657 unsigned int unknown; 00658 00659 p = buf; /* current position in buffer */ 00660 buf_end = &buf[sizeof(buf)]; /* non-inclusive end of buffer */ 00661 separator_len = strlen(separator); 00662 *p = 0; 00663 00664 /* validate there is nothing in the event mask we don't know about */ 00665 unknown = flag & ~(TARGET_FLAG | BACKUP_FLAG | NEEDS_REAPING_FLAG | 00666 STAT_DATA_VALID_FLAG | INC_VERSION_FLAG); 00667 00668 if (unknown) p += snprintf(p, buf_end - p, "unknown bits=0x%x%s", unknown, separator); 00669 if (p >= buf_end) goto fail; 00670 00671 if (flag & TARGET_FLAG) p += snprintf(p, buf_end - p, "TARGET%s", separator); 00672 if (p >= buf_end) goto fail; 00673 if (flag & BACKUP_FLAG) p += snprintf(p, buf_end - p, "BACKUP%s", separator); 00674 if (p >= buf_end) goto fail; 00675 if (flag & NEEDS_REAPING_FLAG) p += snprintf(p, buf_end - p, "NEEDS_REAPING%s", separator); 00676 if (p >= buf_end) goto fail; 00677 if (flag & STAT_DATA_VALID_FLAG) p += snprintf(p, buf_end - p, "STAT_DATA_VALID%s", separator); 00678 if (p >= buf_end) goto fail; 00679 if (flag & INC_VERSION_FLAG) p += snprintf(p, buf_end - p, "INC_VERSION%s", separator); 00680 if (p >= buf_end) goto fail; 00681 00682 if (p > buf) p[-separator_len] = 0; /* nuke trailing separator */ 00683 00684 return buf; 00685 00686 fail: 00687 /* exhausted the buffer; NULL terminate then return truncated string */ 00688 buf_end[-1] = 0; /* should already be NULL terminated, but be safe */ 00689 return buf; 00690 }
static struct lwatch_path_info_t * path_info_iter_next | ( | struct path_info_iter_context_t * | iter | ) | [static, read] |
Used to iterate through SQLite query result of lwatch_path_info_t structs.
[in] | iter | The iteration context, contains the SQLite statement, state, etc. |
Definition at line 469 of file watch_database.c.
Referenced by new_path_info_iter_context().
00470 { 00471 iter->iter.error = SUCCESS; 00472 00473 iter->step_result = sqlite3_step(iter->stmt); 00474 if (iter->step_result == SQLITE_DONE) { 00475 return NULL; 00476 } else if (iter->step_result == SQLITE_ROW) { 00477 populate_path_info(&iter->path_info, iter->stmt); /* FIXME, check error return */ 00478 return &iter->path_info; 00479 } else { 00480 const char *err_msg = sqlite3_errmsg(database_handle); 00481 log_msg(LOG_ERROR, _("sqlite3_step \"%s\", unexpected result %s (%s)\n"), 00482 sqlite3_sql(iter->stmt), sqlite3_result_string(iter->step_result), err_msg); 00483 iter->iter.error = WATCH_DATABASE_ERROR_CANNOT_QUERY; 00484 return NULL; 00485 } 00486 }
char* path_info_string | ( | struct lwatch_path_info_t * | path_info, | |
const char * | prefix | |||
) |
Render a lwatch_path_info_t struct as a string.
[in] | path_info | The lwatch_path_info_t struct to convert to a string |
[in] | prefix | String prepended to each line in the output |
Definition at line 702 of file watch_database.c.
Referenced by dump_database().
00703 { 00704 static __thread char buf[1024]; /* thread local static buffer */ 00705 const char *indent = " "; 00706 char prefix_indent[128]; 00707 char *p, *buf_end; 00708 char *uid_name, *gid_name; 00709 00710 strncpy(prefix_indent, prefix, sizeof(prefix_indent)); 00711 prefix_indent[sizeof(prefix_indent) - 1] = 0; 00712 strncat(prefix_indent, indent, sizeof(prefix_indent) - 1); 00713 00714 get_uid_name(path_info->uid, &uid_name); 00715 get_gid_name(path_info->gid, &gid_name); 00716 00717 00718 p = buf; /* current position in buffer */ 00719 buf_end = &buf[sizeof(buf)]; /* non-inclusive end of buffer */ 00720 *p = 0; 00721 00722 p += snprintf(p, buf_end - p, "%spath: %s\n", 00723 prefix, path_info->path); 00724 if (p >= buf_end) goto fail; 00725 00726 if (path_info->original_path[0]) { 00727 p += snprintf(p, buf_end - p, "%soriginal path: %s\n", 00728 prefix_indent, 00729 path_info->original_path); 00730 if (p >= buf_end) goto fail; 00731 } 00732 00733 p += snprintf(p, buf_end - p, "%sflags: [%s]\n", 00734 prefix_indent, 00735 path_info_flags_string(path_info->flags, ",")); 00736 if (p >= buf_end) goto fail; 00737 00738 p += snprintf(p, buf_end - p, "%sversion: %lu\n", 00739 prefix_indent, 00740 path_info->version); 00741 if (p >= buf_end) goto fail; 00742 00743 p += snprintf(p, buf_end - p, "%sreap_time: %s (%ld)\n", 00744 prefix_indent, 00745 time_string(path_info->reap_time, true, NULL), 00746 path_info->reap_time); 00747 if (p >= buf_end) goto fail; 00748 00749 p += snprintf(p, buf_end - p, "%sreap_position: %ld\n", 00750 prefix_indent, 00751 path_info->reap_position); 00752 if (p >= buf_end) goto fail; 00753 00754 if (path_info->flags & STAT_DATA_VALID_FLAG) { 00755 p += snprintf(p, buf_end - p, "%sdev: %llu\n", 00756 prefix_indent, 00757 path_info->dev); 00758 if (p >= buf_end) goto fail; 00759 00760 p += snprintf(p, buf_end - p, "%sinode: %lu\n", 00761 prefix_indent, 00762 path_info->inode); 00763 if (p >= buf_end) goto fail; 00764 00765 p += snprintf(p, buf_end - p, "%smode: %s (%#o)\n", 00766 prefix_indent, 00767 file_mode_string(path_info->mode), 00768 path_info->mode); 00769 if (p >= buf_end) goto fail; 00770 00771 p += snprintf(p, buf_end - p, "%suid:gid: %s:%s (%u:%u)\n", 00772 prefix_indent, 00773 uid_name, gid_name, 00774 path_info->uid, path_info->gid); 00775 if (p >= buf_end) goto fail; 00776 00777 p += snprintf(p, buf_end - p, "%ssize: %ld\n", 00778 prefix_indent, 00779 path_info->size); 00780 if (p >= buf_end) goto fail; 00781 00782 p += snprintf(p, buf_end - p, "%saccess_time: %s (%ld)\n", 00783 prefix_indent, 00784 time_string(path_info->access_time, true, NULL), 00785 path_info->access_time); 00786 if (p >= buf_end) goto fail; 00787 00788 p += snprintf(p, buf_end - p, "%smodification time: %s (%ld)\n", 00789 prefix_indent, 00790 time_string(path_info->modification_time, true, NULL), 00791 path_info->modification_time); 00792 if (p >= buf_end) goto fail; 00793 00794 p += snprintf(p, buf_end - p, "%schange_time: %s (%ld)\n", 00795 prefix_indent, 00796 time_string(path_info->change_time, true, NULL), 00797 path_info->change_time); 00798 if (p >= buf_end) goto fail; 00799 } 00800 00801 00802 free(uid_name); 00803 free(gid_name); 00804 return buf; 00805 00806 fail: 00807 /* exhausted the buffer; NULL terminate then return truncated string */ 00808 buf_end[-1] = 0; /* should already be NULL terminated, but be safe */ 00809 free(uid_name); 00810 free(gid_name); 00811 return buf; 00812 }
int populate_path_info | ( | struct lwatch_path_info_t * | path_info, | |
sqlite3_stmt * | stmt | |||
) | [static] |
Copy the data from a SQLite query result into a lwatch_path_info_t struct.
[in] | path_info | The lwatch_path_info_t struct to initialize |
[in] | stmt | The SQLite statement containing the query result |
Definition at line 421 of file watch_database.c.
Referenced by database_lookup_path_info(), and path_info_iter_next().
00422 { 00423 int error; 00424 00425 if ((error = copy_path(path_info->path, (const char *)sqlite3_column_text(stmt, PATH_COLUMN), 00426 sizeof(path_info->path))) != SUCCESS) { 00427 log_msg(LOG_ERROR, _("failed to copy path \"%s\" (%s)\n"), (const char *)sqlite3_column_text(stmt, 0), error_string(error)); 00428 return error; 00429 } 00430 if ((error = copy_path(path_info->original_path, (const char *)sqlite3_column_text(stmt, ORIGINAL_PATH_COLUMN), 00431 sizeof(path_info->original_path))) != SUCCESS) { 00432 log_msg(LOG_ERROR, _("failed to copy path \"%s\" (%s)\n"), (const char *)sqlite3_column_text(stmt, 1), error_string(error)); 00433 return error; 00434 } 00435 00436 path_info->flags = sqlite3_column_int64(stmt, FLAGS_COLUMN); 00437 path_info->version = sqlite3_column_int64(stmt, VERSION_COLUMN); 00438 path_info->reap_time = sqlite3_column_int64(stmt, REAP_TIME_COLUMN); 00439 path_info->reap_position = sqlite3_column_int64(stmt, REAP_POSITION_COLUMN); 00440 path_info->dev = sqlite3_column_int64(stmt, DEV_COLUMN); 00441 path_info->inode = sqlite3_column_int64(stmt, INODE_COLUMN); 00442 path_info->mode = sqlite3_column_int64(stmt, MODE_COLUMN); 00443 path_info->uid = sqlite3_column_int64(stmt, UID_COLUMN); 00444 path_info->gid = sqlite3_column_int64(stmt, GID_COLUMN); 00445 path_info->size = sqlite3_column_int64(stmt, SIZE_COLUMN); 00446 path_info->access_time = sqlite3_column_int64(stmt, ACCESS_TIME_COLUMN); 00447 path_info->modification_time = sqlite3_column_int64(stmt, MODIFICATION_TIME_COLUMN); 00448 path_info->change_time = sqlite3_column_int64(stmt, CHANGE_TIME_COLUMN); 00449 00450 return SUCCESS; 00451 }
static int reset_statement | ( | sqlite3_stmt * | stmt | ) | [static] |
Resets a prepared statement readying it for parameter binding and execution.
[in] | stmt | The prepared statement to reset |
Definition at line 258 of file watch_database.c.
Referenced by database_lookup_path_info(), database_query_all_paths_iter(), database_query_backups_iter(), database_query_backups_of_target_iter(), database_query_pending_reaps_iter(), database_query_targets_iter(), database_write_path_info(), and table_exists().
00259 { 00260 int error; 00261 00262 if ((error = sqlite3_reset(stmt)) != SQLITE_OK) { 00263 const char *err_msg = sqlite3_errmsg(database_handle); 00264 log_msg(LOG_ERROR, _("sqlite3_reset \"%s\", (%s)\n"), sqlite3_sql(stmt), err_msg); 00265 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 00266 } 00267 return SUCCESS; 00268 }
static const char * sqlite3_result_string | ( | int | result | ) | [static] |
Translate a SQLite result code to a string.
[in] | result | The result code to translate to a string |
Definition at line 276 of file watch_database.c.
Referenced by database_lookup_path_info(), database_write_path_info(), path_info_iter_next(), and table_exists().
00277 { 00278 static __thread char buf[64]; /* thread local static buffer */ 00279 00280 switch(result) { 00281 case SQLITE_OK: return "SQLITE_OK"; 00282 case SQLITE_ERROR: return "SQLITE_ERROR"; 00283 case SQLITE_INTERNAL: return "SQLITE_INTERNAL"; 00284 case SQLITE_PERM: return "SQLITE_PERM"; 00285 case SQLITE_ABORT: return "SQLITE_ABORT"; 00286 case SQLITE_BUSY: return "SQLITE_BUSY"; 00287 case SQLITE_LOCKED: return "SQLITE_LOCKED"; 00288 case SQLITE_NOMEM: return "SQLITE_NOMEM"; 00289 case SQLITE_READONLY: return "SQLITE_READONLY"; 00290 case SQLITE_INTERRUPT: return "SQLITE_INTERRUPT"; 00291 case SQLITE_IOERR: return "SQLITE_IOERR"; 00292 case SQLITE_CORRUPT: return "SQLITE_CORRUPT"; 00293 case SQLITE_NOTFOUND: return "SQLITE_NOTFOUND"; 00294 case SQLITE_FULL: return "SQLITE_FULL"; 00295 case SQLITE_CANTOPEN: return "SQLITE_CANTOPEN"; 00296 case SQLITE_PROTOCOL: return "SQLITE_PROTOCOL"; 00297 case SQLITE_EMPTY: return "SQLITE_EMPTY"; 00298 case SQLITE_SCHEMA: return "SQLITE_SCHEMA"; 00299 case SQLITE_TOOBIG: return "SQLITE_TOOBIG"; 00300 case SQLITE_CONSTRAINT: return "SQLITE_CONSTRAINT"; 00301 case SQLITE_MISMATCH: return "SQLITE_MISMATCH"; 00302 case SQLITE_MISUSE: return "SQLITE_MISUSE"; 00303 case SQLITE_NOLFS: return "SQLITE_NOLFS"; 00304 case SQLITE_AUTH: return "SQLITE_AUTH"; 00305 case SQLITE_FORMAT: return "SQLITE_FORMAT"; 00306 case SQLITE_RANGE: return "SQLITE_RANGE"; 00307 case SQLITE_NOTADB: return "SQLITE_NOTADB"; 00308 case SQLITE_ROW: return "SQLITE_ROW"; 00309 case SQLITE_DONE: return "SQLITE_DONE"; 00310 00311 case SQLITE_IOERR_READ: return "SQLITE_IOERR_READ"; 00312 case SQLITE_IOERR_SHORT_READ: return "SQLITE_IOERR_SHORT_READ"; 00313 case SQLITE_IOERR_WRITE: return "SQLITE_IOERR_WRITE"; 00314 case SQLITE_IOERR_FSYNC: return "SQLITE_IOERR_FSYNC"; 00315 case SQLITE_IOERR_DIR_FSYNC: return "SQLITE_IOERR_DIR_FSYNC"; 00316 case SQLITE_IOERR_TRUNCATE: return "SQLITE_IOERR_TRUNCATE"; 00317 case SQLITE_IOERR_FSTAT: return "SQLITE_IOERR_FSTAT"; 00318 case SQLITE_IOERR_UNLOCK: return "SQLITE_IOERR_UNLOCK"; 00319 case SQLITE_IOERR_RDLOCK: return "SQLITE_IOERR_RDLOCK"; 00320 case SQLITE_IOERR_DELETE: return "SQLITE_IOERR_DELETE"; 00321 case SQLITE_IOERR_BLOCKED: return "SQLITE_IOERR_BLOCKED"; 00322 case SQLITE_IOERR_NOMEM: return "SQLITE_IOERR_NOMEM"; 00323 default: 00324 snprintf(buf, sizeof(buf), "unknown(%d)", result); 00325 return buf; 00326 } 00327 }
static int table_exists | ( | const char * | table_name, | |
bool * | exists | |||
) | [static] |
Set variable to true if specified table exists in SQLite database.
[in] | table_name | The table whose existence is to be checked. |
[out] | exists | This variable receives the boolean result |
Definition at line 336 of file watch_database.c.
Referenced by watch_database_init().
00337 { 00338 int error, result, step_result, row_count; 00339 const char *name; 00340 00341 result = SUCCESS; 00342 *exists = false; 00343 00344 if ((error = reset_statement(table_exists_stmt)) != SUCCESS) { 00345 result = WATCH_DATABASE_ERROR_CANNOT_QUERY; 00346 goto exit; 00347 } 00348 00349 if ((error = sqlite3_bind_text(table_exists_stmt, 1, table_name, -1, SQLITE_TRANSIENT)) != SQLITE_OK) { 00350 const char *err_msg = sqlite3_errmsg(database_handle); 00351 log_msg(LOG_ERROR, _("sqlite3_bind_text \"%s\", (%s)\n"), sqlite3_sql(table_exists_stmt), err_msg); 00352 result = WATCH_DATABASE_ERROR_CANNOT_QUERY; 00353 goto exit; 00354 } 00355 00356 row_count = 0; 00357 while(true) { 00358 step_result = sqlite3_step(table_exists_stmt); 00359 if (step_result == SQLITE_DONE) { 00360 break; 00361 } else if (step_result == SQLITE_ROW) { 00362 row_count++; 00363 name = (const char *)sqlite3_column_text(table_exists_stmt, 0); 00364 *exists = strcmp(name, table_name) == 0 ? true : false; 00365 } else { 00366 const char *err_msg = sqlite3_errmsg(database_handle); 00367 log_msg(LOG_ERROR, _("sqlite3_step \"%s\", unexpected result %s (%s)\n"), 00368 sqlite3_sql(table_exists_stmt), sqlite3_result_string(step_result), err_msg); 00369 result = WATCH_DATABASE_ERROR_CANNOT_QUERY; 00370 } 00371 } 00372 00373 if (row_count > 1) { 00374 log_msg(LOG_ERROR, _("\"%s\", unexpected multiple rows (%d) returned\n"), 00375 sqlite3_sql(table_exists_stmt), row_count); 00376 result = WATCH_DATABASE_ERROR_FOUND_MULTIPLE; 00377 } 00378 00379 exit: 00380 return result; 00381 }
const char* watch_database_error_string | ( | int | error | ) |
Render a database error code as a string.
[in] | error | The database error code to convert to a string |
Definition at line 820 of file watch_database.c.
Referenced by error_string().
00821 { 00822 static __thread char buf[80]; /* thread local static buffer */ 00823 00824 switch(error) { 00825 case SUCCESS: return _("success"); 00826 case WATCH_DATABASE_ERROR_CANNOT_OPEN: return _("could not open database"); 00827 case WATCH_DATABASE_ERROR_CANNOT_CLOSE: return _("could not close database"); 00828 case WATCH_DATABASE_ERROR_CANNOT_QUERY: return _("database query failed"); 00829 case WATCH_DATABASE_ERROR_CANNOT_CREATE_TABLE: return _("cannot create table"); 00830 case WATCH_DATABASE_ERROR_CANNOT_INSERT: return _("cannot insert record into table"); 00831 case WATCH_DATABASE_ERROR_NOT_FOUND: return _("entry not found"); 00832 case WATCH_DATABASE_ERROR_FOUND_MULTIPLE: return _("found multiple entries, expecting single entry"); 00833 default: 00834 snprintf(buf, sizeof(buf), _("unknown(%d)"), error); 00835 return buf; 00836 } 00837 }
int watch_database_fini | ( | void | ) |
Close the watch database subsystem, release all resources, close database.
Definition at line 935 of file watch_database.c.
Referenced by main().
00936 { 00937 int error; 00938 00939 destroy_statement(&table_exists_stmt); 00940 destroy_statement(&lookup_path_stmt); 00941 destroy_statement(&insert_path_stmt); 00942 destroy_statement(&query_all_stmt); 00943 destroy_statement(&query_backups_stmt); 00944 destroy_statement(&query_backups_of_target_stmt); 00945 destroy_statement(&query_pending_reaps_stmt); 00946 destroy_statement(&query_targets_stmt); 00947 00948 if ((error = sqlite3_close(database_handle)) != SQLITE_OK) { 00949 const char *err_msg = sqlite3_errmsg(database_handle); 00950 log_msg(LOG_ERROR, _("could not close database file \"%s\", (%s)\n"), watch_database_pathname, err_msg); 00951 database_handle = NULL; 00952 return WATCH_DATABASE_ERROR_CANNOT_CLOSE; 00953 } 00954 database_handle = NULL; 00955 return SUCCESS; 00956 }
int watch_database_init | ( | void | ) |
Initialize the watch database subsystem.
Definition at line 850 of file watch_database.c.
Referenced by main().
00851 { 00852 int error; 00853 bool exists; 00854 00855 if ((error = sqlite3_open(watch_database_pathname, &database_handle)) != SQLITE_OK) { 00856 const char *err_msg = sqlite3_errmsg(database_handle); 00857 log_msg(LOG_ERROR, _("could not open database file \"%s\", (%s)\n"),watch_database_pathname, err_msg); 00858 sqlite3_close(database_handle); 00859 database_handle = NULL; 00860 return WATCH_DATABASE_ERROR_CANNOT_OPEN; 00861 } 00862 00863 /* Create prepared SQL statements for master table */ 00864 if ((error = init_statement(&table_exists_stmt, 00865 "SELECT name FROM sqlite_master WHERE type='table' AND name=?1;")) != SUCCESS) { 00866 return error; 00867 } 00868 00869 /* Assure our table exists, if not create it */ 00870 if ((error = table_exists(LWATCH_TABLE_NAME, &exists)) != SUCCESS) { 00871 log_msg(LOG_ERROR, _("table_exists failed \"%s\" (%s)\n"), LWATCH_TABLE_NAME, error_string(error)); 00872 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 00873 } 00874 00875 if (!exists) { 00876 if ((error = create_table(LWATCH_TABLE_NAME, lwatch_table_schema)) != SUCCESS) { 00877 log_msg(LOG_ERROR, _("\"%s\" table does not exist, but failed to create (%s)\n"), 00878 LWATCH_TABLE_NAME, error_string(error)); 00879 return error; 00880 } 00881 } 00882 00883 /* Create prepared SQL statements for our table */ 00884 if ((error = init_statement(&lookup_path_stmt, 00885 "SELECT %s FROM \"%s\" WHERE path=?1;", 00886 COLUMNS_STRING, LWATCH_TABLE_NAME)) != SUCCESS) { 00887 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 00888 } 00889 00890 if ((error = init_statement(&insert_path_stmt, 00891 "INSERT OR REPLACE INTO \"%s\" (%s) VALUES " 00892 "(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15);", 00893 LWATCH_TABLE_NAME, COLUMNS_STRING)) != SUCCESS) { 00894 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 00895 } 00896 00897 if ((error = init_statement(&query_all_stmt, 00898 "SELECT %s FROM \"%s\" where path like ?1;", 00899 COLUMNS_STRING, LWATCH_TABLE_NAME)) != SUCCESS) { 00900 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 00901 } 00902 00903 if ((error = init_statement(&query_backups_stmt, 00904 "SELECT %s FROM \"%s\" where flags & %d;", 00905 COLUMNS_STRING, LWATCH_TABLE_NAME, BACKUP_FLAG)) != SUCCESS) { 00906 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 00907 } 00908 00909 if ((error = init_statement(&query_backups_of_target_stmt, 00910 "SELECT %s FROM \"%s\" where flags & %d AND original_path == ?1;", 00911 COLUMNS_STRING, LWATCH_TABLE_NAME, BACKUP_FLAG)) != SUCCESS) { 00912 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 00913 } 00914 00915 if ((error = init_statement(&query_pending_reaps_stmt, 00916 "SELECT %s FROM \"%s\" where flags & %d;", 00917 COLUMNS_STRING, LWATCH_TABLE_NAME, NEEDS_REAPING_FLAG)) != SUCCESS) { 00918 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 00919 } 00920 00921 if ((error = init_statement(&query_targets_stmt, 00922 "SELECT %s FROM \"%s\" where flags & %d;", 00923 COLUMNS_STRING, LWATCH_TABLE_NAME, TARGET_FLAG)) != SUCCESS) { 00924 return WATCH_DATABASE_ERROR_CANNOT_QUERY; 00925 } 00926 00927 return SUCCESS; 00928 }
const char* lwatch_table_schema [static] |
Initial value:
"path TEXT PRIMARY KEY,\n\ original_path TEXT,\n\ flags INTEGER,\n\ version INTEGER,\n\ reap_time INTEGER,\n\ reap_position INTEGER,\n\ dev INTEGER,\n\ inode INTEGER,\n\ mode INTEGER,\n\ uid INTEGER,\n\ gid INTEGER,\n\ size INTEGER,\n\ access_time INTEGER,\n\ modification_time INTEGER,\n\ change_time INTEGER\n\ "
Definition at line 113 of file watch_database.c.
Referenced by watch_database_init().
sqlite3_stmt* query_pending_reaps_stmt = NULL |
lookup multiple lwatch_path_info_t which have the NEEDS_REAPING_FLAG set, i.e.
all pending reaps
Definition at line 174 of file watch_database.c.
Referenced by database_query_pending_reaps_iter(), watch_database_fini(), and watch_database_init().
sqlite3_stmt* query_targets_stmt = NULL |
lookup multiple lwatch_path_info_t which have the TARGET_FLAG set, i.e.
all primary targets
Definition at line 178 of file watch_database.c.
Referenced by database_query_targets_iter(), watch_database_fini(), and watch_database_init().