** Run a prepared statement and output the result in one of the ** table-oriented formats: MODE_Column, MODE_Markdown, MODE_Table, ** or MODE_Box. ** ** This is different from ordinary exec_prepared_stmt() in that ** it has to run the entire query and gather the results into memory ** first, in order to determine column widths, before providing ** any output. */
| 13201 | ** any output. |
| 13202 | */ |
| 13203 | static void exec_prepared_stmt_columnar( |
| 13204 | ShellState *p, /* Pointer to ShellState */ |
| 13205 | sqlite3_stmt *pStmt /* Statment to run */ |
| 13206 | ){ |
| 13207 | sqlite3_int64 nRow = 0; |
| 13208 | int nColumn = 0; |
| 13209 | char **azData = 0; |
| 13210 | sqlite3_int64 nAlloc = 0; |
| 13211 | const char *z; |
| 13212 | int rc; |
| 13213 | sqlite3_int64 i, nData; |
| 13214 | int j, nTotal, w, n; |
| 13215 | const char *colSep = 0; |
| 13216 | const char *rowSep = 0; |
| 13217 | |
| 13218 | rc = sqlite3_step(pStmt); |
| 13219 | if( rc!=SQLITE_ROW ) return; |
| 13220 | nColumn = sqlite3_column_count(pStmt); |
| 13221 | nAlloc = nColumn*4; |
| 13222 | if( nAlloc<=0 ) nAlloc = 1; |
| 13223 | azData = sqlite3_malloc64( nAlloc*sizeof(char*) ); |
| 13224 | if( azData==0 ) shell_out_of_memory(); |
| 13225 | for(i=0; i<nColumn; i++){ |
| 13226 | azData[i] = strdup(sqlite3_column_name(pStmt,i)); |
| 13227 | } |
| 13228 | do{ |
| 13229 | if( (nRow+2)*nColumn >= nAlloc ){ |
| 13230 | nAlloc *= 2; |
| 13231 | azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*)); |
| 13232 | if( azData==0 ) shell_out_of_memory(); |
| 13233 | } |
| 13234 | nRow++; |
| 13235 | for(i=0; i<nColumn; i++){ |
| 13236 | z = (const char*)sqlite3_column_text(pStmt,i); |
| 13237 | azData[nRow*nColumn + i] = z ? strdup(z) : 0; |
| 13238 | } |
| 13239 | }while( (rc = sqlite3_step(pStmt))==SQLITE_ROW ); |
| 13240 | if( nColumn>p->nWidth ){ |
| 13241 | p->colWidth = realloc(p->colWidth, nColumn*2*sizeof(int)); |
| 13242 | if( p->colWidth==0 ) shell_out_of_memory(); |
| 13243 | for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0; |
| 13244 | p->nWidth = nColumn; |
| 13245 | p->actualWidth = &p->colWidth[nColumn]; |
| 13246 | } |
| 13247 | memset(p->actualWidth, 0, nColumn*sizeof(int)); |
| 13248 | for(i=0; i<nColumn; i++){ |
| 13249 | w = p->colWidth[i]; |
| 13250 | if( w<0 ) w = -w; |
| 13251 | p->actualWidth[i] = w; |
| 13252 | } |
| 13253 | nTotal = nColumn*(nRow+1); |
| 13254 | for(i=0; i<nTotal; i++){ |
| 13255 | z = azData[i]; |
| 13256 | if( z==0 ) z = p->nullValue; |
| 13257 | n = strlenChar(z); |
| 13258 | j = i%nColumn; |
| 13259 | if( n>p->actualWidth[j] ) p->actualWidth[j] = n; |
| 13260 | } |
no test coverage detected