mirror of
https://github.com/sqlite/sqlite.git
synced 2025-10-25 20:58:26 +03:00
Simplify the interface to use just a single API.
FossilOrigin-Name: 82dc13ec4887f90995bd984ede9c2670fb7512962ccceb1848a7e9aab7891c00
This commit is contained in:
@@ -134,8 +134,6 @@ int main(int argc, char **argv){
|
||||
}else
|
||||
if( strcmp(zLine, "--go")==0 ){
|
||||
const char *zSql, *zTail;
|
||||
sqlite3_resfmt *pFmt;
|
||||
int iErr = 0;
|
||||
char *zErr = 0;
|
||||
int n;
|
||||
if( db==0 ){
|
||||
@@ -166,17 +164,16 @@ int main(int argc, char **argv){
|
||||
spec.pzOutput = &zOut;
|
||||
spec.xWrite = 0;
|
||||
}
|
||||
pFmt = sqlite3_resfmt_begin(pStmt, &spec);
|
||||
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
sqlite3_resfmt_row(pFmt);
|
||||
rc = sqlite3_format_query_result(pStmt, &spec, &zErr);
|
||||
if( rc!=SQLITE_OK ){
|
||||
fprintf(stderr, "%s:%d: Error %d: %s\n", zSrc, lineNum,
|
||||
rc, zErr);
|
||||
}else{
|
||||
if( !bUseWriter && zOut ){
|
||||
fputs(zOut, stdout);
|
||||
sqlite3_free(zOut);
|
||||
}
|
||||
}
|
||||
rc = sqlite3_resfmt_finish(pFmt, &iErr, &zErr);
|
||||
if( !bUseWriter && zOut ){
|
||||
fputs(zOut, stdout);
|
||||
sqlite3_free(zOut);
|
||||
}
|
||||
printf("/* rc=%d. error-code=%d. error-message=%s */\n",
|
||||
rc, iErr, zErr ? zErr : "NULL");
|
||||
sqlite3_free(zErr);
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
@@ -190,7 +187,6 @@ int main(int argc, char **argv){
|
||||
{ "box", RESFMT_Box, },
|
||||
{ "column", RESFMT_Column, },
|
||||
{ "count", RESFMT_Count, },
|
||||
{ "csv", RESFMT_Csv, },
|
||||
{ "eqp", RESFMT_EQP, },
|
||||
{ "explain", RESFMT_Explain, },
|
||||
{ "html", RESFMT_Html, },
|
||||
@@ -200,9 +196,7 @@ int main(int argc, char **argv){
|
||||
{ "list", RESFMT_List, },
|
||||
{ "markdown", RESFMT_Markdown, },
|
||||
{ "off", RESFMT_Off, },
|
||||
{ "pretty", RESFMT_Pretty, },
|
||||
{ "table", RESFMT_Table, },
|
||||
{ "tcl", RESFMT_Tcl, },
|
||||
{ "scanexp", RESFMT_ScanExp, },
|
||||
};
|
||||
int i;
|
||||
|
||||
@@ -19,10 +19,11 @@
|
||||
** Private state information. Subject to change from one release to the
|
||||
** next.
|
||||
*/
|
||||
typedef struct sqlite3_resfmt sqlite3_resfmt;
|
||||
struct sqlite3_resfmt {
|
||||
sqlite3_stmt *pStmt; /* The statement whose output is to be rendered */
|
||||
sqlite3 *db; /* The corresponding database connection */
|
||||
sqlite3_str *pErr; /* Error message, or NULL */
|
||||
char **pzErr; /* Write error message here, if not NULL */
|
||||
sqlite3_str *pOut; /* Accumulated output */
|
||||
int iErr; /* Error code */
|
||||
int nCol; /* Number of output columns */
|
||||
@@ -30,14 +31,33 @@ struct sqlite3_resfmt {
|
||||
sqlite3_resfmt_spec spec; /* Copy of the original spec */
|
||||
};
|
||||
|
||||
/*
|
||||
** Set an error code and error message.
|
||||
*/
|
||||
static void resfmtError(
|
||||
sqlite3_resfmt *p, /* Query result state */
|
||||
int iCode, /* Error code */
|
||||
const char *zFormat, /* Message format (or NULL) */
|
||||
...
|
||||
){
|
||||
p->iErr = iCode;
|
||||
if( p->pzErr!=0 ){
|
||||
sqlite3_free(*p->pzErr);
|
||||
*p->pzErr = 0;
|
||||
if( zFormat ){
|
||||
va_list ap;
|
||||
va_start(ap, zFormat);
|
||||
*p->pzErr = sqlite3_mprintf(zFormat, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Free memory associated with pResfmt
|
||||
** Out-of-memory error.
|
||||
*/
|
||||
static void resfmtFree(sqlite3_resfmt *p){
|
||||
if( p->pErr ) sqlite3_free(sqlite3_str_finish(p->pErr));
|
||||
if( p->pOut ) sqlite3_free(sqlite3_str_finish(p->pOut));
|
||||
sqlite3_free(p);
|
||||
static void resfmtOom(sqlite3_resfmt *p){
|
||||
resfmtError(p, SQLITE_NOMEM, "out of memory");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -361,27 +381,29 @@ static void resfmtRenderValue(sqlite3_resfmt *p, int iCol){
|
||||
}
|
||||
|
||||
/*
|
||||
** Create a new rendering object
|
||||
** Initialize the internal sqlite3_resfmt object.
|
||||
*/
|
||||
sqlite3_resfmt *sqlite3_resfmt_begin(
|
||||
sqlite3_stmt *pStmt,
|
||||
sqlite3_resfmt_spec *pSpec
|
||||
static void resfmtInitialize(
|
||||
sqlite3_resfmt *p, /* State object to be initialized */
|
||||
sqlite3_stmt *pStmt, /* Query whose output to be formatted */
|
||||
const sqlite3_resfmt_spec *pSpec, /* Format specification */
|
||||
char **pzErr /* Write errors here */
|
||||
){
|
||||
sqlite3_resfmt *p; /* The new sqlite3_resfmt being created */
|
||||
size_t sz; /* Size of pSpec[], based on pSpec->iVersion */
|
||||
|
||||
if( pStmt==0 ) return 0;
|
||||
if( pSpec==0 ) return 0;
|
||||
if( pSpec->iVersion!=1 ) return 0;
|
||||
p = sqlite3_malloc64( sizeof(*p) );
|
||||
if( p==0 ) return 0;
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->pzErr = pzErr;
|
||||
if( pSpec->iVersion!=1 ){
|
||||
resfmtError(p, SQLITE_ERROR,
|
||||
"unusable sqlite3_resfmt_spec.iVersion (%d)",
|
||||
pSpec->iVersion);
|
||||
return;
|
||||
}
|
||||
p->pStmt = pStmt;
|
||||
p->db = sqlite3_db_handle(pStmt);
|
||||
p->pErr = 0;
|
||||
p->pOut = sqlite3_str_new(p->db);
|
||||
if( p->pOut==0 ){
|
||||
resfmtFree(p);
|
||||
return 0;
|
||||
resfmtOom(p);
|
||||
return;
|
||||
}
|
||||
p->iErr = 0;
|
||||
p->nCol = sqlite3_column_count(p->pStmt);
|
||||
@@ -405,16 +427,13 @@ sqlite3_resfmt *sqlite3_resfmt_begin(
|
||||
break;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** Render a single row of output.
|
||||
*/
|
||||
int sqlite3_resfmt_row(sqlite3_resfmt *p){
|
||||
int rc = SQLITE_OK;
|
||||
static void resfmtDoOneRow(sqlite3_resfmt *p){
|
||||
int i;
|
||||
if( p==0 ) return SQLITE_DONE;
|
||||
switch( p->spec.eFormat ){
|
||||
case RESFMT_Off:
|
||||
case RESFMT_Count: {
|
||||
@@ -441,16 +460,12 @@ int sqlite3_resfmt_row(sqlite3_resfmt *p){
|
||||
}
|
||||
}
|
||||
p->nRow++;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Finish rendering the results
|
||||
*/
|
||||
int sqlite3_resfmt_finish(sqlite3_resfmt *p, int *piErr, char **pzErrMsg){
|
||||
if( p==0 ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
static void resfmtFinalize(sqlite3_resfmt *p){
|
||||
switch( p->spec.eFormat ){
|
||||
case RESFMT_Count: {
|
||||
sqlite3_str_appendf(p->pOut, "%lld\n", p->nRow);
|
||||
@@ -460,15 +475,36 @@ int sqlite3_resfmt_finish(sqlite3_resfmt *p, int *piErr, char **pzErrMsg){
|
||||
}
|
||||
if( p->spec.pzOutput ){
|
||||
*p->spec.pzOutput = sqlite3_str_finish(p->pOut);
|
||||
p->pOut = 0;
|
||||
}else if( p->pOut ){
|
||||
sqlite3_free(sqlite3_str_finish(p->pOut));
|
||||
}
|
||||
if( piErr ){
|
||||
*piErr = p->iErr;
|
||||
}
|
||||
if( pzErrMsg ){
|
||||
*pzErrMsg = sqlite3_str_finish(p->pErr);
|
||||
p->pErr = 0;
|
||||
}
|
||||
resfmtFree(p);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Run the prepared statement pStmt and format the results according
|
||||
** to the specification provided in pSpec. Return an error code.
|
||||
** If pzErr is not NULL and if an error occurs, write an error message
|
||||
** 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_resfmt fmt; /* The new sqlite3_resfmt 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);
|
||||
}
|
||||
if( fmt.iErr==SQLITE_OK ){
|
||||
int rc = sqlite3_reset(fmt.pStmt);
|
||||
if( rc!=SQLITE_OK ){
|
||||
resfmtError(&fmt, rc, "%s", sqlite3_errmsg(fmt.db));
|
||||
}
|
||||
}
|
||||
resfmtFinalize(&fmt);
|
||||
return fmt.iErr;
|
||||
}
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
*/
|
||||
typedef struct sqlite3_resfmt_spec sqlite3_resfmt_spec;
|
||||
struct sqlite3_resfmt_spec {
|
||||
short int iVersion; /* Version number of this structure */
|
||||
unsigned char iVersion; /* Version number of this structure */
|
||||
unsigned char eFormat; /* Output format */
|
||||
unsigned char bShowCNames; /* True to show column names */
|
||||
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 */
|
||||
short 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 */
|
||||
@@ -43,17 +43,14 @@ struct sqlite3_resfmt_spec {
|
||||
/* Additional fields may be added in the future */
|
||||
};
|
||||
|
||||
/*
|
||||
** Opaque state structure used by this library.
|
||||
*/
|
||||
typedef struct sqlite3_resfmt sqlite3_resfmt;
|
||||
|
||||
/*
|
||||
** Interfaces
|
||||
*/
|
||||
sqlite3_resfmt *sqlite3_resfmt_begin(sqlite3_stmt*, sqlite3_resfmt_spec*);
|
||||
int sqlite3_resfmt_row(sqlite3_resfmt*);
|
||||
int sqlite3_resfmt_finish(sqlite3_resfmt*,int*,char**);
|
||||
int sqlite3_format_query_result(
|
||||
sqlite3_stmt *pStmt, /* SQL statement to run */
|
||||
const sqlite3_resfmt_spec *pSpec, /* Result format specification */
|
||||
char **pzErr /* OUT: Write error message here */
|
||||
);
|
||||
|
||||
/*
|
||||
** Output styles:
|
||||
@@ -61,16 +58,17 @@ int sqlite3_resfmt_finish(sqlite3_resfmt*,int*,char**);
|
||||
#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_Insert 3 /* Generate SQL "insert" statements */
|
||||
#define RESFMT_Explain 4 /* EXPLAIN output */
|
||||
#define RESFMT_ScanExp 5 /* EXPLAIN output with vm stats */
|
||||
#define RESFMT_EQP 6 /* Converts EXPLAIN QUERY PLAN output into a graph */
|
||||
#define RESFMT_Markdown 7 /* Markdown formatting */
|
||||
#define RESFMT_Column 8 /* One record per line in neat columns */
|
||||
#define RESFMT_Table 9 /* MySQL-style table formatting */
|
||||
#define RESFMT_Box 10 /* Unicode box-drawing characters */
|
||||
#define RESFMT_Count 11 /* Output only a count of the rows of output */
|
||||
#define RESFMT_Off 12 /* No query output shown */
|
||||
#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 */
|
||||
|
||||
/*
|
||||
** Quoting styles for text.
|
||||
|
||||
16
manifest
16
manifest
@@ -1,5 +1,5 @@
|
||||
C Simplify\sthe\sset\sof\sformatting\schoices.
|
||||
D 2025-10-21T20:10:44.822
|
||||
C Simplify\sthe\sinterface\sto\suse\sjust\sa\ssingle\sAPI.
|
||||
D 2025-10-22T12:09:50.023
|
||||
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
@@ -389,9 +389,9 @@ F ext/misc/qpvtab.c fc189e127f68f791af90a487f4460ec91539a716daf45a0c357e963fd47c
|
||||
F ext/misc/randomjson.c ef835fc64289e76ac4873b85fe12f9463a036168d7683cf2b773e36e6262c4ed
|
||||
F ext/misc/regexp.c 548151f3e57506fda678e6a65e85a763f4eece653287e1ad44e167f9485e0c6b
|
||||
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
|
||||
F ext/misc/resfmt-tester.c 64b799da88145f7bd1b70635ffc629b2058dfa31e33d04c266ebeae36d1381a0
|
||||
F ext/misc/resfmt.c aedb80cf3eae75d85457b116c840c7a834aef867ae4efa1b45926656f13d4c4d
|
||||
F ext/misc/resfmt.h 35b86324479f51ac0a5a2e39ffb7ca0ca4663667b2892583a393c8a8fc6c6264
|
||||
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
|
||||
@@ -2175,8 +2175,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
|
||||
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
|
||||
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 1a28eae74ed354d556f5ba45c716b03ff36d26b8a6729a5428d7895d8337af78
|
||||
R 6892d861551a00de62fd7fcb651f12e2
|
||||
P 1f364ea3c08badd555a9ce70bb96cb8f862d6cc6425e9ff41da228fdd2f29361
|
||||
R e9ac91203f0abef1ee5b35000bb54fe9
|
||||
U drh
|
||||
Z 7c407302cce92000d1b62ee6c390d8da
|
||||
Z 7963d538858020e5fc3e5fc1a9ddc9f8
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
@@ -1 +1 @@
|
||||
1f364ea3c08badd555a9ce70bb96cb8f862d6cc6425e9ff41da228fdd2f29361
|
||||
82dc13ec4887f90995bd984ede9c2670fb7512962ccceb1848a7e9aab7891c00
|
||||
|
||||
Reference in New Issue
Block a user