Skip to content

Instantly share code, notes, and snippets.

@yyamasak
Last active December 18, 2018 08:03
Show Gist options
  • Save yyamasak/9f8e95b9ed8bf59a47c18c5e10c49172 to your computer and use it in GitHub Desktop.
Save yyamasak/9f8e95b9ed8bf59a47c18c5e10c49172 to your computer and use it in GitHub Desktop.
Runtime loadable extension for sqlite3 to add extended_errorcode() function (but failed. do not use this!)
package require sqlite3
set dbfile ./example.db
set extfile ./exterrcode.dll
file delete $dbfile
sqlite3 db $dbfile
db enable_load_extension 1
db eval [format {SELECT load_extension('%s');} $extfile]
db eval {
CREATE TABLE "users" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
"name" TEXT DEFAULT NULL
);
INSERT INTO "users" VALUES(1, 'Taro');
}
if {[catch {
db eval {INSERT INTO "users" VALUES(1, 'Hanako');}; # UNIQUE constraint failed: users.id
} err]} {
puts $err
# db eval {SELECT errcode() as ec} e {parray e}
db eval {SELECT extended_errcode() as ee} e {puts "extended_errcode()=$e(ee)"}; # expected to be 1555 but is 0
# puts "db errorcode=[db errorcode]"
}
/*
** 2018-12-18
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
** Compiling this file with MSYS2 (assuming that sqlite3 devel installed.)
** gcc -g -shared exterrcode.c -o exterrcode.dll
**
** Using this library
** $ sqlite3 example.db
** > .load exterrcode.dll
** > (e.g. violate primary key constraint)
** > SELECT errcode();
** > -- 19 (SQLITE_CONSTRAINT)
** > -- https://www.sqlite.org/rescode.html#primary_result_code_list
** >
** > (e.g. violate primary key constraint)
** > SELECT extended_errcode();
** > -- 1555 (SQLITE_CONSTRAINT_PRIMARYKEY)
** > -- https://www.sqlite.org/rescode.html#extrc
**
******************************************************************************
**
** This SQLite extension implements a extended_errcode() function.
**
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
/*
** Implementation of the errcode() function.
**
** Call sqlite3_errcode(db) function to get the recent errcode.
**
*/
static void errcode_func(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
assert( argc==0 );
sqlite3* db = sqlite3_context_db_handle(context);
int errCode = sqlite3_errcode(db);
sqlite3_result_int(context, errCode);
}
/*
** Implementation of the extended_errcode() function.
**
** Call sqlite3_extended_errcode(db) function to get the recent extended_errcode.
**
*/
static void extended_errcode_func(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
assert( argc==0 );
sqlite3* db = sqlite3_context_db_handle(context);
int errCode = sqlite3_extended_errcode(db);
sqlite3_result_int(context, errCode);
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_exterrcode_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
rc = sqlite3_create_function(db, "errcode", 0, SQLITE_UTF8, 0, errcode_func, 0, 0);
rc = sqlite3_create_function(db, "extended_errcode", 0, SQLITE_UTF8, 0, extended_errcode_func, 0, 0);
return rc;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment