/ Check-in [52d12ba9]
Login

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

Overview
Comment:In the fileio.c extension, change the filetype(MODE) function into lsmode(MODE). Use the new lsmode(MODE) function in shell.c.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | archive-improvements
Files: files | file ages | folders
SHA3-256: 52d12ba9f33c1f2620776e189c81f3bf991759344ecdd167ea2a6107f0972b9d
User & Date: drh 2018-01-10 17:19:16
Context
2018-01-10
17:39
Fix minor problems with the new ".archive" command changes. Closed-Leaf check-in: 612b30c9 user: drh tags: archive-improvements
17:19
In the fileio.c extension, change the filetype(MODE) function into lsmode(MODE). Use the new lsmode(MODE) function in shell.c. check-in: 52d12ba9 user: drh tags: archive-improvements
16:50
Implement the ".ar --create" command using a single "REPLACE INTO sqlar SELECT ... FROM fsdir();" statement. Add the shell_putsnl() SQL function for providing --verbose output. check-in: 28ab9304 user: drh tags: archive-improvements
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/misc/fileio.c.

   354    354       }else{
   355    355         ctxErrorMsg(context, "failed to write file: %s", zFile);
   356    356       }
   357    357     }
   358    358   }
   359    359   
   360    360   /*
   361         -** SQL function:   filetype(MODE)
          361  +** SQL function:   lsmode(MODE)
   362    362   **
   363         -** Based on the integer mode, return one of "file", "directory", or "symlink".
          363  +** Given a numberic st_mode from stat(), convert it into a human-readable
          364  +** text string in the style of "ls -l".
   364    365   */
   365         -static void fileTypeFunc(
          366  +static void lsModeFunc(
   366    367     sqlite3_context *context,
   367    368     int argc,
   368    369     sqlite3_value **argv
   369    370   ){
   370         -  const char *zMode;
          371  +  int i;
   371    372     int iMode = sqlite3_value_int(argv[0]);
          373  +  char z[16];
   372    374     if( S_ISLNK(iMode) ){
   373         -    zMode = "symlink";
          375  +    z[0] = 'l';
   374    376     }else if( S_ISREG(iMode) ){
   375         -    zMode = "file";
          377  +    z[0] = '-';
   376    378     }else if( S_ISDIR(iMode) ){
   377         -    zMode = "directory";
          379  +    z[0] = 'd';
   378    380     }else{
   379         -    zMode = "unknown";
          381  +    z[0] = '?';
   380    382     }
   381         -  sqlite3_result_text(context, zMode, -1, SQLITE_STATIC);
          383  +  for(i=0; i<3; i++){
          384  +    int m = (iMode >> ((2-i)*3));
          385  +    char *a = &z[1 + i*3];
          386  +    a[0] = (m & 0x4) ? 'r' : '-';
          387  +    a[1] = (m & 0x2) ? 'w' : '-';
          388  +    a[2] = (m & 0x1) ? 'x' : '-';
          389  +  }
          390  +  z[10] = '\0';
          391  +  sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
   382    392   }
   383    393   
   384    394   #ifndef SQLITE_OMIT_VIRTUALTABLE
   385    395   
   386    396   /* 
   387    397   ** Cursor type for recursively iterating through a directory structure.
   388    398   */
................................................................................
   789    799     rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
   790    800                                  readfileFunc, 0, 0);
   791    801     if( rc==SQLITE_OK ){
   792    802       rc = sqlite3_create_function(db, "writefile", -1, SQLITE_UTF8, 0,
   793    803                                    writefileFunc, 0, 0);
   794    804     }
   795    805     if( rc==SQLITE_OK ){
   796         -    rc = sqlite3_create_function(db, "fileType", 1, SQLITE_UTF8, 0,
   797         -                                 fileTypeFunc, 0, 0);
          806  +    rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
          807  +                                 lsModeFunc, 0, 0);
   798    808     }
   799    809     if( rc==SQLITE_OK ){
   800    810       rc = fsdirRegister(db);
   801    811     }
   802    812     return rc;
   803    813   }

Changes to src/shell.c.in.

  4852   4852           zSep = " OR ";
  4853   4853         }
  4854   4854       }
  4855   4855     }
  4856   4856     *pzWhere = zWhere;
  4857   4857   }
  4858   4858   
  4859         -/*
  4860         -** Argument zMode must point to a buffer at least 11 bytes in size. This
  4861         -** function populates this buffer with the string interpretation of
  4862         -** the unix file mode passed as the second argument (e.g. "drwxr-xr-x").
  4863         -*/
  4864         -static void shellModeToString(char *zMode, int mode){
  4865         -  int i;
  4866         -
  4867         -  /* Magic numbers copied from [man 2 stat] */
  4868         -  if( mode & 0040000 ){
  4869         -    zMode[0] = 'd';
  4870         -  }else if( (mode & 0120000)==0120000 ){
  4871         -    zMode[0] = 'l';
  4872         -  }else{
  4873         -    zMode[0] = '-';
  4874         -  }
  4875         -
  4876         -  for(i=0; i<3; i++){
  4877         -    int m = (mode >> ((2-i)*3));
  4878         -    char *a = &zMode[1 + i*3];
  4879         -    a[0] = (m & 0x4) ? 'r' : '-';
  4880         -    a[1] = (m & 0x2) ? 'w' : '-';
  4881         -    a[2] = (m & 0x1) ? 'x' : '-';
  4882         -  }
  4883         -  zMode[10] = '\0';
  4884         -}
  4885         -
  4886   4859   /*
  4887   4860   ** Implementation of .ar "lisT" command. 
  4888   4861   */
  4889   4862   static int arListCommand(ArCommand *pAr){
  4890   4863     const char *zSql = "SELECT %s FROM %s WHERE %s"; 
  4891   4864     const char *azCols[] = {
  4892   4865       "name",
  4893         -    "mode, sz, datetime(mtime, 'unixepoch'), name"
         4866  +    "lsmode(mode), sz, datetime(mtime, 'unixepoch'), name"
  4894   4867     };
  4895   4868   
  4896   4869     char *zWhere = 0;
  4897   4870     sqlite3_stmt *pSql = 0;
  4898   4871     int rc;
  4899   4872   
  4900   4873     rc = arCheckEntries(pAr);
................................................................................
  4903   4876     shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose],
  4904   4877                        pAr->zSrcTable, zWhere);
  4905   4878     if( pAr->bDryRun ){
  4906   4879       utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql));
  4907   4880     }else{
  4908   4881       while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
  4909   4882         if( pAr->bVerbose ){
  4910         -        char zMode[11];
  4911         -        shellModeToString(zMode, sqlite3_column_int(pSql, 0));
  4912         -  
  4913         -        utf8_printf(pAr->p->out, "%s % 10d  %s  %s\n", zMode,
         4883  +        utf8_printf(pAr->p->out, "%s % 10d  %s  %s\n",
         4884  +            sqlite3_column_text(pSql, 0),
  4914   4885               sqlite3_column_int(pSql, 1), 
  4915   4886               sqlite3_column_text(pSql, 2),
  4916   4887               sqlite3_column_text(pSql, 3)
  4917   4888           );
  4918   4889         }else{
  4919   4890           utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0));
  4920   4891         }
................................................................................
  5001   4972   */
  5002   4973   static int arExecSql(ArCommand *pAr, const char *zSql){
  5003   4974     int rc;
  5004   4975     if( pAr->bDryRun ){
  5005   4976       utf8_printf(pAr->p->out, "%s\n", zSql);
  5006   4977       rc = SQLITE_OK;
  5007   4978     }else{
  5008         -    rc = sqlite3_exec(pAr->db, zSql, 0, 0, 0);
         4979  +    char *zErr = 0;
         4980  +    rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
         4981  +    if( zErr ){
         4982  +      utf8_printf(stdout, "ERROR: %s\n", zErr);
         4983  +      sqlite3_free(zErr);
         4984  +    }
  5009   4985     }
  5010   4986     return rc;
  5011   4987   }
  5012   4988   
  5013   4989   
  5014   4990   /*
  5015   4991   ** Implementation of .ar "create" and "update" commands.
................................................................................
  5037   5013     const char *zDrop = "DROP TABLE IF EXISTS sqlar";
  5038   5014     const char *zInsertFmt = 
  5039   5015        "REPLACE INTO sqlar(name,mode,mtime,sz,data)\n"
  5040   5016        "  SELECT\n"
  5041   5017        "    %s,\n"
  5042   5018        "    mode,\n"
  5043   5019        "    mtime,\n"
  5044         -     "    CASE filetype(mode)\n"
  5045         -     "      WHEN 'file' THEN length(data)\n"
  5046         -     "      WHEN 'directory' THEN 0\n"
         5020  +     "    CASE substr(lsmode(mode),1,1)\n"
         5021  +     "      WHEN '-' THEN length(data)\n"
         5022  +     "      WHEN 'd' THEN 0\n"
  5047   5023        "      ELSE -1 END,\n"
  5048         -     "    CASE WHEN filetype(mode)<>'directory' THEN data ELSE NULL END\n"
         5024  +     "    CASE WHEN lsmode(mode) LIKE 'd%%' THEN NULL else data END\n"
  5049   5025        "  FROM fsdir(%Q,%Q)\n"
  5050         -     "  WHERE filetype(mode)<>'unknown'";
         5026  +     "  WHERE lsmode(mode) NOT LIKE '?%%';";
  5051   5027     int i;                          /* For iterating through azFile[] */
  5052   5028     int rc;                         /* Return code */
  5053   5029   
  5054   5030     rc = arExecSql(pAr, "SAVEPOINT ar;");
  5055   5031     if( rc!=SQLITE_OK ) return rc;
  5056   5032     if( bUpdate==0 ){
  5057   5033       rc = arExecSql(pAr, zDrop);