diff --git a/contrib/longitudinal_snapshot.py b/contrib/longitudinal_snapshot.py index 97113e8c8..b723624f6 100755 --- a/contrib/longitudinal_snapshot.py +++ b/contrib/longitudinal_snapshot.py @@ -695,6 +695,8 @@ def create_longitudinal_snapshot(args): cmd = [ '@CMAKE_BINARY_DIR@/src/gufi_sqlite3', + '@CMAKE_BINARY_DIR@/src/gufi_vt', + args.outdb, 'ATTACH \'file:{0}?mode=ro\' AS {1};'.format(args.flatdb, FLATDB), diff --git a/include/addqueryfuncs.h b/include/addqueryfuncs.h index 0d0b10356..e47a28010 100644 --- a/include/addqueryfuncs.h +++ b/include/addqueryfuncs.h @@ -65,7 +65,12 @@ OF SUCH DAMAGE. #ifndef ADDQUERYFUNCS_H #define ADDQUERYFUNCS_H +#ifdef SQLITE_CORE #include +#else +#include +SQLITE_EXTENSION_INIT3 +#endif #include "bf.h" #include "histogram.h" @@ -74,8 +79,7 @@ OF SUCH DAMAGE. extern "C" { #endif -/* list of functions to add to a SQLite3 db handle that do not have user data/context */ - +/* prototypes for addqueryfuncs */ void uidtouser(sqlite3_context *context, int argc, sqlite3_value **argv); void gidtogroup(sqlite3_context *context, int argc, sqlite3_value **argv); void modetotxt(sqlite3_context *context, int argc, sqlite3_value **argv); @@ -89,6 +93,8 @@ void stdevp_final(sqlite3_context *context); void median_step(sqlite3_context *context, int argc, sqlite3_value **argv); void median_final(sqlite3_context *context); +/* add functions to a SQLite3 db handle that do not have user data/context */ +/* sqlite3_create_function must be called in the same compilation context as gufi_vt */ static inline int addqueryfuncs(sqlite3 *db) { return !( (sqlite3_create_function(db, "uidtouser", 1, SQLITE_UTF8, @@ -112,9 +118,10 @@ static inline int addqueryfuncs(sqlite3 *db) { (sqlite3_create_function(db, "median", 1, SQLITE_UTF8, NULL, NULL, median_step, median_final) == SQLITE_OK) && addhistfuncs(db) - ); + ); } +/* add functions to a SQLite3 db handle that require gufi_query context */ int addqueryfuncs_with_context(sqlite3 *db, struct work *work); #ifdef __cplusplus diff --git a/include/histogram.h b/include/histogram.h index 7e6176cc3..fc68a9daa 100644 --- a/include/histogram.h +++ b/include/histogram.h @@ -68,7 +68,12 @@ OF SUCH DAMAGE. #include #include +#ifdef SQLITE_CORE #include +#else +#include +SQLITE_EXTENSION_INIT3 +#endif #ifdef __cplusplus extern "C" { @@ -78,9 +83,6 @@ extern "C" { * Public API for parsing returned strings. * * These structs are intended for external use. - * - * Ignore the *_step and *_final functions. They are sqlite3 UDFs that - * need to be exposed here to get linking to work for some reason. */ /* ********************************************* */ @@ -108,8 +110,6 @@ typedef struct log2_hist { size_t ge; /* len >= 2^count */ } log2_hist_t; -void log2_hist_step(sqlite3_context *context, int argc, sqlite3_value **argv); -void log2_hist_final(sqlite3_context *context); log2_hist_t *log2_hist_parse(const char *str); void log2_hist_free(log2_hist_t *hist); /* ********************************************* */ @@ -128,8 +128,6 @@ typedef struct mode_hist { size_t buckets[512]; } mode_hist_t; -void mode_hist_step(sqlite3_context *context, int argc, sqlite3_value **argv); -void mode_hist_final(sqlite3_context *context); mode_hist_t *mode_hist_parse(const char *str); void mode_hist_free(mode_hist_t *hist); /* ********************************************* */ @@ -169,8 +167,6 @@ typedef struct time_hist { time_t ref; } time_hist_t; -void time_hist_step(sqlite3_context *context, int argc, sqlite3_value **argv); -void time_hist_final(sqlite3_context *context); time_hist_t *time_hist_parse(const char *str); void time_hist_free(time_hist_t *hist); /* ********************************************* */ @@ -198,9 +194,6 @@ typedef struct category_hist { size_t count; } category_hist_t; -void category_hist_step(sqlite3_context *context, int argc, sqlite3_value **argv); -void category_hist_combine_step(sqlite3_context *context, int argc, sqlite3_value **argv); -void category_hist_final(sqlite3_context *context); category_hist_t *category_hist_parse(const char *str); category_hist_t *category_hist_combine(category_hist_t *lhs, category_hist_t *rhs); void category_hist_free(category_hist_t *hist); @@ -220,12 +213,24 @@ typedef struct mode_count { size_t count; } mode_count_t; -void mode_count_final(sqlite3_context *context); mode_count_t *mode_count_parse(const char *str); void mode_count_free(mode_count_t *mc); /* ********************************************* */ +/* prototypes for addhistfuncs */ +void log2_hist_step(sqlite3_context *context, int argc, sqlite3_value **argv); +void log2_hist_final(sqlite3_context *context); +void mode_hist_step(sqlite3_context *context, int argc, sqlite3_value **argv); +void mode_hist_final(sqlite3_context *context); +void time_hist_step(sqlite3_context *context, int argc, sqlite3_value **argv); +void time_hist_final(sqlite3_context *context); +void category_hist_step(sqlite3_context *context, int argc, sqlite3_value **argv); +void category_hist_combine_step(sqlite3_context *context, int argc, sqlite3_value **argv); +void category_hist_final(sqlite3_context *context); +void mode_count_final(sqlite3_context *context); + /* use this to add histogram functions to a sqlite database handle */ +/* sqlite3_create_function must be called in the same compilation context as gufi_vt */ static inline int addhistfuncs(sqlite3 *db) { return ( (sqlite3_create_function(db, "log2_hist", 2, SQLITE_UTF8, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e3d847b3b..614eee708 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -124,6 +124,7 @@ set(GUFI_SOURCES ) add_library(GUFI STATIC ${GUFI_SOURCES}) add_dependencies(GUFI install_dependencies) +target_compile_definitions(GUFI PUBLIC SQLITE_CORE) set_source_files_properties(bf.c PROPERTIES COMPILE_FLAGS -DGUFI_VERSION="${VERSION_STRING}") #If the GPFS library exists, build the gpfs scan tool @@ -207,6 +208,7 @@ add_library(gufi_query_lib OBJECT ) add_dependencies(gufi_query_lib GUFI) +target_compile_definitions(gufi_query_lib PUBLIC SQLITE_CORE) build_and_install_one(${BIN} TRUE gufi_query gufi_query/main.c diff --git a/src/gufi_sqlite3.c b/src/gufi_sqlite3.c index 9512799a2..7fd4c0be9 100644 --- a/src/gufi_sqlite3.c +++ b/src/gufi_sqlite3.c @@ -69,11 +69,8 @@ OF SUCH DAMAGE. #include "dbutils.h" #include "print.h" -/* don't ask */ -#define SQLITE_CORE -#include "../src/gufi_vt.c" - static void sub_help(void) { + printf("gufi_vt location of gufi_vt runtime loadable extension\n"); printf("db db file path\n"); printf("SQL SQL statements to run\n"); printf("\n"); @@ -84,7 +81,9 @@ static void sub_help(void) { int main(int argc, char *argv[]) { struct input in; - process_args_and_maybe_exit("hvd:", 0, "[db [SQL]...]", &in); + process_args_and_maybe_exit("hvd:", 1, "gufi_vt [db [SQL]...]", &in); + + const char *gufi_vt = argv[idx++]; const int args_left = argc - idx; const char *dbname = (args_left == 0)?SQLITE_MEMORY:argv[idx++]; @@ -97,8 +96,16 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } + char *err = NULL; + /* this calls addqueryfuncs */ - sqlite3_gufivt_init(db, NULL, NULL); + if (sqlite3_load_extension(db, gufi_vt, "sqlite3_gufivt_init", &err) != SQLITE_OK) { + fprintf(stderr, "Error: Could not initialize virtual tables: %s\n", err); + sqlite3_free(err); + input_fini(&in); + closedb(db); + return EXIT_FAILURE; + } /* no buffering */ struct OutputBuffer ob; @@ -114,7 +121,6 @@ int main(int argc, char *argv[]) { }; /* if using in-memory db or no SQL statements following db path, read from stdin */ - char *err = NULL; if (args_left < 2) { char *line = NULL; size_t len = 0; diff --git a/src/gufi_vt.c b/src/gufi_vt.c index bf253d853..705ee66e0 100644 --- a/src/gufi_vt.c +++ b/src/gufi_vt.c @@ -62,14 +62,14 @@ OF SUCH DAMAGE. -#include -SQLITE_EXTENSION_INIT1 - #include #include #include #include +#include +SQLITE_EXTENSION_INIT1 + #include "addqueryfuncs.h" #include "bf.h" #include "dbutils.h" @@ -331,9 +331,9 @@ static int gufi_vtConnect(sqlite3 *db, #define GUFI_VT_ARG_COLUMNS "indexroot TEXT HIDDEN, threads INT64 HIDDEN, " \ "T TEXT HIDDEN, S TEXT HIDDEN, " -#define GUFI_VT_EXTRA_COLUMNS "path TEXT, epath TEXT, fpath TEXT, rpath TEXT, " -#define GUFI_VT_EXTRA_COLUMNS_SQL "path(), epath(), fpath(), path(), " -#define GUFI_VT_EXTRA_COLUMNS_SQL_VR "path(), epath(), fpath(), rpath(sname, sroll), " +#define GUFI_VT_EXTRA_COLUMNS "path TEXT, epath TEXT, fpath TEXT, rpath TEXT, level INT64, " +#define GUFI_VT_EXTRA_COLUMNS_SQL "path(), epath(), fpath(), path(), level(), " +#define GUFI_VT_EXTRA_COLUMNS_SQL_VR "path(), epath(), fpath(), rpath(sname, sroll), level(), " #define GUFI_VT_ALL_COLUMNS GUFI_VT_ARG_COLUMNS \ GUFI_VT_EXTRA_COLUMNS diff --git a/test/regression/gufi_sqlite3.expected b/test/regression/gufi_sqlite3.expected index 230f02b2d..c1d1e79e6 100644 --- a/test/regression/gufi_sqlite3.expected +++ b/test/regression/gufi_sqlite3.expected @@ -1,11 +1,12 @@ # gufi_sqlite3 help $ gufi_sqlite3 -h -usage: gufi_sqlite3 [options] [db [SQL]...] +usage: gufi_sqlite3 [options] gufi_vt [db [SQL]...] options: -h help -v version -d delimiter (one char) [use 'x' for 0x1E] +gufi_vt location of gufi_vt runtime loadable extension db db file path SQL SQL statements to run @@ -14,10 +15,10 @@ Dot commands are not supported # new db file + argv -$ gufi_sqlite3 "test.db" "CREATE TABLE new_table(i INT);" "INSERT INTO new_table VALUES (0), (1), (2);" +$ gufi_sqlite3 "gufi_vt" "test.db" "CREATE TABLE new_table(i INT);" "INSERT INTO new_table VALUES (0), (1), (2);" # existing db file + argv -$ gufi_sqlite3 "test.db" "SELECT * FROM new_table ORDER BY i DESC;" +$ gufi_sqlite3 "gufi_vt" "test.db" "SELECT * FROM new_table ORDER BY i DESC;" 2 1 0 @@ -25,26 +26,26 @@ $ gufi_sqlite3 "test.db" "SELECT * FROM new_table ORDER BY i DESC;" $ rm -f "test.db" # new db file + stdin -$ (echo "CREATE TABLE new_table(i INT);"; echo "INSERT INTO new_table VALUES (3), (4), (5);") | gufi_sqlite3 "test.db" +$ (echo "CREATE TABLE new_table(i INT);"; echo "INSERT INTO new_table VALUES (3), (4), (5);") | gufi_sqlite3 "gufi_vt" "test.db" # existing db file + stdin -$ echo "SELECT * FROM new_table ORDER BY i DESC;" | gufi_sqlite3 "test.db" +$ echo "SELECT * FROM new_table ORDER BY i DESC;" | gufi_sqlite3 "gufi_vt" "test.db" 5 4 3 # in-memory db -$ (echo "CREATE TABLE new_table(i INT);"; echo "INSERT INTO new_table VALUES (6), (7), (8);"; echo "SELECT * FROM new_table ORDER BY i DESC;") | gufi_sqlite3 +$ (echo "CREATE TABLE new_table(i INT);"; echo "INSERT INTO new_table VALUES (6), (7), (8);"; echo "SELECT * FROM new_table ORDER BY i DESC;") | gufi_sqlite3 "gufi_vt" 8 7 6 # directory as db -$ gufi_sqlite3 "search" +$ gufi_sqlite3 "gufi_vt" "search" Error: Could not open database file "search" # virtual table -$ echo "SELECT size, path || '/' || name FROM gufi_vt_pentries('prefix') ORDER BY size ASC;" | gufi_sqlite3 -d "|" +$ echo "SELECT size, path || '/' || name FROM gufi_vt_pentries('prefix') ORDER BY size ASC;" | gufi_sqlite3 -d "|" "gufi_vt" 0|prefix/old_file 1|prefix/directory/executable 2|prefix/directory/readonly @@ -61,6 +62,6 @@ $ echo "SELECT size, path || '/' || name FROM gufi_vt_pentries('prefix') ORDER B 1048576|prefix/1MB # bad SQL -$ (echo "CREATE TABLE;") | gufi_sqlite3 +$ (echo "CREATE TABLE;") | gufi_sqlite3 "gufi_vt" Error: SQL error: near ";": syntax error diff --git a/test/regression/gufi_sqlite3.sh.in b/test/regression/gufi_sqlite3.sh.in index b86d71d2b..b6caf5fcb 100755 --- a/test/regression/gufi_sqlite3.sh.in +++ b/test/regression/gufi_sqlite3.sh.in @@ -86,12 +86,12 @@ echo "# ${GUFI_SQLITE3} help" | replace run_no_sort "${GUFI_SQLITE3} -h" echo "# new db file + argv" -run_no_sort "${GUFI_SQLITE3} \"${DBNAME}\"" \ +run_no_sort "${GUFI_SQLITE3} \"${GUFI_VT}\" \"${DBNAME}\"" \ "\"CREATE TABLE new_table(i INT);\"" \ "\"INSERT INTO new_table VALUES (0), (1), (2);\"" echo "# existing db file + argv" -run_no_sort "${GUFI_SQLITE3} \"${DBNAME}\"" \ +run_no_sort "${GUFI_SQLITE3} \"${GUFI_VT}\" \"${DBNAME}\"" \ "\"SELECT * FROM new_table ORDER BY i DESC;\"" run_no_sort "rm -f \"${DBNAME}\"" @@ -99,27 +99,27 @@ run_no_sort "rm -f \"${DBNAME}\"" echo "# new db file + stdin" run_no_sort "(echo \"CREATE TABLE new_table(i INT);\";" \ "echo \"INSERT INTO new_table VALUES (3), (4), (5);\") |" \ - "${GUFI_SQLITE3} \"${DBNAME}\"" + "${GUFI_SQLITE3} \"${GUFI_VT}\" \"${DBNAME}\"" echo "# existing db file + stdin" run_no_sort "echo \"SELECT * FROM new_table ORDER BY i DESC;\" |" \ - "${GUFI_SQLITE3} \"${DBNAME}\"" + "${GUFI_SQLITE3} \"${GUFI_VT}\" \"${DBNAME}\"" echo "# in-memory db" run_no_sort "(echo \"CREATE TABLE new_table(i INT);\";" \ "echo \"INSERT INTO new_table VALUES (6), (7), (8);\";" \ "echo \"SELECT * FROM new_table ORDER BY i DESC;\") |" \ - "${GUFI_SQLITE3}" + "${GUFI_SQLITE3} \"${GUFI_VT}\"" echo "# directory as db" -run_no_sort "${GUFI_SQLITE3} \"${SEARCH}\"" +run_no_sort "${GUFI_SQLITE3} \"${GUFI_VT}\" \"${SEARCH}\"" echo "# virtual table" -PATH="@CMAKE_BINARY_DIR@/src:${PATH}" run_no_sort "echo \"SELECT size, path || '/' || name FROM gufi_vt_pentries('${INDEXROOT}') ORDER BY size ASC;\" | ${GUFI_SQLITE3} -d \"|\"" +PATH="@CMAKE_BINARY_DIR@/src:${PATH}" run_no_sort "echo \"SELECT size, path || '/' || name FROM gufi_vt_pentries('${INDEXROOT}') ORDER BY size ASC;\" | ${GUFI_SQLITE3} -d \"|\" \"${GUFI_VT}\"" echo "# bad SQL" run_no_sort "(echo \"CREATE TABLE;\") |" \ - "${GUFI_SQLITE3}" + "${GUFI_SQLITE3} \"${GUFI_VT}\"" ) |& tee "${OUTPUT}" @DIFF@ @CMAKE_CURRENT_BINARY_DIR@/gufi_sqlite3.expected "${OUTPUT}" diff --git a/test/regression/gufi_vt.expected b/test/regression/gufi_vt.expected index dde933d61..3bb54a286 100644 --- a/test/regression/gufi_vt.expected +++ b/test/regression/gufi_vt.expected @@ -5,7 +5,7 @@ $ gufi_treesummary_all "prefix" $ ( echo ".load gufi_vt" echo "SELECT minsize, maxsize, minmtime, maxmtime FROM gufi_vt_treesummary('prefix', 2) ORDER BY minsize ASC, maxsize ASC;" -) | sqlite3 +) | sqlite3 "gufi_vt" -1|0|-1|0 0|1048576|0|1048576 1|5|1|5 @@ -17,7 +17,7 @@ $ ( $ ( echo ".load gufi_vt" echo "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_summary('prefix', 2) ORDER BY name ASC, size ASC;" -) | sqlite3 +) | sqlite3 "gufi_vt" directory|7|drwxrwxr-x|Thu Jan 01 00:00:07 UTC 1970 empty_directory|8|drwxrwxr-x|Thu Jan 01 00:00:08 UTC 1970 leaf_directory|13|drwxrwxr-x|Thu Jan 01 00:00:13 UTC 1970 @@ -29,7 +29,7 @@ unusual#? directory ,|16|drwxrwxr-x|Thu Jan 01 00:00:16 UTC 1970 $ ( echo ".load gufi_vt" echo "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_entries('prefix', 2) ORDER BY name ASC, size ASC;" -) | sqlite3 +) | sqlite3 "gufi_vt" .hidden|10|-rw-rw-r--|Thu Jan 01 00:00:10 UTC 1970 1KB|1024|-rw-rw-r--|Thu Jan 01 00:17:04 UTC 1970 1MB|1048576|-rw-rw-r--|Tue Jan 13 03:16:16 UTC 1970 @@ -49,7 +49,7 @@ writable|3|-rw-rw-rw-|Thu Jan 01 00:00:03 UTC 1970 $ ( echo ".load gufi_vt" echo "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_pentries('prefix', 2) ORDER BY name ASC, size ASC;" -) | sqlite3 +) | sqlite3 "gufi_vt" .hidden|10|-rw-rw-r--|Thu Jan 01 00:00:10 UTC 1970 1KB|1024|-rw-rw-r--|Thu Jan 01 00:17:04 UTC 1970 1MB|1048576|-rw-rw-r--|Tue Jan 13 03:16:16 UTC 1970 @@ -69,7 +69,7 @@ writable|3|-rw-rw-rw-|Thu Jan 01 00:00:03 UTC 1970 $ ( echo ".load gufi_vt" echo "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_vrsummary('prefix', 2) ORDER BY name ASC, size ASC;" -) | sqlite3 +) | sqlite3 "gufi_vt" directory|7|drwxrwxr-x|Thu Jan 01 00:00:07 UTC 1970 empty_directory|8|drwxrwxr-x|Thu Jan 01 00:00:08 UTC 1970 leaf_directory|13|drwxrwxr-x|Thu Jan 01 00:00:13 UTC 1970 @@ -81,7 +81,7 @@ unusual#? directory ,|16|drwxrwxr-x|Thu Jan 01 00:00:16 UTC 1970 $ ( echo ".load gufi_vt" echo "SELECT name, size, modetotxt(mode), strftime('%a %b %d %H:%M:%S UTC %Y', mtime) FROM gufi_vt_vrpentries('prefix', 2) ORDER BY name ASC, size ASC;" -) | sqlite3 +) | sqlite3 "gufi_vt" .hidden|10|-rw-rw-r--|Thu Jan 01 00:00:10 UTC 1970 1KB|1024|-rw-rw-r--|Thu Jan 01 00:17:04 UTC 1970 1MB|1048576|-rw-rw-r--|Tue Jan 13 03:16:16 UTC 1970 @@ -101,7 +101,7 @@ writable|3|-rw-rw-rw-|Thu Jan 01 00:00:03 UTC 1970 $ ( echo ".load gufi_vt" echo "SELECT name, size FROM gufi_vt_pentries('prefix', 2) WHERE size < 10 ORDER BY name ASC, size ASC;" -) | sqlite3 +) | sqlite3 "gufi_vt" directory_symlink|4 executable|1 file_symlink|9 @@ -114,7 +114,7 @@ writable|3 $ ( echo ".load gufi_vt" echo "SELECT name, size FROM gufi_vt_pentries('prefix', 2) WHERE size > 10 ORDER BY name ASC, size ASC;" -) | sqlite3 +) | sqlite3 "gufi_vt" 1KB|1024 1MB|1048576 leaf_file1|11 @@ -123,20 +123,21 @@ repeat_name|14 unusual, name?#|15 # Query entries in directory where name == 'directory' +# WHERE type != 'd' is necessary to remove results from S query $ ( echo ".load gufi_vt" - echo "SELECT name FROM gufi_vt_pentries('prefix', 2, NULL, 'SELECT NULL, NULL, NULL, NULL, * FROM summary WHERE name == ''directory'';') ORDER BY name ASC, size ASC;" -) | sqlite3 -directory + echo "SELECT name FROM gufi_vt_pentries('prefix', 2, NULL, 'SELECT NULL, NULL, NULL, NULL, NULL, * FROM summary WHERE name == ''directory'';') WHERE type != 'd' ORDER BY name ASC, size ASC;" +) | sqlite3 "gufi_vt" executable readonly writable # Query directories that contain entries larger than 1024 (only 1: prefix) +# WHERE type != 'd' is necessary to remove results from S query $ ( echo ".load gufi_vt" - echo "SELECT rowid, name, size, mtime FROM gufi_vt_pentries('prefix', 2, NULL, 'SELECT NULL, NULL, NULL, NULL, * FROM summary WHERE maxsize > 1024;') WHERE type != 'd' ORDER BY rowid ASC;" -) | sqlite3 + echo "SELECT rowid, name, size, mtime FROM gufi_vt_pentries('prefix', 2, NULL, 'SELECT NULL, NULL, NULL, NULL, NULL, * FROM summary WHERE maxsize > 1024;') WHERE type != 'd' ORDER BY rowid ASC;" +) | sqlite3 "gufi_vt" 1|.hidden|10|10 2|1KB|1024|1024 3|1MB|1048576|1048576 @@ -148,21 +149,21 @@ $ ( $ ( echo ".load gufi_vt" echo "SELECT path, epath, fpath, rpath FROM gufi_vt_pentries('prefix', 2) WHERE name == '.hidden';" -) | sqlite3 +) | sqlite3 "gufi_vt" prefix|prefix|prefix|prefix # Make sure all types work $ ( echo ".load gufi_vt" echo "SELECT name, size, size * 1.0, CAST(name AS BLOB), NULL FROM gufi_vt_pentries('prefix', 2) WHERE name == '.hidden';" -) | sqlite3 +) | sqlite3 "gufi_vt" .hidden|10|10.0|.hidden| # Missing thread count (not an error) $ ( echo ".load gufi_vt" echo "SELECT name FROM gufi_vt_pentries('prefix') ORDER BY name ASC, size ASC;" -) | sqlite3 +) | sqlite3 "gufi_vt" .hidden 1KB 1MB @@ -182,7 +183,7 @@ writable $ ( echo ".load gufi_vt" echo "SELECT name FROM gufi_vt_pentries('prefix', NULL) ORDER BY name ASC, size ASC;" -) | sqlite3 +) | sqlite3 "gufi_vt" .hidden 1KB 1MB @@ -202,34 +203,34 @@ writable $ ( echo ".load gufi_vt" echo "SELECT name FROM gufi_vt_pentries();" -) | sqlite3 +) | sqlite3 "gufi_vt" Parse error near line 2: no query solution # Bad indexroot $ ( echo ".load gufi_vt" echo "SELECT name FROM gufi_vt_pentries('baddir') ORDER BY name ASC, size ASC;" -) | sqlite3 +) | sqlite3 "gufi_vt" Could not get realpath of "baddir": No such file or directory (2) # Empty string thread count (error) $ ( echo ".load gufi_vt" echo "SELECT name FROM gufi_vt_pentries('prefix', '') ORDER BY name ASC, size ASC;" -) | sqlite3 +) | sqlite3 "gufi_vt" Runtime error near line 2: Bad thread count: '' (19) # Zero thread count (error) $ ( echo ".load gufi_vt" echo "SELECT name FROM gufi_vt_pentries('prefix', 0) ORDER BY name ASC, size ASC;" -) | sqlite3 +) | sqlite3 "gufi_vt" Runtime error near line 2: Bad thread count: '0' (19) # Bad SQL $ ( echo ".load gufi_vt" echo "SELECT name FROM gufi_vt_pentries('prefix', NULL, 'bad SQL') ORDER BY name ASC, size ASC;" -) | sqlite3 +) | sqlite3 "gufi_vt" Error: Could not prepare 'bad SQL' for getting column types: SQL logic error (1) diff --git a/test/regression/gufi_vt.sh.in b/test/regression/gufi_vt.sh.in index 219dd86fb..d61f274d1 100755 --- a/test/regression/gufi_vt.sh.in +++ b/test/regression/gufi_vt.sh.in @@ -87,11 +87,11 @@ query_vt() { echo "$ (" echo " echo \"${LOAD}\"" echo " echo \"${sql}\"" - echo ") | ${SQLITE3}" + echo ") | ${SQLITE3} \"${GUFI_VT}\"" ( echo "${LOAD}" echo "${sql}" - ) | PATH="@CMAKE_BINARY_DIR@/src:${PATH}" "${SQLITE3}" 2>&1 + ) | PATH="@CMAKE_BINARY_DIR@/src:${PATH}" LD_LIBRARY_PATH="@CMAKE_BINARY_DIR@/src:${LD_LIBRARY_PATH}" "${SQLITE3}" "${GUFI_VT}" 2>&1 echo } @@ -115,10 +115,12 @@ echo "# Query with WHERE size > 10" query_vt "SELECT name, size FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}) WHERE size > 10 ORDER BY name ASC, size ASC;" echo "# Query entries in directory where name == 'directory'" -query_vt "SELECT name FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}, NULL, 'SELECT NULL, NULL, NULL, NULL, * FROM summary WHERE name == ''directory'';') ORDER BY name ASC, size ASC;" +echo "# WHERE type != 'd' is necessary to remove results from S query" +query_vt "SELECT name FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}, NULL, 'SELECT NULL, NULL, NULL, NULL, NULL, * FROM summary WHERE name == ''directory'';') WHERE type != 'd' ORDER BY name ASC, size ASC;" echo "# Query directories that contain entries larger than 1024 (only 1: ${INDEXROOT})" -query_vt "SELECT rowid, name, size, mtime FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}, NULL, 'SELECT NULL, NULL, NULL, NULL, * FROM summary WHERE maxsize > 1024;') WHERE type != 'd' ORDER BY rowid ASC;" +echo "# WHERE type != 'd' is necessary to remove results from S query" +query_vt "SELECT rowid, name, size, mtime FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}, NULL, 'SELECT NULL, NULL, NULL, NULL, NULL, * FROM summary WHERE maxsize > 1024;') WHERE type != 'd' ORDER BY rowid ASC;" echo "# Paths" query_vt "SELECT path, epath, fpath, rpath FROM gufi_vt_pentries('${INDEXROOT}', ${THREADS}) WHERE name == '.hidden';" diff --git a/test/regression/longitudinal_snapshot.expected b/test/regression/longitudinal_snapshot.expected index c4af09c2a..3de0cf713 100644 --- a/test/regression/longitudinal_snapshot.expected +++ b/test/regression/longitudinal_snapshot.expected @@ -85,6 +85,7 @@ GUFI query is INSERT INTO entries SELECT level, name_len, extension, type, inode, mode, nlink, uid, gid, size, blksize, blocks, atime, mtime, ctime, ftime, linkname_len, crtime, ossint1, ossint2, ossint3, ossint4, osstext1_len, osstext2_len, pinode, ppinode, LENGTH(extension) FROM intermediate_entries; ' \ prefix gufi_sqlite3 \ + "gufi_vt" \ "longitudinal_snapshot.db" \ "ATTACH 'file:flattened_index.db?mode=ro' AS flatdb;" \ "DROP TABLE IF EXISTS main.treesummary; CREATE TABLE main.treesummary AS SELECT level, inode, pinode, CAST(SUM(totsubdirs) AS INT64) AS totsubdirs, CAST(MAX(maxsubdirfiles) AS INT64) AS maxsubdirfiles, CAST(MAX(maxsubdirlinks) AS INT64) AS maxsubdirlinks, CAST(MAX(maxsubdirsize) AS INT64) AS maxsubdirsize, CAST(SUM(totfiles) AS INT64) AS totfiles, CAST(SUM(totlinks) AS INT64) AS totlinks, CAST(MIN(minuid) AS INT64) AS minuid, CAST(MAX(maxuid) AS INT64) AS maxuid, CAST(MIN(mingid) AS INT64) AS mingid, CAST(MAX(maxgid) AS INT64) AS maxgid, CAST(MIN(minsize) AS INT64) AS minsize, CAST(MAX(maxsize) AS INT64) AS maxsize, CAST(SUM(totzero) AS INT64) AS totzero, CAST(SUM(totltk) AS INT64) AS totltk, CAST(SUM(totmtk) AS INT64) AS totmtk, CAST(SUM(totltm) AS INT64) AS totltm, CAST(SUM(totmtm) AS INT64) AS totmtm, CAST(SUM(totmtg) AS INT64) AS totmtg, CAST(SUM(totmtt) AS INT64) AS totmtt, CAST(SUM(totsize) AS INT64) AS totsize, CAST(MIN(minctime) AS INT64) AS minctime, CAST(MAX(maxctime) AS INT64) AS maxctime, CAST(MIN(minmtime) AS INT64) AS minmtime, CAST(MAX(maxmtime) AS INT64) AS maxmtime, CAST(MIN(minatime) AS INT64) AS minatime, CAST(MAX(maxatime) AS INT64) AS maxatime, CAST(MIN(minblocks) AS INT64) AS minblocks, CAST(MAX(maxblocks) AS INT64) AS maxblocks, CAST(SUM(totxattr) AS INT64) AS totxattr, CAST(MIN(mincrtime) AS INT64) AS mincrtime, CAST(MAX(maxcrtime) AS INT64) AS maxcrtime, CAST(MIN(minossint1) AS INT64) AS minossint1, CAST(MAX(maxossint1) AS INT64) AS maxossint1, CAST(SUM(totossint1) AS INT64) AS totossint1, CAST(MIN(minossint2) AS INT64) AS minossint2, CAST(MAX(maxossint2) AS INT64) AS maxossint2, CAST(SUM(totossint2) AS INT64) AS totossint2, CAST(MIN(minossint3) AS INT64) AS minossint3, CAST(MAX(maxossint3) AS INT64) AS maxossint3, CAST(SUM(totossint3) AS INT64) AS totossint3, CAST(MIN(minossint4) AS INT64) AS minossint4, CAST(MAX(maxossint4) AS INT64) AS maxossint4, CAST(SUM(totossint4) AS INT64) AS totossint4 FROM treesummary GROUP BY level" \