diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-06-19 16:54:42 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-06-19 16:54:42 +0100 |
commit | 03926b5291fda6282f463fd962ccd74e16ef791d (patch) | |
tree | b503d9f73f912a438b1e4a415a9f221d4dad3542 /src/libstat/backends | |
parent | 928c509a55d571b012559a96a02457cc989705da (diff) | |
download | rspamd-03926b5291fda6282f463fd962ccd74e16ef791d.tar.gz rspamd-03926b5291fda6282f463fd962ccd74e16ef791d.zip |
Implement operations with sqlite3 statistics.
Diffstat (limited to 'src/libstat/backends')
-rw-r--r-- | src/libstat/backends/sqlite3_backend.c | 170 |
1 files changed, 160 insertions, 10 deletions
diff --git a/src/libstat/backends/sqlite3_backend.c b/src/libstat/backends/sqlite3_backend.c index e5471b436..21b5918ac 100644 --- a/src/libstat/backends/sqlite3_backend.c +++ b/src/libstat/backends/sqlite3_backend.c @@ -56,10 +56,10 @@ static const char *create_tables_sql = "learns INTEGER" ");" "CREATE TABLE tokens(" - "token INTEGER," + "token INTEGER PRIMARY KEY," "user INTEGER REFERENCES users(id) ON DELETE CASCADE," - "language INTEGER REFERENCES users(id) ON DELETE CASCADE," - "PRIMARY KEY (token,user,language)" + "language INTEGER REFERENCES languages(id) ON DELETE CASCADE," + "value INTEGER" ");" "CREATE UNIQUE INDEX IF NOT EXISTS un ON users(name);" "CREATE UNIQUE INDEX IF NOT EXISTS ln ON languages(name);" @@ -72,6 +72,11 @@ enum rspamd_stat_sqlite3_stmt_idx { RSPAMD_STAT_BACKEND_TRANSACTION_START = 0, RSPAMD_STAT_BACKEND_TRANSACTION_COMMIT, RSPAMD_STAT_BACKEND_TRANSACTION_ROLLBACK, + RSPAMD_STAT_BACKEND_GET_TOKEN, + RSPAMD_STAT_BACKEND_SET_TOKEN, + RSPAMD_STAT_BACKEND_INC_LEARNS, + RSPAMD_STAT_BACKEND_DEC_LEARNS, + RSPAMD_STAT_BACKEND_GET_LEARNS, RSPAMD_STAT_BACKEND_MAX }; @@ -108,6 +113,52 @@ static struct rspamd_sqlite3_prstmt { .result = SQLITE_DONE, .ret = "" }, + { + .idx = RSPAMD_STAT_BACKEND_GET_TOKEN, + .sql = "SELECT value FROM tokens " + "LEFT JOIN languages ON tokens.language=languages.id " + "LEFT JOIN users ON tokens.user=users.id " + "WHERE token=?1 AND users.name=?2 AND languages.name=?3;", + .stmt = NULL, + .args = "ITT", + .result = SQLITE_ROW, + .ret = "I" + }, + { + .idx = RSPAMD_STAT_BACKEND_SET_TOKEN, + .sql = "INSERT OR REPLACE INTO tokens(token, user, language, value)" + "VALUES (?1, ?2, ?3, ?4);", + .stmt = NULL, + .args = "IIII", + .result = SQLITE_DONE, + .ret = "" + }, + { + .idx = RSPAMD_STAT_BACKEND_INC_LEARNS, + .sql = "UPDATE languages SET learns=learns + 1 WHERE name=?1;" + "UPDATE users SET learns=learns + 1 WHERE name=?2;", + .stmt = NULL, + .args = "TT", + .result = SQLITE_DONE, + .ret = "" + }, + { + .idx = RSPAMD_STAT_BACKEND_DEC_LEARNS, + .sql = "UPDATE languages SET learns=learns - 1 WHERE name=?1;" + "UPDATE users SET learns=learns - 1 WHERE name=?2;", + .stmt = NULL, + .args = "TT", + .result = SQLITE_DONE, + .ret = "" + }, + { + .idx = RSPAMD_STAT_BACKEND_GET_LEARNS, + .sql = "SELECT sum(learns) FROM languages;", + .stmt = NULL, + .args = "", + .result = SQLITE_DONE, + .ret = "I" + } }; static GQuark @@ -368,7 +419,7 @@ rspamd_sqlite3_close (gpointer p) } sqlite3_close (bk->sqlite); - rspamd_sqlite3_close_prstmt (bk->prstmt); + rspamd_sqlite3_close_prstmt (bk); g_slice_free1 (sizeof (*bk), bk); } } @@ -386,22 +437,91 @@ rspamd_sqlite3_runtime (struct rspamd_task *task, gboolean rspamd_sqlite3_process_token (struct token_node_s *tok, - struct rspamd_token_result *res, gpointer ctx) + struct rspamd_token_result *res, gpointer p) { - return FALSE; + struct rspamd_stat_sqlite3_db *bk; + gint64 iv = 0, idx; + + g_assert (res != NULL); + g_assert (p != NULL); + g_assert (res->st_runtime != NULL); + g_assert (tok != NULL); + g_assert (tok->datalen >= sizeof (guint32) * 2); + + bk = res->st_runtime->backend_runtime; + + if (bk == NULL) { + /* Statfile is does not exist, so all values are zero */ + res->value = 0.0; + return FALSE; + } + + memcpy (&idx, tok->data, sizeof (idx)); + + /* TODO: language and user support */ + if (rspamd_sqlite3_run_prstmt (bk, RSPAMD_STAT_BACKEND_GET_TOKEN, + idx, SQLITE3_DEFAULT, SQLITE3_DEFAULT, &iv) == SQLITE_OK) { + res->value = iv; + } + else { + res->value = 0.0; + return FALSE; + } + + + return TRUE; } gboolean rspamd_sqlite3_learn_token (struct token_node_s *tok, - struct rspamd_token_result *res, gpointer ctx) + struct rspamd_token_result *res, gpointer p) { - return FALSE; + struct rspamd_stat_sqlite3_db *bk; + gint64 iv = 0, idx; + + g_assert (res != NULL); + g_assert (p != NULL); + g_assert (res->st_runtime != NULL); + g_assert (tok != NULL); + g_assert (tok->datalen >= sizeof (guint32) * 2); + + bk = res->st_runtime->backend_runtime; + + if (bk == NULL) { + /* Statfile is does not exist, so all values are zero */ + return FALSE; + } + + if (!bk->in_transaction) { + rspamd_sqlite3_run_prstmt (bk, RSPAMD_STAT_BACKEND_TRANSACTION_START); + bk->in_transaction = TRUE; + } + + iv = res->value; + memcpy (&idx, tok->data, sizeof (idx)); + + if (rspamd_sqlite3_run_prstmt (bk, RSPAMD_STAT_BACKEND_SET_TOKEN, + idx, 0, 0, iv) == SQLITE_OK) { + return FALSE; + } + + return TRUE; } void rspamd_sqlite3_finalize_learn (struct rspamd_statfile_runtime *runtime, gpointer ctx) { + struct rspamd_stat_sqlite3_db *bk; + + g_assert (runtime->backend_runtime != NULL); + bk = runtime->backend_runtime; + + if (bk->in_transaction) { + rspamd_sqlite3_run_prstmt (bk, RSPAMD_STAT_BACKEND_TRANSACTION_COMMIT); + bk->in_transaction = FALSE; + } + return; } @@ -409,13 +529,28 @@ gulong rspamd_sqlite3_total_learns (struct rspamd_statfile_runtime *runtime, gpointer ctx) { - return 0; + struct rspamd_stat_sqlite3_db *bk; + guint64 res; + + g_assert (runtime->backend_runtime != NULL); + bk = runtime->backend_runtime; + + rspamd_sqlite3_run_prstmt (bk, RSPAMD_STAT_BACKEND_GET_LEARNS, &res); + + return res; } gulong rspamd_sqlite3_inc_learns (struct rspamd_statfile_runtime *runtime, gpointer ctx) { + struct rspamd_stat_sqlite3_db *bk; + + g_assert (runtime->backend_runtime != NULL); + bk = runtime->backend_runtime; + rspamd_sqlite3_run_prstmt (bk, RSPAMD_STAT_BACKEND_INC_LEARNS, + SQLITE3_DEFAULT, SQLITE3_DEFAULT); + return 0; } @@ -423,6 +558,13 @@ gulong rspamd_sqlite3_dec_learns (struct rspamd_statfile_runtime *runtime, gpointer ctx) { + struct rspamd_stat_sqlite3_db *bk; + + g_assert (runtime->backend_runtime != NULL); + bk = runtime->backend_runtime; + rspamd_sqlite3_run_prstmt (bk, RSPAMD_STAT_BACKEND_DEC_LEARNS, + SQLITE3_DEFAULT, SQLITE3_DEFAULT); + return 0; } @@ -430,7 +572,15 @@ gulong rspamd_sqlite3_learns (struct rspamd_statfile_runtime *runtime, gpointer ctx) { - return 0; + struct rspamd_stat_sqlite3_db *bk; + guint64 res; + + g_assert (runtime->backend_runtime != NULL); + bk = runtime->backend_runtime; + + rspamd_sqlite3_run_prstmt (bk, RSPAMD_STAT_BACKEND_GET_LEARNS, &res); + + return res; } ucl_object_t * |