/ Check-in [8cd70960]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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 Unified Diffs Ignore Whitespace Patch

Changes to src/shell.c.in.

4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246







4247
4248
4249
4250
4251



4252
4253
4254
4255
4256
4257
4258
4259



4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270

4271
4272
4273
4274
4275
4276
4277


/*
** Implementation of .ar "eXtract" command. 
*/
static int arExtractCommand(ShellState *p, ArCommand *pAr){
  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( pAr->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.







|



|




>
>
>
>
>
>
>





>
>
>








>
>
>











>







4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291


/*
** Implementation of .ar "eXtract" command. 
*/
static int arExtractCommand(ShellState *p, ArCommand *pAr){
  const char *zSql1 = 
    "SELECT :1 || name, writefile(:1 || name, "
    "CASE WHEN (data AND sz>=0 AND sz!=length(data)) THEN uncompress(data) "
    "   ELSE data END, "
    "mode) FROM sqlar";
  const char *zSql2 = "SELECT :1 || name, mtime FROM sqlar"; 

  struct timespec times[2];
  sqlite3_stmt *pSql = 0;
  int rc = SQLITE_OK;
  char *zDir = 0;

  if( pAr->zDir ){
    zDir = sqlite3_mprintf("%s/", pAr->zDir);
  }else{
    zDir = sqlite3_mprintf("");
  }

  memset(times, 0, sizeof(times));
  times[0].tv_sec = time(0);

  shellPrepare(p, &rc, zSql1, &pSql);
  if( rc==SQLITE_OK ){
    sqlite3_bind_text(pSql, 1, zDir, -1, SQLITE_STATIC);
  }
  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
    if( pAr->bVerbose ){
      raw_printf(stdout, "%s\n", sqlite3_column_text(pSql, 0));
    }
  }
  shellFinalize(&rc, pSql);

  shellPrepare(p, &rc, zSql2, &pSql);
  if( rc==SQLITE_OK ){
    sqlite3_bind_text(pSql, 1, zDir, -1, SQLITE_STATIC);
  }
  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);

  sqlite3_free(zDir);
  return rc;
}

/*
** Implementation of .ar "Create" command. 
**
** Create the "sqlar" table in the database if it does not already exist.

Changes to test/shell8.test.

30
31
32
33
34
35
36
37


38
39
40
41
42
43
44
45
46
47
48
49
..
73
74
75
76
77
78
79







80
81
82
83
    file mkdir [file dirname $path]
    set fd [open $path w]
    puts -nonewline $fd $d
    close $fd
  }
}

proc dir_to_list {dirname} {


  set res [list]
  foreach f [glob -nocomplain $dirname/*] {
    set mtime [file mtime $f]
    set perm [file attributes $f -perm]
    set relpath [file join {*}[lrange [file split $f] 1 end]]
    lappend res 
    if {[file isdirectory $f]} {
      lappend res [list $relpath / $mtime $perm]
      lappend res {*}[dir_to_list $f]
    } else {
      set fd [open $f]
      set data [read $fd]
................................................................................

  catchcmd test_ar.db ".ar c ar1"
  file delete -force ar1
  catchcmd test_ar.db ".ar x"

  dir_to_list ar1
} $expected










finish_test







|
>
>




|







 







>
>
>
>
>
>
>




30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
..
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
    file mkdir [file dirname $path]
    set fd [open $path w]
    puts -nonewline $fd $d
    close $fd
  }
}

proc dir_to_list {dirname {n -1}} {
  if {$n<0} {set n [llength [file split $dirname]]}

  set res [list]
  foreach f [glob -nocomplain $dirname/*] {
    set mtime [file mtime $f]
    set perm [file attributes $f -perm]
    set relpath [file join {*}[lrange [file split $f] $n end]]
    lappend res 
    if {[file isdirectory $f]} {
      lappend res [list $relpath / $mtime $perm]
      lappend res {*}[dir_to_list $f]
    } else {
      set fd [open $f]
      set data [read $fd]
................................................................................

  catchcmd test_ar.db ".ar c ar1"
  file delete -force ar1
  catchcmd test_ar.db ".ar x"

  dir_to_list ar1
} $expected

do_test 1.2 {
  file delete -force ar3
  file mkdir ar3
  catchcmd test_ar.db ".ar xvC ar3"
  dir_to_list ar3/ar1
} $expected



finish_test