[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Monotone-devel] Re: [PATCH] Updated Typesafe VA_ARGS replacement for da
From: |
Vinzenz 'evilissimo' Feenstra |
Subject: |
[Monotone-devel] Re: [PATCH] Updated Typesafe VA_ARGS replacement for database::execute/fetch |
Date: |
Thu, 19 Jan 2006 12:15:24 +0100 |
User-agent: |
Thunderbird 1.5 (Windows/20051201) |
Just removed the nasty ifndef directive which was added for testing purposes
BR
Vinzenz
// -*- mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil -*-
// vim:et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
#ifndef __QUERY_ARGS_HH__
#define __QUERY_ARGS_HH__ 1
// copyright (C) 2006 vinzenz feenstra <address@hidden>
// all rights reserved.
// licensed to the public under the terms of the GNU GPL (>= 2)
// see the file COPYING for details
#include <string>
#include <utility>
struct sqlite3_stmt;
struct sqlite3;
struct query_args
{
struct blob
{
explicit blob( void const * data , size_t size );
explicit blob( char const * data , size_t size );
explicit blob( std::string const & data );
void const * get_data() const;
size_t const get_size() const;
private:
void const * data_p;
size_t data_size;
};
struct text
{
explicit text( char const * str , size_t size );
explicit text( std::string const & str );
char const * get_text() const;
size_t const get_size() const;
private:
char const * str_p;
size_t data_size;
};
explicit query_args( sqlite3 * db_handle , std::string const & sql_query );
~query_args();
query_args & operator%( blob const & bin );
query_args & operator%( text const & txt );
// Retrieving the statement
// If release is true we don't care anymore whether
// the statement will be cleared anywhere else
sqlite3_stmt * get_statement(bool release = true);
std::string const & get_query() const;
private:
void internal_assert();
protected:
sqlite3_stmt * stmt;
int params_needed;
int last_param_nr;
std::string query;
static bool already_instantiated;
};
#endif // __QUERY_ARGS_HH__
// -*- mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil -*-
// vim:et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
// copyright (C) 2006 vinzenz feenstra <address@hidden>
// all rights reserved.
// licensed to the public under the terms of the GNU GPL (>= 2)
// see the file COPYING for details
#include "sqlite3.h"
#include "query_args.hh"
bool query_args::already_instantiated = false;
query_args::blob::blob( void const * data , size_t size )
:data_p(data),data_size(size)
{}
query_args::blob::blob( char const * data , size_t size )
:data_p(data),data_size(size)
{}
query_args::blob::blob( std::string const & data )
:data_p(data.c_str()),data_size(data.size())
{}
void const * query_args::blob::get_data() const
{
return data_p;
}
size_t const query_args::blob::get_size() const
{
return data_size;
}
query_args::text::text( char const * str , size_t size )
:str_p(str),data_size(size)
{}
query_args::text::text( std::string const & str )
:str_p(str.c_str()),data_size(str.size())
{}
char const * query_args::text::get_text() const
{
return str_p;
}
size_t const query_args::text::get_size() const
{
return data_size;
}
query_args::query_args( sqlite3 * db_handle , std::string const & sql_query )
:stmt(0),
params_needed(0),
last_param_nr(1),
query(sql_query)
{
I(!already_instantiated);
already_instantiated = true;
char const * tail = 0;
sqlite3_prepare(db_handle, query.c_str() , -1, &stmt , &tail);
internal_assert();
L(F("prepared statement %s\n") % query);
// no support for multiple statements here
E(*tail == 0,
F("multiple statements in query: %s\n") % query);
params_needed = sqlite3_bind_parameter_count(stmt);
}
query_args::~query_args()
{
// if the statement still exists we're cleaning it
// since the database can't be closed properly if it
// is still opened
if(stmt)
{
L("Resetting sqlite3_statement");
sqlite3_reset(stmt);
L("Finalizing sqlite3_statement");
sqlite3_finalize(stmt) != SQLITE_OK
}
already_instantiated = false;
}
std::string const & query_args::get_query() const
{
return query;
}
sqlite3_stmt * query_args::get_statement( bool release )
{
// Ensure that we have all params needed, otherwise
I( params_needed == last_param_nr );
// Retrieving the statement
// If release is true we don't care anymore whether
// the statement will be cleared anywhere else
if(release)
{
L("Returning statement and releasing the ownership of the sqlite3_stmt
pointer");
sqlite3_stmt * tmp = stmt;
stmt = 0;
return tmp;
}
// returning the statement and keep ownership of the
// statement
L("Returning statement and keeping the ownership of the sqlite3_stmt
pointer");
return stmt;
}
query_args & query_args::operator%( blob const & bin )
{
L( F("Binding argument %d of %d as BLOB, with Value %s") % last_param_nr %
params_needed % (char const*)bin.get_data() );
if(stmt)
{
sqlite3_bind_blob(stmt,last_param_nr++,bin.get_data(),bin.get_size(),SQLITE_TRANSIENT);
internal_assert();
}
return *this;
}
// as TEXT
query_args & query_args::operator%( text const & txt )
{
L( F("Binding argument %d of %d as TEXT, with Value %s") % last_param_nr %
params_needed % txt.get_text() );
if(stmt)
{
sqlite3_bind_text(stmt,last_param_nr++,txt.get_text(),int(txt.get_size()),SQLITE_TRANSIENT);
internal_assert();
}
return *this;
}
void query_args::internal_assert()
{
sqlite3 * s = sqlite3_db_handle(stmt);
int errcode = sqlite3_errcode(s);
if (errcode == SQLITE_OK) return;
const char * errmsg = sqlite3_errmsg(s);
// sometimes sqlite is not very helpful
// so we keep a table of errors people have gotten and more helpful versions
if (errcode != SQLITE_OK)
{
// first log the code so we can find _out_ what the confusing code
// was... note that code does not uniquely identify the errmsg, unlike
// errno's.
L(F("sqlite error: %d: %s") % errcode % errmsg);
}
std::string auxiliary_message = "";
if (errcode == SQLITE_ERROR)
{
auxiliary_message = _("make sure database and containing directory are
writeable");
}
// if the last message is empty, the \n will be stripped off too
E(errcode == SQLITE_OK,
// kind of string surgery to avoid ~duplicate strings
boost::format("%s\n%s")
% (F("sqlite error: %d: %s") % errcode % errmsg).str()
% auxiliary_message);
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Monotone-devel] Re: [PATCH] Updated Typesafe VA_ARGS replacement for database::execute/fetch,
Vinzenz 'evilissimo' Feenstra <=