SQLite

Check-in [848f87e22f]
Login

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

Overview
Comment:Merge the command-line shell enhancements from trunk. Other edits toward trying to get ssdsim to run.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | ssdsim
Files: files | file ages | folders
SHA1: 848f87e22fc6bfbbb7dbc7491c8a20cdd53b7420
User & Date: drh 2012-10-25 15:32:29.056
Context
2012-10-25
23:47
Further work on getting ssdsim to run. This is an incremental checkin to save my place while jumping off to work on other things. (Leaf check-in: ae2f1627b1 user: drh tags: ssdsim)
15:32
Merge the command-line shell enhancements from trunk. Other edits toward trying to get ssdsim to run. (check-in: 848f87e22f user: drh tags: ssdsim)
15:23
Improvements to the command-line argument parsing in the command-line shell. Command-line options can now occur either before or after the database name and first command and are still accepted and processed. Command-line options are processed even if no database name is given (and :memory: is assumed). (check-in: 317c80cba3 user: drh tags: trunk)
01:50
Initial check-in of a test VFS designed to simulate a NAND-flash SSD for the purpose of measuring and subsequently minimizing write amplification caused by SQLite. The code in this check-in compiles but does not run. (check-in: 9e6efcf054 user: drh tags: ssdsim)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/shell.c.
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838



2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
/*
** Show available command line options
*/
static const char zOptions[] = 
  "   -bail                stop after hitting an error\n"
  "   -batch               force batch I/O\n"
  "   -column              set output mode to 'column'\n"
  "   -cmd command         run \"command\" before reading stdin\n"
  "   -csv                 set output mode to 'csv'\n"
  "   -echo                print commands before execution\n"
  "   -init filename       read/process named file\n"
  "   -[no]header          turn headers on or off\n"



  "   -help                show this message\n"
  "   -html                set output mode to HTML\n"
  "   -interactive         force interactive I/O\n"
  "   -line                set output mode to 'line'\n"
  "   -list                set output mode to 'list'\n"
#ifdef SQLITE_ENABLE_MULTIPLEX
  "   -multiplex           enable the multiplexor VFS\n"
#endif
  "   -nullvalue 'text'    set text string for NULL values\n"
  "   -separator 'x'       set output field separator (|)\n"
  "   -stats               print memory stats before each finalize\n"
  "   -version             show SQLite version\n"
  "   -vfs NAME            use NAME as the default VFS\n"
#ifdef SQLITE_ENABLE_VFSTRACE
  "   -vfstrace            enable tracing of all VFS calls\n"
#endif
;







|




>
>
>








|
|







2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
/*
** Show available command line options
*/
static const char zOptions[] = 
  "   -bail                stop after hitting an error\n"
  "   -batch               force batch I/O\n"
  "   -column              set output mode to 'column'\n"
  "   -cmd COMMIT          run \"COMMAND\" before reading stdin\n"
  "   -csv                 set output mode to 'csv'\n"
  "   -echo                print commands before execution\n"
  "   -init filename       read/process named file\n"
  "   -[no]header          turn headers on or off\n"
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
  "   -heap SIZE           Size of heap for memsys3 or memsys5\n"
#endif
  "   -help                show this message\n"
  "   -html                set output mode to HTML\n"
  "   -interactive         force interactive I/O\n"
  "   -line                set output mode to 'line'\n"
  "   -list                set output mode to 'list'\n"
#ifdef SQLITE_ENABLE_MULTIPLEX
  "   -multiplex           enable the multiplexor VFS\n"
#endif
  "   -nullvalue TEXT      set text string for NULL values. Default ''\n"
  "   -separator SEP       set output field separator. Default: '|'\n"
  "   -stats               print memory stats before each finalize\n"
  "   -version             show SQLite version\n"
  "   -vfs NAME            use NAME as the default VFS\n"
#ifdef SQLITE_ENABLE_VFSTRACE
  "   -vfstrace            enable tracing of all VFS calls\n"
#endif
;
2876
2877
2878
2879
2880
2881
2882













2883
2884
2885
2886
2887
2888
2889
  data->showHeader = 0;
  sqlite3_config(SQLITE_CONFIG_URI, 1);
  sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
  sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
  sqlite3_snprintf(sizeof(continuePrompt), continuePrompt,"   ...> ");
  sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
}














int main(int argc, char **argv){
  char *zErrMsg = 0;
  struct callback_data data;
  const char *zInitFile = 0;
  char *zFirstCmd = 0;
  int i;







>
>
>
>
>
>
>
>
>
>
>
>
>







2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
  data->showHeader = 0;
  sqlite3_config(SQLITE_CONFIG_URI, 1);
  sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
  sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
  sqlite3_snprintf(sizeof(continuePrompt), continuePrompt,"   ...> ");
  sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
}

/*
** Get the argument to an --option.  Throw an error and die if no argument
** is available.
*/
static char *cmdline_option_value(int argc, char **argv, int i){
  if( i==argc ){
    fprintf(stderr, "%s: Error: missing argument to %s\n",
            argv[0], argv[argc-1]);
    exit(1);
  }
  return argv[i];
}

int main(int argc, char **argv){
  char *zErrMsg = 0;
  struct callback_data data;
  const char *zInitFile = 0;
  char *zFirstCmd = 0;
  int i;
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916













2917
2918
2919
2920
2921
2922
2923
2924
2925

2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
#endif

  /* Do an initial pass through the command-line argument to locate
  ** the name of the database file, the name of the initialization file,
  ** the size of the alternative malloc heap,
  ** and the first command to execute.
  */
  for(i=1; i<argc-1; i++){
    char *z;
    if( argv[i][0]!='-' ) break;
    z = argv[i];













    if( z[1]=='-' ) z++;
    if( strcmp(z,"-separator")==0
     || strcmp(z,"-nullvalue")==0
     || strcmp(z,"-cmd")==0
    ){
      i++;
    }else if( strcmp(z,"-init")==0 ){
      i++;
      zInitFile = argv[i];

    /* Need to check for batch mode here to so we can avoid printing
    ** informational messages (like from process_sqliterc) before 
    ** we do the actual processing of arguments later in a second pass.
    */
    }else if( strcmp(z,"-batch")==0 ){
      stdin_is_interactive = 0;
    }else if( strcmp(z,"-heap")==0 ){
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
      int j, c;
      const char *zSize;
      sqlite3_int64 szHeap;

      zSize = argv[++i];
      szHeap = atoi(zSize);
      for(j=0; (c = zSize[j])!=0; j++){
        if( c=='M' ){ szHeap *= 1000000; break; }
        if( c=='K' ){ szHeap *= 1000; break; }
        if( c=='G' ){ szHeap *= 1000000000; break; }
      }
      if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;







|

<

>
>
>
>
>
>
>
>
>
>
>
>
>





|

<
|
>
|
|
|
|
<







|







2922
2923
2924
2925
2926
2927
2928
2929
2930

2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951

2952
2953
2954
2955
2956
2957

2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
#endif

  /* Do an initial pass through the command-line argument to locate
  ** the name of the database file, the name of the initialization file,
  ** the size of the alternative malloc heap,
  ** and the first command to execute.
  */
  for(i=1; i<argc; i++){
    char *z;

    z = argv[i];
    if( z[0]!='-' ){
      if( data.zDbFilename==0 ){
        data.zDbFilename = z;
        continue;
      }
      if( zFirstCmd==0 ){
        zFirstCmd = z;
        continue;
      }
      fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
      fprintf(stderr,"Use -help for a list of options.\n");
      return 1;
    }
    if( z[1]=='-' ) z++;
    if( strcmp(z,"-separator")==0
     || strcmp(z,"-nullvalue")==0
     || strcmp(z,"-cmd")==0
    ){
      (void)cmdline_option_value(argc, argv, ++i);
    }else if( strcmp(z,"-init")==0 ){

      zInitFile = cmdline_option_value(argc, argv, ++i);
    }else if( strcmp(z,"-batch")==0 ){
      /* Need to check for batch mode here to so we can avoid printing
      ** informational messages (like from process_sqliterc) before 
      ** we do the actual processing of arguments later in a second pass.
      */

      stdin_is_interactive = 0;
    }else if( strcmp(z,"-heap")==0 ){
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
      int j, c;
      const char *zSize;
      sqlite3_int64 szHeap;

      zSize = cmdline_option_value(argc, argv, ++i);
      szHeap = atoi(zSize);
      for(j=0; (c = zSize[j])!=0; j++){
        if( c=='M' ){ szHeap *= 1000000; break; }
        if( c=='K' ){ szHeap *= 1000; break; }
        if( c=='G' ){ szHeap *= 1000000000; break; }
      }
      if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994

2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
    }else if( strcmp(z,"-multiplex")==0 ){
      extern int sqlite3_multiple_initialize(const char*,int);
      sqlite3_multiplex_initialize(0, 1);
#endif
#ifdef SQLITE_ENABLE_SSDSIM
    }else if( strcmp(z, "-ssdsim")==0 ){
      extern int ssdsim_register(const char*,const char*,int);
      ssdsim_register(0, argv[++i], 1);
#endif
    }else if( strcmp(z,"-vfs")==0 ){
      sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
      if( pVfs ){
        sqlite3_vfs_register(pVfs, 1);
      }else{
        fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
        exit(1);
      }
    }
  }
  if( i<argc ){
    data.zDbFilename = argv[i++];
  }else{
#ifndef SQLITE_OMIT_MEMORYDB
    data.zDbFilename = ":memory:";
#else
    data.zDbFilename = 0;
#endif
  }
  if( i<argc ){
    zFirstCmd = argv[i++];
  }
  if( i<argc ){
    fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
    fprintf(stderr,"Use -help for a list of options.\n");
    return 1;

  }
  data.out = stdout;

#ifdef SQLITE_OMIT_MEMORYDB
  if( data.zDbFilename==0 ){
    fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
    return 1;
  }
#endif

  /* Go ahead and open the database file if it already exists.  If the
  ** file does not exist, delay opening it.  This prevents empty database
  ** files from being created if a user mistypes the database name argument
  ** to the sqlite command-line tool.
  */
  if( access(data.zDbFilename, 0)==0 ){







|


|








<
|
<



<
<
<
<
<
<
<
|
<

>


<
<
<
<
<
<
<







2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005

3006

3007
3008
3009







3010

3011
3012
3013
3014







3015
3016
3017
3018
3019
3020
3021
    }else if( strcmp(z,"-multiplex")==0 ){
      extern int sqlite3_multiple_initialize(const char*,int);
      sqlite3_multiplex_initialize(0, 1);
#endif
#ifdef SQLITE_ENABLE_SSDSIM
    }else if( strcmp(z, "-ssdsim")==0 ){
      extern int ssdsim_register(const char*,const char*,int);
      ssdsim_register(0, cmdline_option_value(argc,argv,++i), 1);
#endif
    }else if( strcmp(z,"-vfs")==0 ){
      sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
      if( pVfs ){
        sqlite3_vfs_register(pVfs, 1);
      }else{
        fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
        exit(1);
      }
    }
  }

  if( data.zDbFilename==0 ){

#ifndef SQLITE_OMIT_MEMORYDB
    data.zDbFilename = ":memory:";
#else







    fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);

    return 1;
#endif
  }
  data.out = stdout;








  /* Go ahead and open the database file if it already exists.  If the
  ** file does not exist, delay opening it.  This prevents empty database
  ** files from being created if a user mistypes the database name argument
  ** to the sqlite command-line tool.
  */
  if( access(data.zDbFilename, 0)==0 ){
3021
3022
3023
3024
3025
3026
3027
3028
3029

3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053

3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
  }

  /* Make a second pass through the command-line argument and set
  ** options.  This second pass is delayed until after the initialization
  ** file is processed so that the command-line arguments will override
  ** settings in the initialization file.
  */
  for(i=1; i<argc && argv[i][0]=='-'; i++){
    char *z = argv[i];

    if( z[1]=='-' ){ z++; }
    if( strcmp(z,"-init")==0 ){
      i++;
    }else if( strcmp(z,"-html")==0 ){
      data.mode = MODE_Html;
    }else if( strcmp(z,"-list")==0 ){
      data.mode = MODE_List;
    }else if( strcmp(z,"-line")==0 ){
      data.mode = MODE_Line;
    }else if( strcmp(z,"-column")==0 ){
      data.mode = MODE_Column;
    }else if( strcmp(z,"-csv")==0 ){
      data.mode = MODE_Csv;
      memcpy(data.separator,",",2);
    }else if( strcmp(z,"-separator")==0 ){
      i++;
      if(i>=argc){
        fprintf(stderr,"%s: Error: missing argument for option: %s\n",
                        Argv0, z);
        fprintf(stderr,"Use -help for a list of options.\n");
        return 1;
      }
      sqlite3_snprintf(sizeof(data.separator), data.separator,
                       "%.*s",(int)sizeof(data.separator)-1,argv[i]);

    }else if( strcmp(z,"-nullvalue")==0 ){
      i++;
      if(i>=argc){
        fprintf(stderr,"%s: Error: missing argument for option: %s\n",
                        Argv0, z);
        fprintf(stderr,"Use -help for a list of options.\n");
        return 1;
      }
      sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
                       "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
    }else if( strcmp(z,"-header")==0 ){
      data.showHeader = 1;
    }else if( strcmp(z,"-noheader")==0 ){
      data.showHeader = 0;
    }else if( strcmp(z,"-echo")==0 ){
      data.echoOn = 1;
    }else if( strcmp(z,"-stats")==0 ){







|

>















<
<
<
<
<
<
<

<
>

<
<
<
<
<
<
<

|







3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056







3057

3058
3059







3060
3061
3062
3063
3064
3065
3066
3067
3068
  }

  /* Make a second pass through the command-line argument and set
  ** options.  This second pass is delayed until after the initialization
  ** file is processed so that the command-line arguments will override
  ** settings in the initialization file.
  */
  for(i=1; i<argc; i++){
    char *z = argv[i];
    if( z[0]!='-' ) continue;
    if( z[1]=='-' ){ z++; }
    if( strcmp(z,"-init")==0 ){
      i++;
    }else if( strcmp(z,"-html")==0 ){
      data.mode = MODE_Html;
    }else if( strcmp(z,"-list")==0 ){
      data.mode = MODE_List;
    }else if( strcmp(z,"-line")==0 ){
      data.mode = MODE_Line;
    }else if( strcmp(z,"-column")==0 ){
      data.mode = MODE_Column;
    }else if( strcmp(z,"-csv")==0 ){
      data.mode = MODE_Csv;
      memcpy(data.separator,",",2);
    }else if( strcmp(z,"-separator")==0 ){







      sqlite3_snprintf(sizeof(data.separator), data.separator,

                       "%s",cmdline_option_value(argc,argv,++i));
    }else if( strcmp(z,"-nullvalue")==0 ){







      sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
                       "%s",cmdline_option_value(argc,argv,++i));
    }else if( strcmp(z,"-header")==0 ){
      data.showHeader = 1;
    }else if( strcmp(z,"-noheader")==0 ){
      data.showHeader = 0;
    }else if( strcmp(z,"-echo")==0 ){
      data.echoOn = 1;
    }else if( strcmp(z,"-stats")==0 ){
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
    }else if( strcmp(z,"-ssdsim")==0 ){
      i++;
#endif
    }else if( strcmp(z,"-help")==0 ){
      usage(1);
    }else if( strcmp(z,"-cmd")==0 ){
      if( i==argc-1 ) break;
      i++;
      z = argv[i];
      if( z[0]=='.' ){
        rc = do_meta_command(z, &data);
        if( rc && bail_on_error ) return rc;
      }else{
        open_db(&data);
        rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
        if( zErrMsg!=0 ){







<
|







3092
3093
3094
3095
3096
3097
3098

3099
3100
3101
3102
3103
3104
3105
3106
    }else if( strcmp(z,"-ssdsim")==0 ){
      i++;
#endif
    }else if( strcmp(z,"-help")==0 ){
      usage(1);
    }else if( strcmp(z,"-cmd")==0 ){
      if( i==argc-1 ) break;

      z = cmdline_option_value(argc,argv,++i);
      if( z[0]=='.' ){
        rc = do_meta_command(z, &data);
        if( rc && bail_on_error ) return rc;
      }else{
        open_db(&data);
        rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
        if( zErrMsg!=0 ){
Changes to src/test_ssdsim.c.
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190

191
192
193
194
195
196
197
  g.aDealloc = 0;
  g.nDealloc = 0;
  g.mxAlloc = 0;
  g.nPage = 0;
}

/*
** Initialize the ssdsim system.
*/
static void ssdsimInit(void){
  int nPage;
  if( g.nPage ) return;
  if( g.szPage==0 ) g.szPage = 4096;
  if( g.szEBlock==0 ) g.szEBlock = 262144;
  if( g.szDisk==0 ) g.szDisk = 67108864;
  g.nPage = g.szDisk/g.szPage;
  g.nEBlock = g.szDisk/g.szEBlock;
  sqlite3_free(g.apPage);
  g.apPage = sqlite3_malloc( sizeof(g.apPage[0])*g.nPage );
  if( g.apPage==0 ){ ssdsimShutdown(); return; }
  memset(g.apPage, 0, sizeof(g.apPage[0])*nPage);
  g.aDealloc = sqlite3_malloc( sizeof(g.aDealloc[0])*g.nPage );
  if( g.aDealloc==0 ){ ssdsimShutdown(); return; }
  g.nDealloc = 0;
  g.mxAlloc = 0;
  g.nHostWrite = 0;
  g.nNANDWrite = 0;

}

/*
** Allocate a new, unused logical page number
*/
static int ssdsimCoreLpnAlloc(void){
  if( g.nDealloc ){







|

|

|







|
|

|




>







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
  g.aDealloc = 0;
  g.nDealloc = 0;
  g.mxAlloc = 0;
  g.nPage = 0;
}

/*
** Initialize the ssdsim system.  Return non-zero if there is an error.
*/
static int ssdsimInit(void){
  int nPage;
  if( g.nPage ) return 0;
  if( g.szPage==0 ) g.szPage = 4096;
  if( g.szEBlock==0 ) g.szEBlock = 262144;
  if( g.szDisk==0 ) g.szDisk = 67108864;
  g.nPage = g.szDisk/g.szPage;
  g.nEBlock = g.szDisk/g.szEBlock;
  sqlite3_free(g.apPage);
  g.apPage = sqlite3_malloc( sizeof(g.apPage[0])*g.nPage );
  if( g.apPage==0 ){ ssdsimShutdown(); return 1; }
  memset(g.apPage, 0, sizeof(g.apPage[0])*g.nPage);
  g.aDealloc = sqlite3_malloc( sizeof(g.aDealloc[0])*g.nPage );
  if( g.aDealloc==0 ){ ssdsimShutdown(); return 1; }
  g.nDealloc = 0;
  g.mxAlloc = 0;
  g.nHostWrite = 0;
  g.nNANDWrite = 0;
  return 0;
}

/*
** Allocate a new, unused logical page number
*/
static int ssdsimCoreLpnAlloc(void){
  if( g.nDealloc ){
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
      pInode->nShmRegion = 0;
    }
  }
  return SQLITE_OK;
}

static const sqlite3_io_methods ssdsim_io_methods = {
  /* iVersion               */ 2,
  /* xClose                 */ ssdsimClose,
  /* xRead                  */ ssdsimRead,
  /* xWrite                 */ ssdsimWrite,
  /* xTruncate              */ ssdsimTruncate,
  /* xSync                  */ ssdsimSync,
  /* xFileSize              */ ssdsimFileSize,
  /* xLock                  */ ssdsimLock,







|







653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
      pInode->nShmRegion = 0;
    }
  }
  return SQLITE_OK;
}

static const sqlite3_io_methods ssdsim_io_methods = {
  /* iVersion               */ 3,
  /* xClose                 */ ssdsimClose,
  /* xRead                  */ ssdsimRead,
  /* xWrite                 */ ssdsimWrite,
  /* xTruncate              */ ssdsimTruncate,
  /* xSync                  */ ssdsimSync,
  /* xFileSize              */ ssdsimFileSize,
  /* xLock                  */ ssdsimLock,
694
695
696
697
698
699
700
701










702
703
704
705
706
707
708
  const char *zName,
  sqlite3_file *pFile,
  int flags,
  int *pOutFlags
){
  int rc;
  ssdsim_file *p = (ssdsim_file *)pFile;
  ssdsim_inode *pInode = ssdsimFindInode(zName);










  if( pInode==0 ){
    int n = (int)strlen(zName);
    pInode = sqlite3_malloc( sizeof(*pInode) + n + 1 );
    if( pInode==0 ) return SQLITE_NOMEM;
    memset(pInode, 0, sizeof(*pInode));
    pInode->pNext = g.pInode;
    g.pInode = pInode;







|
>
>
>
>
>
>
>
>
>
>







695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
  const char *zName,
  sqlite3_file *pFile,
  int flags,
  int *pOutFlags
){
  int rc;
  ssdsim_file *p = (ssdsim_file *)pFile;
  ssdsim_inode *pInode;
  char zTempname[100];

  if( ssdsimInit() ) return SQLITE_CANTOPEN;
  if( zName==0 ){
    sqlite3_uint64 r;
    sqlite3_randomness(sizeof(r), &r);
    sqlite3_snprintf(sizeof(zTempname), zTempname, "/tmp%llx", r);
    zName = zTempname;
  }
  pInode = ssdsimFindInode(zName);
  if( pInode==0 ){
    int n = (int)strlen(zName);
    pInode = sqlite3_malloc( sizeof(*pInode) + n + 1 );
    if( pInode==0 ) return SQLITE_NOMEM;
    memset(pInode, 0, sizeof(*pInode));
    pInode->pNext = g.pInode;
    g.pInode = pInode;
733
734
735
736
737
738
739
740



741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756


757
758
759
760
761
762
763

/*
** Delete the file located at zPath. If the dirSync argument is true,
** ensure the file-system modifications are synced to disk before
** returning.
*/
static int ssdsimDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
  ssdsim_inode *pInode = ssdsimFindInode(zPath);



  if( pInode==0 ) return SQLITE_NOTFOUND;
  ssdsimDeleteInode(pInode);
  return SQLITE_OK;
}

/*
** Test for access permissions. Return true if the requested permission
** is available, or false otherwise.
*/
static int ssdsimAccess(
  sqlite3_vfs *pVfs, 
  const char *zPath, 
  int flags, 
  int *pResOut
){
  ssdsim_inode *pInode = ssdsimFindInode(zPath);


  *pResOut = pInode!=0;
  return SQLITE_OK;
}

/*
** Populate buffer zOut with the full canonical pathname corresponding
** to the pathname in zPath. zOut is guaranteed to point to a buffer







|
>
>
>















|
>
>







744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779

/*
** Delete the file located at zPath. If the dirSync argument is true,
** ensure the file-system modifications are synced to disk before
** returning.
*/
static int ssdsimDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
  ssdsim_inode *pInode;

  if( ssdsimInit() ) return SQLITE_CANTOPEN;
  pInode = ssdsimFindInode(zPath);
  if( pInode==0 ) return SQLITE_NOTFOUND;
  ssdsimDeleteInode(pInode);
  return SQLITE_OK;
}

/*
** Test for access permissions. Return true if the requested permission
** is available, or false otherwise.
*/
static int ssdsimAccess(
  sqlite3_vfs *pVfs, 
  const char *zPath, 
  int flags, 
  int *pResOut
){
  ssdsim_inode *pInode;
  if( ssdsimInit() ) return SQLITE_CANTOPEN;
  pInode = ssdsimFindInode(zPath);
  *pResOut = pInode!=0;
  return SQLITE_OK;
}

/*
** Populate buffer zOut with the full canonical pathname corresponding
** to the pathname in zPath. zOut is guaranteed to point to a buffer
Changes to test/shell1.test.
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
175
176
177
178
do_test shell1-1.14.2 {
  catchcmd "-separator x test.db" "" 
} {0 {}}
do_test shell1-1.14.3 {
  set res [catchcmd "-separator" ""]
  set rc [lindex $res 0]
  list $rc \
       [regexp {Error: missing argument for option: -separator} $res]
} {1 1}

# -stats               print memory stats before each finalize
do_test shell1-1.14b.1 {
  catchcmd "-stats test.db" "" 
} {0 {}}

# -nullvalue 'text'    set text string for NULL values
do_test shell1-1.15.1 {
  catchcmd "-nullvalue 'x' test.db" ""
} {0 {}}
do_test shell1-1.15.2 {
  catchcmd "-nullvalue x test.db" ""
} {0 {}}
do_test shell1-1.15.3 {
  set res [catchcmd "-nullvalue" ""]
  set rc [lindex $res 0]
  list $rc \
       [regexp {Error: missing argument for option: -nullvalue} $res]
} {1 1}

# -version             show SQLite version
do_test shell1-1.16.1 {
  set x [catchcmd "-version test.db" ""]
} {/3.[0-9.]+ 20\d\d-[01]\d-\d\d \d\d:\d\d:\d\d [0-9a-f]+/}








|


















|







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
175
176
177
178
do_test shell1-1.14.2 {
  catchcmd "-separator x test.db" "" 
} {0 {}}
do_test shell1-1.14.3 {
  set res [catchcmd "-separator" ""]
  set rc [lindex $res 0]
  list $rc \
       [regexp {Error: missing argument to -separator} $res]
} {1 1}

# -stats               print memory stats before each finalize
do_test shell1-1.14b.1 {
  catchcmd "-stats test.db" "" 
} {0 {}}

# -nullvalue 'text'    set text string for NULL values
do_test shell1-1.15.1 {
  catchcmd "-nullvalue 'x' test.db" ""
} {0 {}}
do_test shell1-1.15.2 {
  catchcmd "-nullvalue x test.db" ""
} {0 {}}
do_test shell1-1.15.3 {
  set res [catchcmd "-nullvalue" ""]
  set rc [lindex $res 0]
  list $rc \
       [regexp {Error: missing argument to -nullvalue} $res]
} {1 1}

# -version             show SQLite version
do_test shell1-1.16.1 {
  set x [catchcmd "-version test.db" ""]
} {/3.[0-9.]+ 20\d\d-[01]\d-\d\d \d\d:\d\d:\d\d [0-9a-f]+/}