Permalink
Browse files

adde profile and tracing taps

20080518231553-2f820-dcf793e26fca23b889c400494d522027370e2749.gz
  • Loading branch information...
copiousfreetime authored and git-darcs-import committed May 18, 2008
1 parent 0a72b7f commit 42621cf1bf246ef6df569bb45de7da98595a78e4
View
@@ -188,6 +188,8 @@ void Init_amalgalite3()
rb_define_method(cAS_Database, "close", am_sqlite3_database_close, 0); /* in amalgalite3_database.c */
rb_define_method(cAS_Database, "last_insert_rowid", am_sqlite3_database_last_insert_rowid, 0); /* in amalgalite3_database.c */
rb_define_method(cAS_Database, "autocommit?", am_sqlite3_database_is_autocommit, 0); /* in amalgalite3_database.c */
rb_define_method(cAS_Database, "register_trace_tap", am_sqlite3_database_register_trace_tap, 1); /* in amalgalite3_database.c */
rb_define_method(cAS_Database, "register_profile_tap", am_sqlite3_database_register_profile_tap, 1); /* in amalgalite3_database.c */
/*
* class Statement
View
@@ -15,6 +15,8 @@ extern VALUE eAS_Error;
/* wrapper struct around the sqlite3 opaque pointer */
typedef struct am_sqlite3 {
sqlite3 *db;
VALUE trace_obj;
VALUE profile_obj;
} am_sqlite3;
/* wrapper struct around the sqlite3_statement opaque pointer */
@@ -23,6 +25,8 @@ typedef struct am_sqlite3_stmt {
VALUE remaining_sql;
} am_sqlite3_stmt;
/*
/***********************************************************************
* Prototypes
**********************************************************************/
@@ -40,6 +44,8 @@ extern VALUE am_sqlite3_database_last_insert_rowid(VALUE self);
extern VALUE am_sqlite3_database_is_autocommit(VALUE self);
extern VALUE am_sqlite3_database_prepare(VALUE self, VALUE rSQL);
extern VALUE am_sqlite3_database_register_trace_tap(VALUE self, VALUE tap);
extern VALUE am_sqlite3_database_register_profile_tap(VALUE self, VALUE tap);
/*----------------------------------------------------------------------
* Statement functions
View
@@ -211,17 +211,141 @@ VALUE am_sqlite3_database_prepare(VALUE self, VALUE rSQL)
return stmt;
}
/**
* This function is registered with a sqlite3 database using the sqlite3_trace
* function. During the registration process a handle on a VALUE is also
* registered.
*
* When this function is called, it calls the 'trace' method on the tap object,
* which is the VALUE that was registered during the sqlite3_trace call.
*
* This function corresponds to the SQLite xTrace function specification.
*
*/
void amalgalite_xTrace(void* tap, const char* msg)
{
VALUE trace_obj = (VALUE) tap;
rb_funcall( trace_obj, rb_intern("trace"), 1, rb_str_new2( msg ) );
return;
}
/**
* :call-seq:
* database.register_trace_tap( tap_obj )
*
* This registers an object to be called with every trace event in SQLite.
*
* This is an experimental api and is subject to change, or removal.
*
*/
VALUE am_sqlite3_database_register_trace_tap(VALUE self, VALUE tap)
{
am_sqlite3 *am_db;
int rc;
Data_Get_Struct(self, am_sqlite3, am_db);
/* Qnil, unregister the item and tell the garbage collector we are done with
* it.
*/
if ( Qnil == tap ) {
sqlite3_trace( am_db->db, NULL, NULL );
rb_gc_unregister_address( &(am_db->trace_obj) );
am_db->trace_obj = Qnil;
/* register the item and store the reference to the object in the am_db
* structure. We also have to tell the Ruby garbage collector that we
* point to the Ruby object from C.
*/
} else {
am_db->trace_obj = tap;
rb_gc_register_address( &(am_db->trace_obj) );
sqlite3_trace( am_db->db, amalgalite_xTrace, (void *)am_db->trace_obj );
}
return Qnil;
}
/**
* the amagliate trace function to be registered with register_trace_tap
* When it is called, it calls the 'trace' method on the tap object.
*
* This function conforms to the sqlite3 xProfile function specification.
*/
void amalgalite_xProfile(void* tap, const char* msg, sqlite3_uint64 time)
{
VALUE trace_obj = (VALUE) tap;
rb_funcall( trace_obj, rb_intern("profile"),
2, rb_str_new2( msg ), SQLUINT64_2NUM(time) );
return;
}
/**
* :call-seq:
* database.register_profile_tap( tap_obj )
*
* This registers an object to be called with every profile event in SQLite.
*
* This is an experimental api and is subject to change or removal.
*
*/
VALUE am_sqlite3_database_register_profile_tap(VALUE self, VALUE tap)
{
am_sqlite3 *am_db;
int rc;
Data_Get_Struct(self, am_sqlite3, am_db);
/* Qnil, unregister the item and tell the garbage collector we are done with
* it.
*/
if ( tap == Qnil ) {
sqlite3_profile( am_db->db, NULL, NULL );
rb_gc_unregister_address( &(am_db->profile_obj) );
am_db->profile_obj = Qnil;
/* register the item and store the reference to the object in the am_db
* structure. We also have to tell the Ruby garbage collector that we
* point to the Ruby object from C.
*/
} else {
am_db->profile_obj = tap;
rb_gc_register_address( &(am_db->profile_obj) );
sqlite3_profile( am_db->db, amalgalite_xProfile, (void *)am_db->profile_obj );
}
return Qnil;
}
/***********************************************************************
* Ruby life cycle methods
***********************************************************************/
/*
* garbage collector free method for the am_data structure
* garbage collector free method for the am_data structure. Make sure to un
* registere the trace and profile objects if they are not Qnil
*/
void am_sqlite3_database_free(am_sqlite3* wrapper)
void am_sqlite3_database_free(am_sqlite3* am_db)
{
free(wrapper);
if ( Qnil != am_db->trace_obj ) {
rb_gc_unregister_address( &(am_db->trace_obj) );
am_db->trace_obj = Qnil;
}
if ( Qnil != am_db->profile_obj) {
rb_gc_unregister_address( &(am_db->profile_obj) );
am_db->profile_obj = Qnil;
}
free(am_db);
return;
}
@@ -230,9 +354,12 @@ void am_sqlite3_database_free(am_sqlite3* wrapper)
*/
VALUE am_sqlite3_database_alloc(VALUE klass)
{
am_sqlite3* wrapper = ALLOC(am_sqlite3);
VALUE obj = (VALUE)NULL;
am_sqlite3* am_db = ALLOC(am_sqlite3);
VALUE obj ;
am_db->trace_obj = Qnil;
am_db->profile_obj = Qnil;
obj = Data_Wrap_Struct(klass, NULL, am_sqlite3_database_free, wrapper);
obj = Data_Wrap_Struct(klass, NULL, am_sqlite3_database_free, am_db);
return obj;
}
View
@@ -27,36 +27,30 @@ Core 'Objects'
sqlite3 (typdef struct sqlite3) -> main database handle
-------
*done* int sqlite3_open_v2(*filename, sqlite3**, flags, NULL)
*done* int sqlite3_open16
*done* int sqlite3_extended_result_codes(sqlite3, int onoff) # default to turning this on
*skipped* called during rb_raise
*skipped* const char *sqlite3_errmsg(sqlite3*);
*skipped* const void *sqlite3_errmsg16(sqlite3*);
*done* int sqlite3_close(sqlite3 *)
TODO: int sqlite3_exec -> don't use, wrap in ruby exec
*skipped* int sqlite3_exec -> don't use, wrap in ruby exec
*done* sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*)
*done* int sqlite3_get_autocommit(sqlite3*)
*done* int sqlite3_changes(sqlite3*)
*done* int sqlite3_total_changes(sqlite3*)
*skipped* int sqlite3_errcode(sqlite3 *db)
*done* int sqlite3_prepare_v2(sqlite3* db, sql, nbyte, sqlite3_stmt**, const char **tail)
int sqlite3_prepare16_v2(sqlite3* db, sql, nbyte, sqlite3_stmt**, const char **tail)
// not yet, but implement if/when a purchase of sqlite3 encryption works
int sqlite3_key(sqlite3* db, const void *pKey, int nKey);
int sqlite3_rekey(sqlite3* db, const void *pKey, int nKey);
TODO: int sqlite3_key(sqlite3* db, const void *pKey, int nKey);
TODO: int sqlite3_rekey(sqlite3* db, const void *pKey, int nKey);
// BLOB
int sqlite3_blob_open(sqlite3*, *db, *table, *column, rowid, flags, **blob);
TODO: int sqlite3_blob_open(sqlite3*, *db, *table, *column, rowid, flags, **blob);
TODO: int sqlite3_busy_timeout(sqlite3*)
TODO: void sqlite3_progress_hander(sqlite3*, int, int(*)(void*), void*)
@@ -87,54 +81,43 @@ Core 'Objects'
*done* const char *sqlite3_sql(sqlite3_stmt *pStmt)
*done* int sqlite3_bind_parameter_count(sqlite3_stmt*);
# binding by name or index, if passed in an array to the bind() method then
# bind by index, if passed in a hash, bind by name, using hte keys of the hash
sqlite3_bind_blob(sqlite3_stmt*, int, const void *, int n, void(*)(void*));
sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
*done* sqlite3_bind_double(sqlite3_stmt*, int, double);
*done* sqlite3_bind_int(sqlite3_stmt*, int, int);
*done* sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
*done* sqlite3_bind_null(sqlite3_stmt*, int);
*done* sqlite3_bind_text(sqlite3_stmt*, int, constc char*, int n, void(*)(void*));
sqlite3_bind_text16(sqlite3_stmt*, int, constc char*, int, void(*)(void*));
* skipping *sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
// returns a pointer to the name of nth sql paramter in the statemetn
*done* const char* sqlite3_bind_parameter_name(sqlite3_stmt*, int )
// returns the index of the named parameters
*done* sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
*done* sqlite3_clear_bindings(sqlite3_stmt*);
*done* sqlite3_column_count(sqlite3_stmt *pStmt);
*done* sqlite3_column_name(sqlite3_stmt*, int N);
sqlite3_column_name16(sqlite3_stmt*, int N);
*skip - used internally* sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
*done* sqlite3_column_database_name(sqlite3_stmt*, int);
*done* sqlite3_column_table_name(sqlite3_stmt*, int);
*done* sqlite3_column_origin_name(sqlite3_stmt*, int);
*done* sqlite3_step(sqlite3_stmt*);
*done - as 'close' *int sqlite3_finalize(sqlite3_stmt *pStmt);
*done* int sqlite3_reset(sqlite3_stmt *pStmt);
*done - same as sqlite3_column_count* sqlite3_data_count(sqlite3_stmt *pStmt);
*do not use* sqlite3_value* sqlite3_column_value(sqlite3_stmt*, int iCol);
sqlite3_column_database_name(sqlite3_stmt*, int);
sqlite3_column_table_name(sqlite3_stmt*, int);
sqlite3_column_origin_name(sqlite3_stmt*, int);
sqlite3_bind_text16(sqlite3_stmt*, int, constc char*, int, void(*)(void*));
sqlite3_column_database_name16(sqlite3_stmt*, int);
sqlite3_column_table_name16(sqlite3_stmt*, int);
sqlite3_column_origin_name16(sqlite3_stmt*, int);
sqlite3_column_name16(sqlite3_stmt*, int N);
sqlite3_column_decltype(sqlite3_stmt*, int);
sqlite3_column_decltype16(sqlite3_stmt*, int);
*done* sqlite3_step(sqlite3_stmt*);
*done - as 'close' *int sqlite3_finalize(sqlite3_stmt *pStmt);
*done* int sqlite3_reset(sqlite3_stmt *pStmt);
*done - same as sqlite3_column_count* sqlite3_data_count(sqlite3_stmt *pStmt);
// use this to find the type and then call the appropriate method afterwards.
sqlite3_column_type(sqlite3_stmt*, int iCol);
sqlite3_value* sqlite3_column_value(sqlite3_stmt*, int iCol);
# binding by name or index, if passed in an array to the bind() method then
# bind by index, if passed in a hash, bind by name, using hte keys of the hash
sqlite3_bind_blob(sqlite3_stmt*, int, const void *, int n, void(*)(void*));
sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
sqlite3_blob
Oops, something went wrong.

0 comments on commit 42621cf

Please sign in to comment.