| ︙ | | | ︙ | |
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
# define shell_read_history(X) linenoiseHistoryLoad(X)
# define shell_write_history(X) linenoiseHistorySave(X)
# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
# define shell_readline(X) linenoise(X)
#else
# define shell_read_history(X)
# define shell_write_history(X)
# define shell_stifle_history(X)
# define SHELL_USE_LOCAL_GETLINE 1
#endif
|
|
|
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
# define shell_read_history(X) linenoiseHistoryLoad(X)
# define shell_write_history(X) linenoiseHistorySave(X)
# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
# define shell_readline(X) linenoise(X)
#else
# define shell_read_history(X)
# define shell_write_history(X)
# define shell_stifle_history(X)
# define SHELL_USE_LOCAL_GETLINE 1
#endif
|
| ︙ | | | ︙ | |
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
|
#define isatty(x) 1
#endif
/* ctype macros that work with signed characters */
#define IsSpace(X) isspace((unsigned char)X)
#define IsDigit(X) isdigit((unsigned char)X)
#define ToLower(X) (char)tolower((unsigned char)X)
/* On Windows, we normally run with output mode of TEXT so that \n characters
** are automatically translated into \r\n. However, this behavior needs
** to be disabled in some cases (ex: when generating CSV output and when
** rendering quoted strings that contain \n characters). The following
** routines take care of that.
*/
#if defined(_WIN32) || defined(WIN32)
static void setBinaryMode(FILE *out){
fflush(out);
_setmode(_fileno(out), _O_BINARY);
}
static void setTextMode(FILE *out){
fflush(out);
_setmode(_fileno(out), _O_TEXT);
}
#else
# define setBinaryMode(X)
# define setTextMode(X)
#endif
/* True if the timer is enabled */
static int enableTimer = 0;
/* Return the current wall-clock time */
|
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
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
|
#define isatty(x) 1
#endif
/* ctype macros that work with signed characters */
#define IsSpace(X) isspace((unsigned char)X)
#define IsDigit(X) isdigit((unsigned char)X)
#define ToLower(X) (char)tolower((unsigned char)X)
#if defined(_WIN32) || defined(WIN32)
#include <windows.h>
/* string conversion routines only needed on Win32 */
extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int);
extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int);
#endif
/* On Windows, we normally run with output mode of TEXT so that \n characters
** are automatically translated into \r\n. However, this behavior needs
** to be disabled in some cases (ex: when generating CSV output and when
** rendering quoted strings that contain \n characters). The following
** routines take care of that.
*/
#if defined(_WIN32) || defined(WIN32)
static void setBinaryMode(FILE *file, int isOutput){
if( isOutput ) fflush(file);
_setmode(_fileno(file), _O_BINARY);
}
static void setTextMode(FILE *file, int isOutput){
if( isOutput ) fflush(file);
_setmode(_fileno(file), _O_TEXT);
}
#else
# define setBinaryMode(X,Y)
# define setTextMode(X,Y)
#endif
/* True if the timer is enabled */
static int enableTimer = 0;
/* Return the current wall-clock time */
|
| ︙ | | | ︙ | |
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
getrusage(RUSAGE_SELF, &sBegin);
iBegin = timeOfDay();
}
}
/* Return the difference of two time_structs in seconds */
static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
(double)(pEnd->tv_sec - pStart->tv_sec);
}
/*
** Print the timing results.
*/
static void endTimer(void){
|
|
|
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
|
getrusage(RUSAGE_SELF, &sBegin);
iBegin = timeOfDay();
}
}
/* Return the difference of two time_structs in seconds */
static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
(double)(pEnd->tv_sec - pStart->tv_sec);
}
/*
** Print the timing results.
*/
static void endTimer(void){
|
| ︙ | | | ︙ | |
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
|
#define BEGIN_TIMER beginTimer()
#define END_TIMER endTimer()
#define HAS_TIMER 1
#elif (defined(_WIN32) || defined(WIN32))
#include <windows.h>
/* Saved resource information for the beginning of an operation */
static HANDLE hProcess;
static FILETIME ftKernelBegin;
static FILETIME ftUserBegin;
static sqlite3_int64 ftWallBegin;
typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
LPFILETIME, LPFILETIME);
|
<
<
|
234
235
236
237
238
239
240
241
242
243
244
245
246
247
|
#define BEGIN_TIMER beginTimer()
#define END_TIMER endTimer()
#define HAS_TIMER 1
#elif (defined(_WIN32) || defined(WIN32))
/* Saved resource information for the beginning of an operation */
static HANDLE hProcess;
static FILETIME ftKernelBegin;
static FILETIME ftUserBegin;
static sqlite3_int64 ftWallBegin;
typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
LPFILETIME, LPFILETIME);
|
| ︙ | | | ︙ | |
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
if( NULL != hinstLib ){
getProcessTimesAddr =
(GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
if( NULL != getProcessTimesAddr ){
return 1;
}
FreeLibrary(hinstLib);
}
}
}
return 0;
}
/*
|
|
|
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
|
HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
if( NULL != hinstLib ){
getProcessTimesAddr =
(GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
if( NULL != getProcessTimesAddr ){
return 1;
}
FreeLibrary(hinstLib);
}
}
}
return 0;
}
/*
|
| ︙ | | | ︙ | |
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
|
}
#define BEGIN_TIMER beginTimer()
#define END_TIMER endTimer()
#define HAS_TIMER hasTimer()
#else
#define BEGIN_TIMER
#define END_TIMER
#define HAS_TIMER 0
#endif
/*
** Used to prevent warnings about unused parameters
*/
|
|
|
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
|
}
#define BEGIN_TIMER beginTimer()
#define END_TIMER endTimer()
#define HAS_TIMER hasTimer()
#else
#define BEGIN_TIMER
#define END_TIMER
#define HAS_TIMER 0
#endif
/*
** Used to prevent warnings about unused parameters
*/
|
| ︙ | | | ︙ | |
357
358
359
360
361
362
363
364
365
366
367
368
369
370
|
/*
** Prompt strings. Initialized in main. Settable with
** .prompt main continue
*/
static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
/*
** Write I/O traces to the following stream.
*/
#ifdef SQLITE_ENABLE_IOTRACE
static FILE *iotrace = 0;
#endif
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
|
/*
** Prompt strings. Initialized in main. Settable with
** .prompt main continue
*/
static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
/*
** Render output like fprintf(). Except, if the output is going to the
** console and if this is running on a Windows machine, translate the
** output from UTF-8 into MBCS.
*/
#if defined(_WIN32) || defined(WIN32)
void utf8_printf(FILE *out, const char *zFormat, ...){
va_list ap;
va_start(ap, zFormat);
if( stdout_is_console && (out==stdout || out==stderr) ){
char *z1 = sqlite3_vmprintf(zFormat, ap);
char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0);
sqlite3_free(z1);
fputs(z2, out);
sqlite3_free(z2);
}else{
vfprintf(out, zFormat, ap);
}
va_end(ap);
}
#elif !defined(utf8_printf)
# define utf8_printf fprintf
#endif
/*
** Render output like fprintf(). This should not be used on anything that
** includes string formatting (e.g. "%s").
*/
#if !defined(raw_printf)
# define raw_printf fprintf
#endif
/*
** Write I/O traces to the following stream.
*/
#ifdef SQLITE_ENABLE_IOTRACE
static FILE *iotrace = 0;
#endif
|
| ︙ | | | ︙ | |
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
|
static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
va_list ap;
char *z;
if( iotrace==0 ) return;
va_start(ap, zFormat);
z = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
fprintf(iotrace, "%s", z);
sqlite3_free(z);
}
#endif
/*
** Determines if a string is a number of not.
|
|
|
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
|
static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
va_list ap;
char *z;
if( iotrace==0 ) return;
va_start(ap, zFormat);
z = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
utf8_printf(iotrace, "%s", z);
sqlite3_free(z);
}
#endif
/*
** Determines if a string is a number of not.
|
| ︙ | | | ︙ | |
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
|
while( IsDigit(*z) ){ z++; }
if( realnum ) *realnum = 1;
}
return *z==0;
}
/*
** A global char* and an SQL function to access its current value
** from within an SQL statement. This program used to use the
** sqlite_exec_printf() API to substitue a string into an SQL statement.
** The correct way to do this with sqlite3 is to use the bind API, but
** since the shell is built around the callback paradigm it would be a lot
** of work. Instead just use this hack, which is quite harmless.
*/
static const char *zShellStatic = 0;
static void shellstaticFunc(
|
|
|
|
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
|
while( IsDigit(*z) ){ z++; }
if( realnum ) *realnum = 1;
}
return *z==0;
}
/*
** A global char* and an SQL function to access its current value
** from within an SQL statement. This program used to use the
** sqlite_exec_printf() API to substitue a string into an SQL statement.
** The correct way to do this with sqlite3 is to use the bind API, but
** since the shell is built around the callback paradigm it would be a lot
** of work. Instead just use this hack, which is quite harmless.
*/
static const char *zShellStatic = 0;
static void shellstaticFunc(
|
| ︙ | | | ︙ | |
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
|
n--;
if( n>0 && zLine[n-1]=='\r' ) n--;
zLine[n] = 0;
break;
}
}
#if defined(_WIN32) || defined(WIN32)
/* For interactive input on Windows systems, translate the
** multi-byte characterset characters into UTF-8. */
if( stdin_is_interactive ){
extern char *sqlite3_win32_mbcs_to_utf8(const char*);
char *zTrans = sqlite3_win32_mbcs_to_utf8(zLine);
if( zTrans ){
int nTrans = strlen30(zTrans)+1;
if( nTrans>nLine ){
zLine = realloc(zLine, nTrans);
if( zLine==0 ){
sqlite3_free(zTrans);
return 0;
|
|
<
|
|
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
|
n--;
if( n>0 && zLine[n-1]=='\r' ) n--;
zLine[n] = 0;
break;
}
}
#if defined(_WIN32) || defined(WIN32)
/* For interactive input on Windows systems, translate the
** multi-byte characterset characters into UTF-8. */
if( stdin_is_interactive ){
char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
if( zTrans ){
int nTrans = strlen30(zTrans)+1;
if( nTrans>nLine ){
zLine = realloc(zLine, nTrans);
if( zLine==0 ){
sqlite3_free(zTrans);
return 0;
|
| ︙ | | | ︙ | |
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
|
zResult = shell_readline(zPrompt);
if( zResult && *zResult ) shell_add_history(zResult);
#endif
}
return zResult;
}
/*
** Render output like fprintf(). Except, if the output is going to the
** console and if this is running on a Windows machine, translate the
** output from UTF-8 into MBCS.
*/
#if defined(_WIN32) || defined(WIN32)
void utf8_printf(FILE *out, const char *zFormat, ...){
va_list ap;
va_start(ap, zFormat);
if( stdout_is_console && (out==stdout || out==stderr) ){
extern char *sqlite3_win32_utf8_to_mbcs(const char*);
char *z1 = sqlite3_vmprintf(zFormat, ap);
char *z2 = sqlite3_win32_utf8_to_mbcs(z1);
sqlite3_free(z1);
fputs(z2, out);
sqlite3_free(z2);
}else{
vfprintf(out, zFormat, ap);
}
va_end(ap);
}
#elif !defined(utf8_printf)
# define utf8_printf fprintf
#endif
/*
** Render output like fprintf(). This should not be used on anything that
** includes string formatting (e.g. "%s").
*/
#if !defined(raw_printf)
# define raw_printf fprintf
#endif
/*
** Shell output mode information from before ".explain on",
** saved so that it can be restored by ".explain off"
*/
typedef struct SavedModeInfo SavedModeInfo;
struct SavedModeInfo {
int valid; /* Is there legit data in here? */
int mode; /* Mode prior to ".explain on" */
int showHeader; /* The ".header" setting prior to ".explain on" */
|
>
<
|
<
<
<
>
|
<
<
<
|
>
|
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
|
zResult = shell_readline(zPrompt);
if( zResult && *zResult ) shell_add_history(zResult);
#endif
}
return zResult;
}
#if defined(SQLITE_ENABLE_SESSION)
/*
** State information for a single open session
*/
typedef struct OpenSession OpenSession;
struct OpenSession {
char *zName; /* Symbolic name for this session */
int nFilter; /* Number of xFilter rejection GLOB patterns */
char **azFilter; /* Array of xFilter rejection GLOB patterns */
sqlite3_session *p; /* The open session */
};
#endif
/*
** Shell output mode information from before ".explain on",
** saved so that it can be restored by ".explain off"
*/
typedef struct SavedModeInfo SavedModeInfo;
struct SavedModeInfo {
int valid; /* Is there legit data in here? */
int mode; /* Mode prior to ".explain on" */
int showHeader; /* The ".header" setting prior to ".explain on" */
|
| ︙ | | | ︙ | |
621
622
623
624
625
626
627
628
629
630
631
632
633
634
|
char *zFreeOnClose; /* Filename to free when closing */
const char *zVfs; /* Name of VFS to use */
sqlite3_stmt *pStmt; /* Current statement if any. */
FILE *pLog; /* Write log output here */
int *aiIndent; /* Array of indents used in MODE_Explain */
int nIndent; /* Size of array aiIndent[] */
int iIndent; /* Index of current op in aiIndent[] */
};
/*
** These are the allowed shellFlgs values
*/
#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
|
>
>
>
>
|
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
|
char *zFreeOnClose; /* Filename to free when closing */
const char *zVfs; /* Name of VFS to use */
sqlite3_stmt *pStmt; /* Current statement if any. */
FILE *pLog; /* Write log output here */
int *aiIndent; /* Array of indents used in MODE_Explain */
int nIndent; /* Size of array aiIndent[] */
int iIndent; /* Index of current op in aiIndent[] */
#if defined(SQLITE_ENABLE_SESSION)
int nSession; /* Number of active sessions */
OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
#endif
};
/*
** These are the allowed shellFlgs values
*/
#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
|
| ︙ | | | ︙ | |
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
|
/*
** Output the given string as a quoted string using SQL quoting conventions.
*/
static void output_quoted_string(FILE *out, const char *z){
int i;
int nSingle = 0;
setBinaryMode(out);
for(i=0; z[i]; i++){
if( z[i]=='\'' ) nSingle++;
}
if( nSingle==0 ){
utf8_printf(out,"'%s'",z);
}else{
raw_printf(out,"'");
|
|
|
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
|
/*
** Output the given string as a quoted string using SQL quoting conventions.
*/
static void output_quoted_string(FILE *out, const char *z){
int i;
int nSingle = 0;
setBinaryMode(out, 1);
for(i=0; z[i]; i++){
if( z[i]=='\'' ) nSingle++;
}
if( nSingle==0 ){
utf8_printf(out,"'%s'",z);
}else{
raw_printf(out,"'");
|
| ︙ | | | ︙ | |
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
|
}else{
utf8_printf(out,"%s",z);
break;
}
}
raw_printf(out,"'");
}
setTextMode(out);
}
/*
** Output the given string as a quoted according to C or TCL quoting rules.
*/
static void output_c_string(FILE *out, const char *z){
unsigned int c;
|
|
|
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
|
}else{
utf8_printf(out,"%s",z);
break;
}
}
raw_printf(out,"'");
}
setTextMode(out, 1);
}
/*
** Output the given string as a quoted according to C or TCL quoting rules.
*/
static void output_c_string(FILE *out, const char *z){
unsigned int c;
|
| ︙ | | | ︙ | |
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
|
** Output the given string with characters that are special to
** HTML escaped.
*/
static void output_html_string(FILE *out, const char *z){
int i;
if( z==0 ) z = "";
while( *z ){
for(i=0; z[i]
&& z[i]!='<'
&& z[i]!='&'
&& z[i]!='>'
&& z[i]!='\"'
&& z[i]!='\'';
i++){}
if( i>0 ){
utf8_printf(out,"%.*s",i,z);
}
if( z[i]=='<' ){
raw_printf(out,"<");
|
|
|
|
|
|
|
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
|
** Output the given string with characters that are special to
** HTML escaped.
*/
static void output_html_string(FILE *out, const char *z){
int i;
if( z==0 ) z = "";
while( *z ){
for(i=0; z[i]
&& z[i]!='<'
&& z[i]!='&'
&& z[i]!='>'
&& z[i]!='\"'
&& z[i]!='\'';
i++){}
if( i>0 ){
utf8_printf(out,"%.*s",i,z);
}
if( z[i]=='<' ){
raw_printf(out,"<");
|
| ︙ | | | ︙ | |
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
|
}
/*
** If a field contains any character identified by a 1 in the following
** array, then the string must be quoted for CSV.
*/
static const char needCsvQuote[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
};
/*
** Output a single term of CSV. Actually, p->colSeparator is used for
** the separator, which may or may not be a comma. p->nullValue is
** the null value. Strings are quoted if necessary. The separator
** is only issued if bSep is true.
*/
static void output_csv(ShellState *p, const char *z, int bSep){
FILE *out = p->out;
if( z==0 ){
utf8_printf(out,"%s",p->nullValue);
}else{
int i;
int nSep = strlen30(p->colSeparator);
for(i=0; z[i]; i++){
if( needCsvQuote[((unsigned char*)z)[i]]
|| (z[i]==p->colSeparator[0] &&
(nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
i = 0;
break;
}
}
if( i==0 ){
putc('"', out);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
|
}
/*
** If a field contains any character identified by a 1 in the following
** array, then the string must be quoted for CSV.
*/
static const char needCsvQuote[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
};
/*
** Output a single term of CSV. Actually, p->colSeparator is used for
** the separator, which may or may not be a comma. p->nullValue is
** the null value. Strings are quoted if necessary. The separator
** is only issued if bSep is true.
*/
static void output_csv(ShellState *p, const char *z, int bSep){
FILE *out = p->out;
if( z==0 ){
utf8_printf(out,"%s",p->nullValue);
}else{
int i;
int nSep = strlen30(p->colSeparator);
for(i=0; z[i]; i++){
if( needCsvQuote[((unsigned char*)z)[i]]
|| (z[i]==p->colSeparator[0] &&
(nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
i = 0;
break;
}
}
if( i==0 ){
putc('"', out);
|
| ︙ | | | ︙ | |
865
866
867
868
869
870
871
872
873
874
875
876
877
878
|
static void interrupt_handler(int NotUsed){
UNUSED_PARAMETER(NotUsed);
seenInterrupt++;
if( seenInterrupt>2 ) exit(1);
if( globalDb ) sqlite3_interrupt(globalDb);
}
#endif
/*
** This is the callback routine that the shell
** invokes for each row of a query result.
*/
static int shell_callback(
void *pArg,
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
|
static void interrupt_handler(int NotUsed){
UNUSED_PARAMETER(NotUsed);
seenInterrupt++;
if( seenInterrupt>2 ) exit(1);
if( globalDb ) sqlite3_interrupt(globalDb);
}
#endif
/*
** When the ".auth ON" is set, the following authorizer callback is
** invoked. It always returns SQLITE_OK.
*/
static int shellAuth(
void *pClientData,
int op,
const char *zA1,
const char *zA2,
const char *zA3,
const char *zA4
){
ShellState *p = (ShellState*)pClientData;
static const char *azAction[] = { 0,
"CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX",
"CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW",
"CREATE_TRIGGER", "CREATE_VIEW", "DELETE",
"DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX",
"DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW",
"DROP_TRIGGER", "DROP_VIEW", "INSERT",
"PRAGMA", "READ", "SELECT",
"TRANSACTION", "UPDATE", "ATTACH",
"DETACH", "ALTER_TABLE", "REINDEX",
"ANALYZE", "CREATE_VTABLE", "DROP_VTABLE",
"FUNCTION", "SAVEPOINT", "RECURSIVE"
};
int i;
const char *az[4];
az[0] = zA1;
az[1] = zA2;
az[2] = zA3;
az[3] = zA4;
raw_printf(p->out, "authorizer: %s", azAction[op]);
for(i=0; i<4; i++){
raw_printf(p->out, " ");
if( az[i] ){
output_c_string(p->out, az[i]);
}else{
raw_printf(p->out, "NULL");
}
}
raw_printf(p->out, "\n");
return SQLITE_OK;
}
/*
** This is the callback routine that the shell
** invokes for each row of a query result.
*/
static int shell_callback(
void *pArg,
|
| ︙ | | | ︙ | |
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
|
output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
}
utf8_printf(p->out, "%s", p->rowSeparator);
break;
}
case MODE_Csv: {
setBinaryMode(p->out);
if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){
output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
}
utf8_printf(p->out, "%s", p->rowSeparator);
}
if( nArg>0 ){
for(i=0; i<nArg; i++){
output_csv(p, azArg[i], i<nArg-1);
}
utf8_printf(p->out, "%s", p->rowSeparator);
}
setTextMode(p->out);
break;
}
case MODE_Insert: {
p->cnt++;
if( azArg==0 ) break;
utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
if( p->showHeader ){
|
|
|
|
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
|
output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
}
utf8_printf(p->out, "%s", p->rowSeparator);
break;
}
case MODE_Csv: {
setBinaryMode(p->out, 1);
if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){
output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
}
utf8_printf(p->out, "%s", p->rowSeparator);
}
if( nArg>0 ){
for(i=0; i<nArg; i++){
output_csv(p, azArg[i], i<nArg-1);
}
utf8_printf(p->out, "%s", p->rowSeparator);
}
setTextMode(p->out, 1);
break;
}
case MODE_Insert: {
p->cnt++;
if( azArg==0 ) break;
utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
if( p->showHeader ){
|
| ︙ | | | ︙ | |
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
|
}
/* zIn is either a pointer to a NULL-terminated string in memory obtained
** from malloc(), or a NULL pointer. The string pointed to by zAppend is
** added to zIn, and the result returned in memory obtained from malloc().
** zIn, if it was not NULL, is freed.
**
** If the third argument, quote, is not '\0', then it is used as a
** quote character for zAppend.
*/
static char *appendText(char *zIn, char const *zAppend, char quote){
int len;
int i;
int nAppend = strlen30(zAppend);
int nIn = (zIn?strlen30(zIn):0);
|
|
|
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
|
}
/* zIn is either a pointer to a NULL-terminated string in memory obtained
** from malloc(), or a NULL pointer. The string pointed to by zAppend is
** added to zIn, and the result returned in memory obtained from malloc().
** zIn, if it was not NULL, is freed.
**
** If the third argument, quote, is not '\0', then it is used as a
** quote character for zAppend.
*/
static char *appendText(char *zIn, char const *zAppend, char quote){
int len;
int i;
int nAppend = strlen30(zAppend);
int nIn = (zIn?strlen30(zIn):0);
|
| ︙ | | | ︙ | |
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
|
/*
** Execute a query statement that will generate SQL output. Print
** the result columns, comma-separated, on a line and then add a
** semicolon terminator to the end of that line.
**
** If the number of columns is 1 and that column contains text "--"
** then write the semicolon on a separate line. That way, if a
** "--" comment occurs at the end of the statement, the comment
** won't consume the semicolon terminator.
*/
static int run_table_dump_query(
ShellState *p, /* Query context */
const char *zSelect, /* SELECT statement to extract content */
const char *zFirstRow /* Print before first row, if not NULL */
|
|
|
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
|
/*
** Execute a query statement that will generate SQL output. Print
** the result columns, comma-separated, on a line and then add a
** semicolon terminator to the end of that line.
**
** If the number of columns is 1 and that column contains text "--"
** then write the semicolon on a separate line. That way, if a
** "--" comment occurs at the end of the statement, the comment
** won't consume the semicolon terminator.
*/
static int run_table_dump_query(
ShellState *p, /* Query context */
const char *zSelect, /* SELECT statement to extract content */
const char *zFirstRow /* Print before first row, if not NULL */
|
| ︙ | | | ︙ | |
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
|
while( rc==SQLITE_ROW ){
if( zFirstRow ){
utf8_printf(p->out, "%s", zFirstRow);
zFirstRow = 0;
}
z = (const char*)sqlite3_column_text(pSelect, 0);
utf8_printf(p->out, "%s", z);
for(i=1; i<nResult; i++){
utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
}
if( z==0 ) z = "";
while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
if( z[0] ){
raw_printf(p->out, "\n;\n");
}else{
raw_printf(p->out, ";\n");
}
rc = sqlite3_step(pSelect);
}
rc = sqlite3_finalize(pSelect);
if( rc!=SQLITE_OK ){
utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
sqlite3_errmsg(p->db));
if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
|
|
|
|
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
|
while( rc==SQLITE_ROW ){
if( zFirstRow ){
utf8_printf(p->out, "%s", zFirstRow);
zFirstRow = 0;
}
z = (const char*)sqlite3_column_text(pSelect, 0);
utf8_printf(p->out, "%s", z);
for(i=1; i<nResult; i++){
utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
}
if( z==0 ) z = "";
while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
if( z[0] ){
raw_printf(p->out, "\n;\n");
}else{
raw_printf(p->out, ";\n");
}
rc = sqlite3_step(pSelect);
}
rc = sqlite3_finalize(pSelect);
if( rc!=SQLITE_OK ){
utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
sqlite3_errmsg(p->db));
if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
|
| ︙ | | | ︙ | |
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
|
if( strncmp(aTrans[i].zPattern, z, n)==0 ){
raw_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
break;
}
}
}
fclose(in);
}
#endif
/*
** Display memory stats.
*/
static int display_stats(
sqlite3 *db, /* Database to query */
ShellState *pArg, /* Pointer to ShellState */
int bReset /* True to reset the stats */
){
int iCur;
int iHiwtr;
if( pArg && pArg->out ){
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
raw_printf(pArg->out,
"Memory Used: %d (max %d) bytes\n",
iCur, iHiwtr);
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
|
|
|
|
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
|
if( strncmp(aTrans[i].zPattern, z, n)==0 ){
raw_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
break;
}
}
}
fclose(in);
}
#endif
/*
** Display memory stats.
*/
static int display_stats(
sqlite3 *db, /* Database to query */
ShellState *pArg, /* Pointer to ShellState */
int bReset /* True to reset the stats */
){
int iCur;
int iHiwtr;
if( pArg && pArg->out ){
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
raw_printf(pArg->out,
"Memory Used: %d (max %d) bytes\n",
iCur, iHiwtr);
iHiwtr = iCur = -1;
sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
|
| ︙ | | | ︙ | |
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
|
raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
iCur);
}
if( pArg && pArg->out && db && pArg->pStmt ){
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
bReset);
raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
|
|
|
|
|
|
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
|
raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
iCur);
}
if( pArg && pArg->out && db && pArg->pStmt ){
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
bReset);
raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
|
| ︙ | | | ︙ | |
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
|
}
n++;
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
rEstLoop *= rEst;
raw_printf(pArg->out,
" nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
);
}
}
raw_printf(pArg->out, "---------------------------\n");
#endif
|
|
|
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
|
}
n++;
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
rEstLoop *= rEst;
raw_printf(pArg->out,
" nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
);
}
}
raw_printf(pArg->out, "---------------------------\n");
#endif
|
| ︙ | | | ︙ | |
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
|
}
return 0;
}
/*
** If compiled statement pSql appears to be an EXPLAIN statement, allocate
** and populate the ShellState.aiIndent[] array with the number of
** spaces each opcode should be indented before it is output.
**
** The indenting rules are:
**
** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
** all opcodes that occur between the p2 jump destination and the opcode
** itself by 2 spaces.
**
|
|
|
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
|
}
return 0;
}
/*
** If compiled statement pSql appears to be an EXPLAIN statement, allocate
** and populate the ShellState.aiIndent[] array with the number of
** spaces each opcode should be indented before it is output.
**
** The indenting rules are:
**
** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
** all opcodes that occur between the p2 jump destination and the opcode
** itself by 2 spaces.
**
|
| ︙ | | | ︙ | |
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
|
sqlite3_free(p->aiIndent);
p->aiIndent = 0;
p->nIndent = 0;
p->iIndent = 0;
}
/*
** Execute a statement or set of statements. Print
** any result rows/columns depending on the current mode
** set via the supplied callback.
**
** This is very similar to SQLite's built-in sqlite3_exec()
** function except it takes a slightly different callback
** and callback data argument.
*/
static int shell_exec(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
/* (not the same as sqlite3_exec) */
|
|
|
|
|
|
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
|
sqlite3_free(p->aiIndent);
p->aiIndent = 0;
p->nIndent = 0;
p->iIndent = 0;
}
/*
** Execute a statement or set of statements. Print
** any result rows/columns depending on the current mode
** set via the supplied callback.
**
** This is very similar to SQLite's built-in sqlite3_exec()
** function except it takes a slightly different callback
** and callback data argument.
*/
static int shell_exec(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
/* (not the same as sqlite3_exec) */
|
| ︙ | | | ︙ | |
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
|
pArg->cMode = pArg->mode;
if( pArg->autoExplain
&& sqlite3_column_count(pStmt)==8
&& sqlite3_strlike("%EXPLAIN%", sqlite3_sql(pStmt),0)==0
){
pArg->cMode = MODE_Explain;
}
/* If the shell is currently in ".explain" mode, gather the extra
** data required to add indents to the output.*/
if( pArg->cMode==MODE_Explain ){
explain_data_prepare(pArg, pStmt);
}
}
|
|
|
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
|
pArg->cMode = pArg->mode;
if( pArg->autoExplain
&& sqlite3_column_count(pStmt)==8
&& sqlite3_strlike("%EXPLAIN%", sqlite3_sql(pStmt),0)==0
){
pArg->cMode = MODE_Explain;
}
/* If the shell is currently in ".explain" mode, gather the extra
** data required to add indents to the output.*/
if( pArg->cMode==MODE_Explain ){
explain_data_prepare(pArg, pStmt);
}
}
|
| ︙ | | | ︙ | |
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
|
if( !pData ){
rc = SQLITE_NOMEM;
}else{
char **azCols = (char **)pData; /* Names of result columns */
char **azVals = &azCols[nCol]; /* Results */
int *aiTypes = (int *)&azVals[nCol]; /* Result types */
int i, x;
assert(sizeof(int) <= sizeof(char *));
/* save off ptrs to column names */
for(i=0; i<nCol; i++){
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
}
do{
/* extract the data and data types */
for(i=0; i<nCol; i++){
aiTypes[i] = x = sqlite3_column_type(pStmt, i);
if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
azVals[i] = "";
}else{
azVals[i] = (char*)sqlite3_column_text(pStmt, i);
}
if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
rc = SQLITE_NOMEM;
break; /* from for */
}
} /* end for */
/* if data and types extracted successfully... */
if( SQLITE_ROW == rc ){
/* call the supplied callback with the result row data */
if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
rc = SQLITE_ABORT;
}else{
rc = sqlite3_step(pStmt);
}
}
|
|
|
|
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
|
if( !pData ){
rc = SQLITE_NOMEM;
}else{
char **azCols = (char **)pData; /* Names of result columns */
char **azVals = &azCols[nCol]; /* Results */
int *aiTypes = (int *)&azVals[nCol]; /* Result types */
int i, x;
assert(sizeof(int) <= sizeof(char *));
/* save off ptrs to column names */
for(i=0; i<nCol; i++){
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
}
do{
/* extract the data and data types */
for(i=0; i<nCol; i++){
aiTypes[i] = x = sqlite3_column_type(pStmt, i);
if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
azVals[i] = "";
}else{
azVals[i] = (char*)sqlite3_column_text(pStmt, i);
}
if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
rc = SQLITE_NOMEM;
break; /* from for */
}
} /* end for */
/* if data and types extracted successfully... */
if( SQLITE_ROW == rc ){
/* call the supplied callback with the result row data */
if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
rc = SQLITE_ABORT;
}else{
rc = sqlite3_step(pStmt);
}
}
|
| ︙ | | | ︙ | |
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
|
}
/* print loop-counters if required */
if( pArg && pArg->scanstatsOn ){
display_scanstats(db, pArg);
}
/* Finalize the statement just executed. If this fails, save a
** copy of the error message. Otherwise, set zSql to point to the
** next statement to execute. */
rc2 = sqlite3_finalize(pStmt);
if( rc!=SQLITE_NOMEM ) rc = rc2;
if( rc==SQLITE_OK ){
zSql = zLeftover;
while( IsSpace(zSql[0]) ) zSql++;
|
|
|
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
|
}
/* print loop-counters if required */
if( pArg && pArg->scanstatsOn ){
display_scanstats(db, pArg);
}
/* Finalize the statement just executed. If this fails, save a
** copy of the error message. Otherwise, set zSql to point to the
** next statement to execute. */
rc2 = sqlite3_finalize(pStmt);
if( rc!=SQLITE_NOMEM ) rc = rc2;
if( rc==SQLITE_OK ){
zSql = zLeftover;
while( IsSpace(zSql[0]) ) zSql++;
|
| ︙ | | | ︙ | |
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
|
ShellState *p = (ShellState *)pArg;
UNUSED_PARAMETER(azCol);
if( nArg!=3 ) return 1;
zTable = azArg[0];
zType = azArg[1];
zSql = azArg[2];
if( strcmp(zTable, "sqlite_sequence")==0 ){
zPrepStmt = "DELETE FROM sqlite_sequence;\n";
}else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
raw_printf(p->out, "ANALYZE sqlite_master;\n");
}else if( strncmp(zTable, "sqlite_", 7)==0 ){
return 0;
}else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
|
|
|
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
|
ShellState *p = (ShellState *)pArg;
UNUSED_PARAMETER(azCol);
if( nArg!=3 ) return 1;
zTable = azArg[0];
zType = azArg[1];
zSql = azArg[2];
if( strcmp(zTable, "sqlite_sequence")==0 ){
zPrepStmt = "DELETE FROM sqlite_sequence;\n";
}else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
raw_printf(p->out, "ANALYZE sqlite_master;\n");
}else if( strncmp(zTable, "sqlite_", 7)==0 ){
return 0;
}else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
|
| ︙ | | | ︙ | |
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
|
if( strcmp(zType, "table")==0 ){
sqlite3_stmt *pTableInfo = 0;
char *zSelect = 0;
char *zTableInfo = 0;
char *zTmp = 0;
int nRow = 0;
zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
zTableInfo = appendText(zTableInfo, zTable, '"');
zTableInfo = appendText(zTableInfo, ");", 0);
rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
free(zTableInfo);
if( rc!=SQLITE_OK || !pTableInfo ){
|
|
|
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
|
if( strcmp(zType, "table")==0 ){
sqlite3_stmt *pTableInfo = 0;
char *zSelect = 0;
char *zTableInfo = 0;
char *zTmp = 0;
int nRow = 0;
zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
zTableInfo = appendText(zTableInfo, zTable, '"');
zTableInfo = appendText(zTableInfo, ");", 0);
rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
free(zTableInfo);
if( rc!=SQLITE_OK || !pTableInfo ){
|
| ︙ | | | ︙ | |
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
|
** Run zQuery. Use dump_callback() as the callback routine so that
** the contents of the query are output as SQL statements.
**
** If we get a SQLITE_CORRUPT error, rerun the query after appending
** "ORDER BY rowid DESC" to the end.
*/
static int run_schema_dump_query(
ShellState *p,
const char *zQuery
){
int rc;
char *zErr = 0;
rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
if( rc==SQLITE_CORRUPT ){
char *zQ2;
|
|
|
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
|
** Run zQuery. Use dump_callback() as the callback routine so that
** the contents of the query are output as SQL statements.
**
** If we get a SQLITE_CORRUPT error, rerun the query after appending
** "ORDER BY rowid DESC" to the end.
*/
static int run_schema_dump_query(
ShellState *p,
const char *zQuery
){
int rc;
char *zErr = 0;
rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
if( rc==SQLITE_CORRUPT ){
char *zQ2;
|
| ︙ | | | ︙ | |
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
|
return rc;
}
/*
** Text of a help message
*/
static char zHelp[] =
".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
".bail on|off Stop after hitting an error. Default OFF\n"
".binary on|off Turn binary output on or off. Default OFF\n"
".changes on|off Show number of rows changed by SQL\n"
".clone NEWDB Clone data into NEWDB from the existing database\n"
".databases List names and files of attached databases\n"
".dbinfo ?DB? Show status information about the database\n"
|
>
|
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
|
return rc;
}
/*
** Text of a help message
*/
static char zHelp[] =
".auth ON|OFF Show authorizer callbacks\n"
".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
".bail on|off Stop after hitting an error. Default OFF\n"
".binary on|off Turn binary output on or off. Default OFF\n"
".changes on|off Show number of rows changed by SQL\n"
".clone NEWDB Clone data into NEWDB from the existing database\n"
".databases List names and files of attached databases\n"
".dbinfo ?DB? Show status information about the database\n"
|
| ︙ | | | ︙ | |
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
|
".save FILE Write in-memory database into FILE\n"
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
".schema ?TABLE? Show the CREATE statements\n"
" If TABLE specified, only show tables matching\n"
" LIKE pattern TABLE.\n"
".separator COL ?ROW? Change the column separator and optionally the row\n"
" separator for both the output mode and .import\n"
".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
".show Show the current values for various settings\n"
".stats ?on|off? Show stats or turn stats on or off\n"
".system CMD ARGS... Run CMD ARGS... in a system shell\n"
".tables ?TABLE? List names of tables\n"
" If TABLE specified, only list tables matching\n"
" LIKE pattern TABLE.\n"
".timeout MS Try opening locked tables for MS milliseconds\n"
".timer on|off Turn SQL timer on or off\n"
".trace FILE|off Output each SQL statement as it is run\n"
".vfsinfo ?AUX? Information about the top-level VFS\n"
".vfslist List all available VFSes\n"
".vfsname ?AUX? Print the name of the VFS stack\n"
".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
" Negative values right-justify\n"
;
/* Forward reference */
static int process_input(ShellState *p, FILE *in);
/*
** Implementation of the "readfile(X)" SQL function. The entire content
** of the file named X is read and returned as a BLOB. NULL is returned
** if the file does not exist or is unreadable.
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
|
".save FILE Write in-memory database into FILE\n"
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
".schema ?TABLE? Show the CREATE statements\n"
" If TABLE specified, only show tables matching\n"
" LIKE pattern TABLE.\n"
".separator COL ?ROW? Change the column separator and optionally the row\n"
" separator for both the output mode and .import\n"
#if defined(SQLITE_ENABLE_SESSION)
".session CMD ... Create or control sessions\n"
#endif
".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
".show Show the current values for various settings\n"
".stats ?on|off? Show stats or turn stats on or off\n"
".system CMD ARGS... Run CMD ARGS... in a system shell\n"
".tables ?TABLE? List names of tables\n"
" If TABLE specified, only list tables matching\n"
" LIKE pattern TABLE.\n"
".timeout MS Try opening locked tables for MS milliseconds\n"
".timer on|off Turn SQL timer on or off\n"
".trace FILE|off Output each SQL statement as it is run\n"
".vfsinfo ?AUX? Information about the top-level VFS\n"
".vfslist List all available VFSes\n"
".vfsname ?AUX? Print the name of the VFS stack\n"
".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
" Negative values right-justify\n"
;
#if defined(SQLITE_ENABLE_SESSION)
/*
** Print help information for the ".sessions" command
*/
void session_help(ShellState *p){
raw_printf(p->out,
".session ?NAME? SUBCOMMAND ?ARGS...?\n"
"If ?NAME? is omitted, the first defined session is used.\n"
"Subcommands:\n"
" attach TABLE Attach TABLE\n"
" changeset FILE Write a changeset into FILE\n"
" close Close one session\n"
" enable ?BOOLEAN? Set or query the enable bit\n"
" filter GLOB... Reject tables matching GLOBs\n"
" indirect ?BOOLEAN? Mark or query the indirect status\n"
" isempty Query whether the session is empty\n"
" list List currently open session names\n"
" open DB NAME Open a new session on DB\n"
" patchset FILE Write a patchset into FILE\n"
);
}
#endif
/* Forward reference */
static int process_input(ShellState *p, FILE *in);
/*
** Implementation of the "readfile(X)" SQL function. The entire content
** of the file named X is read and returned as a BLOB. NULL is returned
** if the file does not exist or is unreadable.
|
| ︙ | | | ︙ | |
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
|
}else{
rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
}
fclose(out);
sqlite3_result_int64(context, rc);
}
/*
** Make sure the database is open. If it is not, then open it. If
** the database fails to open, print an error message and exit.
*/
static void open_db(ShellState *p, int keepAlive){
if( p->db==0 ){
sqlite3_initialize();
sqlite3_open(p->zDbFilename, &p->db);
globalDb = p->db;
if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
shellstaticFunc, 0, 0);
}
if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
p->zDbFilename, sqlite3_errmsg(p->db));
if( keepAlive ) return;
exit(1);
}
#ifndef SQLITE_OMIT_LOAD_EXTENSION
sqlite3_enable_load_extension(p->db, 1);
#endif
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
|
}else{
rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
}
fclose(out);
sqlite3_result_int64(context, rc);
}
#if defined(SQLITE_ENABLE_SESSION)
/*
** Close a single OpenSession object and release all of its associated
** resources.
*/
static void session_close(OpenSession *pSession){
int i;
sqlite3session_delete(pSession->p);
sqlite3_free(pSession->zName);
for(i=0; i<pSession->nFilter; i++){
sqlite3_free(pSession->azFilter[i]);
}
sqlite3_free(pSession->azFilter);
memset(pSession, 0, sizeof(OpenSession));
}
#endif
/*
** Close all OpenSession objects and release all associated resources.
*/
#if defined(SQLITE_ENABLE_SESSION)
static void session_close_all(ShellState *p){
int i;
for(i=0; i<p->nSession; i++){
session_close(&p->aSession[i]);
}
p->nSession = 0;
}
#else
# define session_close_all(X)
#endif
/*
** Implementation of the xFilter function for an open session. Omit
** any tables named by ".session filter" but let all other table through.
*/
#if defined(SQLITE_ENABLE_SESSION)
static int session_filter(void *pCtx, const char *zTab){
OpenSession *pSession = (OpenSession*)pCtx;
int i;
for(i=0; i<pSession->nFilter; i++){
if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
}
return 1;
}
#endif
/*
** Make sure the database is open. If it is not, then open it. If
** the database fails to open, print an error message and exit.
*/
static void open_db(ShellState *p, int keepAlive){
if( p->db==0 ){
sqlite3_initialize();
sqlite3_open(p->zDbFilename, &p->db);
globalDb = p->db;
if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
shellstaticFunc, 0, 0);
}
if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
p->zDbFilename, sqlite3_errmsg(p->db));
if( keepAlive ) return;
exit(1);
}
#ifndef SQLITE_OMIT_LOAD_EXTENSION
sqlite3_enable_load_extension(p->db, 1);
#endif
|
| ︙ | | | ︙ | |
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
|
*/
static void output_file_close(FILE *f){
if( f && f!=stdout && f!=stderr ) fclose(f);
}
/*
** Try to open an output file. The names "stdout" and "stderr" are
** recognized and do the right thing. NULL is returned if the output
** filename is "off".
*/
static FILE *output_file_open(const char *zFile){
FILE *f;
if( strcmp(zFile,"stdout")==0 ){
f = stdout;
}else if( strcmp(zFile, "stderr")==0 ){
|
|
|
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
|
*/
static void output_file_close(FILE *f){
if( f && f!=stdout && f!=stderr ) fclose(f);
}
/*
** Try to open an output file. The names "stdout" and "stderr" are
** recognized and do the right thing. NULL is returned if the output
** filename is "off".
*/
static FILE *output_file_open(const char *zFile){
FILE *f;
if( strcmp(zFile,"stdout")==0 ){
f = stdout;
}else if( strcmp(zFile, "stderr")==0 ){
|
| ︙ | | | ︙ | |
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
|
** work for WITHOUT ROWID tables.
*/
static void tryToCloneData(
ShellState *p,
sqlite3 *newDb,
const char *zTable
){
sqlite3_stmt *pQuery = 0;
sqlite3_stmt *pInsert = 0;
char *zQuery = 0;
char *zInsert = 0;
int rc;
int i, j, n;
int nTable = (int)strlen(zTable);
int k = 0;
|
|
|
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
|
** work for WITHOUT ROWID tables.
*/
static void tryToCloneData(
ShellState *p,
sqlite3 *newDb,
const char *zTable
){
sqlite3_stmt *pQuery = 0;
sqlite3_stmt *pInsert = 0;
char *zQuery = 0;
char *zInsert = 0;
int rc;
int i, j, n;
int nTable = (int)strlen(zTable);
int k = 0;
|
| ︙ | | | ︙ | |
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
|
utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
for(i=0; i<ArraySize(aField); i++){
int ofst = aField[i].ofst;
unsigned int val = get4byteInt(aHdr + ofst);
utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
switch( ofst ){
case 56: {
if( val==1 ) raw_printf(p->out, " (utf8)");
if( val==2 ) raw_printf(p->out, " (utf16le)");
if( val==3 ) raw_printf(p->out, " (utf16be)");
}
}
raw_printf(p->out, "\n");
}
if( zDb==0 ){
zSchemaTab = sqlite3_mprintf("main.sqlite_master");
}else if( strcmp(zDb,"temp")==0 ){
|
|
|
|
|
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
|
utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
for(i=0; i<ArraySize(aField); i++){
int ofst = aField[i].ofst;
unsigned int val = get4byteInt(aHdr + ofst);
utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
switch( ofst ){
case 56: {
if( val==1 ) raw_printf(p->out, " (utf8)");
if( val==2 ) raw_printf(p->out, " (utf16le)");
if( val==3 ) raw_printf(p->out, " (utf16be)");
}
}
raw_printf(p->out, "\n");
}
if( zDb==0 ){
zSchemaTab = sqlite3_mprintf("main.sqlite_master");
}else if( strcmp(zDb,"temp")==0 ){
|
| ︙ | | | ︙ | |
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
|
*/
while( zLine[h] && nArg<ArraySize(azArg) ){
while( IsSpace(zLine[h]) ){ h++; }
if( zLine[h]==0 ) break;
if( zLine[h]=='\'' || zLine[h]=='"' ){
int delim = zLine[h++];
azArg[nArg++] = &zLine[h];
while( zLine[h] && zLine[h]!=delim ){
if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
h++;
}
if( zLine[h]==delim ){
zLine[h++] = 0;
}
if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
}else{
azArg[nArg++] = &zLine[h];
while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
if( zLine[h] ) zLine[h++] = 0;
resolve_backslashes(azArg[nArg-1]);
}
}
/* Process the input line.
*/
if( nArg==0 ) return 0; /* no tokens, no error */
n = strlen30(azArg[0]);
c = azArg[0][0];
if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
|| (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
){
const char *zDestFile = 0;
const char *zDb = 0;
sqlite3 *pDest;
sqlite3_backup *pBackup;
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
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
|
*/
while( zLine[h] && nArg<ArraySize(azArg) ){
while( IsSpace(zLine[h]) ){ h++; }
if( zLine[h]==0 ) break;
if( zLine[h]=='\'' || zLine[h]=='"' ){
int delim = zLine[h++];
azArg[nArg++] = &zLine[h];
while( zLine[h] && zLine[h]!=delim ){
if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
h++;
}
if( zLine[h]==delim ){
zLine[h++] = 0;
}
if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
}else{
azArg[nArg++] = &zLine[h];
while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
if( zLine[h] ) zLine[h++] = 0;
resolve_backslashes(azArg[nArg-1]);
}
}
/* Process the input line.
*/
if( nArg==0 ) return 0; /* no tokens, no error */
n = strlen30(azArg[0]);
c = azArg[0][0];
if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
if( nArg!=2 ){
raw_printf(stderr, "Usage: .auth ON|OFF\n");
rc = 1;
goto meta_command_exit;
}
open_db(p, 0);
if( booleanValue(azArg[1]) ){
sqlite3_set_authorizer(p->db, shellAuth, p);
}else{
sqlite3_set_authorizer(p->db, 0, 0);
}
}else
if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
|| (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
){
const char *zDestFile = 0;
const char *zDb = 0;
sqlite3 *pDest;
sqlite3_backup *pBackup;
|
| ︙ | | | ︙ | |
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
|
rc = 1;
}
}else
if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
if( nArg==2 ){
if( booleanValue(azArg[1]) ){
setBinaryMode(p->out);
}else{
setTextMode(p->out);
}
}else{
raw_printf(stderr, "Usage: .binary on|off\n");
rc = 1;
}
}else
|
|
|
|
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
|
rc = 1;
}
}else
if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
if( nArg==2 ){
if( booleanValue(azArg[1]) ){
setBinaryMode(p->out, 1);
}else{
setTextMode(p->out, 1);
}
}else{
raw_printf(stderr, "Usage: .binary on|off\n");
rc = 1;
}
}else
|
| ︙ | | | ︙ | |
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
|
}
raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
raw_printf(p->out, "BEGIN TRANSACTION;\n");
p->writableSchema = 0;
sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
p->nErr = 0;
if( nArg==1 ){
run_schema_dump_query(p,
"SELECT name, type, sql FROM sqlite_master "
"WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
);
run_schema_dump_query(p,
"SELECT name, type, sql FROM sqlite_master "
"WHERE name=='sqlite_sequence'"
);
run_table_dump_query(p,
"SELECT sql FROM sqlite_master "
"WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
);
|
|
|
|
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
|
}
raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
raw_printf(p->out, "BEGIN TRANSACTION;\n");
p->writableSchema = 0;
sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
p->nErr = 0;
if( nArg==1 ){
run_schema_dump_query(p,
"SELECT name, type, sql FROM sqlite_master "
"WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
);
run_schema_dump_query(p,
"SELECT name, type, sql FROM sqlite_master "
"WHERE name=='sqlite_sequence'"
);
run_table_dump_query(p,
"SELECT sql FROM sqlite_master "
"WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
);
|
| ︙ | | | ︙ | |
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
|
if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
if( nArg==2 ){
p->autoEQP = booleanValue(azArg[1]);
}else{
raw_printf(stderr, "Usage: .eqp on|off\n");
rc = 1;
}
}else
if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
rc = 2;
}else
|
|
|
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
|
if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
if( nArg==2 ){
p->autoEQP = booleanValue(azArg[1]);
}else{
raw_printf(stderr, "Usage: .eqp on|off\n");
rc = 1;
}
}else
if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
rc = 2;
}else
|
| ︙ | | | ︙ | |
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
|
{ "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
{ "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
};
int i, n2;
open_db(p, 0);
if( nArg==1 ){
for(i=0; i<ArraySize(aLimit); i++){
printf("%20s %d\n", aLimit[i].zLimitName,
sqlite3_limit(p->db, aLimit[i].limitCode, -1));
}
}else if( nArg>3 ){
raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
rc = 1;
goto meta_command_exit;
}else{
|
|
|
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
|
{ "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
{ "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
};
int i, n2;
open_db(p, 0);
if( nArg==1 ){
for(i=0; i<ArraySize(aLimit); i++){
printf("%20s %d\n", aLimit[i].zLimitName,
sqlite3_limit(p->db, aLimit[i].limitCode, -1));
}
}else if( nArg>3 ){
raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
rc = 1;
goto meta_command_exit;
}else{
|
| ︙ | | | ︙ | |
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
|
const char *zSavedFilename = p->zDbFilename;
char *zNewFilename = 0;
p->db = 0;
if( nArg>=2 ) zNewFilename = sqlite3_mprintf("%s", azArg[1]);
p->zDbFilename = zNewFilename;
open_db(p, 1);
if( p->db!=0 ){
sqlite3_close(savedDb);
sqlite3_free(p->zFreeOnClose);
p->zFreeOnClose = zNewFilename;
}else{
sqlite3_free(zNewFilename);
p->db = savedDb;
p->zDbFilename = zSavedFilename;
|
>
|
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
|
const char *zSavedFilename = p->zDbFilename;
char *zNewFilename = 0;
p->db = 0;
if( nArg>=2 ) zNewFilename = sqlite3_mprintf("%s", azArg[1]);
p->zDbFilename = zNewFilename;
open_db(p, 1);
if( p->db!=0 ){
session_close_all(p);
sqlite3_close(savedDb);
sqlite3_free(p->zFreeOnClose);
p->zFreeOnClose = zNewFilename;
}else{
sqlite3_free(zNewFilename);
p->db = savedDb;
p->zDbFilename = zSavedFilename;
|
| ︙ | | | ︙ | |
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
|
raw_printf(stderr,"Error: querying schema information\n");
rc = 1;
}else{
rc = 0;
}
}else
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
extern int sqlite3SelectTrace;
sqlite3SelectTrace = integerValue(azArg[1]);
}else
#endif
#ifdef SQLITE_DEBUG
/* Undocumented commands for internal testing. Subject to change
** without notice. */
if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
int i, v;
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
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
|
raw_printf(stderr,"Error: querying schema information\n");
rc = 1;
}else{
rc = 0;
}
}else
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
extern int sqlite3SelectTrace;
sqlite3SelectTrace = integerValue(azArg[1]);
}else
#endif
#if defined(SQLITE_ENABLE_SESSION)
if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
OpenSession *pSession = &p->aSession[0];
char **azCmd = &azArg[1];
int iSes = 0;
int nCmd = nArg - 1;
int i;
if( nArg<=1 ) goto session_syntax_error;
open_db(p, 0);
if( nArg>=3 ){
for(iSes=0; iSes<p->nSession; iSes++){
if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
}
if( iSes<p->nSession ){
pSession = &p->aSession[iSes];
azCmd++;
nCmd--;
}else{
pSession = &p->aSession[0];
iSes = 0;
}
}
/* .session attach TABLE
** Invoke the sqlite3session_attach() interface to attach a particular
** table so that it is never filtered.
*/
if( strcmp(azCmd[0],"attach")==0 ){
if( nCmd!=2 ) goto session_syntax_error;
if( pSession->p==0 ){
session_not_open:
raw_printf(stderr, "ERROR: No sessions are open\n");
}else{
rc = sqlite3session_attach(pSession->p, azCmd[1]);
if( rc ){
raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
rc = 0;
}
}
}else
/* .session changeset FILE
** .session patchset FILE
** Write a changeset or patchset into a file. The file is overwritten.
*/
if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
FILE *out = 0;
if( nCmd!=2 ) goto session_syntax_error;
if( pSession->p==0 ) goto session_not_open;
out = fopen(azCmd[1], "wb");
if( out==0 ){
utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
}else{
int szChng;
void *pChng;
if( azCmd[0][0]=='c' ){
rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
}else{
rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
}
if( rc ){
printf("Error: error code %d\n", rc);
rc = 0;
}
if( pChng
&& fwrite(pChng, szChng, 1, out)!=1 ){
raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
szChng);
}
sqlite3_free(pChng);
fclose(out);
}
}else
/* .session close
** Close the identified session
*/
if( strcmp(azCmd[0], "close")==0 ){
if( nCmd!=1 ) goto session_syntax_error;
if( p->nSession ){
session_close(pSession);
p->aSession[iSes] = p->aSession[--p->nSession];
}
}else
/* .session enable ?BOOLEAN?
** Query or set the enable flag
*/
if( strcmp(azCmd[0], "enable")==0 ){
int ii;
if( nCmd>2 ) goto session_syntax_error;
ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
if( p->nSession ){
ii = sqlite3session_enable(pSession->p, ii);
utf8_printf(p->out, "session %s enable flag = %d\n",
pSession->zName, ii);
}
}else
/* .session filter GLOB ....
** Set a list of GLOB patterns of table names to be excluded.
*/
if( strcmp(azCmd[0], "filter")==0 ){
int ii, nByte;
if( nCmd<2 ) goto session_syntax_error;
if( p->nSession ){
for(ii=0; ii<pSession->nFilter; ii++){
sqlite3_free(pSession->azFilter[ii]);
}
sqlite3_free(pSession->azFilter);
nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
pSession->azFilter = sqlite3_malloc( nByte );
if( pSession->azFilter==0 ){
raw_printf(stderr, "Error: out or memory\n");
exit(1);
}
for(ii=1; ii<nCmd; ii++){
pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
}
pSession->nFilter = ii-1;
}
}else
/* .session indirect ?BOOLEAN?
** Query or set the indirect flag
*/
if( strcmp(azCmd[0], "indirect")==0 ){
int ii;
if( nCmd>2 ) goto session_syntax_error;
ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
if( p->nSession ){
ii = sqlite3session_indirect(pSession->p, ii);
utf8_printf(p->out, "session %s indirect flag = %d\n",
pSession->zName, ii);
}
}else
/* .session isempty
** Determine if the session is empty
*/
if( strcmp(azCmd[0], "isempty")==0 ){
int ii;
if( nCmd!=1 ) goto session_syntax_error;
if( p->nSession ){
ii = sqlite3session_isempty(pSession->p);
utf8_printf(p->out, "session %s isempty flag = %d\n",
pSession->zName, ii);
}
}else
/* .session list
** List all currently open sessions
*/
if( strcmp(azCmd[0],"list")==0 ){
for(i=0; i<p->nSession; i++){
utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
}
}else
/* .session open DB NAME
** Open a new session called NAME on the attached database DB.
** DB is normally "main".
*/
if( strcmp(azCmd[0],"open")==0 ){
char *zName;
if( nCmd!=3 ) goto session_syntax_error;
zName = azCmd[2];
if( zName[0]==0 ) goto session_syntax_error;
for(i=0; i<p->nSession; i++){
if( strcmp(p->aSession[i].zName,zName)==0 ){
utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
goto meta_command_exit;
}
}
if( p->nSession>=ArraySize(p->aSession) ){
raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
goto meta_command_exit;
}
pSession = &p->aSession[p->nSession];
rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
if( rc ){
raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
rc = 0;
goto meta_command_exit;
}
pSession->nFilter = 0;
sqlite3session_table_filter(pSession->p, session_filter, pSession);
p->nSession++;
pSession->zName = sqlite3_mprintf("%s", zName);
}else
/* If no command name matches, show a syntax error */
session_syntax_error:
session_help(p);
}else
#endif
#ifdef SQLITE_DEBUG
/* Undocumented commands for internal testing. Subject to change
** without notice. */
if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
int i, v;
|
| ︙ | | | ︙ | |
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
|
if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
}else{
switch(testctrl){
/* sqlite3_test_control(int, db, int) */
case SQLITE_TESTCTRL_OPTIMIZATIONS:
case SQLITE_TESTCTRL_RESERVE:
if( nArg==3 ){
int opt = (int)strtol(azArg[2], 0, 0);
rc2 = sqlite3_test_control(testctrl, p->db, opt);
raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
} else {
utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
azArg[1]);
}
break;
|
|
|
|
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
|
if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
}else{
switch(testctrl){
/* sqlite3_test_control(int, db, int) */
case SQLITE_TESTCTRL_OPTIMIZATIONS:
case SQLITE_TESTCTRL_RESERVE:
if( nArg==3 ){
int opt = (int)strtol(azArg[2], 0, 0);
rc2 = sqlite3_test_control(testctrl, p->db, opt);
raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
} else {
utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
azArg[1]);
}
break;
|
| ︙ | | | ︙ | |
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
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
|
} else {
utf8_printf(stderr,"Error: testctrl %s takes no options\n",
azArg[1]);
}
break;
/* sqlite3_test_control(int, uint) */
case SQLITE_TESTCTRL_PENDING_BYTE:
if( nArg==3 ){
unsigned int opt = (unsigned int)integerValue(azArg[2]);
rc2 = sqlite3_test_control(testctrl, opt);
raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
} else {
utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
" int option\n", azArg[1]);
}
break;
/* sqlite3_test_control(int, int) */
case SQLITE_TESTCTRL_ASSERT:
case SQLITE_TESTCTRL_ALWAYS:
case SQLITE_TESTCTRL_NEVER_CORRUPT:
if( nArg==3 ){
int opt = booleanValue(azArg[2]);
rc2 = sqlite3_test_control(testctrl, opt);
raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
} else {
utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
azArg[1]);
}
break;
/* sqlite3_test_control(int, char *) */
#ifdef SQLITE_N_KEYWORD
case SQLITE_TESTCTRL_ISKEYWORD:
if( nArg==3 ){
const char *opt = azArg[2];
rc2 = sqlite3_test_control(testctrl, opt);
raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
} else {
utf8_printf(stderr,
"Error: testctrl %s takes a single char * option\n",
azArg[1]);
}
break;
#endif
case SQLITE_TESTCTRL_IMPOSTER:
if( nArg==5 ){
rc2 = sqlite3_test_control(testctrl, p->db,
azArg[2],
integerValue(azArg[3]),
integerValue(azArg[4]));
raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
}else{
raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
}
break;
case SQLITE_TESTCTRL_BITVEC_TEST:
case SQLITE_TESTCTRL_FAULT_INSTALL:
case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
case SQLITE_TESTCTRL_SCRATCHMALLOC:
default:
utf8_printf(stderr,
"Error: CLI support for testctrl %s not implemented\n",
azArg[1]);
break;
}
}
}else
if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
open_db(p, 0);
sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
}else
if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
if( nArg==2 ){
enableTimer = booleanValue(azArg[1]);
if( enableTimer && !HAS_TIMER ){
raw_printf(stderr, "Error: timer not available on this system.\n");
enableTimer = 0;
}
}else{
raw_printf(stderr, "Usage: .timer on|off\n");
rc = 1;
}
}else
if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
open_db(p, 0);
if( nArg!=2 ){
raw_printf(stderr, "Usage: .trace FILE|off\n");
rc = 1;
goto meta_command_exit;
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
|
} else {
utf8_printf(stderr,"Error: testctrl %s takes no options\n",
azArg[1]);
}
break;
/* sqlite3_test_control(int, uint) */
case SQLITE_TESTCTRL_PENDING_BYTE:
if( nArg==3 ){
unsigned int opt = (unsigned int)integerValue(azArg[2]);
rc2 = sqlite3_test_control(testctrl, opt);
raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
} else {
utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
" int option\n", azArg[1]);
}
break;
/* sqlite3_test_control(int, int) */
case SQLITE_TESTCTRL_ASSERT:
case SQLITE_TESTCTRL_ALWAYS:
case SQLITE_TESTCTRL_NEVER_CORRUPT:
if( nArg==3 ){
int opt = booleanValue(azArg[2]);
rc2 = sqlite3_test_control(testctrl, opt);
raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
} else {
utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
azArg[1]);
}
break;
/* sqlite3_test_control(int, char *) */
#ifdef SQLITE_N_KEYWORD
case SQLITE_TESTCTRL_ISKEYWORD:
if( nArg==3 ){
const char *opt = azArg[2];
rc2 = sqlite3_test_control(testctrl, opt);
raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
} else {
utf8_printf(stderr,
"Error: testctrl %s takes a single char * option\n",
azArg[1]);
}
break;
#endif
case SQLITE_TESTCTRL_IMPOSTER:
if( nArg==5 ){
rc2 = sqlite3_test_control(testctrl, p->db,
azArg[2],
integerValue(azArg[3]),
integerValue(azArg[4]));
raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
}else{
raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
}
break;
case SQLITE_TESTCTRL_BITVEC_TEST:
case SQLITE_TESTCTRL_FAULT_INSTALL:
case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
case SQLITE_TESTCTRL_SCRATCHMALLOC:
default:
utf8_printf(stderr,
"Error: CLI support for testctrl %s not implemented\n",
azArg[1]);
break;
}
}
}else
if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
open_db(p, 0);
sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
}else
if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
if( nArg==2 ){
enableTimer = booleanValue(azArg[1]);
if( enableTimer && !HAS_TIMER ){
raw_printf(stderr, "Error: timer not available on this system.\n");
enableTimer = 0;
}
}else{
raw_printf(stderr, "Usage: .timer on|off\n");
rc = 1;
}
}else
if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
open_db(p, 0);
if( nArg!=2 ){
raw_printf(stderr, "Usage: .trace FILE|off\n");
rc = 1;
goto meta_command_exit;
}
|
| ︙ | | | ︙ | |
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
|
raw_printf(stderr, "User-Delete failed: %d\n", rc);
rc = 1;
}
}else{
raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
rc = 1;
goto meta_command_exit;
}
}else
#endif /* SQLITE_USER_AUTHENTICATION */
if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
sqlite3_libversion(), sqlite3_sourceid());
}else
|
|
|
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
|
raw_printf(stderr, "User-Delete failed: %d\n", rc);
rc = 1;
}
}else{
raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
rc = 1;
goto meta_command_exit;
}
}else
#endif /* SQLITE_USER_AUTHENTICATION */
if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
sqlite3_libversion(), sqlite3_sourceid());
}else
|
| ︙ | | | ︙ | |
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
|
if( p->backslashOn ) resolve_backslashes(zSql);
BEGIN_TIMER;
rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
END_TIMER;
if( rc || zErrMsg ){
char zPrefix[100];
if( in!=0 || !stdin_is_interactive ){
sqlite3_snprintf(sizeof(zPrefix), zPrefix,
"Error: near line %d:", startline);
}else{
sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
}
if( zErrMsg!=0 ){
utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
sqlite3_free(zErrMsg);
|
|
|
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
|
if( p->backslashOn ) resolve_backslashes(zSql);
BEGIN_TIMER;
rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
END_TIMER;
if( rc || zErrMsg ){
char zPrefix[100];
if( in!=0 || !stdin_is_interactive ){
sqlite3_snprintf(sizeof(zPrefix), zPrefix,
"Error: near line %d:", startline);
}else{
sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
}
if( zErrMsg!=0 ){
utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
sqlite3_free(zErrMsg);
|
| ︙ | | | ︙ | |
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
|
}
sqlite3_free(zBuf);
}
/*
** Show available command line options
*/
static const char zOptions[] =
" -ascii set output mode to 'ascii'\n"
" -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"
|
|
|
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
|
}
sqlite3_free(zBuf);
}
/*
** Show available command line options
*/
static const char zOptions[] =
" -ascii set output mode to 'ascii'\n"
" -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"
|
| ︙ | | | ︙ | |
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
|
" -vfs NAME use NAME as the default VFS\n"
#ifdef SQLITE_ENABLE_VFSTRACE
" -vfstrace enable tracing of all VFS calls\n"
#endif
;
static void usage(int showDetail){
utf8_printf(stderr,
"Usage: %s [OPTIONS] FILENAME [SQL]\n"
"FILENAME is the name of an SQLite database. A new database is created\n"
"if the file does not previously exist.\n", Argv0);
if( showDetail ){
utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
}else{
raw_printf(stderr, "Use the -help option for additional information\n");
}
|
|
|
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
|
" -vfs NAME use NAME as the default VFS\n"
#ifdef SQLITE_ENABLE_VFSTRACE
" -vfstrace enable tracing of all VFS calls\n"
#endif
;
static void usage(int showDetail){
utf8_printf(stderr,
"Usage: %s [OPTIONS] FILENAME [SQL]\n"
"FILENAME is the name of an SQLite database. A new database is created\n"
"if the file does not previously exist.\n", Argv0);
if( showDetail ){
utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
}else{
raw_printf(stderr, "Use the -help option for additional information\n");
}
|
| ︙ | | | ︙ | |
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
|
utf8_printf(stderr, "%s: Error: missing argument to %s\n",
argv[0], argv[argc-1]);
exit(1);
}
return argv[i];
}
int SQLITE_CDECL main(int argc, char **argv){
char *zErrMsg = 0;
ShellState data;
const char *zInitFile = 0;
int i;
int rc = 0;
int warnInmemoryDb = 0;
int readStdin = 1;
int nCmd = 0;
char **azCmd = 0;
#if USE_SYSTEM_SQLITE+0!=1
if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
sqlite3_sourceid(), SQLITE_SOURCE_ID);
exit(1);
}
#endif
setBinaryMode(stdin);
setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
Argv0 = argv[0];
main_init(&data);
stdin_is_interactive = isatty(0);
stdout_is_console = isatty(1);
/* Make sure we have a valid signal handler early, before anything
** else is done.
*/
#ifdef SIGINT
signal(SIGINT, interrupt_handler);
#endif
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
<
<
<
|
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
|
utf8_printf(stderr, "%s: Error: missing argument to %s\n",
argv[0], argv[argc-1]);
exit(1);
}
return argv[i];
}
#ifndef SQLITE_SHELL_IS_UTF8
# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
# define SQLITE_SHELL_IS_UTF8 (0)
# else
# define SQLITE_SHELL_IS_UTF8 (1)
# endif
#endif
#if SQLITE_SHELL_IS_UTF8
int SQLITE_CDECL main(int argc, char **argv){
#else
int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
char **argv;
#endif
char *zErrMsg = 0;
ShellState data;
const char *zInitFile = 0;
int i;
int rc = 0;
int warnInmemoryDb = 0;
int readStdin = 1;
int nCmd = 0;
char **azCmd = 0;
setBinaryMode(stdin, 0);
setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
stdin_is_interactive = isatty(0);
stdout_is_console = isatty(1);
#if USE_SYSTEM_SQLITE+0!=1
if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
sqlite3_sourceid(), SQLITE_SOURCE_ID);
exit(1);
}
#endif
main_init(&data);
#if !SQLITE_SHELL_IS_UTF8
sqlite3_initialize();
argv = sqlite3_malloc64(sizeof(argv[0])*argc);
if( argv==0 ){
raw_printf(stderr, "out of memory\n");
exit(1);
}
for(i=0; i<argc; i++){
argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);
if( argv[i]==0 ){
raw_printf(stderr, "out of memory\n");
exit(1);
}
}
#endif
assert( argc>=1 && argv && argv[0] );
Argv0 = argv[0];
/* Make sure we have a valid signal handler early, before anything
** else is done.
*/
#ifdef SIGINT
signal(SIGINT, interrupt_handler);
#endif
|
| ︙ | | | ︙ | |
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
|
|| 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)
const char *zSize;
sqlite3_int64 szHeap;
|
|
|
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
|
|| 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)
const char *zSize;
sqlite3_int64 szHeap;
|
| ︙ | | | ︙ | |
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
|
}
}else{
rc = process_input(&data, stdin);
}
}
set_table_name(&data, 0);
if( data.db ){
sqlite3_close(data.db);
}
sqlite3_free(data.zFreeOnClose);
return rc;
}
|
>
|
>
>
>
>
|
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
|
}
}else{
rc = process_input(&data, stdin);
}
}
set_table_name(&data, 0);
if( data.db ){
session_close_all(&data);
sqlite3_close(data.db);
}
sqlite3_free(data.zFreeOnClose);
#if !SQLITE_SHELL_IS_UTF8
for(i=0; i<argc; i++) sqlite3_free(argv[i]);
sqlite3_free(argv);
#endif
return rc;
}
|