Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the ".ar x" command to the shell. For extracting the contents of sqlar archives. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | sqlar-shell-support |
Files: | files | file ages | folders |
SHA3-256: |
0cc699d14adfe8c7b7be50c180186562 |
User & Date: | dan 2017-12-07 21:03:33.903 |
Context
2017-12-09
| ||
17:58 | Improve parsing of ".ar" commands. Add new test file for the same. (check-in: 840401cc8c user: dan tags: sqlar-shell-support) | |
2017-12-07
| ||
21:03 | Add the ".ar x" command to the shell. For extracting the contents of sqlar archives. (check-in: 0cc699d14a user: dan tags: sqlar-shell-support) | |
15:44 | Begin adding support for the sqlar archive format to shell.c. There is no "extract" command so far, only "create". (check-in: c9827a01a6 user: dan tags: sqlar-shell-support) | |
Changes
Changes to ext/misc/fileio.c.
︙ | ︙ | |||
26 27 28 29 30 31 32 33 34 35 36 37 38 39 | ** data: For a regular file, a blob containing the file data. For a ** symlink, a text value containing the text of the link. For a ** directory, NULL. */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #include <stdio.h> #define FSDIR_SCHEMA "CREATE TABLE x(name,mode,mtime,data,dir HIDDEN)" static void readFileContents(sqlite3_context *ctx, const char *zName){ FILE *in; long nIn; void *pBuf; | > > > > > > > > > > > | 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 | ** data: For a regular file, a blob containing the file data. For a ** symlink, a text value containing the text of the link. For a ** directory, NULL. */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #include <stdio.h> #include <string.h> #include <assert.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <dirent.h> #include <time.h> #include <utime.h> #define FSDIR_SCHEMA "CREATE TABLE x(name,mode,mtime,data,dir HIDDEN)" static void readFileContents(sqlite3_context *ctx, const char *zName){ FILE *in; long nIn; void *pBuf; |
︙ | ︙ | |||
64 65 66 67 68 69 70 71 72 | ){ const char *zName; (void)(argc); /* Unused parameter */ zName = (const char*)sqlite3_value_text(argv[0]); if( zName==0 ) return; readFileContents(context, zName); } /* | > > > > > > > > > > | > | | | < | > | > | > > > | | > > > > > > > > > > > > > > > > > > > > > | | > > > > > | | < < | > > > > | > | > | > > > > > > > < < < < < | 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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | ){ const char *zName; (void)(argc); /* Unused parameter */ zName = (const char*)sqlite3_value_text(argv[0]); if( zName==0 ) return; readFileContents(context, zName); } static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){ char *zMsg = 0; va_list ap; va_start(ap, zFmt); zMsg = sqlite3_vmprintf(zFmt, ap); sqlite3_result_error(ctx, zMsg, -1); sqlite3_free(zMsg); va_end(ap); } /* ** Implementation of the "writefile(W,X[,Y]])" SQL function. ** ** The argument X is written into file W. The number of bytes written is ** returned. Or NULL is returned if something goes wrong, such as being unable ** to open file X for writing. */ static void writefileFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zFile; mode_t mode = 0; if( argc<2 || argc>3 ){ sqlite3_result_error(context, "wrong number of arguments to function writefile()", -1 ); return; } zFile = (const char*)sqlite3_value_text(argv[0]); if( zFile==0 ) return; if( argc>=3 ){ sqlite3_result_int(context, 0); mode = sqlite3_value_int(argv[2]); } if( S_ISLNK(mode) ){ const char *zTo = (const char*)sqlite3_value_text(argv[1]); if( symlink(zTo, zFile)<0 ){ ctxErrorMsg(context, "failed to create symlink: %s", zFile); return; } }else{ if( S_ISDIR(mode) ){ if( mkdir(zFile, mode) ){ ctxErrorMsg(context, "failed to create directory: %s", zFile); return; } }else{ sqlite3_int64 nWrite = 0; const char *z; int rc = 0; FILE *out = fopen(zFile, "wb"); if( out==0 ){ if( argc>2 ){ ctxErrorMsg(context, "failed to open file for writing: %s", zFile); } return; } z = (const char*)sqlite3_value_blob(argv[1]); if( z ){ sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out); nWrite = sqlite3_value_bytes(argv[1]); if( nWrite!=n ){ ctxErrorMsg(context, "failed to write file: %s", zFile); rc = 1; } } fclose(out); if( rc ) return; sqlite3_result_int64(context, nWrite); } if( argc>2 && chmod(zFile, mode & 0777) ){ ctxErrorMsg(context, "failed to chmod file: %s", zFile); return; } } } #ifndef SQLITE_OMIT_VIRTUALTABLE /* */ typedef struct fsdir_cursor fsdir_cursor; struct fsdir_cursor { sqlite3_vtab_cursor base; /* Base class - must be first */ int eType; /* One of FSDIR_DIR or FSDIR_ENTRY */ DIR *pDir; /* From opendir() */ |
︙ | ︙ | |||
459 460 461 462 463 464 465 | ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0, readfileFunc, 0, 0); if( rc==SQLITE_OK ){ | | | 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 | ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0, readfileFunc, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "writefile", -1, SQLITE_UTF8, 0, writefileFunc, 0, 0); } if( rc==SQLITE_OK ){ rc = fsdirRegister(db); } return rc; } |
Changes to src/shell.c.in.
︙ | ︙ | |||
4092 4093 4094 4095 4096 4097 4098 | } } static void shellFinalize( int *pRc, sqlite3_stmt *pStmt ){ | > > | | > > > > > > | > > > | > > > > > > | > > | | > > > > > > > > > > > > > | 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 | } } static void shellFinalize( int *pRc, sqlite3_stmt *pStmt ){ if( pStmt ){ sqlite3 *db = sqlite3_db_handle(pStmt); int rc = sqlite3_finalize(pStmt); if( *pRc==SQLITE_OK ){ if( rc!=SQLITE_OK ){ raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db)); } *pRc = rc; } } } static void shellReset( int *pRc, sqlite3_stmt *pStmt ){ int rc = sqlite3_reset(pStmt); if( *pRc==SQLITE_OK ) *pRc = rc; } /* ** Implementation of .ar "eXtract" command. */ static int arExtractCommand(ShellState *p, int bVerbose){ const char *zSql1 = "SELECT name, writefile(name, " "CASE WHEN (data AND sz>=0 AND sz!=length(data)) THEN uncompress(data) " " ELSE data END, " "mode) FROM sqlar"; const char *zSql2 = "SELECT name, mtime FROM sqlar"; struct timespec times[2]; sqlite3_stmt *pSql = 0; int rc = SQLITE_OK; memset(times, 0, sizeof(times)); times[0].tv_sec = time(0); shellPrepare(p, &rc, zSql1, &pSql); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ if( bVerbose ){ raw_printf(stdout, "%s\n", sqlite3_column_text(pSql, 0)); } } shellFinalize(&rc, pSql); shellPrepare(p, &rc, zSql2, &pSql); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ const char *zPath = (const char*)sqlite3_column_text(pSql, 0); times[1].tv_sec = (time_t)sqlite3_column_int64(pSql, 1); if( utimensat(AT_FDCWD, zPath, times, AT_SYMLINK_NOFOLLOW) ){ raw_printf(stderr, "failed to set timestamp for %s\n", zPath); rc = SQLITE_ERROR; break; } } shellFinalize(&rc, pSql); return rc; } /* ** Implementation of .ar "Create" command. ** ** Create the "sqlar" table in the database if it does not already exist. |
︙ | ︙ |