viernes, 8 de julio de 2016

Using SQLITE3 with Threads in Harbour



The wrapper of the library SQLITE3 to Harbour, support THEADSAFE, but it is important to use the same handle  pSqlite3, 
using https://en.wikipedia.org/wiki/Singleton_pattern

An easy example to see;

CLASS TLogSqlite3
      CLASSDATA Self 

      DATA pSqlite3
      DATA cErrorSqlite3

      METHOD getInstance()
      METHOD Open()      PROTECTED

      METHOD Exec( cSql )
      METHOD Close() INLINE ::pSqlite3 := NIL

      METHOD InitClass ()

END CLASS
 

METHOD InitClass CLASS TLogSqlite3
  if ::Self = NIL
     ::Self := Self
     ::Open()
  endif  
RETURN Self

METHOD getInstance CLASS TLogSqlite3
RETURN ::Self


METHOD Open( ) CLASS TLogSqlite3
   Local lRet := .T.
  
   ::pSqlite3 := sqlite3_open( hb_dirBase() + "text.db", .T. )
 
   IF !( sqlite3_errcode( ::pSqlite3 ) == SQLITE_OK )
      ::cErrorSqlite3 := sqlite3_errmsg( ::pSqlite3 )

            lRet := .T.
   ENDIF

RETURN lRet


METHOD Exec( cSql ) CLASS TLogSqlite3
  Local cSql, lRet := .T., cOldDataFormat, cOldTimeFormat
  Local cWarning := ""

  IF sqlite3_exec( ::pSqlite3, "BEGIN TRANSACTION;") == SQLITE_OK


     IF sqlite3_exec( ::pSqlite3, cSql ) != SQLITE_OK
        ::cErrorSqlite3 := sqlite3_errmsg( ::pSqlite3 )
        sqlite3_exec( ::pSqlite3, " ROLLBACK;")
        lRet := .F.
     ENDIF

     IF empty( ::cErrorSqlite3 )
        sqlite3_exec( ::pSqlite3, "COMMIT;" )
        lRet := .T.
     ENDIF
                       
  ENDIF

RETURN lRet  


For use in you aplicattion with threads ;

oSqlite3 := TLogSqlite3():getInstance()
oSqlite3:Exec( cSql ) 

The explanation is very simple.
If the TLogSqlite3 object instance per thread, then insert each other will be blocked, because the table is locked, not being theadSafe.

But for compliance Thread Safe, need to use the same variable pSqlite3 for all calls. Using the singleton pattern, we solve the problem of locking the table.
 

Android y Git. Disponer del hash automáticamente.

Una de las cosas a las que estoy acostumbrado, es tener siempre en mi código, el hash/tag/versión del control de versiones que estoy usan...