From: Ian Jackson Date: Sun, 4 Oct 2009 21:14:19 +0000 (+0100) Subject: WIP routesearch; New SQL_DISTINCT_{DECL,STEP} X-Git-Tag: 5.0^2~75 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~yarrgweb/git?p=ypp-sc-tools.db-test.git;a=commitdiff_plain;h=4119041216579a6020e649469037c3088364e214;hp=5f317a6465f48831fd170a745b58763602218421 WIP routesearch; New SQL_DISTINCT_{DECL,STEP} --- diff --git a/yarrg/rscommon.h b/yarrg/rscommon.h index f62fd99..5cf25f6 100644 --- a/yarrg/rscommon.h +++ b/yarrg/rscommon.h @@ -30,9 +30,34 @@ void sql_fatal(const char *stmt_what, int sqr, const char *act_what) NORET; -#define SQL_STEP(ssh) (sql_step_wrap((ssh), #ssh, __FILE__, __LINE__)) -int sql_step_wrap(sqlite3_stmt *ssh, const char *ssh_string, - const char *file, int line); +#define SQL_STEP(ssh) (sql_step((ssh), #ssh, __FILE__, __LINE__)) +int sql_step(sqlite3_stmt *ssh, const char *ssh_string, + const char *file, int line); + +#define SQL_DISTINCT_DECL(cols, nintcols) \ + int cols[nintcols]; \ + cols[0]= -1; +#define SQL_DISTINCT_STEP(ssh, cols, nkeycols) \ + (sql_step_distinct((ssh), #ssh, __FILE__, __LINE__, \ + (cols), sizeof((cols))/sizeof((cols)[0]), nkeycols)) +int sql_step_distinct(sqlite3_stmt *ssh, const char *ssh_string, + const char *file, int line, + int *cols, int ncols, int nkeycols); + /* These work if we're making a query whose columns consist of: + * - keys: integer column(s) on which the results are sorted by the query + * - consequences: zero or more integer cols strictly dependent on the keys + * - extra: zero or more further (possibly non-integer) columns + * + * Call SQL_DISTINCT_DECL, passing intcols = the total number of keys and + * consequences; it will declare int cols[intfields]; + * + * Then each SQL_DISTINCT_STEP is like SQL_STEP only you have to + * pass the number of key columns and it only returns rows with + * distinct keys. Rows with all-identical keys are asserted to + * have identical consequences. After each call to + * SQL_DISTINCT_STEP the keys and consequences will be stored in + * cols. + */ int sql_single_int(const char *stmt); diff --git a/yarrg/rssql.c b/yarrg/rssql.c index 898ac3b..bfe60d6 100644 --- a/yarrg/rssql.c +++ b/yarrg/rssql.c @@ -57,8 +57,28 @@ sqlite3_stmt *sql_prepare(const char *stmt, const char *what) { return ssr; } -int sql_step_wrap(sqlite3_stmt *ssh, const char *ssh_string, - const char *file, int line) { +int sql_step_distinct(sqlite3_stmt *ssh, const char *ssh_string, + const char *file, int line, + int *cols, int ncols, int nkeycols) { + for (;;) { + if (!sql_step(ssh, ssh_string, file, line)) return 0; + + int i; + for (i=0; i