apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rick Keiner <rick_kei...@yahoo.com>
Subject Fwd: Re: SQLite3 patch
Date Wed, 04 May 2005 03:05:07 GMT

--- Rick Keiner <rick_keiner@yahoo.com> wrote:

> Date: Tue, 3 May 2005 19:58:34 -0700 (PDT)
> From: Rick Keiner <rick_keiner@yahoo.com>
> Subject: Re: SQLite3 patch
> To: Paul Querna <chip@force-elite.com>
> 
> Hi Paul,
> 
> Thanks for checking out the patch. I think I've
> addressed most of the comments you made. Here's a
> summary.
> 
> 1) sleep with SQLite3. You are not alone in your
> apprehension about the way the SQLite API handles
> the
> busy condition. There has been a lot of discussion
> in
> the SQLite community about this very issue. There
> are
> functions SQLite provides to handle the state but
> without asynchronous calls to the apr_dbd we can't
> take advantage of these.
> 
> 2) The style - I ran it through indent with the
> parameters.
> 
> -kr -nut -nsob -c0 -cd0 -cp0 -lc130 -l130
> 
> 3) Should you be registering this cleanup if you
> didn't allocate it out of pool?
> 
> This has been deleted and the finalize done properly
> at the end of the function.
> 
> 4) The do while. I cleaned that up.
> 
> 5) The crash in get row. Fixed.
> 
> 6) cast to (const char *) I have no idea what that
> was. fixed.
> 
> 7) Creating a pool from a NULL parent. It's parent
> is
> now the pool passed in the open.
> 
> 8) relying on the SQLite_free. Making another
> storage
> allocation is using more resources. Why can't the
> cleanup free the SQLite resources?
> 
> 9) For the prepared statements - More consideration
> should be given to this area. However, for this
> version, it will probably have to go not implemented
> for now. 
> 
> 10) Nested mutex - I modified that to the system
> default.
> 
> 11) ping of the server - Since it's an embedded
> driver
> a NULL check is adequate. There really isn't a
> server.
> 
> 12) I think the above is slightly wrong. The
> AC_DEFUN
> for sqlite2 should be
> down bellow...  Oooops. fixed that.
> 
> 
> Attached is a patched patch. :). It would be great
> if
> it could get in the svn. Thanks again for the
> review.
> 
> Regards,
> Rick Keiner
> 
> --- Paul Querna <chip@force-elite.com> wrote:
> 
> > Rick Keiner wrote:
> > > Attached is a patch that supports SQLite3 using
> > the
> > > apr_dbd.h interface. Could it be included in the
> > svn
> > > checkout?
> > 
> > I have put some comments inline with the patch
> > bellow...
> > 
> > >
> >
>
------------------------------------------------------------------------
> > > 
> > > Index: include/apu.h.in
> > >
> >
>
===================================================================
> > > --- include/apu.h.in	(revision 164613)
> > > +++ include/apu.h.in	(working copy)
> > > @@ -79,6 +79,7 @@
> > >  
> > >  #define APU_HAVE_PGSQL         @apu_have_pgsql@
> > >  #define APU_HAVE_MYSQL         @apu_have_mysql@
> > > +#define APU_HAVE_SQLITE3      
> @apu_have_sqlite3@
> > >  #define APU_HAVE_SQLITE2      
> @apu_have_sqlite2@
> > >  
> > >  #define APU_HAVE_APR_ICONV     @have_apr_iconv@
> > > Index: configure.in
> > >
> >
>
===================================================================
> > > --- configure.in	(revision 164613)
> > > +++ configure.in	(working copy)
> > > @@ -120,6 +120,7 @@
> > >  APU_CHECK_DBM
> > >  APU_CHECK_DBD
> > >  APU_CHECK_DBD_MYSQL
> > > +APU_CHECK_DBD_SQLITE3
> > >  APU_CHECK_DBD_SQLITE2
> > >  APU_FIND_EXPAT
> > >  APU_FIND_ICONV
> > > Index: dbd/apr_dbd_sqlite3.c
> > >
> >
>
===================================================================
> > > --- dbd/apr_dbd_sqlite3.c	(revision 0)
> > > +++ dbd/apr_dbd_sqlite3.c	(revision 0)
> > > @@ -0,0 +1,431 @@
> > > +/* Copyright 2000-2005 The Apache Software
> > Foundation or its licensors, as
> > > + * applicable.
> > > + *
> > > + * Licensed under the Apache License, Version
> 2.0
> > (the "License");
> > > + * you may not use this file except in
> compliance
> > with the License.
> > > + * You may obtain a copy of the License at
> > > + *
> > > + *    
> http://www.apache.org/licenses/LICENSE-2.0
> > > + *
> > > + * Unless required by applicable law or agreed
> to
> > in writing, software
> > > + * distributed under the License is distributed
> > on an "AS IS" BASIS,
> > > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY
> KIND,
> > either express or implied.
> > > + * See the License for the specific language
> > governing permissions and
> > > + * limitations under the License.
> > > + */
> > > +
> > > +#include "apu.h"
> > > +
> > > +#if APU_HAVE_SQLITE3
> > > +
> > > +#include <ctype.h>
> > > +#include <stdlib.h>
> > > +
> > > +#include <sqlite3.h>
> > > +
> > > +#include "apr_strings.h"
> > > +#include "apr_time.h"
> > > +
> > > +#define MAX_RETRY_COUNT 15
> > > +#define MAX_RETRY_SLEEP 100000
> > > +
> > 
> > I still don't like the 'sleep()' call when it
> cannot
> > get the connection
> > to the database.
> > 
> > 15*1000000 / 1000000 = 1.5 seconds max sleeping
> > 
> > It seems like this is the standard solution for
> > SQLite.  I wish we had a
> > good way to expose this in someway to the caller
> > API.  Some applications
> > will not tolerate a 1.5 second delay.  It also
> makes
> > debugging some
> > types of bugs very hard, since sometimes you will
> > get a reply on the
> > first try, others it could take up to 1.5 seconds.
> > 
> > I guess it is a limitation of the Sqlite library,
> > and there isn't much
> > we can do about it, but I would like a better way
> to
> > control it.
> > 
> > Thoughts/Alternatives?
> > 
> > > +typedef struct apr_dbd_t apr_dbd_t;
> > > +typedef struct apr_dbd_results_t
> > apr_dbd_results_t;
> > > +typedef struct apr_dbd_column_t
> apr_dbd_column_t;
> > > +typedef struct apr_dbd_row_t apr_dbd_row_t;
> > > +typedef struct {
> > > +	int errnum;
> > > +	apr_dbd_t *handle;
> > > +} apr_dbd_transaction_t;
> > > +
> > > +struct apr_dbd_t {
> > > +	sqlite3 *conn;
> > > +	apr_dbd_transaction_t *trans;
> > > +        apr_thread_mutex_t *mutex;
> > > +};
> > > +
> > 
> > Style nit, it should be 4 spaces for indentation.
> No
> > Tabs.  It looks
> > like *mutex is at 8 spaces too.  I think the
> entire
> > file uses tabs...
> > not a huge problem, but before it is committed,
> > someone will have to
> > convert it.
> > 
> > > +struct apr_dbd_row_t {
> > > +	apr_dbd_results_t *res;
> > > +	apr_dbd_column_t **columns;
> > > +	apr_dbd_row_t  *next_row;
> > > +	int rownum;
> > > +} ;
> > > +
> > > +struct apr_dbd_column_t {
> > > +	char *name;
> > > +	char *value;
> > > +	int size;
> > > +	int type;
> > > +} ;
> > > +
> > > +struct apr_dbd_results_t {
> > > +	int random;
> > > +	sqlite3 *handle;
> > > +	sqlite3_stmt *stmt;
> > > +	apr_dbd_row_t *next_row;
> > > +	size_t sz;
> > > +	int tuples;
> > > +} ;
> > > +
> > > +
> > > +
> > > +typedef struct {
> > > +	const char *name;
> > > +	int prepared;
> > > +} apr_dbd_prepared_t;
> > > +
> > > +#define dbd_sqlite3_is_success(x) (((x) ==
> > SQLITE_DONE ) \
> > > +		|| ((x) == SQLITE_OK ))
> > > +
> > > +#define APR_DBD_INTERNAL
> > > +#include "apr_dbd.h"
> > > +
> > > +static int dbd_sqlite3_select(apr_pool_t *pool,
> > apr_dbd_t *sql,
> > > +		apr_dbd_results_t **results,
> > > +		const char *query, int seek)
> > > +{
> > > +	sqlite3_stmt *stmt= NULL;
> > > +	const char   *tail = NULL;
> > > +	int i, ret, retry_count;
> > > +	size_t num_tuples=0;
> > > +	int increment =0;
> > > +        apr_dbd_row_t *row = NULL;
> > > +	apr_dbd_row_t *lastrow = NULL;
> > > +	apr_dbd_column_t *column;
> > > +	
> > > +	char *hold = NULL;
> > > +	
> > > +	apr_thread_mutex_lock(sql->mutex);
> > > +	
> > > +	ret = sqlite3_prepare(sql->conn, query,
> > strlen(query), &stmt, &tail);
> > > +	if(!dbd_sqlite3_is_success(ret)) { 
> > > +	    apr_thread_mutex_unlock(sql->mutex);
> > > +	    return ret;
> > > +	}
> > > +	else {
> > > +		int column_count;
> > > + 		column_count = sqlite3_column_count(stmt);
> > > +		if (!*results) {
> > > +			*results = apr_pcalloc(pool,
> > sizeof(apr_dbd_results_t));
> > > +		}
> > > +		(*results)->stmt = stmt;
> > 
> === message truncated ===> Index:
apr-util/include/apu.h.in
>
===================================================================
> --- apr-util/include/apu.h.in	(revision 164613)
> +++ apr-util/include/apu.h.in	(working copy)
> @@ -79,6 +79,7 @@
>  
>  #define APU_HAVE_PGSQL         @apu_have_pgsql@
>  #define APU_HAVE_MYSQL         @apu_have_mysql@
> +#define APU_HAVE_SQLITE3       @apu_have_sqlite3@
>  #define APU_HAVE_SQLITE2       @apu_have_sqlite2@
>  
>  #define APU_HAVE_APR_ICONV     @have_apr_iconv@
> Index: apr-util/configure.in
>
===================================================================
> --- apr-util/configure.in	(revision 164613)
> +++ apr-util/configure.in	(working copy)
> @@ -120,6 +120,7 @@
>  APU_CHECK_DBM
>  APU_CHECK_DBD
>  APU_CHECK_DBD_MYSQL
> +APU_CHECK_DBD_SQLITE3
>  APU_CHECK_DBD_SQLITE2
>  APU_FIND_EXPAT
>  APU_FIND_ICONV
> Index: apr-util/dbd/apr_dbd_sqlite3.c
>
===================================================================
> --- apr-util/dbd/apr_dbd_sqlite3.c	(revision 0)
> +++ apr-util/dbd/apr_dbd_sqlite3.c	(revision 0)
> @@ -0,0 +1,413 @@
> +/* Copyright 2000-2005 The Apache Software
> Foundation or its licensors, as
> + * applicable.
> + *
> + * Licensed under the Apache License, Version 2.0
> (the "License");
> + * you may not use this file except in compliance
> with the License.
> + * You may obtain a copy of the License at
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to
> in writing, software
> + * distributed under the License is distributed on
> an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
> either express or implied.
> + * See the License for the specific language
> governing permissions and
> + * limitations under the License.
> + */
> +
> +#include "apu.h"
> +
> +#if APU_HAVE_SQLITE3
> +
> +#include <ctype.h>
> +#include <stdlib.h>
> +
> +#include <sqlite3.h>
> +
> +#include "apr_strings.h"
> +#include "apr_time.h"
> +
> +#define MAX_RETRY_COUNT 15
> +#define MAX_RETRY_SLEEP 100000
> +
> +typedef struct apr_dbd_t apr_dbd_t;
> +typedef struct apr_dbd_results_t apr_dbd_results_t;
> +typedef struct apr_dbd_column_t apr_dbd_column_t;
> +typedef struct apr_dbd_row_t apr_dbd_row_t;
> +typedef struct {
> +    int errnum;
> +    apr_dbd_t *handle;
> +} apr_dbd_transaction_t;
> +
> +struct apr_dbd_t {
> +    sqlite3 *conn;
> +    apr_dbd_transaction_t *trans;
> +    apr_thread_mutex_t *mutex;
> +    apr_pool_t *pool;
> +};
> +
> +struct apr_dbd_row_t {
> +    apr_dbd_results_t *res;
> +    apr_dbd_column_t **columns;
> +    apr_dbd_row_t *next_row;
> +    int columnCount;
> +    int rownum;
> +};
> +
> +struct apr_dbd_column_t {
> +    char *name;
> +    char *value;
> +    int size;
> +    int type;
> +};
> +
> +struct apr_dbd_results_t {
> +    int random;
> +    sqlite3 *handle;
> +    sqlite3_stmt *stmt;
> +    apr_dbd_row_t *next_row;
> +    size_t sz;
> +    int tuples;
> +};
> +
> +
> +
> +typedef struct {
> +    const char *name;
> +    int prepared;
> +} apr_dbd_prepared_t;
> +
> +#define dbd_sqlite3_is_success(x) (((x) ==
> SQLITE_DONE ) \
> +		|| ((x) == SQLITE_OK ))
> +
> +#define APR_DBD_INTERNAL
> +#include "apr_dbd.h"
> +
> +static int dbd_sqlite3_select(apr_pool_t * pool,
> apr_dbd_t * sql, apr_dbd_results_t ** results, const
> char *query, int seek)
> +{
> +    sqlite3_stmt *stmt = NULL;
> +    const char *tail = NULL;
> +    int i, ret, retry_count;
> +    size_t num_tuples = 0;
> +    int increment = 0;
> +    apr_dbd_row_t *row = NULL;
> +    apr_dbd_row_t *lastrow = NULL;
> +    apr_dbd_column_t *column;
> +
> +    char *hold = NULL;
> +
> +    apr_thread_mutex_lock(sql->mutex);
> +
> +    ret = sqlite3_prepare(sql->conn, query,
> strlen(query), &stmt, &tail);
> +    if (!dbd_sqlite3_is_success(ret)) {
> +        apr_thread_mutex_unlock(sql->mutex);
> +        return ret;
> +    } else {
> +        int column_count;
> +        column_count = sqlite3_column_count(stmt);
> +        if (!*results) {
> +            *results = apr_pcalloc(pool,
> sizeof(apr_dbd_results_t));
> +        }
> +        (*results)->stmt = stmt;
> +        (*results)->sz = column_count;
> +        (*results)->random = seek;
> +        (*results)->next_row = 0;
> +        (*results)->tuples = 0;
> +        do {
> +            ret = sqlite3_step((*results)->stmt);
> +            if (ret == SQLITE_BUSY) {
> +                if (retry_count++ >
> MAX_RETRY_COUNT) {
> +                    ret = SQLITE_ERROR;
> +                } else {
> +                   
> apr_thread_mutex_unlock(sql->mutex);
> +                    apr_sleep(MAX_RETRY_SLEEP);
> +                }
> +            } else if (ret == SQLITE_ROW) {
> +                int length;
> +                apr_dbd_column_t *col;
> +                row = apr_palloc(pool,
> sizeof(apr_dbd_row_t));
> +                row->res = *results;
> +                row->res->stmt = (*results)->stmt;
> +                increment = sizeof(apr_dbd_column_t
> *);
> +                length = increment *
> (*results)->sz;
> +                row->columns = apr_palloc(pool,
> length);
> +                row->columnCount = column_count;
> +                for (i = 0; i < (*results)->sz;
> i++) {
> +                    column = apr_palloc(pool,
> sizeof(apr_dbd_column_t));
> +                    row->columns[i] = column;
> +                    column->name = (char *)
> sqlite3_column_name((*results)->stmt, i);
> +                    column->size =
> sqlite3_column_bytes((*results)->stmt, i);
> +                    column->type =
> sqlite3_column_type((*results)->stmt, i);
> +                    switch (column->type) {
> +
> +                    case SQLITE_FLOAT:
> +                        break;
> +                    case SQLITE_INTEGER:
> +                    case SQLITE_TEXT:
> +                        hold = NULL;
> +                        hold = (char *)
> sqlite3_column_text((*results)->stmt, i);
> +                        if (hold) {
> +                            column->value =
> apr_palloc(pool, column->size + 1);
> +                            strncpy(column->value,
> hold, column->size + 1);
> +                        }
> +                        break;
> +                    case SQLITE_BLOB:
> +                        break;
> +                    case SQLITE_NULL:
> +                        break;
> +                    }
> +                    col = row->columns[i];
> +                }
> +                row->rownum = num_tuples++;
> +                row->next_row = 0;
> +                (*results)->tuples = num_tuples;
> +                if ((*results)->next_row == 0) {
> +                    (*results)->next_row = row;
> +                }
> +                if (lastrow != 0) {
> +                    lastrow->next_row = row;
> +                }
> +                lastrow = row;
> +            } else if (ret == SQLITE_DONE) {
> +                ret = SQLITE_OK;
> +            }
> +        } while (ret == SQLITE_ROW || ret ==
> SQLITE_BUSY);
> +    }
> +    ret = sqlite3_finalize(stmt);
> +    apr_thread_mutex_unlock(sql->mutex);
> +    return ret;
> +}
> +
> +static int dbd_sqlite3_get_row(apr_pool_t * pool,
> apr_dbd_results_t * res, apr_dbd_row_t ** rowp, int
> rownum)
> +{
> +    int ret, retry_count, i = 0;
> +    apr_dbd_row_t *row;
> +    if (rownum == -1) {
> +        *rowp = res->next_row;
> +        if (*rowp == 0)
> +            return -1;
> +        res->next_row = (*rowp)->next_row;
> +        return 0;
> +    }
> +    if (rownum > res->tuples) {
> +        return -1;
> +    }
> +    *rowp = res->next_row;
> +    for (; *rowp != 0; i++, *rowp =
> (*rowp)->next_row) {
> +        if (i == rownum) {
> +            return 0;
> +        }
> +    }
> +
> +    return -1;
> +
> +}
> +
> +static const char *dbd_sqlite3_get_entry(const
> apr_dbd_row_t * row, int n)
> +{
> +    apr_dbd_column_t *column;
> +    const char *value;
> +    if ((n + 1) > row->columnCount) {
> +        return NULL;
> +    }
> +    column = row->columns[n];
> +    value = column->value;
> +    return value;
> +}
> +
> +static const char *dbd_sqlite3_error(apr_dbd_t *
> sql, int n)
> +{
> +    return sqlite3_errmsg(sql->conn);
> +}
> +
> +static int dbd_sqlite3_query(apr_dbd_t * sql, int
> *nrows, const char *query)
> +{
> +    sqlite3_stmt *stmt = NULL;
> +    const char *tail = NULL;
> +    int ret, retry_count = 0, length = 0;
> +    apr_status_t res;
> +    apr_pool_t *pool;
> +
> +    res = apr_pool_create(&pool, sql->pool);
> +    if (res != APR_SUCCESS) {
> +        return SQLITE_ERROR;
> +    }
> +    length = strlen(query);
> +    apr_thread_mutex_lock(sql->mutex);
> +
> +    do {
> +        ret = sqlite3_prepare(sql->conn, query,
> length, &stmt, &tail);
> +        if (ret != SQLITE_OK) {
> +            sqlite3_finalize(stmt);
> +            apr_thread_mutex_unlock(sql->mutex);
> +            return ret;
> +        }
> +
> +        ret = sqlite3_step(stmt);
> +        *nrows = sqlite3_changes(sql->conn);
> +        sqlite3_finalize(stmt);
> +        length -= (tail - query);
> +        query = tail;
> +    } while (length > 0);
> +
> +    if (dbd_sqlite3_is_success(ret)) {
> +        ret = 0;
> +    }
> +    apr_thread_mutex_unlock(sql->mutex);
> +    apr_pool_destroy(pool);
> +    return ret;
> +}
> +
> +static const char *dbd_sqlite3_escape(apr_pool_t *
> pool, const char *arg, apr_dbd_t * sql)
> +{
> +    char *ret = sqlite3_mprintf(arg);
> +    apr_pool_cleanup_register(pool, ret, (void *)
> sqlite3_free, apr_pool_cleanup_null);
> +    return ret;
> +}
> +
> +static int dbd_sqlite3_prepare(apr_pool_t * pool,
> apr_dbd_t * sql,
> +                               const char *query,
> const char *label, apr_dbd_prepared_t ** statement)
> +{
> +    return APR_ENOTIMPL;
> +}
> +
> +static int dbd_sqlite3_pquery(apr_pool_t * pool,
> apr_dbd_t * sql,
> +                              int *nrows,
> apr_dbd_prepared_t * statement, int nargs, const
> char **values)
> +{
> +    return APR_ENOTIMPL;
> +}
> +
> +static int dbd_sqlite3_pvquery(apr_pool_t * pool,
> apr_dbd_t * sql, int *nrows, apr_dbd_prepared_t *
> statement, ...)
> +{
> +    return APR_ENOTIMPL;
> +}
> +
> +static int dbd_sqlite3_pselect(apr_pool_t * pool,
> apr_dbd_t * sql,
> +                               apr_dbd_results_t **
> results,
> +                               apr_dbd_prepared_t *
> statement, int seek, int nargs, const char **values)
> +{
> +    return APR_ENOTIMPL;
> +}
> +
> +static int dbd_sqlite3_pvselect(apr_pool_t * pool,
> apr_dbd_t * sql,
> +                                apr_dbd_results_t
> ** results, apr_dbd_prepared_t * statement, int
> seek, ...)
> +{
> +    return APR_ENOTIMPL;
> +}
> +
> +static int dbd_sqlite3_start_transaction(apr_pool_t
> * pool, apr_dbd_t * handle, apr_dbd_transaction_t **
> trans)
> +{
> +    int ret = 0;
> +    int nrows = 0;
> +
> +    ret = dbd_sqlite3_query(handle, &nrows, "BEGIN
> TRANSACTION;");
> +    if (!*trans) {
> +        *trans = apr_pcalloc(pool,
> sizeof(apr_dbd_transaction_t));
> +        (*trans)->handle = handle;
> +        handle->trans = *trans;
> +    }
> +
> +    return ret;
> +}
> +
> +static int
> dbd_sqlite3_end_transaction(apr_dbd_transaction_t *
> trans)
> +{
> +    int ret = 0;
> +    int nrows = 0;
> +
> +    if (trans) {
> +        ret = dbd_sqlite3_query(trans->handle,
> &nrows, "END TRANSACTION;");
> +        if (trans->errnum) {
> +            trans->errnum = 0;
> +            ret = dbd_sqlite3_query(trans->handle,
> &nrows, "ROLLBACK;");
> +        } else {
> +            ret = dbd_sqlite3_query(trans->handle,
> &nrows, "COMMIT;");
> +        }
> +        trans->handle->trans = NULL;
> +    }
> +
> +    return ret;
> +}
> +
> +static apr_dbd_t *dbd_sqlite3_open(apr_pool_t *
> pool, const char *params)
> +{
> +    apr_dbd_t *sql = NULL;
> +    sqlite3 *conn = NULL;
> +    apr_status_t res;
> +    int sqlres;
> +    if (!params)
> +        return NULL;
> +    sqlres = sqlite3_open(params, &conn);
> +    if (sqlres != SQLITE_OK) {
> +        sqlite3_close(conn);
> +        return NULL;
> +    }
> +    /* should we register rand or power functions
> to the sqlite VM? */
> +    sql = apr_pcalloc(pool, sizeof(*sql));
> +    sql->conn = conn;
> +    sql->pool = pool;
> +    /* Create a mutex */
> +    res = apr_thread_mutex_create(&sql->mutex,
> APR_THREAD_MUTEX_DEFAULT, pool);
> +    if (res != APR_SUCCESS) {
> +        return NULL;
> +    }
> +
> +    return sql;
> +}
> +
> +static apr_status_t dbd_sqlite3_close(apr_dbd_t *
> handle)
> +{
> +    sqlite3_close(handle->conn);
> +    apr_thread_mutex_destroy(handle->mutex);
> +    return APR_SUCCESS;
> +}
> +
> +static apr_status_t
> dbd_sqlite3_check_conn(apr_pool_t * pool, apr_dbd_t
> * handle)
> +{
> +    return (handle->conn != NULL) ? APR_SUCCESS :
> APR_EGENERAL;
> +}
> +
> +static int dbd_sqlite3_select_db(apr_pool_t * pool,
> apr_dbd_t * handle, const char *name)
> +{
> +    return APR_ENOTIMPL;
> +}
> +
> +static void *dbd_sqlite3_native(apr_dbd_t * handle)
> +{
> +    return handle->conn;
> +}
> +
> +static int dbd_sqlite3_num_cols(apr_dbd_results_t *
> res)
> +{
> +    return res->sz;
> +}
> +
> +static int dbd_sqlite3_num_tuples(apr_dbd_results_t
> * res)
> +{
> +    return res->tuples;
> +}
> +
> +APU_DECLARE_DATA const apr_dbd_driver_t
> apr_dbd_sqlite3_driver = {
> +    "sqlite3",
> +    NULL,
> +    dbd_sqlite3_native,
> +    dbd_sqlite3_open,
> +    dbd_sqlite3_check_conn,
> +    dbd_sqlite3_close,
> +    dbd_sqlite3_select_db,
> +    dbd_sqlite3_start_transaction,
> +    dbd_sqlite3_end_transaction,
> +    dbd_sqlite3_query,
> +    dbd_sqlite3_select,
> +    dbd_sqlite3_num_cols,
> +    dbd_sqlite3_num_tuples,
> +    dbd_sqlite3_get_row,
> +    dbd_sqlite3_get_entry,
> +    dbd_sqlite3_error,
> +    dbd_sqlite3_escape,
> +    dbd_sqlite3_prepare,
> +    dbd_sqlite3_pvquery,
> +    dbd_sqlite3_pvselect,
> +    dbd_sqlite3_pquery,
> +    dbd_sqlite3_pselect,
> +};
> +#endif
> Index: apr-util/dbd/apr_dbd.c
>
===================================================================
> --- apr-util/dbd/apr_dbd.c	(revision 164613)
> +++ apr-util/dbd/apr_dbd.c	(working copy)
> @@ -68,6 +68,9 @@
>  #if APU_HAVE_PGSQL
>      DRIVER_LOAD("pgsql", apr_dbd_pgsql_driver,
> pool);
>  #endif
> +#if APU_HAVE_SQLITE3
> +    DRIVER_LOAD("sqlite3", apr_dbd_sqlite3_driver,
> pool);
> +#endif
>  #if APU_HAVE_SQLITE2
>      DRIVER_LOAD("sqlite2", apr_dbd_sqlite2_driver,
> pool);
>  #endif
> @@ -135,6 +138,7 @@
>                                         apr_pool_t
> *pool, const char *params,
>                                         apr_dbd_t
> **handle)
>  {
> +
>      *handle = driver->open(pool, params);
>      if (*handle == NULL) {
>          return APR_EGENERAL;
> Index: apr-util/build/dbd.m4
>
===================================================================
> --- apr-util/build/dbd.m4	(revision 164613)
> +++ apr-util/build/dbd.m4	(working copy)
> @@ -119,6 +119,44 @@
>      APR_ADDTO(APRUTIL_LIBS,[-lmysqlclient_r])
>    fi
>  ])
> +dnl
> +AC_DEFUN([APU_CHECK_DBD_SQLITE3], [
> +  apu_have_sqlite3=0
> +
> +  AC_ARG_WITH([sqlite3], [
> +  --with-sqlite3=DIR         
> +  ], [
> +    apu_have_sqlite3=0
> +    if test "$withval" = "yes"; then
> +      AC_CHECK_HEADER(sqlite3.h,
> AC_CHECK_LIB(sqlite3, sqlite3_open,
> [apu_have_sqlite3=1]))
> +    elif test "$withval" = "no"; then
> +      apu_have_sqlite3=0
> +    else
> +      CPPFLAGS="-I$withval/include"
> +      LIBS="-L$withval/lib "
> +
> +      AC_MSG_NOTICE(checking for sqlite3 in
> $withval)
> +      AC_CHECK_HEADER(sqlite3.h,
> AC_CHECK_LIB(sqlite3, sqlite3_open,
> [apu_have_sqlite3=1]))
> +      if test "$apu_have_sqlite3" != "0"; then
> +        APR_ADDTO(APRUTIL_LDFLAGS,
> [-L$withval/lib])
> +        APR_ADDTO(APRUTIL_INCLUDES,
> [-I$withval/include])
> +      fi
> +    fi
> +  ], [
> +    apu_have_sqlite3=0
> +    AC_CHECK_HEADER(sqlite3.h,
> AC_CHECK_LIB(sqlite3, sqlite3_open,
> [apu_have_sqlite3=1]))
> +  ])
> +
> +  AC_SUBST(apu_have_sqlite3)
> +
> +  dnl Since we have already done the AC_CHECK_LIB
> tests, if we have it, 
> +  dnl we know the library is there.
> +  if test "$apu_have_sqlite3" = "1"; then
> +    APR_ADDTO(APRUTIL_EXPORT_LIBS,[-lsqlite3])
> +    APR_ADDTO(APRUTIL_LIBS,[-lsqlite3])
> +  fi
> +])
> +dnl
>  AC_DEFUN([APU_CHECK_DBD_SQLITE2], [
>    apu_have_sqlite2=0
>  
> 

Mime
View raw message