#include <string.h>
#include <ctype.h>
#include "sqlite3.h"
-#include "resfmt.h"
+#include "qrf.h"
#define COUNT(X) (sizeof(X)/sizeof(X[0]))
int rc;
int lineNum = 0;
int bUseWriter = 1;
- sqlite3_resfmt_spec spec;
+ sqlite3_qrf_spec spec;
char zLine[1000];
if( argc<2 ){
}
memset(&spec, 0, sizeof(spec));
spec.iVersion = 1;
- spec.eFormat = RESFMT_List;
+ spec.eFormat = QRF_MODE_List;
spec.xWrite = testWriter;
pBuf = sqlite3_str_new(0);
rc = sqlite3_open(":memory:", &db);
}else
if( strncmp(zLine, "--eFormat=", 10)==0 ){
const struct { const char *z; int e; } aFmt[] = {
- { "box", RESFMT_Box, },
- { "column", RESFMT_Column, },
- { "count", RESFMT_Count, },
- { "eqp", RESFMT_EQP, },
- { "explain", RESFMT_Explain, },
- { "html", RESFMT_Html, },
- { "insert", RESFMT_Insert, },
- { "json", RESFMT_Json, },
- { "line", RESFMT_Line, },
- { "list", RESFMT_List, },
- { "markdown", RESFMT_Markdown, },
- { "off", RESFMT_Off, },
- { "table", RESFMT_Table, },
- { "scanexp", RESFMT_ScanExp, },
+ { "box", QRF_MODE_Box, },
+ { "column", QRF_MODE_Column, },
+ { "count", QRF_MODE_Count, },
+ { "eqp", QRF_MODE_EQP, },
+ { "explain", QRF_MODE_Explain, },
+ { "html", QRF_MODE_Html, },
+ { "insert", QRF_MODE_Insert, },
+ { "json", QRF_MODE_Json, },
+ { "line", QRF_MODE_Line, },
+ { "list", QRF_MODE_List, },
+ { "markdown", QRF_MODE_Markdown, },
+ { "off", QRF_MODE_Off, },
+ { "table", QRF_MODE_Table, },
+ { "scanexp", QRF_MODE_ScanExp, },
};
int i;
for(i=0; i<COUNT(aFmt); i++){
}else
if( strncmp(zLine, "--eQuote=", 9)==0 ){
const struct { const char *z; int e; } aQuote[] = {
- { "csv", RESFMT_Q_Csv },
- { "html", RESFMT_Q_Html },
- { "json", RESFMT_Q_Json },
- { "off", RESFMT_Q_Off },
- { "sql", RESFMT_Q_Sql },
- { "tcl", RESFMT_Q_Tcl },
+ { "csv", QRF_TXT_Csv },
+ { "html", QRF_TXT_Html },
+ { "json", QRF_TXT_Json },
+ { "off", QRF_TXT_Off },
+ { "sql", QRF_TXT_Sql },
+ { "tcl", QRF_TXT_Tcl },
};
int i;
for(i=0; i<COUNT(aQuote); i++){
}else
if( strncmp(zLine, "--eBlob=", 8)==0 ){
const struct { const char *z; int e; } aBlob[] = {
- { "auto", RESFMT_B_Auto },
- { "hex", RESFMT_B_Hex },
- { "json", RESFMT_B_Json },
- { "tcl", RESFMT_B_Tcl },
- { "text", RESFMT_B_Text },
- { "sql", RESFMT_B_Sql },
+ { "auto", QRF_BLOB_Auto },
+ { "hex", QRF_BLOB_Hex },
+ { "json", QRF_BLOB_Json },
+ { "tcl", QRF_BLOB_Tcl },
+ { "text", QRF_BLOB_Text },
+ { "sql", QRF_BLOB_Sql },
};
int i;
for(i=0; i<COUNT(aBlob); i++){
}else
if( strncmp(zLine, "--eEscape=", 10)==0 ){
const struct { const char *z; int e; } aEscape[] = {
- { "ascii", RESFMT_E_Ascii },
- { "off", RESFMT_E_Off },
- { "symbol", RESFMT_E_Symbol },
+ { "ascii", QRF_ESC_Ascii },
+ { "off", QRF_ESC_Off },
+ { "symbol", QRF_ESC_Symbol },
};
int i;
for(i=0; i<COUNT(aEscape); i++){
** Implementation of the Result-Format or "resfmt" utility library for SQLite.
** See the resfmt.md documentation for additional information.
*/
-#include "resfmt.h"
+#include "qrf.h"
#include <string.h>
/*
** Private state information. Subject to change from one release to the
** next.
*/
-typedef struct sqlite3_resfmt sqlite3_resfmt;
-struct sqlite3_resfmt {
+typedef struct Qrf Qrf;
+struct Qrf {
sqlite3_stmt *pStmt; /* The statement whose output is to be rendered */
sqlite3 *db; /* The corresponding database connection */
char **pzErr; /* Write error message here, if not NULL */
int iErr; /* Error code */
int nCol; /* Number of output columns */
sqlite3_int64 nRow; /* Number of rows handled so far */
- sqlite3_resfmt_spec spec; /* Copy of the original spec */
+ sqlite3_qrf_spec spec; /* Copy of the original spec */
};
/*
** Set an error code and error message.
*/
static void resfmtError(
- sqlite3_resfmt *p, /* Query result state */
+ Qrf *p, /* Query result state */
int iCode, /* Error code */
const char *zFormat, /* Message format (or NULL) */
...
/*
** Out-of-memory error.
*/
-static void resfmtOom(sqlite3_resfmt *p){
+static void resfmtOom(Qrf *p){
resfmtError(p, SQLITE_NOMEM, "out of memory");
}
** If xWrite is defined, send all content of pOut to xWrite and
** reset pOut.
*/
-static void resfmtWrite(sqlite3_resfmt *p){
+static void resfmtWrite(Qrf *p){
int n;
if( p->spec.xWrite && (n = sqlite3_str_length(p->pOut))>0 ){
p->spec.xWrite(p->spec.pWriteArg,
/*
** Escape the input string if it is needed and in accordance with
-** eEscape, which is either RESFMT_E_Ascii or RESFMT_E_Symbol.
+** eEscape, which is either QRF_ESC_Ascii or QRF_ESC_Symbol.
**
** Escaping is needed if the string contains any control characters
** other than \t, \n, and \r\n
** to reclaim memory.
*/
static void resfmtEscape(
- int eEscape, /* RESFMT_E_Ascii or RESFMT_E_Symbol */
+ int eEscape, /* QRF_ESC_Ascii or QRF_ESC_Symbol */
sqlite3_str *pStr, /* String to be escaped */
int iStart /* Begin escapding on this byte of pStr */
){
/* Make space to hold the escapes. Copy the original text to the end
** of the available space. */
sz = sqlite3_str_length(pStr) - iStart;
- if( eEscape==RESFMT_E_Symbol ) nCtrl *= 2;
+ if( eEscape==QRF_ESC_Symbol ) nCtrl *= 2;
sqlite3_str_appendchar(pStr, nCtrl, ' ');
zOut = (unsigned char*)sqlite3_str_value(pStr);
if( zOut==0 ) return;
}
zIn += i+1;
i = -1;
- if( eEscape==RESFMT_E_Symbol ){
+ if( eEscape==QRF_ESC_Symbol ){
zOut[j++] = 0xe2;
zOut[j++] = 0x90;
zOut[j++] = 0x80+c;
/*
** Encode text appropriately and append it to p->pOut.
*/
-static void resfmtEncodeText(sqlite3_resfmt *p, const char *zTxt){
+static void resfmtEncodeText(Qrf *p, const char *zTxt){
int iStart = sqlite3_str_length(p->pOut);
switch( p->spec.eQuote ){
- case RESFMT_Q_Sql: {
+ case QRF_TXT_Sql: {
sqlite3_str_appendf(p->pOut, "%Q", zTxt);
break;
}
- case RESFMT_Q_Csv: {
+ case QRF_TXT_Csv: {
unsigned int i;
for(i=0; zTxt[i]; i++){
if( resfmtCsvQuote[((const unsigned char*)zTxt)[i]] ){
}
break;
}
- case RESFMT_Q_Html: {
+ case QRF_TXT_Html: {
const unsigned char *z = (const unsigned char*)zTxt;
while( *z ){
unsigned int i = 0;
}
break;
}
- case RESFMT_Q_Tcl:
- case RESFMT_Q_Json: {
+ case QRF_TXT_Tcl:
+ case QRF_TXT_Json: {
const unsigned char *z = (const unsigned char*)zTxt;
sqlite3_str_append(p->pOut, "\"", 1);
while( *z ){
case '\r': sqlite3_str_append(p->pOut, "\\r", 2); break;
case '\t': sqlite3_str_append(p->pOut, "\\t", 2); break;
default: {
- if( p->spec.eQuote==RESFMT_Q_Json ){
+ if( p->spec.eQuote==QRF_TXT_Json ){
sqlite3_str_appendf(p->pOut, "\\u%04x", z[i]);
}else{
sqlite3_str_appendf(p->pOut, "\\%03o", z[i]);
break;
}
}
- if( p->spec.eEscape!=RESFMT_E_Off ){
+ if( p->spec.eEscape!=QRF_ESC_Off ){
resfmtEscape(p->spec.eEscape, p->pOut, iStart);
}
}
/*
** Render value pVal into p->pOut
*/
-static void resfmtRenderValue(sqlite3_resfmt *p, int iCol){
+static void resfmtRenderValue(Qrf *p, int iCol){
if( p->spec.xRender ){
sqlite3_value *pVal;
char *z;
}
case SQLITE_BLOB: {
switch( p->spec.eBlob ){
- case RESFMT_B_Hex:
- case RESFMT_B_Sql: {
+ case QRF_BLOB_Hex:
+ case QRF_BLOB_Sql: {
int iStart;
int nBlob = sqlite3_column_bytes(p->pStmt,iCol);
int i, j;
char *zVal;
const unsigned char *a = sqlite3_column_blob(p->pStmt,iCol);
- if( p->spec.eBlob==RESFMT_B_Sql ){
+ if( p->spec.eBlob==QRF_BLOB_Sql ){
sqlite3_str_append(p->pOut, "x'", 2);
}
iStart = sqlite3_str_length(p->pOut);
sqlite3_str_appendchar(p->pOut, nBlob, ' ');
sqlite3_str_appendchar(p->pOut, nBlob, ' ');
- if( p->spec.eBlob==RESFMT_B_Sql ){
+ if( p->spec.eBlob==QRF_BLOB_Sql ){
sqlite3_str_appendchar(p->pOut, 1, '\'');
}
if( sqlite3_str_errcode(p->pOut) ) return;
}
break;
}
- case RESFMT_B_Tcl:
- case RESFMT_B_Json: {
+ case QRF_BLOB_Tcl:
+ case QRF_BLOB_Json: {
int iStart;
int nBlob = sqlite3_column_bytes(p->pStmt,iCol);
int i, j;
char *zVal;
const unsigned char *a = sqlite3_column_blob(p->pStmt,iCol);
- int szC = p->spec.eBlob==RESFMT_B_Json ? 6 : 4;
+ int szC = p->spec.eBlob==QRF_BLOB_Json ? 6 : 4;
sqlite3_str_append(p->pOut, "\"", 1);
iStart = sqlite3_str_length(p->pOut);
for(i=szC; i>0; i--){
}
/*
-** Initialize the internal sqlite3_resfmt object.
+** Initialize the internal Qrf object.
*/
static void resfmtInitialize(
- sqlite3_resfmt *p, /* State object to be initialized */
+ Qrf *p, /* State object to be initialized */
sqlite3_stmt *pStmt, /* Query whose output to be formatted */
- const sqlite3_resfmt_spec *pSpec, /* Format specification */
+ const sqlite3_qrf_spec *pSpec, /* Format specification */
char **pzErr /* Write errors here */
){
size_t sz; /* Size of pSpec[], based on pSpec->iVersion */
p->pzErr = pzErr;
if( pSpec->iVersion!=1 ){
resfmtError(p, SQLITE_ERROR,
- "unusable sqlite3_resfmt_spec.iVersion (%d)",
+ "unusable sqlite3_qrf_spec.iVersion (%d)",
pSpec->iVersion);
return;
}
p->iErr = 0;
p->nCol = sqlite3_column_count(p->pStmt);
p->nRow = 0;
- sz = sizeof(sqlite3_resfmt_spec);
+ sz = sizeof(sqlite3_qrf_spec);
memcpy(&p->spec, pSpec, sz);
if( p->spec.zNull==0 ) p->spec.zNull = "";
- if( p->spec.eBlob==RESFMT_B_Auto ){
+ if( p->spec.eBlob==QRF_BLOB_Auto ){
switch( p->spec.eQuote ){
- case RESFMT_Q_Sql: p->spec.eBlob = RESFMT_B_Sql; break;
- case RESFMT_Q_Csv: p->spec.eBlob = RESFMT_B_Tcl; break;
- case RESFMT_Q_Tcl: p->spec.eBlob = RESFMT_B_Tcl; break;
- case RESFMT_Q_Json: p->spec.eBlob = RESFMT_B_Json; break;
- default: p->spec.eBlob = RESFMT_B_Text; break;
+ case QRF_TXT_Sql: p->spec.eBlob = QRF_BLOB_Sql; break;
+ case QRF_TXT_Csv: p->spec.eBlob = QRF_BLOB_Tcl; break;
+ case QRF_TXT_Tcl: p->spec.eBlob = QRF_BLOB_Tcl; break;
+ case QRF_TXT_Json: p->spec.eBlob = QRF_BLOB_Json; break;
+ default: p->spec.eBlob = QRF_BLOB_Text; break;
}
}
switch( p->spec.eFormat ){
- case RESFMT_List: {
+ case QRF_MODE_List: {
if( p->spec.zColumnSep==0 ) p->spec.zColumnSep = "|";
if( p->spec.zRowSep==0 ) p->spec.zRowSep = "\n";
break;
/*
** Render a single row of output.
*/
-static void resfmtDoOneRow(sqlite3_resfmt *p){
+static void resfmtDoOneRow(Qrf *p){
int i;
switch( p->spec.eFormat ){
- case RESFMT_Off:
- case RESFMT_Count: {
+ case QRF_MODE_Off:
+ case QRF_MODE_Count: {
/* No-op */
break;
}
- default: { /* RESFMT_List */
+ default: { /* QRF_MODE_List */
if( p->nRow==0 && p->spec.bShowCNames ){
for(i=0; i<p->nCol; i++){
const char *zCName = sqlite3_column_name(p->pStmt, i);
/*
** Finish rendering the results
*/
-static void resfmtFinalize(sqlite3_resfmt *p){
+static void resfmtFinalize(Qrf *p){
switch( p->spec.eFormat ){
- case RESFMT_Count: {
+ case QRF_MODE_Count: {
sqlite3_str_appendf(p->pOut, "%lld\n", p->nRow);
resfmtWrite(p);
break;
** into *pzErr.
*/
int sqlite3_format_query_result(
- sqlite3_stmt *pStmt, /* Statement to evaluate */
- const sqlite3_resfmt_spec *pSpec, /* Format specification */
- char **pzErr /* Write error message here */
+ sqlite3_stmt *pStmt, /* Statement to evaluate */
+ const sqlite3_qrf_spec *pSpec, /* Format specification */
+ char **pzErr /* Write error message here */
){
- sqlite3_resfmt fmt; /* The new sqlite3_resfmt being created */
+ Qrf qrf; /* The new Qrf being created */
if( pStmt==0 ) return SQLITE_OK; /* No-op */
if( pSpec==0 ) return SQLITE_MISUSE;
- resfmtInitialize(&fmt, pStmt, pSpec, pzErr);
- while( fmt.iErr==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
- resfmtDoOneRow(&fmt);
+ resfmtInitialize(&qrf, pStmt, pSpec, pzErr);
+ while( qrf.iErr==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
+ resfmtDoOneRow(&qrf);
}
- if( fmt.iErr==SQLITE_OK ){
- int rc = sqlite3_reset(fmt.pStmt);
+ if( qrf.iErr==SQLITE_OK ){
+ int rc = sqlite3_reset(qrf.pStmt);
if( rc!=SQLITE_OK ){
- resfmtError(&fmt, rc, "%s", sqlite3_errmsg(fmt.db));
+ resfmtError(&qrf, rc, "%s", sqlite3_errmsg(qrf.db));
}
}
- resfmtFinalize(&fmt);
- return fmt.iErr;
+ resfmtFinalize(&qrf);
+ return qrf.iErr;
}
/*
** Specification used by clients to define the output format they want
*/
-typedef struct sqlite3_resfmt_spec sqlite3_resfmt_spec;
-struct sqlite3_resfmt_spec {
+typedef struct sqlite3_qrf_spec sqlite3_qrf_spec;
+struct sqlite3_qrf_spec {
unsigned char iVersion; /* Version number of this structure */
unsigned char eFormat; /* Output format */
unsigned char bShowCNames; /* True to show column names */
*/
int sqlite3_format_query_result(
sqlite3_stmt *pStmt, /* SQL statement to run */
- const sqlite3_resfmt_spec *pSpec, /* Result format specification */
+ const sqlite3_qrf_spec *pSpec, /* Result format specification */
char **pzErr /* OUT: Write error message here */
);
/*
** Output styles:
*/
-#define RESFMT_List 0 /* One record per line with a separator */
-#define RESFMT_Line 1 /* One column per line. */
-#define RESFMT_Html 2 /* Generate an XHTML table */
-#define RESFMT_Json 3 /* Output is a list of JSON objects */
-#define RESFMT_Insert 4 /* Generate SQL "insert" statements */
-#define RESFMT_Explain 5 /* EXPLAIN output */
-#define RESFMT_ScanExp 6 /* EXPLAIN output with vm stats */
-#define RESFMT_EQP 7 /* Converts EXPLAIN QUERY PLAN output into a graph */
-#define RESFMT_Markdown 8 /* Markdown formatting */
-#define RESFMT_Column 9 /* One record per line in neat columns */
-#define RESFMT_Table 10 /* MySQL-style table formatting */
-#define RESFMT_Box 11 /* Unicode box-drawing characters */
-#define RESFMT_Count 12 /* Output only a count of the rows of output */
-#define RESFMT_Off 13 /* No query output shown */
+#define QRF_MODE_List 0 /* One record per line with a separator */
+#define QRF_MODE_Line 1 /* One column per line. */
+#define QRF_MODE_Html 2 /* Generate an XHTML table */
+#define QRF_MODE_Json 3 /* Output is a list of JSON objects */
+#define QRF_MODE_Insert 4 /* Generate SQL "insert" statements */
+#define QRF_MODE_Explain 5 /* EXPLAIN output */
+#define QRF_MODE_ScanExp 6 /* EXPLAIN output with vm stats */
+#define QRF_MODE_EQP 7 /* Format EXPLAIN QUERY PLAN output */
+#define QRF_MODE_Markdown 8 /* Markdown formatting */
+#define QRF_MODE_Column 9 /* One record per line in neat columns */
+#define QRF_MODE_Table 10 /* MySQL-style table formatting */
+#define QRF_MODE_Box 11 /* Unicode box-drawing characters */
+#define QRF_MODE_Count 12 /* Output only a count of the rows of output */
+#define QRF_MODE_Off 13 /* No query output shown */
/*
** Quoting styles for text.
-** Allowed values for sqlite3_resfmt_spec.eQuote
+** Allowed values for sqlite3_qrf_spec.eQuote
*/
-#define RESFMT_Q_Off 0 /* Literal text */
-#define RESFMT_Q_Sql 1 /* Quote as an SQL literal */
-#define RESFMT_Q_Csv 2 /* CSV-style quoting */
-#define RESFMT_Q_Html 3 /* HTML-style quoting */
-#define RESFMT_Q_Tcl 4 /* C/Tcl quoting */
-#define RESFMT_Q_Json 5 /* JSON quoting */
+#define QRF_TXT_Off 0 /* Literal text */
+#define QRF_TXT_Sql 1 /* Quote as an SQL literal */
+#define QRF_TXT_Csv 2 /* CSV-style quoting */
+#define QRF_TXT_Html 3 /* HTML-style quoting */
+#define QRF_TXT_Tcl 4 /* C/Tcl quoting */
+#define QRF_TXT_Json 5 /* JSON quoting */
/*
** Quoting styles for BLOBs
-** Allowed values for sqlite3_resfmt_spec.eBlob
+** Allowed values for sqlite3_qrf_spec.eBlob
*/
-#define RESFMT_B_Auto 0 /* Determine BLOB quoting using eQuote */
-#define RESFMT_B_Text 1 /* Display content exactly as it is */
-#define RESFMT_B_Sql 2 /* Quote as an SQL literal */
-#define RESFMT_B_Hex 3 /* Hexadecimal representation */
-#define RESFMT_B_Tcl 4 /* "\000" notation */
-#define RESFMT_B_Json 5 /* A JSON string */
+#define QRF_BLOB_Auto 0 /* Determine BLOB quoting using eQuote */
+#define QRF_BLOB_Text 1 /* Display content exactly as it is */
+#define QRF_BLOB_Sql 2 /* Quote as an SQL literal */
+#define QRF_BLOB_Hex 3 /* Hexadecimal representation */
+#define QRF_BLOB_Tcl 4 /* "\000" notation */
+#define QRF_BLOB_Json 5 /* A JSON string */
/*
** Control-character escape modes.
-** Allowed values for sqlite3_resfmt_spec.eEscape
+** Allowed values for sqlite3_qrf_spec.eEscape
*/
-#define RESFMT_E_Off 0 /* Do not escape control characters */
-#define RESFMT_E_Ascii 1 /* Unix-style escapes. Ex: U+0007 shows ^G */
-#define RESFMT_E_Symbol 2 /* Unicode escapes. Ex: U+0007 shows U+2407 */
+#define QRF_ESC_Off 0 /* Do not escape control characters */
+#define QRF_ESC_Ascii 1 /* Unix-style escapes. Ex: U+0007 shows ^G */
+#define QRF_ESC_Symbol 2 /* Unicode escapes. Ex: U+0007 shows U+2407 */
-# SQLite Result Formatting Subsystem
+# SQLite Query Result Formatting Subsystem
-The "resfmt" subsystem is a set of C-language subroutines that work
-together to format the output from an SQLite query. The output format
+The "Query Result Formatter" or "QRF" subsystem is a set of C-language
+subroutines that formats the output from an SQLite query. The output format
is configurable. The application can request CSV, or a table, or
any of several other formats, according to needs.
prepared statement, use code similar to the following:
> ~~~
-sqlite3_resfmt_spec spec; /* Formatter spec */
-sqlite3_resfmt *pFmt; /* Formatter object */
-int errCode; /* Error code */
-char *zErrMsg; /* Text error message (optional) */
+sqlite3_qrf_ spec; /* Format specification */
+char *zErrMsg; /* Text error message (optional) */
+int rc; /* Result code */
memset(&spec, 0, sizeof(spec));
-// Additional spec initialization here
-pFmt = sqlite3_resfmt_begin(pStmt, &spec);
-while( SQLITE_ROW==sqlite3_step(pStmt) ){
- sqlite3_resfmt_row(pFmt, pStmt);
-}
-sqlite3_resfmt_finish(pFmt, &errCode, &zErrMsg);
-// Do something with errcode and zErrMsg
+// Fill out the spec object to describe the desired output format
+zErrMsg = 0;
+rc = sqlite3_format_query_result(pStmt, &spec, &zErrMsg);
+if( rc ) printf("Error (%d): %s\n", rc, zErrMsg);
sqlite3_free(zErrMsg);
~~~
-The `sqlite3_resfmt_spec` structure (defined below) describes the desired
-output format. The `pFmt` variable is a pointer to an opaque sqlite3_resfmt
-object that maintains the statement of the formatter.
-The pFmt object is used as the first parameter to two other
-routines, `sqlite3_resfmt_row()` and `sqlite3_resfmt_finish()`, and
-is not usable for any other purpose by the caller. The
-`sqlite3_resfmt_finish()` interface serves as a destructor for
-the pFmt object.
+The `sqlite3_qrf_spec` object describes the desired output format
+and what to do with the generated output. Most of the work in using
+the QRF involves filling out the sqlite3_qrf_spec.
-## 2.0 The `sqlite3_resfmt_spec` object
+## 2.0 The `sqlite3_qrf_spec` object
-A pointer to an instance of the following structure is the second
-parameter to the `sqlite3_resfmt_begin()` interface. This structure
-defines how the rules of the statement are to be formatted.
+This structure defines how the results of a query are to be
+formatted, and what to do with the formatted text.
> ~~~
-typedef struct sqlite3_resfmt_spec sqlite3_resfmt_spec;
-struct sqlite3_resfmt_spec {
- int iVersion; /* Version number of this structure */
- int eFormat; /* Output format */
+typedef struct sqlite3_qrf_spec sqlite3_qrf_spec;
+struct sqlite3_qrf_spec {
+ unsigned char iVersion; /* Version number of this structure */
+ unsigned char eFormat; /* Output format */
unsigned char bShowCNames; /* True to show column names */
- unsigned char eEscMode; /* How to deal with control characters */
- unsigned char bQuote; /* Quote output values as SQL literals */
+ unsigned char eEscape; /* How to deal with control characters */
+ unsigned char eQuote; /* Quoting style for text */
+ unsigned char eBlob; /* Quoting style for BLOBs */
unsigned char bWordWrap; /* Try to wrap on word boundaries */
- int mxWidth; /* Maximum column width in columnar modes */
+ short int mxWidth; /* Maximum width of any column */
+ int nWidth; /* Number of column width parameters */
+ short int *aWidth; /* Column widths */
const char *zColumnSep; /* Alternative column separator */
const char *zRowSep; /* Alternative row separator */
const char *zTableName; /* Output table name */
const char *zNull; /* Rendering of NULL */
const char *zFloatFmt; /* printf-style string for rendering floats */
- int nWidth; /* Number of column width parameters */
- short int *aWidth; /* Column widths */
- char *(*xRender)(void*,sqlite3_value*); /* Render a value */
- ssize_t (*xWrite)(void*,const unsigned char*,ssize_t); /* Write callback */
+ char *(*xRender)(void*,sqlite3_value*); /* Render a value */
+ ssize_t (*xWrite)(void*,const unsigned char*,size_t); /* Write callback */
void *pRenderArg; /* First argument to the xRender callback */
void *pWriteArg; /* First argument to the xWrite callback */
char **pzOutput; /* Storage location for output string */
};
~~~
-The sqlite3_resfmt_spec object must be fully initialized prior
+The sqlite3_qrf_spec object must be fully initialized prior
to calling `sqlite3_resfmt_begin()` and its value must not change
by the application until after the corresponding call to
`sqlite3_resfmt_finish()`. Note that the result formatter itself
-might change values in the sqlite3_resfmt_spec object as it runs.
+might change values in the sqlite3_qrf_spec object as it runs.
But the application should not try to change or use any fields of
-the sqlite3_resfmt_spec object while the formatter is running.
+the sqlite3_qrf_spec object while the formatter is running.
### 2.1 Structure Version Number
-The sqlite3_resfmt_spec.iVersion field must be 1. Future enhancements to this
-subsystem might add new fields onto the bottom of the sqlite3_resfmt_spec
+The sqlite3_qrf_spec.iVersion field must be 1. Future enhancements to
+the QRF might add new fields onto the bottom of the sqlite3_qrf_spec
object. Those new fields will only be accessible if the iVersion is greater
than 1. Thus the iVersion field is used to support upgradability.
-### 2.2 Output Deposition
+### 2.2 Output Deposition (xWrite and pzOutput)
The formatted output can either be sent to a callback function
or accumulated into an output buffer in memory obtained
-from system malloc(). If the sqlite3_resfmt_spec.xWrite column is not NULL,
-then that function is invoked (using sqlite3_resfmt_spec.xWriteArg as its
+from system malloc(). If the sqlite3_qrf_spec.xWrite column is not NULL,
+then that function is invoked (using sqlite3_qrf_spec.xWriteArg as its
first argument) to transmit the formatted output. Or, if
-sqlite3_resfmt_spec.pzOutput points to a pointer to a character, then that
-pointer is made to point to memory obtained from malloc() that
+sqlite3_qrf_spec.pzOutput points to a pointer to a character, then that
+pointer is made to point to memory obtained from sqlite3_malloc() that
contains the complete text of the formatted output.
-When `sqlite3_resfmt_begin()` is called,
-one of sqlite3_resfmt_spec.xWrite and sqlite3_resfmt_spec.pzOutput must be
+One of sqlite3_qrf_spec.xWrite and sqlite3_qrf_spec.pzOutput must be
non-NULL and the other must be NULL.
-Output might be generated row by row, on each call to
-`sqlite3_resfmt_row()` or it might be written all at once
-on the final call to `sqlite3_resfmt_finish()`, depending
-on the output format.
-
### 2.3 Output Format
-The sqlite3_resfmt_spec.eFormat field is an integer code that defines the
+The sqlite3_qrf_spec.eFormat field is an integer code that defines the
specific output format that will be generated. See the
output format describes below for additional detail.
### 2.4 Show Column Names
-The sqlite3_resfmt_spec.bShowCNames field is a boolean. If true, then column
+The sqlite3_qrf_spec.bShowCNames field is a boolean. If true, then column
names appear in the output. If false, column names are omitted.
### 2.5 Control Character Escapes
-The sqlite3_resfmt_spec.eEscMode determines how ASCII control characters are
+The sqlite3_qrf_spec.eEscMode determines how ASCII control characters are
formatted in the output. If this value is zero, then the control character
with value X is displayed as ^Y where Y is X+0x40. Hence, a
backspace character (U+0008) is shown as "^H". This is the default.
### 2.6 Render output as SQL literals
-If the sqlite3_resfmt_spec.bQuote field is non-zero (true), then outputs
+If the sqlite3_qrf_spec.bQuote field is non-zero (true), then outputs
are rendered as SQL literal values. String are written within `'...'`
with appropriate escapes. BLOBs are of the form `x'...'`. NULL values
come out as "NULL".
### 2.7 Word Wrapping In Columnar Modes
For output modes that attempt to display equal-width columns, the
-sqlite3_resfmt_spec.bWordWrap boolean determines whether long values
+sqlite3_qrf_spec.bWordWrap boolean determines whether long values
are broken at word boundaries, or at arbitrary characters. The
-sqlite3_resfmt_spec.mxWidth determines the maximum width of an output column.
+sqlite3_qrf_spec.mxWidth determines the maximum width of an output column.
### 2.8 Row and Column Separator Strings
-The sqlite3_resfmt_spec.zColumnSep and sqlite3_resfmt_spec.zRowSep strings
+The sqlite3_qrf_spec.zColumnSep and sqlite3_qrf_spec.zRowSep strings
are alternative column and row separator character sequences. If not
specified (if these pointers are left as NULL) then appropriate defaults
are used.
### 2.9 The Output Table Name
-The sqlite3_resfmt_spec.zTableName value is the name of the output table
+The sqlite3_qrf_spec.zTableName value is the name of the output table
when the MODE_Insert output mode is used.
### 2.10 The Rendering Of NULL
-If a value is NULL and sqlite3_resfmt_spec.xRender() does not exist
+If a value is NULL and sqlite3_qrf_spec.xRender() does not exist
or declines to provide a rendering, then show the NULL using the string
-found in sqlite3_resfmt_spec.zNull. If zNull is itself a NULL pointer
+found in sqlite3_qrf_spec.zNull. If zNull is itself a NULL pointer
then NULL values are rendered as an empty string.
### 2.11 Floating Point Value Format
If a value is a floating-point number other than Infinity or NaN, then
the value is rendered using the printf-style format given by the
-sqlite3_resfmt_spec.zFloatFmt string.
+sqlite3_qrf_spec.zFloatFmt string.
### 2.12 Column Widths And Alignments
-The sqlite3_resfmt_spec.aWidth[] array, if specified, is an array of
+The sqlite3_qrf_spec.aWidth[] array, if specified, is an array of
16-bit signed integers that specify the minimum column width and
the alignment for all columns in columnar output modes. Negative
values mean right-justify. The
These widths are deliberately stored in a 16-bit signed integer
as no good can come from having column widths greater than 32767.
-The sqlite3_resfmt_spec.nWidth field is the number of values in the aWidth[]
+The sqlite3_qrf_spec.nWidth field is the number of values in the aWidth[]
array. Any column beyond the nWidth-th column are assumed to have
a minimum width of 0.
### 2.13 Optional Value Rendering Callback
-If the sqlite3_resfmt_spec.xRender field is not NULL, then each rendered
+If the sqlite3_qrf_spec.xRender field is not NULL, then each rendered
sqlite3_value is first passed to the xRender function, giving it
an opportunity to render the results. If xRender chooses to render,
it should write the rendering into memory obtained from sqlite3_malloc()
The SQLite result formatter is implemented in three source code files:
- * `resfmt.c` → The implementation, written in portable C99
- * `resfmt.h` → A header file defining interfaces
- * `resfmt.md` → This documentation, in Markdown
+ * `qrf.c` → The implementation, written in portable C99
+ * `qrf.h` → A header file defining interfaces
+ * `qrf.md` → This documentation, in Markdown
-To use the SQLite result formatter, include the "`resfmt.h`" header file
-and link the application against the "`resfmt.c`" source file.
+To use the SQLite result formatter, include the "`qrf.h`" header file
+and link the application against the "`qrf.c`" source file.
$(T.link) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS.libsqlite3)
xbin: threadtest5
-resfmt-test: sqlite3.o $(TOP)/ext/misc/resfmt-tester.c $(TOP)/ext/misc/resfmt.c $(TOP)/ext/misc/resfmt.h
- $(T.link) -I$(TOP)/ext/misc -I. \
- $(TOP)/ext/misc/resfmt-tester.c $(TOP)/ext/misc/resfmt.c sqlite3.o \
+qrf-tester: sqlite3.o $(TOP)/ext/qrf/qrf-tester.c $(TOP)/ext/qrf/qrf.c $(TOP)/ext/qrf/qrf.h
+ $(T.link) -I$(TOP)/ext/qrf -I. \
+ $(TOP)/ext/qrf/qrf-tester.c $(TOP)/ext/qrf/qrf.c sqlite3.o \
-o $@ $(LDFLAGS.libsqlite3)
#
-C Simplify\sthe\sinterface\sto\suse\sjust\sa\ssingle\sAPI.
-D 2025-10-22T12:09:50.023
+C Refactor:\s\sName\schange\sto\s"query\sresult\sformatter"\sor\s"QRF".\s\sSimplify\snames.\nput\sall\sthe\scode\sinto\sits\sown\ssubdirectory\sof\sext/
+D 2025-10-22T12:33:59.118
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F ext/misc/randomjson.c ef835fc64289e76ac4873b85fe12f9463a036168d7683cf2b773e36e6262c4ed
F ext/misc/regexp.c 548151f3e57506fda678e6a65e85a763f4eece653287e1ad44e167f9485e0c6b
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
-F ext/misc/resfmt-tester.c 3188324e10f945429fd684c1d1a468a1bde43e1379af60f0d34c5411a04b0edc
-F ext/misc/resfmt.c 86c6e1a4e77a64423de38942fcbc1c07ba052b405be3550f1e72980173e0d7f1
-F ext/misc/resfmt.h ebb635f87324499a1487cdad812f64ab9f98a1b09accf0ba45fea0e274e2bd3b
-F ext/misc/resfmt.md 6f6cefd95fa11ce30e4f34ea84052e7a8291dd48b7e666352bd7cf2e22c22ec4
F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c
F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946
F ext/misc/series.c 22c6d8f00cc1b5089b1b37392e9097e9df9a5db53be86daf9a7669d95bb179f4
F ext/misc/windirent.h 02211ce51f3034c675f2dbf4d228194d51b3ee05734678bad5106fff6292e60c
F ext/misc/zipfile.c 09e6e3a3ff40a99677de3c0bc6569bd5f4709b1844ac3d1c1452a456c5a62f1c
F ext/misc/zorder.c bddff2e1b9661a90c95c2a9a9c7ecd8908afab5763256294dd12d609d4664eee
+F ext/qrf/qrf-tester.c 59cb5b1ed889ba57836d0fbb07b583fdfdfe409b1344f4f119fc13dff3a7356a w ext/misc/resfmt-tester.c
+F ext/qrf/qrf.c 702769f174817330ebe92af2334e5f5529f6f5b6315ace318a359e3a9bde10ac w ext/misc/resfmt.c
+F ext/qrf/qrf.h e9585fbadc45e8182faf208a0f86984d5130d89742364424fd1c39f12457f013 w ext/misc/resfmt.h
+F ext/qrf/qrf.md 4eea619191dab7bbf483eff3fe3b074a07d7c8c50bc86070a4485797d386d1ff w ext/misc/resfmt.md
F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8
F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255
F ext/rbu/rbu10.test 7c22caa32c2ff26983ca8320779a31495a6555737684af7aba3daaf762ef3363
F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36e0f6991460fff0cb7c15079454679a4e2
F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
-F main.mk bf63775585a99e8e7158c4d67c30aeeae45b84572c474f9d41c7bba927788f46
+F main.mk e402d12e7c0f5cd3150679847c791b84018f72cd18bc96544b91a90a4651bb41
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 1f364ea3c08badd555a9ce70bb96cb8f862d6cc6425e9ff41da228fdd2f29361
-R e9ac91203f0abef1ee5b35000bb54fe9
+P 82dc13ec4887f90995bd984ede9c2670fb7512962ccceb1848a7e9aab7891c00
+R 876ffc4381d775206ba278a9f63b44f7
+T *branch * qrf
+T *sym-qrf *
+T -sym-resfmt *
U drh
-Z 7963d538858020e5fc3e5fc1a9ddc9f8
+Z c3eafc0dfedaee8eb5b7be16a8347846
# Remove this line to create a well-formed Fossil manifest.
-branch resfmt
-tag resfmt
+branch qrf
+tag qrf
-82dc13ec4887f90995bd984ede9c2670fb7512962ccceb1848a7e9aab7891c00
+8646a2ee224819cf459989aa03bd1b9e1a77fc1f8bee8fd45dba778c63467d61