Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Bring in the enhanced "shell.c" with the improved ".schema" and ".tables" commands from upstream SQLite. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
d9e555194ac7709eb4eb6c3d3d2cdeac |
| User & Date: | drh 2017-06-15 12:52:12.112 |
Context
|
2017-06-15
| ||
| 13:12 | Fix compiler warnings in the shell.c from the previous check-in. Also bring in the latest trunk version of SQLite for testing. check-in: 2ada39bab8 user: drh tags: trunk | |
| 12:52 | Bring in the enhanced "shell.c" with the improved ".schema" and ".tables" commands from upstream SQLite. check-in: d9e555194a user: drh tags: trunk | |
| 03:37 | Fix TTY comment line break logic for UTF8 multi-byte characters. check-in: e62161976e user: drh tags: trunk | |
Changes
Changes to src/shell.c.
| ︙ | ︙ | |||
14 15 16 17 18 19 20 | */ #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS) /* This needs to come before any includes for MSVC compiler */ #define _CRT_SECURE_NO_WARNINGS #endif /* | | | | > > > > > > > > > > > > > > | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | */ #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS) /* This needs to come before any includes for MSVC compiler */ #define _CRT_SECURE_NO_WARNINGS #endif /* ** Warning pragmas copied from msvc.h in the core. */ #if defined(_MSC_VER) #pragma warning(disable : 4054) #pragma warning(disable : 4055) #pragma warning(disable : 4100) #pragma warning(disable : 4127) #pragma warning(disable : 4130) #pragma warning(disable : 4152) #pragma warning(disable : 4189) #pragma warning(disable : 4206) #pragma warning(disable : 4210) #pragma warning(disable : 4232) #pragma warning(disable : 4244) #pragma warning(disable : 4305) #pragma warning(disable : 4306) #pragma warning(disable : 4702) #pragma warning(disable : 4706) #endif /* defined(_MSC_VER) */ /* ** No support for loadable extensions in VxWorks. */ #if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION # define SQLITE_OMIT_LOAD_EXTENSION 1 #endif |
| ︙ | ︙ | |||
490 491 492 493 494 495 496 497 498 499 500 501 502 503 |
** lower 30 bits of a 32-bit signed integer.
*/
static int strlen30(const char *z){
const char *z2 = z;
while( *z2 ){ z2++; }
return 0x3fffffff & (int)(z2 - z);
}
/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text. NULL is returned at end of file, or if malloc()
** fails.
**
| > > > > > > > > > > > > | 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 |
** lower 30 bits of a 32-bit signed integer.
*/
static int strlen30(const char *z){
const char *z2 = z;
while( *z2 ){ z2++; }
return 0x3fffffff & (int)(z2 - z);
}
/*
** Return the length of a string in characters. Multibyte UTF8 characters
** count as a single character.
*/
static int strlenChar(const char *z){
int n = 0;
while( *z ){
if( (0xc0&*(z++))!=0x80 ) n++;
}
return n;
}
/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text. NULL is returned at end of file, or if malloc()
** fails.
**
|
| ︙ | ︙ | |||
1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 |
SHA3Update(p, &c3, 1);
}
for(i=0; i<p->nRate; i++){
p->u.x[i+p->nRate] = p->u.x[i^p->ixMask];
}
return &p->u.x[p->nRate];
}
/*
** Implementation of the sha3(X,SIZE) function.
**
** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 |
SHA3Update(p, &c3, 1);
}
for(i=0; i<p->nRate; i++){
p->u.x[i+p->nRate] = p->u.x[i^p->ixMask];
}
return &p->u.x[p->nRate];
}
/*
** SQL function: shell_add_schema(S,X)
**
** Add the schema name X to the CREATE statement in S and return the result.
** Examples:
**
** CREATE TABLE t1(x) -> CREATE TABLE xyz.t1(x);
**
** Also works on
**
** CREATE INDEX
** CREATE UNIQUE INDEX
** CREATE VIEW
** CREATE TRIGGER
** CREATE VIRTUAL TABLE
**
** This UDF is used by the .schema command to insert the schema name of
** attached databases into the middle of the sqlite_master.sql field.
*/
static void shellAddSchemaName(
sqlite3_context *pCtx,
int nVal,
sqlite3_value **apVal
){
static const char *aPrefix[] = {
"TABLE",
"INDEX",
"UNIQUE INDEX",
"VIEW",
"TRIGGER",
"VIRTUAL TABLE"
};
int i = 0, n;
const char *zIn = (const char*)sqlite3_value_text(apVal[0]);
const char *zSchema = (const char*)sqlite3_value_text(apVal[1]);
assert( nVal==2 );
if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){
for(i=0; i<sizeof(aPrefix)/sizeof(aPrefix[0]); i++){
int n = strlen30(aPrefix[i]);
if( strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){
char cQuote = quoteChar(zSchema);
char *z;
if( cQuote ){
z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8);
}else{
z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8);
}
sqlite3_result_text(pCtx, z, -1, sqlite3_free);
return;
}
}
}
sqlite3_result_value(pCtx, apVal[0]);
}
/*
** Implementation of the sha3(X,SIZE) function.
**
** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default
** size is 256. If X is a BLOB, it is hashed as is.
** For all other non-NULL types of input, X is converted into a UTF-8 string
** and the string is hashed without the trailing 0x00 terminator. The hash
** of a NULL value is NULL.
*/
static void sha3Func(
sqlite3_context *context,
int argc,
|
| ︙ | ︙ | |||
1899 1900 1901 1902 1903 1904 1905 |
int w, n;
if( i<ArraySize(p->colWidth) ){
w = colWidth[i];
}else{
w = 0;
}
if( w==0 ){
| | | | 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 |
int w, n;
if( i<ArraySize(p->colWidth) ){
w = colWidth[i];
}else{
w = 0;
}
if( w==0 ){
w = strlenChar(azCol[i] ? azCol[i] : "");
if( w<10 ) w = 10;
n = strlenChar(azArg && azArg[i] ? azArg[i] : p->nullValue);
if( w<n ) w = n;
}
if( i<ArraySize(p->actualWidth) ){
p->actualWidth[i] = w;
}
if( showHdr ){
utf8_width_print(p->out, w, azCol[i]);
|
| ︙ | ︙ | |||
1936 1937 1938 1939 1940 1941 1942 |
for(i=0; i<nArg; i++){
int w;
if( i<ArraySize(p->actualWidth) ){
w = p->actualWidth[i];
}else{
w = 10;
}
| | | | 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 |
for(i=0; i<nArg; i++){
int w;
if( i<ArraySize(p->actualWidth) ){
w = p->actualWidth[i];
}else{
w = 10;
}
if( p->cMode==MODE_Explain && azArg[i] && strlenChar(azArg[i])>w ){
w = strlenChar(azArg[i]);
}
if( i==1 && p->aiIndent && p->pStmt ){
if( p->iIndent<p->nIndent ){
utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
}
p->iIndent++;
}
|
| ︙ | ︙ | |||
2993 2994 2995 2996 2997 2998 2999 |
}
}
azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
if( sqlite3_column_int(pStmt, 5) ){
nPK++;
if( nPK==1
&& sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2),
| | | 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 |
}
}
azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
if( sqlite3_column_int(pStmt, 5) ){
nPK++;
if( nPK==1
&& sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2),
"INTEGER")==0
){
isIPK = 1;
}else{
isIPK = 0;
}
}
}
|
| ︙ | ︙ | |||
3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 | static char zHelp[] = #ifndef SQLITE_OMIT_AUTHORIZATION ".auth ON|OFF Show authorizer callbacks\n" #endif ".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" ".check GLOB Fail if output since .testcase does not match\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" ".dump ?TABLE? ... Dump the database in an SQL text format\n" " If TABLE specified, only dump tables matching\n" | > | 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 | static char zHelp[] = #ifndef SQLITE_OMIT_AUTHORIZATION ".auth ON|OFF Show authorizer callbacks\n" #endif ".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" ".cd DIRECTORY Change the working directory to DIRECTORY\n" ".changes on|off Show number of rows changed by SQL\n" ".check GLOB Fail if output since .testcase does not match\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" ".dump ?TABLE? ... Dump the database in an SQL text format\n" " If TABLE specified, only dump tables matching\n" |
| ︙ | ︙ | |||
3275 3276 3277 3278 3279 3280 3281 | " line One value per line\n" " list Values delimited by \"|\"\n" " quote Escape answers as for SQL\n" " tabs Tab-separated values\n" " tcl TCL list elements\n" ".nullvalue STRING Use STRING in place of NULL values\n" ".once FILENAME Output for the next SQL command only to FILENAME\n" | | | | 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 | " line One value per line\n" " list Values delimited by \"|\"\n" " quote Escape answers as for SQL\n" " tabs Tab-separated values\n" " tcl TCL list elements\n" ".nullvalue STRING Use STRING in place of NULL values\n" ".once FILENAME Output for the next SQL command only to FILENAME\n" ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n" " The --new option starts with an empty file\n" ".output ?FILENAME? Send output to FILENAME or stdout\n" ".print STRING... Print literal STRING\n" ".prompt MAIN CONTINUE Replace the standard prompts\n" ".quit Exit this program\n" ".read FILENAME Execute SQL in FILENAME\n" ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" ".save FILE Write in-memory database into FILE\n" |
| ︙ | ︙ | |||
3341 3342 3343 3344 3345 3346 3347 | /* Forward reference */ static int process_input(ShellState *p, FILE *in); /* ** Read the content of file zName into memory obtained from sqlite3_malloc64() | | | | 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 | /* Forward reference */ static int process_input(ShellState *p, FILE *in); /* ** Read the content of file zName into memory obtained from sqlite3_malloc64() ** and return a pointer to the buffer. The caller is responsible for freeing ** the memory. ** ** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes ** read. ** ** For convenience, a nul-terminator byte is always appended to the data read ** from the file before the buffer is returned. This byte is not included in ** the final value of (*pnByte), if applicable. |
| ︙ | ︙ | |||
3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 |
sha3Func, 0, 0);
sqlite3_create_function(p->db, "sha3", 2, SQLITE_UTF8, 0,
sha3Func, 0, 0);
sqlite3_create_function(p->db, "sha3_query", 1, SQLITE_UTF8, 0,
sha3QueryFunc, 0, 0);
sqlite3_create_function(p->db, "sha3_query", 2, SQLITE_UTF8, 0,
sha3QueryFunc, 0, 0);
}
}
/*
** Do C-language style dequoting.
**
** \a -> alarm
| > > > | 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 |
sha3Func, 0, 0);
sqlite3_create_function(p->db, "sha3", 2, SQLITE_UTF8, 0,
sha3Func, 0, 0);
sqlite3_create_function(p->db, "sha3_query", 1, SQLITE_UTF8, 0,
sha3QueryFunc, 0, 0);
sqlite3_create_function(p->db, "sha3_query", 2, SQLITE_UTF8, 0,
sha3QueryFunc, 0, 0);
sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0,
shellAddSchemaName, 0, 0);
}
}
/*
** Do C-language style dequoting.
**
** \a -> alarm
|
| ︙ | ︙ | |||
4349 4350 4351 4352 4353 4354 4355 |
** by the ".lint fkey-indexes" command. This scalar function is always
** called with four arguments - the parent table name, the parent column name,
** the child table name and the child column name.
**
** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col')
**
** If either of the named tables or columns do not exist, this function
| | | | | | 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 |
** by the ".lint fkey-indexes" command. This scalar function is always
** called with four arguments - the parent table name, the parent column name,
** the child table name and the child column name.
**
** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col')
**
** If either of the named tables or columns do not exist, this function
** returns an empty string. An empty string is also returned if both tables
** and columns exist but have the same default collation sequence. Or,
** if both exist but the default collation sequences are different, this
** function returns the string " COLLATE <parent-collation>", where
** <parent-collation> is the default collation sequence of the parent column.
*/
static void shellFkeyCollateClause(
sqlite3_context *pCtx,
int nVal,
sqlite3_value **apVal
){
sqlite3 *db = sqlite3_context_db_handle(pCtx);
const char *zParent;
const char *zParentCol;
const char *zParentSeq;
const char *zChild;
const char *zChildCol;
const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */
int rc;
assert( nVal==4 );
zParent = (const char*)sqlite3_value_text(apVal[0]);
zParentCol = (const char*)sqlite3_value_text(apVal[1]);
zChild = (const char*)sqlite3_value_text(apVal[2]);
zChildCol = (const char*)sqlite3_value_text(apVal[3]);
sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC);
|
| ︙ | ︙ | |||
4490 4491 4492 4493 4494 4495 4496 |
else{
raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n",
azArg[0], azArg[1]
);
return SQLITE_ERROR;
}
}
| | | 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 |
else{
raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n",
azArg[0], azArg[1]
);
return SQLITE_ERROR;
}
}
/* Register the fkey_collate_clause() SQL function */
rc = sqlite3_create_function(db, "fkey_collate_clause", 4, SQLITE_UTF8,
0, shellFkeyCollateClause, 0, 0
);
if( rc==SQLITE_OK ){
|
| ︙ | ︙ | |||
4533 4534 4535 4536 4537 4538 4539 |
rc = sqlite3_finalize(pExplain);
if( rc!=SQLITE_OK ) break;
if( res<0 ){
raw_printf(stderr, "Error: internal error");
break;
}else{
| | | | | 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 |
rc = sqlite3_finalize(pExplain);
if( rc!=SQLITE_OK ) break;
if( res<0 ){
raw_printf(stderr, "Error: internal error");
break;
}else{
if( bGroupByParent
&& (bVerbose || res==0)
&& (zPrev==0 || sqlite3_stricmp(zParent, zPrev))
){
raw_printf(out, "-- Parent table %s\n", zParent);
sqlite3_free(zPrev);
zPrev = sqlite3_mprintf("%s", zParent);
}
if( res==0 ){
raw_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget);
}else if( bVerbose ){
raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n",
zIndent, zFrom, zTarget
);
}
}
}
sqlite3_free(zPrev);
|
| ︙ | ︙ | |||
4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 |
setTextMode(p->out, 1);
}
}else{
raw_printf(stderr, "Usage: .binary on|off\n");
rc = 1;
}
}else
/* The undocumented ".breakpoint" command causes a call to the no-op
** routine named test_breakpoint().
*/
if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
test_breakpoint();
}else
| > > > > > > > > > > > > > > > > > > > | 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 |
setTextMode(p->out, 1);
}
}else{
raw_printf(stderr, "Usage: .binary on|off\n");
rc = 1;
}
}else
if( c=='c' && strcmp(azArg[0],"cd")==0 ){
if( nArg==2 ){
#if defined(_WIN32) || defined(WIN32)
wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]);
rc = !SetCurrentDirectoryW(z);
sqlite3_free(z);
#else
rc = chdir(azArg[1]);
#endif
if( rc ){
utf8_printf(stderr, "Cannot change to directory \"%s\"\n", azArg[1]);
rc = 1;
}
}else{
raw_printf(stderr, "Usage: .cd DIRECTORY\n");
rc = 1;
}
}else
/* The undocumented ".breakpoint" command causes a call to the no-op
** routine named test_breakpoint().
*/
if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
test_breakpoint();
}else
|
| ︙ | ︙ | |||
5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 |
}else{
raw_printf(stderr, "Usage: .scanstats on|off\n");
rc = 1;
}
}else
if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
ShellState data;
char *zErrMsg = 0;
open_db(p, 0);
memcpy(&data, p, sizeof(data));
data.showHeader = 0;
data.cMode = data.mode = MODE_Semi;
if( nArg>=2 && optionMatch(azArg[1], "indent") ){
data.cMode = data.mode = MODE_Pretty;
nArg--;
if( nArg==2 ) azArg[1] = azArg[2];
}
if( nArg==2 && azArg[1][0]!='-' ){
int i;
| > > > > > | 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 |
}else{
raw_printf(stderr, "Usage: .scanstats on|off\n");
rc = 1;
}
}else
if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
ShellText sSelect;
ShellState data;
char *zErrMsg = 0;
const char *zDiv = 0;
int iSchema = 0;
open_db(p, 0);
memcpy(&data, p, sizeof(data));
data.showHeader = 0;
data.cMode = data.mode = MODE_Semi;
initText(&sSelect);
if( nArg>=2 && optionMatch(azArg[1], "indent") ){
data.cMode = data.mode = MODE_Pretty;
nArg--;
if( nArg==2 ) azArg[1] = azArg[2];
}
if( nArg==2 && azArg[1][0]!='-' ){
int i;
|
| ︙ | ︙ | |||
5682 5683 5684 5685 5686 5687 5688 |
")";
new_argv[1] = 0;
new_colv[0] = "sql";
new_colv[1] = 0;
callback(&data, 1, new_argv, new_colv);
rc = SQLITE_OK;
}else{
| < | < < < < < < < < < | < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 |
")";
new_argv[1] = 0;
new_colv[0] = "sql";
new_colv[1] = 0;
callback(&data, 1, new_argv, new_colv);
rc = SQLITE_OK;
}else{
zDiv = "(";
}
}else if( nArg==1 ){
zDiv = "(";
}else{
raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
rc = 1;
goto meta_command_exit;
}
if( zDiv ){
sqlite3_stmt *pStmt = 0;
sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
-1, &pStmt, 0);
appendText(&sSelect, "SELECT sql FROM", 0);
iSchema = 0;
while( sqlite3_step(pStmt)==SQLITE_ROW ){
const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
char zScNum[30];
sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
appendText(&sSelect, zDiv, 0);
zDiv = " UNION ALL ";
if( strcmp(zDb, "main")!=0 ){
appendText(&sSelect, "SELECT shell_add_schema(sql,", 0);
appendText(&sSelect, sqlite3_column_text(pStmt, 0), '"');
appendText(&sSelect, ") AS sql, type, tbl_name, name, rowid,", 0);
appendText(&sSelect, zScNum, 0);
appendText(&sSelect, " AS snum, ", 0);
appendText(&sSelect, zDb, '\'');
appendText(&sSelect, " AS sname FROM ", 0);
appendText(&sSelect, sqlite3_column_text(pStmt, 0), '"');
appendText(&sSelect, ".sqlite_master", 0);
}else{
appendText(&sSelect, "SELECT sql, type, tbl_name, name, rowid, ", 0);
appendText(&sSelect, zScNum, 0);
appendText(&sSelect, " AS snum, 'main' AS sname FROM sqlite_master",0);
}
}
sqlite3_finalize(pStmt);
appendText(&sSelect, ") WHERE ", 0);
if( nArg>1 ){
char *zQarg = sqlite3_mprintf("%Q", azArg[1]);
if( strchr(azArg[1], '.') ){
appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0);
}else{
appendText(&sSelect, "lower(tbl_name)", 0);
}
appendText(&sSelect, strchr(azArg[1], '*') ? " GLOB " : " LIKE ", 0);
appendText(&sSelect, zQarg, 0);
appendText(&sSelect, " AND ", 0);
sqlite3_free(zQarg);
}
appendText(&sSelect, "type!='meta' AND sql IS NOT NULL"
" ORDER BY snum, rowid", 0);
rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
freeText(&sSelect);
}
if( zErrMsg ){
utf8_printf(stderr,"Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
rc = 1;
}else if( rc != SQLITE_OK ){
raw_printf(stderr,"Error: querying schema information\n");
rc = 1;
|
| ︙ | ︙ | |||
5950 5951 5952 5953 5954 5955 5956 |
}else
#endif
if( c=='s' && n>=4 && strncmp(azArg[0],"selftest",n)==0 ){
int bIsInit = 0; /* True to initialize the SELFTEST table */
int bVerbose = 0; /* Verbose output */
int bSelftestExists; /* True if SELFTEST already exists */
| < < < | < < | < < < | 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 |
}else
#endif
if( c=='s' && n>=4 && strncmp(azArg[0],"selftest",n)==0 ){
int bIsInit = 0; /* True to initialize the SELFTEST table */
int bVerbose = 0; /* Verbose output */
int bSelftestExists; /* True if SELFTEST already exists */
int i, k; /* Loop counters */
int nTest = 0; /* Number of tests runs */
int nErr = 0; /* Number of errors seen */
ShellText str; /* Answer for a query */
sqlite3_stmt *pStmt = 0; /* Query against the SELFTEST table */
open_db(p,0);
for(i=1; i<nArg; i++){
const char *z = azArg[i];
if( z[0]=='-' && z[1]=='-' ) z++;
if( strcmp(z,"-init")==0 ){
bIsInit = 1;
|
| ︙ | ︙ | |||
5992 5993 5994 5995 5996 5997 5998 |
}else{
bSelftestExists = 1;
}
if( bIsInit ){
createSelftestTable(p);
bSelftestExists = 1;
}
| > > | > | | | > > > > > > | < < < < < < < < < < | | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > < | 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 |
}else{
bSelftestExists = 1;
}
if( bIsInit ){
createSelftestTable(p);
bSelftestExists = 1;
}
initText(&str);
appendText(&str, "x", 0);
for(k=bSelftestExists; k>=0; k--){
if( k==1 ){
rc = sqlite3_prepare_v2(p->db,
"SELECT tno,op,cmd,ans FROM selftest ORDER BY tno",
-1, &pStmt, 0);
}else{
rc = sqlite3_prepare_v2(p->db,
"VALUES(0,'memo','Missing SELFTEST table - default checks only',''),"
" (1,'run','PRAGMA integrity_check','ok')",
-1, &pStmt, 0);
}
if( rc ){
raw_printf(stderr, "Error querying the selftest table\n");
rc = 1;
sqlite3_finalize(pStmt);
goto meta_command_exit;
}
for(i=1; sqlite3_step(pStmt)==SQLITE_ROW; i++){
int tno = sqlite3_column_int(pStmt, 0);
const char *zOp = (const char*)sqlite3_column_text(pStmt, 1);
const char *zSql = (const char*)sqlite3_column_text(pStmt, 2);
const char *zAns = (const char*)sqlite3_column_text(pStmt, 3);
k = 0;
if( bVerbose>0 ){
char *zQuote = sqlite3_mprintf("%q", zSql);
printf("%d: %s %s\n", tno, zOp, zSql);
sqlite3_free(zQuote);
}
if( strcmp(zOp,"memo")==0 ){
utf8_printf(p->out, "%s\n", zSql);
}else
if( strcmp(zOp,"run")==0 ){
char *zErrMsg = 0;
str.n = 0;
str.z[0] = 0;
rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
nTest++;
if( bVerbose ){
utf8_printf(p->out, "Result: %s\n", str.z);
}
if( rc || zErrMsg ){
nErr++;
rc = 1;
utf8_printf(p->out, "%d: error-code-%d: %s\n", tno, rc, zErrMsg);
sqlite3_free(zErrMsg);
}else if( strcmp(zAns,str.z)!=0 ){
nErr++;
rc = 1;
utf8_printf(p->out, "%d: Expected: [%s]\n", tno, zAns);
utf8_printf(p->out, "%d: Got: [%s]\n", tno, str.z);
}
}else
{
utf8_printf(stderr,
"Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
rc = 1;
break;
}
} /* End loop over rows of content from SELFTEST */
sqlite3_finalize(pStmt);
} /* End loop over k */
freeText(&str);
utf8_printf(p->out, "%d errors out of %d tests\n", nErr, nTest);
}else
if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
if( nArg<2 || nArg>3 ){
raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
rc = 1;
|
| ︙ | ︙ | |||
6095 6096 6097 6098 6099 6100 6101 |
const char *z = azArg[i];
if( z[0]=='-' ){
z++;
if( z[0]=='-' ) z++;
if( strcmp(z,"schema")==0 ){
bSchema = 1;
}else
| | | | 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 |
const char *z = azArg[i];
if( z[0]=='-' ){
z++;
if( z[0]=='-' ) z++;
if( strcmp(z,"schema")==0 ){
bSchema = 1;
}else
if( strcmp(z,"sha3-224")==0 || strcmp(z,"sha3-256")==0
|| strcmp(z,"sha3-384")==0 || strcmp(z,"sha3-512")==0
){
iSize = atoi(&z[5]);
}else
if( strcmp(z,"debug")==0 ){
bDebug = 1;
}else
{
|
| ︙ | ︙ | |||
6264 6265 6266 6267 6268 6269 6270 |
if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0)
|| (c=='i' && (strncmp(azArg[0], "indices", n)==0
|| strncmp(azArg[0], "indexes", n)==0) )
){
sqlite3_stmt *pStmt;
char **azResult;
int nRow, nAlloc;
| < > > < < < < < < < < < | < < < < < | | > > > > > > > > > > < < < | | | < < < | | < | | < | < | 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 |
if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0)
|| (c=='i' && (strncmp(azArg[0], "indices", n)==0
|| strncmp(azArg[0], "indexes", n)==0) )
){
sqlite3_stmt *pStmt;
char **azResult;
int nRow, nAlloc;
int ii;
ShellText s;
initText(&s);
open_db(p, 0);
rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
if( rc ) return shellDatabaseError(p->db);
if( nArg>2 && c=='i' ){
/* It is an historical accident that the .indexes command shows an error
** when called with the wrong number of arguments whereas the .tables
** command does not. */
raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
rc = 1;
goto meta_command_exit;
}
for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
if( zDbName==0 ) continue;
if( s.z && s.z[0] ) appendText(&s, " UNION ALL ", 0);
if( sqlite3_stricmp(zDbName, "main")==0 ){
appendText(&s, "SELECT name FROM ", 0);
}else{
appendText(&s, "SELECT ", 0);
appendText(&s, zDbName, '\'');
appendText(&s, "||'.'||name FROM ", 0);
}
appendText(&s, zDbName, '"');
appendText(&s, ".sqlite_master ", 0);
if( c=='t' ){
appendText(&s," WHERE type IN ('table','view')"
" AND name NOT LIKE 'sqlite_%'"
" AND name LIKE ?1", 0);
}else{
appendText(&s," WHERE type='index'"
" AND tbl_name LIKE ?1", 0);
}
}
rc = sqlite3_finalize(pStmt);
appendText(&s, " ORDER BY 1", 0);
rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0);
freeText(&s);
if( rc ) return shellDatabaseError(p->db);
/* Run the SQL statement prepared by the above block. Store the results
** as an array of nul-terminated strings in azResult[]. */
nRow = nAlloc = 0;
azResult = 0;
if( nArg>1 ){
|
| ︙ | ︙ |