| | @@ -701,11 +701,10 @@ |
| 701 | 701 | unsigned char eTitle; /* Quating style for the text of column names */ |
| 702 | 702 | unsigned char eBlob; /* Quoting style for BLOBs */ |
| 703 | 703 | unsigned char bTitles; /* True to show column names */ |
| 704 | 704 | unsigned char bWordWrap; /* Try to wrap on word boundaries */ |
| 705 | 705 | unsigned char bTextJsonb; /* Render JSONB blobs as JSON text */ |
| 706 | | - unsigned char bTextNull; /* Apply eText encoding to zNull[] */ |
| 707 | 706 | unsigned char eDfltAlign; /* Default alignment, no covered by aAlignment */ |
| 708 | 707 | unsigned char eTitleAlign; /* Alignment for column headers */ |
| 709 | 708 | unsigned char bSplitColumn; /* Wrap single-column output into many columns */ |
| 710 | 709 | short int nWrap; /* Wrap columns wider than this */ |
| 711 | 710 | short int nScreenWidth; /* Maximum overall table width */ |
| | @@ -787,10 +786,11 @@ |
| 787 | 786 | #define QRF_BLOB_Text 1 /* Display content exactly as it is */ |
| 788 | 787 | #define QRF_BLOB_Sql 2 /* Quote as an SQL literal */ |
| 789 | 788 | #define QRF_BLOB_Hex 3 /* Hexadecimal representation */ |
| 790 | 789 | #define QRF_BLOB_Tcl 4 /* "\000" notation */ |
| 791 | 790 | #define QRF_BLOB_Json 5 /* A JSON string */ |
| 791 | +#define QRF_BLOB_Size 6 /* Display the blob size only */ |
| 792 | 792 | |
| 793 | 793 | /* |
| 794 | 794 | ** Control-character escape modes. |
| 795 | 795 | ** Allowed values for sqlite3_qrf_spec.eEsc |
| 796 | 796 | */ |
| | @@ -1841,24 +1841,25 @@ |
| 1841 | 1841 | zVal[j+4] = "0123456789abcdef"[(c>>4)&0xf]; |
| 1842 | 1842 | zVal[j+5] = "0123456789abcdef"[(c)&0xf]; |
| 1843 | 1843 | } |
| 1844 | 1844 | } |
| 1845 | 1845 | break; |
| 1846 | + } |
| 1847 | + case QRF_BLOB_Size: { |
| 1848 | + int nBlob = sqlite3_column_bytes(p->pStmt,iCol); |
| 1849 | + sqlite3_str_appendf(pOut, "(%d-byte blob)", nBlob); |
| 1850 | + break; |
| 1846 | 1851 | } |
| 1847 | 1852 | default: { |
| 1848 | 1853 | const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol); |
| 1849 | 1854 | qrfEncodeText(p, pOut, zTxt); |
| 1850 | 1855 | } |
| 1851 | 1856 | } |
| 1852 | 1857 | break; |
| 1853 | 1858 | } |
| 1854 | 1859 | case SQLITE_NULL: { |
| 1855 | | - if( p->spec.bTextNull==QRF_Yes ){ |
| 1856 | | - qrfEncodeText(p, pOut, p->spec.zNull); |
| 1857 | | - }else{ |
| 1858 | | - sqlite3_str_appendall(pOut, p->spec.zNull); |
| 1859 | | - } |
| 1860 | + sqlite3_str_appendall(pOut, p->spec.zNull); |
| 1860 | 1861 | break; |
| 1861 | 1862 | } |
| 1862 | 1863 | case SQLITE_TEXT: { |
| 1863 | 1864 | const char *zTxt = (const char*)sqlite3_column_text(p->pStmt,iCol); |
| 1864 | 1865 | qrfEncodeText(p, pOut, zTxt); |
| | @@ -2690,21 +2691,23 @@ |
| 2690 | 2691 | colSep = "|"; |
| 2691 | 2692 | rowSep = "|\n"; |
| 2692 | 2693 | } |
| 2693 | 2694 | qrfRowSeparator(p->pOut, &data, '+'); |
| 2694 | 2695 | break; |
| 2695 | | - case QRF_STYLE_Column: |
| 2696 | + case QRF_STYLE_Column: { |
| 2697 | + static const char zSpace[] = " "; |
| 2696 | 2698 | rowStart = ""; |
| 2697 | 2699 | if( data.nMargin<2 ){ |
| 2698 | 2700 | colSep = " "; |
| 2699 | 2701 | }else if( data.nMargin<=5 ){ |
| 2700 | | - colSep = " " + (5-data.nMargin); |
| 2702 | + colSep = &zSpace[5-data.nMargin]; |
| 2701 | 2703 | }else{ |
| 2702 | | - colSep = " "; |
| 2704 | + colSep = zSpace; |
| 2703 | 2705 | } |
| 2704 | 2706 | rowSep = "\n"; |
| 2705 | 2707 | break; |
| 2708 | + } |
| 2706 | 2709 | default: /*case QRF_STYLE_Markdown:*/ |
| 2707 | 2710 | if( data.nMargin ){ |
| 2708 | 2711 | rowStart = "| "; |
| 2709 | 2712 | colSep = " | "; |
| 2710 | 2713 | rowSep = " |\n"; |
| | @@ -3277,10 +3280,15 @@ |
| 3277 | 3280 | if( p->spec.zNull==0 ) p->spec.zNull = ""; |
| 3278 | 3281 | p->mxWidth = p->spec.nScreenWidth; |
| 3279 | 3282 | if( p->mxWidth<=0 ) p->mxWidth = QRF_MAX_WIDTH; |
| 3280 | 3283 | p->mxHeight = p->spec.nLineLimit; |
| 3281 | 3284 | if( p->mxHeight<=0 ) p->mxHeight = 2147483647; |
| 3285 | + if( p->spec.eStyle>QRF_STYLE_Table ) p->spec.eStyle = QRF_Auto; |
| 3286 | + if( p->spec.eEsc>QRF_ESC_Symbol ) p->spec.eEsc = QRF_Auto; |
| 3287 | + if( p->spec.eText>QRF_TEXT_Json ) p->spec.eText = QRF_Auto; |
| 3288 | + if( p->spec.eTitle>QRF_TEXT_Json ) p->spec.eTitle = QRF_Auto; |
| 3289 | + if( p->spec.eBlob>QRF_BLOB_Size ) p->spec.eBlob = QRF_Auto; |
| 3282 | 3290 | qrf_reinit: |
| 3283 | 3291 | switch( p->spec.eStyle ){ |
| 3284 | 3292 | case QRF_Auto: { |
| 3285 | 3293 | switch( sqlite3_stmt_isexplain(pStmt) ){ |
| 3286 | 3294 | case 0: p->spec.eStyle = QRF_STYLE_Box; break; |
| | @@ -3295,11 +3303,10 @@ |
| 3295 | 3303 | break; |
| 3296 | 3304 | } |
| 3297 | 3305 | case QRF_STYLE_JObject: |
| 3298 | 3306 | case QRF_STYLE_Json: { |
| 3299 | 3307 | p->spec.eText = QRF_TEXT_Json; |
| 3300 | | - p->spec.eBlob = QRF_BLOB_Json; |
| 3301 | 3308 | p->spec.zNull = "null"; |
| 3302 | 3309 | break; |
| 3303 | 3310 | } |
| 3304 | 3311 | case QRF_STYLE_Html: { |
| 3305 | 3312 | p->spec.eText = QRF_TEXT_Html; |
| | @@ -3306,29 +3313,26 @@ |
| 3306 | 3313 | p->spec.zNull = "null"; |
| 3307 | 3314 | break; |
| 3308 | 3315 | } |
| 3309 | 3316 | case QRF_STYLE_Insert: { |
| 3310 | 3317 | p->spec.eText = QRF_TEXT_Sql; |
| 3311 | | - p->spec.eBlob = QRF_BLOB_Sql; |
| 3312 | 3318 | p->spec.zNull = "NULL"; |
| 3313 | 3319 | if( p->spec.zTableName==0 || p->spec.zTableName[0]==0 ){ |
| 3314 | 3320 | p->spec.zTableName = "tab"; |
| 3315 | 3321 | } |
| 3316 | 3322 | break; |
| 3317 | 3323 | } |
| 3318 | 3324 | case QRF_STYLE_Csv: { |
| 3319 | 3325 | p->spec.eStyle = QRF_STYLE_List; |
| 3320 | 3326 | p->spec.eText = QRF_TEXT_Csv; |
| 3321 | | - p->spec.eBlob = QRF_BLOB_Text; |
| 3322 | 3327 | p->spec.zColumnSep = ","; |
| 3323 | 3328 | p->spec.zRowSep = "\r\n"; |
| 3324 | 3329 | p->spec.zNull = ""; |
| 3325 | 3330 | break; |
| 3326 | 3331 | } |
| 3327 | 3332 | case QRF_STYLE_Quote: { |
| 3328 | 3333 | p->spec.eText = QRF_TEXT_Sql; |
| 3329 | | - p->spec.eBlob = QRF_BLOB_Sql; |
| 3330 | 3334 | p->spec.zNull = "NULL"; |
| 3331 | 3335 | p->spec.zColumnSep = ","; |
| 3332 | 3336 | p->spec.zRowSep = "\n"; |
| 3333 | 3337 | break; |
| 3334 | 3338 | } |
| | @@ -24153,47 +24157,48 @@ |
| 24153 | 24157 | "", "NULL", "null", "\"\"" }; |
| 24154 | 24158 | /* 9 10 11 12 */ |
| 24155 | 24159 | |
| 24156 | 24160 | static const ModeInfo aModeInfo[] = { |
| 24157 | 24161 | /* zName eCSep eRSep eNull eText eHdr eBlob bHdr eStyle eCx */ |
| 24158 | | - { "ascii", 7, 6, 9, 1, 1, 1, 1, 12, 0 }, |
| 24159 | | - { "box", 0, 0, 9, 1, 1, 1, 2, 1, 2 }, |
| 24162 | + { "ascii", 7, 6, 9, 1, 1, 0, 1, 12, 0 }, |
| 24163 | + { "box", 0, 0, 9, 1, 1, 0, 2, 1, 2 }, |
| 24160 | 24164 | { "c", 4, 1, 10, 5, 5, 4, 1, 12, 0 }, |
| 24161 | | - { "column", 0, 0, 9, 1, 1, 1, 2, 2, 2 }, |
| 24165 | + { "column", 0, 0, 9, 1, 1, 0, 2, 2, 2 }, |
| 24162 | 24166 | { "count", 0, 0, 0, 0, 0, 0, 0, 3, 0 }, |
| 24163 | | - { "csv", 4, 5, 9, 3, 3, 3, 1, 12, 0 }, |
| 24164 | | - { "html", 0, 0, 9, 4, 4, 1, 2, 7, 0 }, |
| 24165 | | - { "insert", 0, 0, 10, 2, 2, 2, 1, 8, 0 }, |
| 24166 | | - { "jatom", 4, 1, 11, 6, 6, 5, 1, 12, 0 }, |
| 24167 | | - { "jobject", 0, 1, 11, 6, 6, 5, 0, 10, 0 }, |
| 24167 | + { "csv", 4, 5, 9, 3, 3, 0, 1, 12, 0 }, |
| 24168 | + { "html", 0, 0, 9, 4, 4, 0, 2, 7, 0 }, |
| 24169 | + { "insert", 0, 0, 10, 2, 2, 0, 1, 8, 0 }, |
| 24170 | + { "jatom", 4, 1, 11, 6, 6, 0, 1, 12, 0 }, |
| 24171 | + { "jobject", 0, 1, 11, 6, 6, 0, 0, 10, 0 }, |
| 24168 | 24172 | { "json", 0, 0, 11, 6, 6, 0, 0, 9, 0 }, |
| 24169 | 24173 | { "line", 0, 1, 9, 1, 1, 0, 0, 11, 1 }, |
| 24170 | | - { "list", 2, 1, 9, 1, 1, 1, 1, 12, 0 }, |
| 24171 | | - { "markdown", 0, 0, 9, 1, 1, 1, 2, 13, 2 }, |
| 24174 | + { "list", 2, 1, 9, 1, 1, 0, 1, 12, 0 }, |
| 24175 | + { "markdown", 0, 0, 9, 1, 1, 0, 2, 13, 2 }, |
| 24172 | 24176 | { "off", 0, 0, 0, 0, 0, 0, 0, 14, 0 }, |
| 24173 | | - { "qbox", 0, 0, 9, 2, 1, 2, 2, 1, 2 }, |
| 24174 | | - { "quote", 4, 1, 10, 2, 2, 2, 1, 12, 0 }, |
| 24175 | | - { "split", 0, 0, 9, 1, 1, 1, 1, 2, 2 }, |
| 24176 | | - { "table", 0, 0, 9, 1, 1, 1, 2, 19, 2 }, |
| 24177 | | - { "tabs", 8, 1, 9, 3, 3, 1, 1, 12, 0 }, |
| 24177 | + { "qbox", 0, 0, 10, 2, 1, 0, 2, 1, 2 }, |
| 24178 | + { "quote", 4, 1, 10, 2, 2, 0, 1, 12, 0 }, |
| 24179 | + { "split", 0, 0, 9, 1, 1, 0, 1, 2, 2 }, |
| 24180 | + { "table", 0, 0, 9, 1, 1, 0, 2, 19, 2 }, |
| 24181 | + { "tabs", 8, 1, 9, 3, 3, 0, 1, 12, 0 }, |
| 24178 | 24182 | { "tcl", 3, 1, 12, 5, 5, 4, 1, 12, 0 }, |
| 24179 | | - { "www", 0, 0, 9, 4, 4, 1, 2, 7, 0 } |
| 24183 | + { "www", 0, 0, 9, 4, 4, 0, 2, 7, 0 } |
| 24180 | 24184 | }; /* | / / | / / | | \ |
| 24181 | 24185 | ** | / / | / / | | \_ 2: columnar |
| 24182 | 24186 | ** Index into aModeStr[] | / / | | 1: line |
| 24183 | 24187 | ** | / / | | 0: other |
| 24184 | 24188 | ** | / / | \ |
| 24185 | 24189 | ** text encoding |/ | show | \ |
| 24186 | 24190 | ** v-------------------' | hdrs? | The QRF style |
| 24187 | 24191 | ** 0: n/a blob | v-----' |
| 24188 | 24192 | ** 1: plain v_---------' 0: n/a |
| 24189 | | - ** 2: sql 0: n/a 1: no |
| 24193 | + ** 2: sql 0: auto 1: no |
| 24190 | 24194 | ** 3: csv 1: as-text 2: yes |
| 24191 | 24195 | ** 4: html 2: sql |
| 24192 | 24196 | ** 5: c 3: hex |
| 24193 | 24197 | ** 6: json 4: c |
| 24194 | 24198 | ** 5: json |
| 24199 | + ** 6: size |
| 24195 | 24200 | ******************************************************************/ |
| 24196 | 24201 | /* |
| 24197 | 24202 | ** These are the column/row/line separators used by the various |
| 24198 | 24203 | ** import/export modes. |
| 24199 | 24204 | */ |
| | @@ -25879,10 +25884,17 @@ |
| 25879 | 25884 | assert( pArg->mode.eMode>=0 && pArg->mode.eMode<ArraySize(aModeInfo) ); |
| 25880 | 25885 | eStyle = aModeInfo[pArg->mode.eMode].eStyle; |
| 25881 | 25886 | if( pArg->mode.bAutoScreenWidth ){ |
| 25882 | 25887 | spec.nScreenWidth = shellScreenWidth(); |
| 25883 | 25888 | } |
| 25889 | + if( spec.eBlob==QRF_BLOB_Auto ){ |
| 25890 | + switch( spec.eText ){ |
| 25891 | + case QRF_TEXT_Sql: spec.eBlob = QRF_BLOB_Sql; break; |
| 25892 | + case QRF_TEXT_Json: spec.eBlob = QRF_BLOB_Json; break; |
| 25893 | + default: spec.eBlob = QRF_BLOB_Text; break; |
| 25894 | + } |
| 25895 | + } |
| 25884 | 25896 | |
| 25885 | 25897 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 25886 | 25898 | if( pArg->expert.pExpert ){ |
| 25887 | 25899 | rc = expertHandleSQL(pArg, zSql, pzErrMsg); |
| 25888 | 25900 | return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg); |
| | @@ -26246,10 +26258,12 @@ |
| 26246 | 26258 | |
| 26247 | 26259 | |
| 26248 | 26260 | savedMode = p->mode; |
| 26249 | 26261 | p->mode.spec.zTableName = (char*)zTable; |
| 26250 | 26262 | p->mode.eMode = MODE_Insert; |
| 26263 | + p->mode.spec.eText = QRF_TEXT_Sql; |
| 26264 | + p->mode.spec.eBlob = QRF_BLOB_Sql; |
| 26251 | 26265 | p->mode.spec.bTitles = QRF_No; |
| 26252 | 26266 | rc = shell_exec(p, sSelect.zTxt, 0); |
| 26253 | 26267 | if( (rc&0xff)==SQLITE_CORRUPT ){ |
| 26254 | 26268 | cli_puts("/****** CORRUPTION ERROR *******/\n", p->out); |
| 26255 | 26269 | toggleSelectOrder(p->db); |
| | @@ -26596,52 +26610,54 @@ |
| 26596 | 26610 | " -v Verbose mode\n" |
| 26597 | 26611 | }, |
| 26598 | 26612 | { ".mode", |
| 26599 | 26613 | "USAGE: .mode [MODE] [OPTIONS]\n" |
| 26600 | 26614 | "\n" |
| 26601 | | -"Change the output mode to MODE and/or apply OPTIONS to the\n" |
| 26602 | | -"output mode. If no arguments, show the current output mode\n" |
| 26603 | | -"and relevant options.\n" |
| 26615 | +"Change the output mode to MODE and/or apply OPTIONS to the output mode.\n" |
| 26616 | +"Arguments are processed from left to right. If no arguments, show the\n" |
| 26617 | +"current output mode and relevant options.\n" |
| 26604 | 26618 | "\n" |
| 26605 | 26619 | "Options:\n" |
| 26606 | 26620 | " --align STRING Set the alignment of text in columnar modes\n" |
| 26607 | 26621 | " String consists of characters 'L', 'C', 'R'\n" |
| 26608 | 26622 | " meaning \"left\", \"centered\", and \"right\", with\n" |
| 26609 | 26623 | " one letter per column starting from the left.\n" |
| 26610 | 26624 | " Unspecified alignment defaults to 'L'.\n" |
| 26625 | +" --blob-quote ARG ARG can be \"auto\", \"text\", \"sql\", \"hex\", \"tcl\",\n" |
| 26626 | +" \"json\", or \"size\". Default is \"auto\".\n" |
| 26611 | 26627 | " --charlimit N Set the maximum number of output characters to\n" |
| 26612 | 26628 | " show for any single SQL value to N. Longer values\n" |
| 26613 | 26629 | " truncated. Zero means \"no limit\".\n" |
| 26614 | 26630 | " --colsep STRING Use STRING as the column separator\n" |
| 26615 | 26631 | " --escape ESC Enable/disable escaping of control characters\n" |
| 26616 | | -" in output. ESC can be \"off\", \"ascii\", or\n" |
| 26617 | | -" \"symbol\".\n" |
| 26632 | +" found in the output. ESC can be \"off\", \"ascii\",\n" |
| 26633 | +" or \"symbol\".\n" |
| 26618 | 26634 | " --linelimit N Set the maximum number of output lines to show for\n" |
| 26619 | 26635 | " any single SQL value to N. Longer values are\n" |
| 26620 | 26636 | " truncated. Zero means \"no limit\". Only works\n" |
| 26621 | 26637 | " in \"line\" mode and in columnar modes.\n" |
| 26638 | +" --limits L,C Shorthand for \"--linelimit L --charlimit C\".\n" |
| 26639 | +" Or \"off\" to mean \"0,0\". Or \"on\" for \"5,300\".\n" |
| 26622 | 26640 | " --list List available modes\n" |
| 26623 | | -" --no-limits Shorthand to turn off --linelimit, --charlimit,\n" |
| 26624 | | -" and --screenwidth.\n" |
| 26625 | 26641 | " --null STRING Render SQL NULL values as the given string\n" |
| 26626 | 26642 | " --once Setting changes to the right are reverted after\n" |
| 26627 | 26643 | " the next SQL command.\n" |
| 26628 | 26644 | " --quote ARG Enable/disable quoting of text. ARG can be\n" |
| 26629 | 26645 | " \"off\", \"on\", \"sql\", \"csv\", \"html\", \"tcl\",\n" |
| 26630 | 26646 | " or \"json\". \"off\" means show the text as-is.\n" |
| 26631 | | -" \"on and \"sql\" are synonyms.\n" |
| 26647 | +" \"on\" is an alias for \"sql\".\n" |
| 26632 | 26648 | " --reset Changes all mode settings back to their default.\n" |
| 26633 | 26649 | " --rowsep STRING Use STRING as the row separator\n" |
| 26634 | | -" --screenwidth N Declare the screen width of the output device\n" |
| 26650 | +" --sw|--screenwidth N Declare the screen width of the output device\n" |
| 26635 | 26651 | " to be N characters. An attempt may be made to\n" |
| 26636 | 26652 | " wrap output text to fit within this limit. Zero\n" |
| 26637 | 26653 | " means \"no limit\". Or N can be \"auto\" to set the\n" |
| 26638 | 26654 | " width automatically.\n" |
| 26639 | 26655 | " --tablename NAME Set the name of the table for \"insert\" mode.\n" |
| 26640 | 26656 | " --tag NAME Save mode to the left as NAME.\n" |
| 26641 | 26657 | " --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON.\n" |
| 26642 | | -" --title ARG Whether or not to show column headers, and if so\n" |
| 26658 | +" --title ARG Whether or not to show column headers, and if so\n" |
| 26643 | 26659 | " how to encode them. ARG can be \"off\", \"on\",\n" |
| 26644 | 26660 | " \"sql\", \"csv\", \"html\", \"tcl\", or \"json\".\n" |
| 26645 | 26661 | " -v|--verbose Verbose output\n" |
| 26646 | 26662 | " --widths LIST Set the columns widths for columnar modes. The\n" |
| 26647 | 26663 | " argument is a list of integers, one for each\n" |
| | @@ -30477,52 +30493,54 @@ |
| 30477 | 30493 | /* |
| 30478 | 30494 | ** DOT-COMMAND: .mode |
| 30479 | 30495 | ** |
| 30480 | 30496 | ** USAGE: .mode [MODE] [OPTIONS] |
| 30481 | 30497 | ** |
| 30482 | | -** Change the output mode to MODE and/or apply OPTIONS to the |
| 30483 | | -** output mode. If no arguments, show the current output mode |
| 30484 | | -** and relevant options. |
| 30498 | +** Change the output mode to MODE and/or apply OPTIONS to the output mode. |
| 30499 | +** Arguments are processed from left to right. If no arguments, show the |
| 30500 | +** current output mode and relevant options. |
| 30485 | 30501 | ** |
| 30486 | 30502 | ** Options: |
| 30487 | 30503 | ** --align STRING Set the alignment of text in columnar modes |
| 30488 | 30504 | ** String consists of characters 'L', 'C', 'R' |
| 30489 | 30505 | ** meaning "left", "centered", and "right", with |
| 30490 | 30506 | ** one letter per column starting from the left. |
| 30491 | 30507 | ** Unspecified alignment defaults to 'L'. |
| 30508 | +** --blob-quote ARG ARG can be "auto", "text", "sql", "hex", "tcl", |
| 30509 | +** "json", or "size". Default is "auto". |
| 30492 | 30510 | ** --charlimit N Set the maximum number of output characters to |
| 30493 | 30511 | ** show for any single SQL value to N. Longer values |
| 30494 | 30512 | ** truncated. Zero means "no limit". |
| 30495 | 30513 | ** --colsep STRING Use STRING as the column separator |
| 30496 | 30514 | ** --escape ESC Enable/disable escaping of control characters |
| 30497 | | -** in output. ESC can be "off", "ascii", or |
| 30498 | | -** "symbol". |
| 30515 | +** found in the output. ESC can be "off", "ascii", |
| 30516 | +** or "symbol". |
| 30499 | 30517 | ** --linelimit N Set the maximum number of output lines to show for |
| 30500 | 30518 | ** any single SQL value to N. Longer values are |
| 30501 | 30519 | ** truncated. Zero means "no limit". Only works |
| 30502 | 30520 | ** in "line" mode and in columnar modes. |
| 30521 | +** --limits L,C Shorthand for "--linelimit L --charlimit C". |
| 30522 | +** Or "off" to mean "0,0". Or "on" for "5,300". |
| 30503 | 30523 | ** --list List available modes |
| 30504 | | -** --no-limits Shorthand to turn off --linelimit, --charlimit, |
| 30505 | | -** and --screenwidth. |
| 30506 | 30524 | ** --null STRING Render SQL NULL values as the given string |
| 30507 | 30525 | ** --once Setting changes to the right are reverted after |
| 30508 | 30526 | ** the next SQL command. |
| 30509 | 30527 | ** --quote ARG Enable/disable quoting of text. ARG can be |
| 30510 | 30528 | ** "off", "on", "sql", "csv", "html", "tcl", |
| 30511 | 30529 | ** or "json". "off" means show the text as-is. |
| 30512 | | -** "on and "sql" are synonyms. |
| 30530 | +** "on" is an alias for "sql". |
| 30513 | 30531 | ** --reset Changes all mode settings back to their default. |
| 30514 | 30532 | ** --rowsep STRING Use STRING as the row separator |
| 30515 | | -** --screenwidth N Declare the screen width of the output device |
| 30533 | +** --sw|--screenwidth N Declare the screen width of the output device |
| 30516 | 30534 | ** to be N characters. An attempt may be made to |
| 30517 | 30535 | ** wrap output text to fit within this limit. Zero |
| 30518 | 30536 | ** means "no limit". Or N can be "auto" to set the |
| 30519 | 30537 | ** width automatically. |
| 30520 | 30538 | ** --tablename NAME Set the name of the table for "insert" mode. |
| 30521 | 30539 | ** --tag NAME Save mode to the left as NAME. |
| 30522 | 30540 | ** --textjsonb BOOLEAN If enabled, JSONB text is displayed as text JSON. |
| 30523 | | -** --title ARG Whether or not to show column headers, and if so |
| 30541 | +** --title ARG Whether or not to show column headers, and if so |
| 30524 | 30542 | ** how to encode them. ARG can be "off", "on", |
| 30525 | 30543 | ** "sql", "csv", "html", "tcl", or "json". |
| 30526 | 30544 | ** -v|--verbose Verbose output |
| 30527 | 30545 | ** --widths LIST Set the columns widths for columnar modes. The |
| 30528 | 30546 | ** argument is a list of integers, one for each |
| | @@ -30592,10 +30610,23 @@ |
| 30592 | 30610 | if( nErr ){ |
| 30593 | 30611 | dotCmdError(p, i, "bad alignment string", |
| 30594 | 30612 | "Should contain only characters L, C, and R."); |
| 30595 | 30613 | return 1; |
| 30596 | 30614 | } |
| 30615 | + }else if( pickStr(z,0,"-blob","-blob-quote","")>=0 ){ |
| 30616 | + if( (++i)>=nArg ){ |
| 30617 | + dotCmdError(p, i-1, "missing argument", 0); |
| 30618 | + return 1; |
| 30619 | + } |
| 30620 | + k = pickStr(azArg[i], 0, |
| 30621 | + "auto", "text", "sql", "hex", "tcl", "json", "size", ""); |
| 30622 | + /* 0 1 2 3 4 5 6 |
| 30623 | + ** Must match QRF_BLOB_xxxx values. See also tag-20251124a */ |
| 30624 | + if( k>=0 ){ |
| 30625 | + p->mode.spec.eBlob = k & 0xff; |
| 30626 | + } |
| 30627 | + chng = 1; |
| 30597 | 30628 | }else if( 0<=(k=pickStr(z,0,"-charlimit","-linelimit","")) ){ |
| 30598 | 30629 | int w; /* 0 1 */ |
| 30599 | 30630 | if( i+1>=nArg ){ |
| 30600 | 30631 | dotCmdError(p, i, "missing argument", 0); |
| 30601 | 30632 | return 1; |
| | @@ -30622,22 +30653,45 @@ |
| 30622 | 30653 | } |
| 30623 | 30654 | chng = 1; |
| 30624 | 30655 | }else if( optionMatch(z,"escape") ){ |
| 30625 | 30656 | /* See similar code at tag-20250224-1 */ |
| 30626 | 30657 | char *zErr = 0; |
| 30627 | | - if( i+1>=nArg ){ |
| 30628 | | - dotCmdError(p, i, "missing argument", 0); |
| 30658 | + if( (++i)>=nArg ){ |
| 30659 | + dotCmdError(p, i-1, "missing argument", 0); |
| 30629 | 30660 | return 1; |
| 30630 | | - } |
| 30631 | | - i++; /* 0 1 2 <-- One less than QRF_ESC_ */ |
| 30661 | + } /* 0 1 2 <-- One less than QRF_ESC_ */ |
| 30632 | 30662 | k = pickStr(azArg[i],&zErr,"off","ascii","symbol",""); |
| 30633 | 30663 | if( k<0 ){ |
| 30634 | 30664 | dotCmdError(p, i, "unknown escape type", "%s", zErr); |
| 30635 | 30665 | sqlite3_free(zErr); |
| 30636 | 30666 | return 1; |
| 30637 | 30667 | } |
| 30638 | 30668 | p->mode.spec.eEsc = k+1; |
| 30669 | + chng = 1; |
| 30670 | + }else if( optionMatch(z,"limits") ){ |
| 30671 | + if( (++i)>=nArg ){ |
| 30672 | + dotCmdError(p, i-1, "missing argument", 0); |
| 30673 | + return 1; |
| 30674 | + } |
| 30675 | + k = pickStr(azArg[i],0,"on","off",""); |
| 30676 | + if( k==0 ){ |
| 30677 | + p->mode.spec.nLineLimit = 5; |
| 30678 | + p->mode.spec.nCharLimit = 300; |
| 30679 | + }else if( k==1 ){ |
| 30680 | + p->mode.spec.nLineLimit = 0; |
| 30681 | + p->mode.spec.nCharLimit = 0; |
| 30682 | + }else{ |
| 30683 | + int L, C; |
| 30684 | + int nNum = sscanf(azArg[i], "%d,%d", &L, &C); |
| 30685 | + if( nNum!=2 || L<0 || C<0 ){ |
| 30686 | + dotCmdError(p, i, "bad argument", "Should be \"L,C\" where L and C" |
| 30687 | + " are unsigned integers"); |
| 30688 | + return 1; |
| 30689 | + } |
| 30690 | + p->mode.spec.nLineLimit = L; |
| 30691 | + p->mode.spec.nCharLimit = C; |
| 30692 | + } |
| 30639 | 30693 | chng = 1; |
| 30640 | 30694 | }else if( optionMatch(z,"list") ){ |
| 30641 | 30695 | int ii; |
| 30642 | 30696 | cli_puts("available modes:", p->out); |
| 30643 | 30697 | for(ii=0; ii<ArraySize(aModeInfo); ii++){ |
| | @@ -30646,24 +30700,20 @@ |
| 30646 | 30700 | } |
| 30647 | 30701 | for(ii=0; ii<p->nSavedModes; ii++){ |
| 30648 | 30702 | cli_printf(p->out, " %s", p->aSavedModes[ii].zTag); |
| 30649 | 30703 | } |
| 30650 | 30704 | cli_puts(" batch tty\n", p->out); |
| 30705 | + chng = 1; /* Not really a change, but we still want to suppress the |
| 30706 | + ** "current mode" output */ |
| 30651 | 30707 | }else if( optionMatch(z,"once") ){ |
| 30652 | 30708 | p->nPopMode = 0; |
| 30653 | 30709 | modePush(p); |
| 30654 | 30710 | p->nPopMode = 1; |
| 30655 | 30711 | }else if( optionMatch(z,"noquote") ){ |
| 30656 | 30712 | /* (undocumented legacy) --noquote always turns quoting off */ |
| 30657 | 30713 | p->mode.spec.eText = QRF_TEXT_Plain; |
| 30658 | | - p->mode.spec.eBlob = QRF_BLOB_Text; |
| 30659 | | - chng = 1; |
| 30660 | | - }else if( optionMatch(z,"no-limits") ){ |
| 30661 | | - p->mode.spec.nLineLimit = 0; |
| 30662 | | - p->mode.spec.nCharLimit = 0; |
| 30663 | | - p->mode.spec.nScreenWidth = 0; |
| 30664 | | - p->mode.bAutoScreenWidth = 0; |
| 30714 | + p->mode.spec.eBlob = QRF_BLOB_Auto; |
| 30665 | 30715 | chng = 1; |
| 30666 | 30716 | }else if( optionMatch(z,"quote") ){ |
| 30667 | 30717 | if( i+1<nArg |
| 30668 | 30718 | && azArg[i+1][0]!='-' |
| 30669 | 30719 | && (iMode>0 || strcmp(azArg[i+1],"off")==0 || modeFind(p, azArg[i+1])<0) |
| | @@ -30687,59 +30737,54 @@ |
| 30687 | 30737 | /* (Legacy) no following boolean argument. Turn quoting on */ |
| 30688 | 30738 | k = 1; |
| 30689 | 30739 | } |
| 30690 | 30740 | switch( k ){ |
| 30691 | 30741 | case 1: /* on */ |
| 30742 | + modeSetStr(&p->mode.spec.zNull, "NULL"); |
| 30743 | + /* Fall through */ |
| 30692 | 30744 | case 2: /* sql */ |
| 30693 | 30745 | p->mode.spec.eText = QRF_TEXT_Sql; |
| 30694 | | - p->mode.spec.eBlob = QRF_BLOB_Sql; |
| 30695 | 30746 | break; |
| 30696 | 30747 | case 3: /* csv */ |
| 30697 | 30748 | p->mode.spec.eText = QRF_TEXT_Csv; |
| 30698 | | - p->mode.spec.eBlob = QRF_BLOB_Text; |
| 30699 | 30749 | break; |
| 30700 | 30750 | case 4: /* html */ |
| 30701 | 30751 | p->mode.spec.eText = QRF_TEXT_Html; |
| 30702 | | - p->mode.spec.eBlob = QRF_BLOB_Text; |
| 30703 | 30752 | break; |
| 30704 | 30753 | case 5: /* tcl */ |
| 30705 | 30754 | p->mode.spec.eText = QRF_TEXT_Tcl; |
| 30706 | | - p->mode.spec.eBlob = QRF_BLOB_Text; |
| 30707 | 30755 | break; |
| 30708 | 30756 | case 6: /* json */ |
| 30709 | 30757 | p->mode.spec.eText = QRF_TEXT_Json; |
| 30710 | | - p->mode.spec.eBlob = QRF_BLOB_Json; |
| 30711 | 30758 | break; |
| 30712 | | - default: /* off */ |
| 30759 | + default: /* off */ |
| 30713 | 30760 | p->mode.spec.eText = QRF_TEXT_Plain; |
| 30714 | | - p->mode.spec.eBlob = QRF_BLOB_Text; |
| 30715 | 30761 | break; |
| 30716 | 30762 | } |
| 30717 | 30763 | chng = 1; |
| 30718 | 30764 | }else if( optionMatch(z,"reset") ){ |
| 30719 | 30765 | int saved_eMode = p->mode.eMode; |
| 30720 | 30766 | modeFree(&p->mode); |
| 30721 | 30767 | modeChange(p, saved_eMode); |
| 30722 | | - }else if( optionMatch(z,"screenwidth") ){ |
| 30723 | | - if( i+1>=nArg ){ |
| 30724 | | - dotCmdError(p, i, "missing argument", 0); |
| 30768 | + }else if( optionMatch(z,"screenwidth") || optionMatch(z,"sw") ){ |
| 30769 | + if( (++i)>=nArg ){ |
| 30770 | + dotCmdError(p, i-1, "missing argument", 0); |
| 30725 | 30771 | return 1; |
| 30726 | 30772 | } |
| 30727 | | - k = pickStr(azArg[i+1],0,"off","auto",""); |
| 30773 | + k = pickStr(azArg[i],0,"off","auto",""); |
| 30728 | 30774 | if( k==0 ){ |
| 30729 | 30775 | p->mode.bAutoScreenWidth = 0; |
| 30730 | 30776 | p->mode.spec.nScreenWidth = 0; |
| 30731 | 30777 | }else if( k==1 ){ |
| 30732 | 30778 | p->mode.bAutoScreenWidth = 1; |
| 30733 | 30779 | }else{ |
| 30734 | | - i64 w = integerValue(azArg[i+1]); |
| 30780 | + i64 w = integerValue(azArg[i]); |
| 30735 | 30781 | p->mode.bAutoScreenWidth = 0; |
| 30736 | 30782 | if( w<0 ) w = 0; |
| 30737 | 30783 | if( w>QRF_MAX_WIDTH ) w = QRF_MAX_WIDTH; |
| 30738 | 30784 | p->mode.spec.nScreenWidth = w; |
| 30739 | 30785 | } |
| 30740 | | - i++; |
| 30741 | 30786 | chng = 1; |
| 30742 | 30787 | }else if( optionMatch(z,"tag") ){ |
| 30743 | 30788 | size_t nByte; |
| 30744 | 30789 | int n; |
| 30745 | 30790 | const char *zTag; |
| | @@ -30880,11 +30925,19 @@ |
| 30880 | 30925 | unsigned char a = p->mode.spec.aAlign[ii]; |
| 30881 | 30926 | sqlite3_str_appendchar(pDesc, 1, "LLCR"[a&3]); |
| 30882 | 30927 | } |
| 30883 | 30928 | sqlite3_str_append(pDesc, "\"", 1); |
| 30884 | 30929 | } |
| 30885 | | - if( bAll || p->mode.spec.nCharLimit>0 ){ |
| 30930 | + if( bAll || p->mode.spec.eBlob!=QRF_BLOB_Auto ){ |
| 30931 | + const char *azBQuote[] = |
| 30932 | + { "auto", "text", "sql", "hex", "tcl", "json", "size" }; |
| 30933 | + /* 0 1 2 3 4 5 6 |
| 30934 | + ** Must match QRF_BLOB_xxxx values. See all instances of tag-20251124a */ |
| 30935 | + u8 e = p->mode.spec.eBlob; |
| 30936 | + sqlite3_str_appendf(pDesc, " --blob-quote %s", azBQuote[e]); |
| 30937 | + } |
| 30938 | + if( !bAll && p->mode.spec.nLineLimit==0 && p->mode.spec.nCharLimit>0 ){ |
| 30886 | 30939 | sqlite3_str_appendf(pDesc, " --charlimit %d",p->mode.spec.nCharLimit); |
| 30887 | 30940 | } |
| 30888 | 30941 | zSetting = aModeStr[pI->eCSep]; |
| 30889 | 30942 | if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zColumnSep)!=0) ){ |
| 30890 | 30943 | sqlite3_str_appendf(pDesc, " --colsep "); |
| | @@ -30891,11 +30944,19 @@ |
| 30891 | 30944 | append_c_string(pDesc, p->mode.spec.zColumnSep); |
| 30892 | 30945 | } |
| 30893 | 30946 | if( bAll || p->mode.spec.eEsc!=QRF_Auto ){ |
| 30894 | 30947 | sqlite3_str_appendf(pDesc, " --escape %s",qrfEscNames[p->mode.spec.eEsc]); |
| 30895 | 30948 | } |
| 30896 | | - if( bAll || (p->mode.spec.nLineLimit>0 && pI->eCx>0) ){ |
| 30949 | + if( bAll || (p->mode.spec.nLineLimit>0 && p->mode.spec.nCharLimit>0) ){ |
| 30950 | + if( p->mode.spec.nLineLimit==0 && p->mode.spec.nCharLimit==0 ){ |
| 30951 | + sqlite3_str_appendf(pDesc, " --limits off"); |
| 30952 | + }else{ |
| 30953 | + sqlite3_str_appendf(pDesc, " --limits %d,%d", |
| 30954 | + p->mode.spec.nLineLimit, p->mode.spec.nCharLimit); |
| 30955 | + } |
| 30956 | + }else |
| 30957 | + if( p->mode.spec.nCharLimit==0 && p->mode.spec.nLineLimit>0 && pI->eCx>0 ){ |
| 30897 | 30958 | sqlite3_str_appendf(pDesc, " --linelimit %d",p->mode.spec.nLineLimit); |
| 30898 | 30959 | } |
| 30899 | 30960 | zSetting = aModeStr[pI->eNull]; |
| 30900 | 30961 | if( bAll || (zSetting && cli_strcmp(zSetting,p->mode.spec.zNull)!=0) ){ |
| 30901 | 30962 | sqlite3_str_appendf(pDesc, " --null "); |
| 30902 | 30963 | |