[vlc-devel] [PATCH] SQLite module
Rémi Denis-Courmont
remi at remlab.net
Wed Nov 11 18:27:30 CET 2009
+if test "${SYS}" != "darwin"; then
+ PKG_ENABLE_MODULES_VLC([SQLITE], [], [sqlite3], [sqlite3], [auto])
+else
+ AC_ARG_ENABLE(sqlite,
+ [ --enable-sqlite SQLite (default disabled)])
AC_ARG_ENABLE is not supposed to be in a conditional.
+ if test "${enable_sqlite}" = "yes"
This check is wrong. It will fail with --enable-sqlite=foobar.
+ then
+ AC_ARG_WITH(sqlite,
+ [ --with-sqlite=PATH sqlite path linking])
Do we really need this? Also, same error as AC_ARG_ENABLE.
+struct sql_sys_t
+{
+ sqlite3 *db; /**< Database connection. */
+ vlc_mutex_t lock; /**< SQLite mutex. Threads are evil here. */
+ vlc_mutex_t trans_lock; /**< Mutex for running transactions */
+};
Why do you need two locks?
+struct sql_stmt_t
+{
+ sqlite3_stmt* p_sqlitestmt;
+};
Using the SQLite pointer directly would be simpler.
+ /* Initialize sys_t */
+ p_sql->p_sys = calloc( 1, sizeof( *p_sql->p_sys ) );
+ if( !p_sql->p_sys )
+ return VLC_ENOMEM;
+
+ vlc_mutex_init( &p_sql->p_sys->lock );
+ vlc_mutex_init( &p_sql->p_sys->trans_lock );
+
+ /* Open Database */
+ if( OpenDatabase( p_sql ) == VLC_SUCCESS )
+ msg_Dbg( p_sql, "sqlite module loaded" );
+ else
+ return VLC_EGENERIC;
The error path is leaking.
+static int OpenDatabase( sql_t *p_sql )
+{
+ vlc_mutex_lock( &p_sql->p_sys->lock );
Why do you need the mutex here?
+ assert( !p_sql->p_sys->db );
For a pedant, this is wrong since you are zeroing bits instead of NULLifying
the pointer.
+static int CloseDatabase( sql_t *p_sql )
+{
+ vlc_mutex_lock( &p_sql->p_sys->lock );
Why do you need the mutex here?
+ assert( p_sql->p_sys->db );
+
+ /* Close database */
+ int i_ret = sqlite3_close( p_sql->p_sys->db );
+ p_sql->p_sys->db = NULL;
What's the point? You're about to free p_sys anyway.
+ vlc_mutex_unlock( &p_sql->p_sys->lock );
+ return ( i_ret == SQLITE_OK ) ? VLC_SUCCESS : VLC_EGENERIC;
The API does not allow failing to close the database...
+static int Query( sql_t * p_sql,
+ const char * query,
+ char *** result,
+ int * nrow,
+ int * ncol )
+{
+ vlc_mutex_lock( &p_sql->p_sys->lock );
+
+ assert( p_sql->p_sys->db );
+
+#ifndef NDEBUG
+ msg_Dbg( p_sql, "Query: %s", query );
+#endif
+ sqlite3_get_table( p_sql->p_sys->db, query, result, nrow, ncol, NULL );
+ if( sqlite3_errcode( p_sql->p_sys->db ) != SQLITE_OK )
+ {
+ msg_Warn( p_sql, "sqlite3 error: %d: %s",
+ sqlite3_errcode( p_sql->p_sys->db ),
+ sqlite3_errmsg( p_sql->p_sys->db ) );
+ vlc_mutex_unlock( &p_sql->p_sys->lock );
+ return VLC_EGENERIC;
+ }
+
+ vlc_mutex_unlock( &p_sql->p_sys->lock );
+ return VLC_SUCCESS;
+}
You could really factor vlc_mutex_unlock() while adding a return value
variable here and in latter functions.
+static int GetTables( sql_t * p_sql,
+ char *** result )
+{
+ int nrow, i_num = false;
Assigning false to an integer is legal but weird.
+static char* VMSprintf( const char* psz_fmt, va_list args )
+{
+ char *psz = sqlite3_vmprintf( psz_fmt, args );
+ char *ret = strdup( psz );
+ sqlite3_free( psz );
+ return ret;
+}
Do we really need this double copy/allocation?
+static int CommitTransaction( sql_t* p_sql )
+{
+ assert( p_sql->p_sys->db );
+
+ vlc_mutex_lock( &p_sql->p_sys->lock );
+
+ /** This turns the auto commit on. */
+ sqlite3_exec( p_sql->p_sys->db, "COMMIT;", NULL, NULL, NULL );
+#ifndef NDEBUG
+ msg_Dbg( p_sql, "Transaction Query: COMMIT;" );
+#endif
+ if( sqlite3_errcode( p_sql->p_sys->db ) != SQLITE_OK )
+ {
+ msg_Warn( p_sql, "sqlite3 error: %d: %s",
+ sqlite3_errcode( p_sql->p_sys->db ),
+ sqlite3_errmsg( p_sql->p_sys->db ) );
+ vlc_mutex_unlock( &p_sql->p_sys->lock );
How does the caller recover from this? Is the transaction lock not stalled?
+static int RollbackTransaction( sql_t* p_sql )
+{
+ assert( p_sql->p_sys->db );
+
+ vlc_mutex_lock( &p_sql->p_sys->lock );
+
+ sqlite3_exec( p_sql->p_sys->db, "ROLLBACK;", NULL, NULL, NULL );
+#ifndef NDEBUG
+ msg_Dbg( p_sql, "Transaction Query: ROLLBACK;" );
+#endif
+ if( sqlite3_errcode( p_sql->p_sys->db ) != SQLITE_OK )
+ {
+ msg_Warn( p_sql, "sqlite3 error: %d: %s",
+ sqlite3_errcode( p_sql->p_sys->db ),
+ sqlite3_errmsg( p_sql->p_sys->db ) );
+ vlc_mutex_unlock( &p_sql->p_sys->lock );
Same stalling problem.
IMHO, RollbackTransaction should return void, because it does not make much
sense to fail here.
+static sql_stmt_t* PrepareStatement( sql_t* p_sql, const char* psz_fmt, int
i_length )
+{
+ assert( p_sql->p_sys->db );
+ vlc_mutex_lock( &p_sql->p_sys->lock );
+ sql_stmt_t* p_stmt;
+ p_stmt = calloc( 1, sizeof( *p_stmt ) );
+ if( p_stmt == NULL )
+ {
+ vlc_mutex_unlock( &p_sql->p_sys->lock );
+ return NULL;
+ }
Why do you need the lock to allocate memory?
--
Rémi Denis-Courmont
http://www.remlab.net/
More information about the vlc-devel
mailing list