Differences From:
File
src/db.c
part of check-in
[6f05b4292a]
- Added /admin/sql page. Added a 'const' to db_generic_query_view()
by
stephan on
2008-02-05 00:01:44.
[view]
To:
File
src/db.c
part of check-in
[0dc3e7a0d5]
- refactored db_generic_query_view() to use sqlite3 API directly so that it can treat SQL errors as non-fatal.
by
stephan on
2008-02-06 19:37:08.
[view]
@@ -1140,8 +1140,10 @@
* xform, then the xform function will be called to transform the
* column data before rendering it. This function takes care of freeing
* the strings created by the xform functions.
*
+* Returns SQLITE_OK on success and any other value on error.
+*
* Example:
*
* char const * const colnames[] = {
* "Tag ID", "Tag Name", "Something Else", "UUID"
@@ -1154,55 +1156,61 @@
* };
* db_generic_query_view( "select a,b,c,d from foo", colnames, xf );
*
*/
-void db_generic_query_view(
+int db_generic_query_view(
char const * sql,
char const * const * coln,
string_unary_xform_f const * xform )
{
-
- Stmt st;
- int i = 0;
- int rc = db_prepare( &st, sql );
/**
- Achtung: makeheaders apparently can't pull the function
- name from this:
- if( SQLITE_OK != db_prepare( &st, sql ) )
+ Reminder: we use sqlite3_stmt directly, instead
+ of using db_prepare(), so that we can treat SQL
+ errors as non-fatal. We are executing arbitrary
+ SQL here, some of it entered via the browser,
+ and we don't want to kill the app when some of
+ the SQL isn't quite right.
*/
+ sqlite3_stmt * st;
+ int rc = sqlite3_prepare(g.db, sql, -1, &st, 0);
if( SQLITE_OK != rc )
{
- @ db_generic_query_view(): Error processing SQL: [%s(sql)]
- return;
+ @ <span style='color:red'>db_generic_query_view() SQL error:
+ @ %h(sqlite3_errmsg(g.db))</span>
+ return rc;
}
- int colc = db_column_count(&st);
+ int colc = sqlite3_column_count(st);
@ <table class='fossil_db_generic_query_view'><tbody>
@ <tr class='header'>
+ int i = 0;
for( i = 0; i < colc; ++i ) {
if( coln )
{
- @ <th>%s(coln[i] ? coln[i] : db_column_name(&st,i))</th>
+ @ <th>%s(coln[i] ? coln[i] : sqlite3_column_name(st,i))</th>
}
else
{
- @ <td>%s(db_column_name(&st,i))</td>
+ @ <td>%s(sqlite3_column_name(st,i))</td>
}
}
@ </tr>
int row = 0;
- while( SQLITE_ROW == db_step(&st) ){
+ char const * text = 0;
+ while( SQLITE_ROW == sqlite3_step(st) ){
@ <tr class='%s( (row++%2) ? "odd" : "even")'>
for( i = 0; i < colc; ++i ) {
+ text = (char const *) sqlite3_column_text(st,i);
char * xf = 0;
char const * xcf = 0;
xcf = (xform && xform[i])
- ? (xf=(xform[i])(db_column_text(&st,i)))
- : db_column_text(&st,i);
+ ? (xf=(xform[i])(text))
+ : text;
@ <td>%s(xcf)</td>
if( xf ) free( xf );
}
@ </tr>
}
- db_finalize( &st );
@ </tbody></table>
+ sqlite3_finalize(st);
+ return SQLITE_OK;
}