/ Check-in [8cd70960]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add support for -C to ".ar x".
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sqlar-shell-support
Files: files | file ages | folders
SHA3-256: 8cd70960c5ddf0d0b2c40b8b6af4ce6b0277ffdaf04f33fcb33227d2b99ad515
User & Date: dan 2017-12-09 18:28:22
Context
2017-12-11
20:22
Enhance virtual table "fsdir" in ext/misc/fileio.c. Add support for "-C" to the shell command's ".ar c" command. check-in: 0394889a user: dan tags: sqlar-shell-support
2017-12-09
18:28
Add support for -C to ".ar x". check-in: 8cd70960 user: dan tags: sqlar-shell-support
17:58
Improve parsing of ".ar" commands. Add new test file for the same. check-in: 840401cc user: dan tags: sqlar-shell-support
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/shell.c.in.

  4231   4231   
  4232   4232   
  4233   4233   /*
  4234   4234   ** Implementation of .ar "eXtract" command. 
  4235   4235   */
  4236   4236   static int arExtractCommand(ShellState *p, ArCommand *pAr){
  4237   4237     const char *zSql1 = 
  4238         -    "SELECT name, writefile(name, "
         4238  +    "SELECT :1 || name, writefile(:1 || name, "
  4239   4239       "CASE WHEN (data AND sz>=0 AND sz!=length(data)) THEN uncompress(data) "
  4240   4240       "   ELSE data END, "
  4241   4241       "mode) FROM sqlar";
  4242         -  const char *zSql2 = "SELECT name, mtime FROM sqlar"; 
         4242  +  const char *zSql2 = "SELECT :1 || name, mtime FROM sqlar"; 
  4243   4243   
  4244   4244     struct timespec times[2];
  4245   4245     sqlite3_stmt *pSql = 0;
  4246   4246     int rc = SQLITE_OK;
         4247  +  char *zDir = 0;
         4248  +
         4249  +  if( pAr->zDir ){
         4250  +    zDir = sqlite3_mprintf("%s/", pAr->zDir);
         4251  +  }else{
         4252  +    zDir = sqlite3_mprintf("");
         4253  +  }
  4247   4254   
  4248   4255     memset(times, 0, sizeof(times));
  4249   4256     times[0].tv_sec = time(0);
  4250   4257   
  4251   4258     shellPrepare(p, &rc, zSql1, &pSql);
         4259  +  if( rc==SQLITE_OK ){
         4260  +    sqlite3_bind_text(pSql, 1, zDir, -1, SQLITE_STATIC);
         4261  +  }
  4252   4262     while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
  4253   4263       if( pAr->bVerbose ){
  4254   4264         raw_printf(stdout, "%s\n", sqlite3_column_text(pSql, 0));
  4255   4265       }
  4256   4266     }
  4257   4267     shellFinalize(&rc, pSql);
  4258   4268   
  4259   4269     shellPrepare(p, &rc, zSql2, &pSql);
         4270  +  if( rc==SQLITE_OK ){
         4271  +    sqlite3_bind_text(pSql, 1, zDir, -1, SQLITE_STATIC);
         4272  +  }
  4260   4273     while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
  4261   4274       const char *zPath = (const char*)sqlite3_column_text(pSql, 0);
  4262   4275       times[1].tv_sec = (time_t)sqlite3_column_int64(pSql, 1);
  4263   4276       if( utimensat(AT_FDCWD, zPath, times, AT_SYMLINK_NOFOLLOW) ){
  4264   4277         raw_printf(stderr, "failed to set timestamp for %s\n", zPath);
  4265   4278         rc = SQLITE_ERROR;
  4266   4279         break;
  4267   4280       }
  4268   4281     }
  4269   4282     shellFinalize(&rc, pSql);
  4270   4283   
         4284  +  sqlite3_free(zDir);
  4271   4285     return rc;
  4272   4286   }
  4273   4287   
  4274   4288   /*
  4275   4289   ** Implementation of .ar "Create" command. 
  4276   4290   **
  4277   4291   ** Create the "sqlar" table in the database if it does not already exist.

Changes to test/shell8.test.

    30     30       file mkdir [file dirname $path]
    31     31       set fd [open $path w]
    32     32       puts -nonewline $fd $d
    33     33       close $fd
    34     34     }
    35     35   }
    36     36   
    37         -proc dir_to_list {dirname} {
           37  +proc dir_to_list {dirname {n -1}} {
           38  +  if {$n<0} {set n [llength [file split $dirname]]}
           39  +
    38     40     set res [list]
    39     41     foreach f [glob -nocomplain $dirname/*] {
    40     42       set mtime [file mtime $f]
    41     43       set perm [file attributes $f -perm]
    42         -    set relpath [file join {*}[lrange [file split $f] 1 end]]
           44  +    set relpath [file join {*}[lrange [file split $f] $n end]]
    43     45       lappend res 
    44     46       if {[file isdirectory $f]} {
    45     47         lappend res [list $relpath / $mtime $perm]
    46     48         lappend res {*}[dir_to_list $f]
    47     49       } else {
    48     50         set fd [open $f]
    49     51         set data [read $fd]
................................................................................
    73     75   
    74     76     catchcmd test_ar.db ".ar c ar1"
    75     77     file delete -force ar1
    76     78     catchcmd test_ar.db ".ar x"
    77     79   
    78     80     dir_to_list ar1
    79     81   } $expected
           82  +
           83  +do_test 1.2 {
           84  +  file delete -force ar3
           85  +  file mkdir ar3
           86  +  catchcmd test_ar.db ".ar xvC ar3"
           87  +  dir_to_list ar3/ar1
           88  +} $expected
    80     89   
    81     90   
    82     91   
    83     92   finish_test