2006-06-13 19:24:47 -03:00
/* module.c - the module itself
*
* Copyright ( C ) 2004 - 2006 Gerhard H <EFBFBD> ring < gh @ ghaering . de >
*
* This file is part of pysqlite .
*
* This software is provided ' as - is ' , without any express or implied
* warranty . In no event will the authors be held liable for any damages
* arising from the use of this software .
*
* Permission is granted to anyone to use this software for any purpose ,
* including commercial applications , and to alter it and redistribute it
* freely , subject to the following restrictions :
*
* 1. The origin of this software must not be misrepresented ; you must not
* claim that you wrote the original software . If you use this software
* in a product , an acknowledgment in the product documentation would be
* appreciated but is not required .
* 2. Altered source versions must be plainly marked as such , and must not be
* misrepresented as being the original software .
* 3. This notice may not be removed or altered from any source distribution .
*/
2006-03-31 20:57:31 -04:00
# include "connection.h"
# include "statement.h"
# include "cursor.h"
# include "cache.h"
# include "prepare_protocol.h"
# include "microprotocols.h"
# include "row.h"
# if SQLITE_VERSION_NUMBER >= 3003003
# define HAVE_SHARED_CACHE
# endif
/* static objects at module-level */
2007-01-13 21:43:50 -04:00
PyObject * pysqlite_Error , * pysqlite_Warning , * pysqlite_InterfaceError , * pysqlite_DatabaseError ,
* pysqlite_InternalError , * pysqlite_OperationalError , * pysqlite_ProgrammingError ,
* pysqlite_IntegrityError , * pysqlite_DataError , * pysqlite_NotSupportedError , * pysqlite_OptimizedUnicode ;
2006-03-31 20:57:31 -04:00
PyObject * converters ;
2006-06-13 19:24:47 -03:00
int _enable_callback_tracebacks ;
2006-03-31 20:57:31 -04:00
static PyObject * module_connect ( PyObject * self , PyObject * args , PyObject *
kwargs )
{
/* Python seems to have no way of extracting a single keyword-arg at
* C - level , so this code is redundant with the one in connection_init in
* connection . c and must always be copied from there . . . */
static char * kwlist [ ] = { " database " , " timeout " , " detect_types " , " isolation_level " , " check_same_thread " , " factory " , " cached_statements " , NULL , NULL } ;
char * database ;
int detect_types = 0 ;
PyObject * isolation_level ;
PyObject * factory = NULL ;
int check_same_thread = 1 ;
int cached_statements ;
double timeout = 5.0 ;
PyObject * result ;
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " s|diOiOi " , kwlist ,
& database , & timeout , & detect_types , & isolation_level , & check_same_thread , & factory , & cached_statements ) )
{
return NULL ;
}
if ( factory = = NULL ) {
2007-01-13 21:43:50 -04:00
factory = ( PyObject * ) & pysqlite_ConnectionType ;
2006-03-31 20:57:31 -04:00
}
result = PyObject_Call ( factory , args , kwargs ) ;
return result ;
}
static PyObject * module_complete ( PyObject * self , PyObject * args , PyObject *
kwargs )
{
static char * kwlist [ ] = { " statement " , NULL , NULL } ;
char * statement ;
PyObject * result ;
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " s " , kwlist , & statement ) )
{
return NULL ;
}
if ( sqlite3_complete ( statement ) ) {
result = Py_True ;
} else {
result = Py_False ;
}
Py_INCREF ( result ) ;
return result ;
}
# ifdef HAVE_SHARED_CACHE
static PyObject * module_enable_shared_cache ( PyObject * self , PyObject * args , PyObject *
kwargs )
{
static char * kwlist [ ] = { " do_enable " , NULL , NULL } ;
int do_enable ;
int rc ;
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " i " , kwlist , & do_enable ) )
{
return NULL ;
}
rc = sqlite3_enable_shared_cache ( do_enable ) ;
if ( rc ! = SQLITE_OK ) {
2007-01-13 21:43:50 -04:00
PyErr_SetString ( pysqlite_OperationalError , " Changing the shared_cache flag failed " ) ;
2006-03-31 20:57:31 -04:00
return NULL ;
} else {
Py_INCREF ( Py_None ) ;
return Py_None ;
}
}
# endif /* HAVE_SHARED_CACHE */
static PyObject * module_register_adapter ( PyObject * self , PyObject * args , PyObject * kwargs )
{
PyTypeObject * type ;
PyObject * caster ;
if ( ! PyArg_ParseTuple ( args , " OO " , & type , & caster ) ) {
return NULL ;
}
2007-01-13 21:43:50 -04:00
microprotocols_add ( type , ( PyObject * ) & pysqlite_PrepareProtocolType , caster ) ;
2006-03-31 20:57:31 -04:00
Py_INCREF ( Py_None ) ;
return Py_None ;
}
static PyObject * module_register_converter ( PyObject * self , PyObject * args , PyObject * kwargs )
{
2007-01-13 21:43:50 -04:00
PyObject * orig_name ;
PyObject * name = NULL ;
2006-03-31 20:57:31 -04:00
PyObject * callable ;
2006-06-13 19:24:47 -03:00
PyObject * retval = NULL ;
2006-03-31 20:57:31 -04:00
2007-01-13 21:43:50 -04:00
if ( ! PyArg_ParseTuple ( args , " SO " , & orig_name , & callable ) ) {
2006-03-31 20:57:31 -04:00
return NULL ;
}
2007-01-13 21:43:50 -04:00
/* convert the name to upper case */
name = PyObject_CallMethod ( orig_name , " upper " , " " ) ;
2006-06-13 19:24:47 -03:00
if ( ! name ) {
goto error ;
}
2007-01-13 21:43:50 -04:00
if ( PyDict_SetItem ( converters , name , callable ) ! = 0 ) {
2006-06-13 19:24:47 -03:00
goto error ;
}
Py_INCREF ( Py_None ) ;
retval = Py_None ;
error :
2007-01-13 21:43:50 -04:00
Py_XDECREF ( name ) ;
2006-06-13 19:24:47 -03:00
return retval ;
}
static PyObject * enable_callback_tracebacks ( PyObject * self , PyObject * args , PyObject * kwargs )
{
if ( ! PyArg_ParseTuple ( args , " i " , & _enable_callback_tracebacks ) ) {
2006-04-04 03:29:05 -03:00
return NULL ;
}
2006-03-31 20:57:31 -04:00
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2007-01-13 21:43:50 -04:00
static void converters_init ( PyObject * dict )
2006-03-31 20:57:31 -04:00
{
converters = PyDict_New ( ) ;
2006-04-04 03:29:05 -03:00
if ( ! converters ) {
return ;
}
2006-03-31 20:57:31 -04:00
PyDict_SetItemString ( dict , " converters " , converters ) ;
}
static PyMethodDef module_methods [ ] = {
{ " connect " , ( PyCFunction ) module_connect , METH_VARARGS | METH_KEYWORDS , PyDoc_STR ( " Creates a connection. " ) } ,
2006-04-23 12:24:26 -03:00
{ " complete_statement " , ( PyCFunction ) module_complete , METH_VARARGS | METH_KEYWORDS , PyDoc_STR ( " Checks if a string contains a complete SQL statement. Non-standard. " ) } ,
2006-03-31 20:57:31 -04:00
# ifdef HAVE_SHARED_CACHE
2006-04-23 12:24:26 -03:00
{ " enable_shared_cache " , ( PyCFunction ) module_enable_shared_cache , METH_VARARGS | METH_KEYWORDS , PyDoc_STR ( " Enable or disable shared cache mode for the calling thread. Experimental/Non-standard. " ) } ,
2006-03-31 20:57:31 -04:00
# endif
2006-04-23 12:24:26 -03:00
{ " register_adapter " , ( PyCFunction ) module_register_adapter , METH_VARARGS , PyDoc_STR ( " Registers an adapter with pysqlite's adapter registry. Non-standard. " ) } ,
{ " register_converter " , ( PyCFunction ) module_register_converter , METH_VARARGS , PyDoc_STR ( " Registers a converter with pysqlite. Non-standard. " ) } ,
2006-03-31 20:57:31 -04:00
{ " adapt " , ( PyCFunction ) psyco_microprotocols_adapt , METH_VARARGS , psyco_microprotocols_adapt_doc } ,
2006-06-13 19:24:47 -03:00
{ " enable_callback_tracebacks " , ( PyCFunction ) enable_callback_tracebacks , METH_VARARGS , PyDoc_STR ( " Enable or disable callback functions throwing errors to stderr. " ) } ,
2006-03-31 20:57:31 -04:00
{ NULL , NULL }
} ;
2006-06-13 19:24:47 -03:00
struct _IntConstantPair {
char * constant_name ;
int constant_value ;
} ;
typedef struct _IntConstantPair IntConstantPair ;
static IntConstantPair _int_constants [ ] = {
{ " PARSE_DECLTYPES " , PARSE_DECLTYPES } ,
{ " PARSE_COLNAMES " , PARSE_COLNAMES } ,
{ " SQLITE_OK " , SQLITE_OK } ,
{ " SQLITE_DENY " , SQLITE_DENY } ,
{ " SQLITE_IGNORE " , SQLITE_IGNORE } ,
{ " SQLITE_CREATE_INDEX " , SQLITE_CREATE_INDEX } ,
{ " SQLITE_CREATE_TABLE " , SQLITE_CREATE_TABLE } ,
{ " SQLITE_CREATE_TEMP_INDEX " , SQLITE_CREATE_TEMP_INDEX } ,
{ " SQLITE_CREATE_TEMP_TABLE " , SQLITE_CREATE_TEMP_TABLE } ,
{ " SQLITE_CREATE_TEMP_TRIGGER " , SQLITE_CREATE_TEMP_TRIGGER } ,
{ " SQLITE_CREATE_TEMP_VIEW " , SQLITE_CREATE_TEMP_VIEW } ,
{ " SQLITE_CREATE_TRIGGER " , SQLITE_CREATE_TRIGGER } ,
{ " SQLITE_CREATE_VIEW " , SQLITE_CREATE_VIEW } ,
{ " SQLITE_DELETE " , SQLITE_DELETE } ,
{ " SQLITE_DROP_INDEX " , SQLITE_DROP_INDEX } ,
{ " SQLITE_DROP_TABLE " , SQLITE_DROP_TABLE } ,
{ " SQLITE_DROP_TEMP_INDEX " , SQLITE_DROP_TEMP_INDEX } ,
{ " SQLITE_DROP_TEMP_TABLE " , SQLITE_DROP_TEMP_TABLE } ,
{ " SQLITE_DROP_TEMP_TRIGGER " , SQLITE_DROP_TEMP_TRIGGER } ,
{ " SQLITE_DROP_TEMP_VIEW " , SQLITE_DROP_TEMP_VIEW } ,
{ " SQLITE_DROP_TRIGGER " , SQLITE_DROP_TRIGGER } ,
{ " SQLITE_DROP_VIEW " , SQLITE_DROP_VIEW } ,
{ " SQLITE_INSERT " , SQLITE_INSERT } ,
{ " SQLITE_PRAGMA " , SQLITE_PRAGMA } ,
{ " SQLITE_READ " , SQLITE_READ } ,
{ " SQLITE_SELECT " , SQLITE_SELECT } ,
{ " SQLITE_TRANSACTION " , SQLITE_TRANSACTION } ,
{ " SQLITE_UPDATE " , SQLITE_UPDATE } ,
{ " SQLITE_ATTACH " , SQLITE_ATTACH } ,
{ " SQLITE_DETACH " , SQLITE_DETACH } ,
# if SQLITE_VERSION_NUMBER >= 3002001
{ " SQLITE_ALTER_TABLE " , SQLITE_ALTER_TABLE } ,
{ " SQLITE_REINDEX " , SQLITE_REINDEX } ,
# endif
# if SQLITE_VERSION_NUMBER >= 3003000
{ " SQLITE_ANALYZE " , SQLITE_ANALYZE } ,
# endif
{ ( char * ) NULL , 0 }
} ;
2006-03-31 20:57:31 -04:00
PyMODINIT_FUNC init_sqlite3 ( void )
{
PyObject * module , * dict ;
2006-04-04 03:29:05 -03:00
PyObject * tmp_obj ;
2006-06-13 19:24:47 -03:00
int i ;
2006-03-31 20:57:31 -04:00
module = Py_InitModule ( " _sqlite3 " , module_methods ) ;
2006-04-04 03:29:05 -03:00
if ( ! module | |
2007-01-13 21:43:50 -04:00
( pysqlite_row_setup_types ( ) < 0 ) | |
( pysqlite_cursor_setup_types ( ) < 0 ) | |
( pysqlite_connection_setup_types ( ) < 0 ) | |
( pysqlite_cache_setup_types ( ) < 0 ) | |
( pysqlite_statement_setup_types ( ) < 0 ) | |
( pysqlite_prepare_protocol_setup_types ( ) < 0 )
2006-03-31 20:57:31 -04:00
) {
return ;
}
2007-01-13 21:43:50 -04:00
Py_INCREF ( & pysqlite_ConnectionType ) ;
PyModule_AddObject ( module , " Connection " , ( PyObject * ) & pysqlite_ConnectionType ) ;
Py_INCREF ( & pysqlite_CursorType ) ;
PyModule_AddObject ( module , " Cursor " , ( PyObject * ) & pysqlite_CursorType ) ;
Py_INCREF ( & pysqlite_CacheType ) ;
PyModule_AddObject ( module , " Statement " , ( PyObject * ) & pysqlite_StatementType ) ;
Py_INCREF ( & pysqlite_StatementType ) ;
PyModule_AddObject ( module , " Cache " , ( PyObject * ) & pysqlite_CacheType ) ;
Py_INCREF ( & pysqlite_PrepareProtocolType ) ;
PyModule_AddObject ( module , " PrepareProtocol " , ( PyObject * ) & pysqlite_PrepareProtocolType ) ;
Py_INCREF ( & pysqlite_RowType ) ;
PyModule_AddObject ( module , " Row " , ( PyObject * ) & pysqlite_RowType ) ;
2006-03-31 20:57:31 -04:00
2006-04-04 03:29:05 -03:00
if ( ! ( dict = PyModule_GetDict ( module ) ) ) {
2006-03-31 20:57:31 -04:00
goto error ;
}
/*** Create DB-API Exception hierarchy */
2007-01-13 21:43:50 -04:00
if ( ! ( pysqlite_Error = PyErr_NewException ( MODULE_NAME " .Error " , PyExc_StandardError , NULL ) ) ) {
2006-04-04 03:29:05 -03:00
goto error ;
}
2007-01-13 21:43:50 -04:00
PyDict_SetItemString ( dict , " Error " , pysqlite_Error ) ;
2006-03-31 20:57:31 -04:00
2007-01-13 21:43:50 -04:00
if ( ! ( pysqlite_Warning = PyErr_NewException ( MODULE_NAME " .Warning " , PyExc_StandardError , NULL ) ) ) {
2006-04-04 03:29:05 -03:00
goto error ;
}
2007-01-13 21:43:50 -04:00
PyDict_SetItemString ( dict , " Warning " , pysqlite_Warning ) ;
2006-03-31 20:57:31 -04:00
/* Error subclasses */
2007-01-13 21:43:50 -04:00
if ( ! ( pysqlite_InterfaceError = PyErr_NewException ( MODULE_NAME " .InterfaceError " , pysqlite_Error , NULL ) ) ) {
2006-04-04 03:29:05 -03:00
goto error ;
}
2007-01-13 21:43:50 -04:00
PyDict_SetItemString ( dict , " InterfaceError " , pysqlite_InterfaceError ) ;
2006-03-31 20:57:31 -04:00
2007-01-13 21:43:50 -04:00
if ( ! ( pysqlite_DatabaseError = PyErr_NewException ( MODULE_NAME " .DatabaseError " , pysqlite_Error , NULL ) ) ) {
2006-04-04 03:29:05 -03:00
goto error ;
}
2007-01-13 21:43:50 -04:00
PyDict_SetItemString ( dict , " DatabaseError " , pysqlite_DatabaseError ) ;
2006-03-31 20:57:31 -04:00
2007-01-13 21:43:50 -04:00
/* pysqlite_DatabaseError subclasses */
2006-03-31 20:57:31 -04:00
2007-01-13 21:43:50 -04:00
if ( ! ( pysqlite_InternalError = PyErr_NewException ( MODULE_NAME " .InternalError " , pysqlite_DatabaseError , NULL ) ) ) {
2006-04-04 03:29:05 -03:00
goto error ;
}
2007-01-13 21:43:50 -04:00
PyDict_SetItemString ( dict , " InternalError " , pysqlite_InternalError ) ;
2006-03-31 20:57:31 -04:00
2007-01-13 21:43:50 -04:00
if ( ! ( pysqlite_OperationalError = PyErr_NewException ( MODULE_NAME " .OperationalError " , pysqlite_DatabaseError , NULL ) ) ) {
2006-04-04 03:29:05 -03:00
goto error ;
}
2007-01-13 21:43:50 -04:00
PyDict_SetItemString ( dict , " OperationalError " , pysqlite_OperationalError ) ;
2006-03-31 20:57:31 -04:00
2007-01-13 21:43:50 -04:00
if ( ! ( pysqlite_ProgrammingError = PyErr_NewException ( MODULE_NAME " .ProgrammingError " , pysqlite_DatabaseError , NULL ) ) ) {
2006-04-04 03:29:05 -03:00
goto error ;
}
2007-01-13 21:43:50 -04:00
PyDict_SetItemString ( dict , " ProgrammingError " , pysqlite_ProgrammingError ) ;
2006-03-31 20:57:31 -04:00
2007-01-13 21:43:50 -04:00
if ( ! ( pysqlite_IntegrityError = PyErr_NewException ( MODULE_NAME " .IntegrityError " , pysqlite_DatabaseError , NULL ) ) ) {
2006-04-04 03:29:05 -03:00
goto error ;
}
2007-01-13 21:43:50 -04:00
PyDict_SetItemString ( dict , " IntegrityError " , pysqlite_IntegrityError ) ;
2006-03-31 20:57:31 -04:00
2007-01-13 21:43:50 -04:00
if ( ! ( pysqlite_DataError = PyErr_NewException ( MODULE_NAME " .DataError " , pysqlite_DatabaseError , NULL ) ) ) {
2006-04-04 03:29:05 -03:00
goto error ;
}
2007-01-13 21:43:50 -04:00
PyDict_SetItemString ( dict , " DataError " , pysqlite_DataError ) ;
2006-03-31 20:57:31 -04:00
2007-01-13 21:43:50 -04:00
if ( ! ( pysqlite_NotSupportedError = PyErr_NewException ( MODULE_NAME " .NotSupportedError " , pysqlite_DatabaseError , NULL ) ) ) {
2006-04-04 03:29:05 -03:00
goto error ;
}
2007-01-13 21:43:50 -04:00
PyDict_SetItemString ( dict , " NotSupportedError " , pysqlite_NotSupportedError ) ;
2006-03-31 20:57:31 -04:00
2007-01-13 21:43:50 -04:00
/* We just need "something" unique for pysqlite_OptimizedUnicode. It does not really
2006-04-04 03:29:05 -03:00
* need to be a string subclass . Just anything that can act as a special
* marker for us . So I pulled PyCell_Type out of my magic hat .
*/
2006-03-31 20:57:31 -04:00
Py_INCREF ( ( PyObject * ) & PyCell_Type ) ;
2007-01-13 21:43:50 -04:00
pysqlite_OptimizedUnicode = ( PyObject * ) & PyCell_Type ;
PyDict_SetItemString ( dict , " OptimizedUnicode " , pysqlite_OptimizedUnicode ) ;
2006-03-31 20:57:31 -04:00
2006-06-13 19:24:47 -03:00
/* Set integer constants */
for ( i = 0 ; _int_constants [ i ] . constant_name ! = 0 ; i + + ) {
tmp_obj = PyInt_FromLong ( _int_constants [ i ] . constant_value ) ;
if ( ! tmp_obj ) {
goto error ;
}
PyDict_SetItemString ( dict , _int_constants [ i ] . constant_name , tmp_obj ) ;
Py_DECREF ( tmp_obj ) ;
2006-04-04 03:29:05 -03:00
}
if ( ! ( tmp_obj = PyString_FromString ( PYSQLITE_VERSION ) ) ) {
goto error ;
}
PyDict_SetItemString ( dict , " version " , tmp_obj ) ;
2006-06-02 01:54:52 -03:00
Py_DECREF ( tmp_obj ) ;
2006-04-04 03:29:05 -03:00
if ( ! ( tmp_obj = PyString_FromString ( sqlite3_libversion ( ) ) ) ) {
goto error ;
}
PyDict_SetItemString ( dict , " sqlite_version " , tmp_obj ) ;
2006-06-02 01:54:52 -03:00
Py_DECREF ( tmp_obj ) ;
2006-03-31 20:57:31 -04:00
/* initialize microprotocols layer */
microprotocols_init ( dict ) ;
/* initialize the default converters */
converters_init ( dict ) ;
2006-06-13 19:24:47 -03:00
_enable_callback_tracebacks = 0 ;
2006-03-31 20:57:31 -04:00
/* Original comment form _bsddb.c in the Python core. This is also still
* needed nowadays for Python 2.3 / 2.4 .
*
* PyEval_InitThreads is called here due to a quirk in python 1.5
* - 2.2 .1 ( at least ) according to Russell Williamson < merel @ wt . net > :
* The global interepreter lock is not initialized until the first
* thread is created using thread . start_new_thread ( ) or fork ( ) is
* called . that would cause the ALLOW_THREADS here to segfault due
* to a null pointer reference if no threads or child processes
* have been created . This works around that and is a no - op if
* threads have already been initialized .
* ( see pybsddb - users mailing list post on 2002 - 08 - 07 )
*/
PyEval_InitThreads ( ) ;
error :
if ( PyErr_Occurred ( ) )
{
2006-04-05 15:25:33 -03:00
PyErr_SetString ( PyExc_ImportError , MODULE_NAME " : init failed " ) ;
2006-03-31 20:57:31 -04:00
}
}