VASmalltalk – SQLite and Trace-API

With the newest version of the wrapper I start working on using EsEntryPoints within VASmalltalk to offer SQLite callback handlers to tell VASmalltalk, what the database is doing. This offers several new possibilities – the best ones would be to create database functions defined in VASmalltalk (ignoring possible speed problems :-)).

Actually I thought, that it would not work, because I thought, that SQLite used “cdecl” callback definition, but it seems to work – therefore SQlite seems to use “stdcall” to call back to Smalltalk. Otherwise VASmalltalk would crash at once.

This morning I began to wrap the Trace-API call of SQLite. This callback is used, whenever SQLite executes a SQL command against the database (even those within triggers – normally not seen). Good tool for debugging.

As usual with EsEntryPoint: always do synchronous call-outs (synchronous c-function calls) ! Never asynchronous calls !

As an example I created (within the test app of this wrapper) a new test:

| bindIndex  preparedStatement rc  |

self createDatabaseConnection.

  execSQL: 'create table TESTME2 (aColumn1 blob);' ;
preparedStatement := dbConnection prepare: 'insert into TESTME2 VALUES(:aBlob);'.

rc := dbConnection close .

Here the most interesting part is “setAndActivateDefaultTranscriptTraceHandler”, which builds the needed objects for support of the Trace-API within the library wrapper:

| aHandler |
"build a handler"
aHandler := self defaultTraceCallbackHandler.

"add a block, which should do something ..."
aHandler callbackBlocks 
  add: (MSKSQLiteCallbackBlock 
             newWithBlock: MSKSQLiteCallbackBlock defaultTranscriptThreeArgBlock 
             needsSyncExecution: true).

"set the trace-api handler within the library wrapper"
self traceCallbackHandler: aHandler.

"start tracing"
self apiTrace: aHandler esEntryPoint with: nil.

and the definition of the EsEntryPoint is done in:

| aMSKSQLiteCallbackHandler |

aMSKSQLiteCallbackHandler := MSKSQLiteCallbackHandler new initialize.
      receiver: self 
      selector: #traceCallback:name: 
      callingConvention: 'c' 
      arrayBased: false 
      parameterTypes: #(#pointer #pointer) 
      returnType: #void).

You can see, that SQLite tries to call the method #traceCallback:name of the instance of MSKSQLiteConnection (the wrapper of the library). the wrapper is pretty simple:

traceCallback: aPointer name: ptrToString
| aString |
"the string from SQLite contains the full SQL command"
aString := self convertOSStringZInUTF8ToCCP: (OSStringZ address: ptrToString).

"with this information execute all defined blocks - either in a background process or synchronous"
self traceCallbackHandler callbackBlocks do: [ :eachCallbackBlock |
  eachCallbackBlock needsSyncExecution
    ifTrue:[ eachCallbackBlock block value: self value: nil value: aString ]
    ifFalse:[ [eachCallbackBlock block value: self value: nil value: aString] fork ]

and the execution block of the example handler looks like:

[ :sqliteConnection :ptr :aString | Transcript cr ; show: aString ]

and the result viewable in the Transcript is:

create table TESTME2 (aColumn1 blob);
begin ;

The code is available with version 3.7.2-04 at vastgoodies

This entry was posted in Smalltalk and tagged , . Bookmark the permalink.

One Response to VASmalltalk – SQLite and Trace-API

  1. Sam says:

    I am using VAST 5.0. I am trying to create a routine to store and retrieve a CLOB object (Oracle). Can some one please suggest me how to do that? I have searched few post on the web nothing seems to be working for me.

    Thanks in Advance.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s