📄 e32dbmodule.cpp
字号:
/**
* ====================================================================
* e32dbmodule.cpp
*
* Python API to Symbian DB.
*
* Copyright (c) 2005 - 2007 Nokia Corporation
*
* 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 "Python.h"
#include "symbian_python_ext_util.h"
#include <eikenv.h>
#include <e32std.h>
#include <f32file.h>
#include <d32dbms.h>
#include "debugutil.h"
//#define IFDEB
#define IFDEB if (0)
#define DPYPRINTF IFDEB pyprintf
_LIT(KUnixEpoch, "19700000:");
/*
*
* Implementation of e32db.Dbms
*
*/
/*
* Implementation of Dbms object
*/
#define Dbms_type ((PyTypeObject*)SPyGetGlobalString("DbmsType"))
struct DB_data {
RDbs dbsession;
RDbNamedDatabase dbname;
bool dbOpen;
TBuf<KMaxFileName> fullName;
};
/*
* No class members here
* as they do not get
* properly initialized by PyObject_New() !!!
*/
struct dbms_object {
PyObject_VAR_HEAD
DB_data* db_obj;
};
extern "C" PyObject *
new_dbms_object()
{
dbms_object *dbo = PyObject_New(dbms_object, Dbms_type);
if (dbo == NULL)
return PyErr_NoMemory();
dbo->db_obj = new DB_data();
dbo->db_obj->dbOpen=false;
if (dbo->db_obj == NULL) {
PyObject_Del(dbo);
return PyErr_NoMemory();
}
return (PyObject *) dbo;
}
extern "C" PyObject *
dbms_create(dbms_object *self, PyObject *args)
{
TInt error = KErrNone;
int l;
char* b;
if (!PyArg_ParseTuple(args, "u#", &b, &l))
return NULL;
self->db_obj->fullName.Copy((TUint16*)b, l);
/*RFs session needed*/
RFs* rfs = new RFs();
if (rfs == NULL)
return PyErr_NoMemory();
error = rfs->Connect();
if (error == KErrNone) {
// Make sure the database is closed before we try to Replace it.
self->db_obj->dbname.Close();
error = self->db_obj->dbname.Replace(*rfs, self->db_obj->fullName);
}
self->db_obj->dbname.Close();
self->db_obj->dbOpen = false;
rfs->Close();
delete rfs;
RETURN_ERROR_OR_PYNONE(error);
}
extern "C" PyObject *
dbms_open(dbms_object *self, PyObject *args)
{
TInt error = KErrNone;
int l;
char* b;
if (!PyArg_ParseTuple(args, "u#", &b, &l))
return NULL;
self->db_obj->fullName.Copy((TUint16*)b, l);
error = self->db_obj->dbsession.Connect();
if (error == KErrNone) {
// Make sure the database is closed before we try to open a new one.
self->db_obj->dbname.Close();
error = self->db_obj->dbname.Open(self->db_obj->dbsession, self->db_obj->fullName);
}
self->db_obj->dbOpen = (error == KErrNone);
RETURN_ERROR_OR_PYNONE(error);
}
extern "C" PyObject *
dbms_close(dbms_object *self)
{
self->db_obj->dbname.Close();
self->db_obj->dbOpen=false;
Py_INCREF(Py_None);
return Py_None;
}
#define ASSERT_DBOPEN \
if (!self->db_obj->dbOpen) { \
PyErr_SetString(PyExc_RuntimeError, "Database not open"); \
return NULL; \
}
#define ASSERT_ATROW \
if (!self->view_obj->view.AtRow()) { \
PyErr_SetString(PyExc_RuntimeError, "Not on a row"); \
return NULL; \
}
#define ASSERT_ROWREADY \
if (!self->view_obj->rowReady) { \
PyErr_SetString(PyExc_RuntimeError, "Row not ready (did you remember to call get_line?)"); \
return NULL; \
}
#define ASSERT_ISPREPARED \
if (!self->view_obj->isPrepared) { \
PyErr_SetString(PyExc_RuntimeError, "View not prepared"); \
return NULL; \
}
#define ASSERT_VALIDCOLUMN \
TInt nCols = self->view_obj->view.ColCount(); \
if ((nCols<=0) || (column <=0) || (column > nCols)) { \
PyErr_SetString(PyExc_RuntimeError, "Invalid column number"); \
return NULL; \
}
extern "C" PyObject *
dbms_begin(dbms_object *self)
{
ASSERT_DBOPEN;
self->db_obj->dbname.Begin();
Py_INCREF(Py_None);
return Py_None;
}
extern "C" PyObject *
dbms_commit(dbms_object *self)
{
ASSERT_DBOPEN;
self->db_obj->dbname.Commit();
Py_INCREF(Py_None);
return Py_None;
}
extern "C" PyObject *
dbms_rollback(dbms_object *self)
{
ASSERT_DBOPEN;
self->db_obj->dbname.Rollback();
Py_INCREF(Py_None);
return Py_None;
}
extern "C" PyObject *
dbms_compact(dbms_object *self)
{
ASSERT_DBOPEN;
self->db_obj->dbname.Compact();
Py_INCREF(Py_None);
return Py_None;
}
extern "C" PyObject *
dbms_execute(dbms_object *self, PyObject *args)
{
TInt updated;
int l;
char* b;
if (!PyArg_ParseTuple(args, "u#", &b, &l))
return NULL;
ASSERT_DBOPEN;
TPtrC query((TUint16 *)b, l);
updated = self->db_obj->dbname.Execute(query);
if (updated < 0)
return SPyErr_SetFromSymbianOSErr(updated);
else
return Py_BuildValue("i", updated);
}
extern "C" {
static void dbms_dealloc(dbms_object *dbo)
{
dbo->db_obj->dbname.Close();
dbo->db_obj->dbsession.Close();
delete dbo->db_obj;
PyObject_Del(dbo);
}
const static PyMethodDef dbms_methods[] = {
{"create", (PyCFunction)dbms_create, METH_VARARGS},
{"execute", (PyCFunction)dbms_execute, METH_VARARGS},
{"open", (PyCFunction)dbms_open, METH_VARARGS},
{"close", (PyCFunction)dbms_close, METH_NOARGS},
{"begin", (PyCFunction)dbms_begin, METH_NOARGS},
{"commit", (PyCFunction)dbms_commit, METH_NOARGS},
{"rollback", (PyCFunction)dbms_rollback, METH_NOARGS},
{"compact", (PyCFunction)dbms_compact, METH_NOARGS},
{NULL, NULL} // sentinel
};
static PyObject *
dbms_getattr(dbms_object *op, char *name)
{
return Py_FindMethod((PyMethodDef*)dbms_methods,
(PyObject *)op, name);
}
static const PyTypeObject c_dbms_type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"e32db.Dbms", /*tp_name*/
sizeof(dbms_object), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor)dbms_dealloc, /*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)dbms_getattr, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
};
} //extern C
/*
*
* Implementation of e32db.Db_view
*
*/
/*
* Implementation of Db_view object
*/
#define DBView_type ((PyTypeObject*)SPyGetGlobalString("DBViewType"))
struct View_data {
RDbView view;
int isPrepared;
int rowReady;
};
/*
* No class members here
* as they do not get
* properly initialized by PyObject_New() !!!
*/
struct dbview_object {
PyObject_VAR_HEAD
View_data* view_obj;
struct dbms_object* dbms_obj;
};
extern "C" PyObject *
new_dbview_object()
{
dbview_object *dbv = PyObject_New(dbview_object, DBView_type);
if (dbv == NULL)
return PyErr_NoMemory();
dbv->view_obj = new View_data();
dbv->view_obj->isPrepared=0;
dbv->view_obj->rowReady=0;
dbv->dbms_obj=NULL;
if (dbv->view_obj == NULL) {
PyObject_Del(dbv);
return PyErr_NoMemory();
}
else
return (PyObject *) dbv;
}
static void
dbview_dealloc(dbview_object *dbv)
{
dbv->view_obj->view.Close();
delete dbv->view_obj;
// If the view has been prepared to refer to some database object,
// decrease its' reference count, so that it gets properly destroyed
// when there are no more references to it. When doing the cleanup
// it is crucial that the database is not destroyed before the views
// that refer to it.
if (dbv->dbms_obj)
Py_DECREF(dbv->dbms_obj);
PyObject_Del(dbv);
}
extern "C" PyObject *
dbview_prepare(dbview_object *self, PyObject *args)
{
TInt error = KErrNone;
int l;
char* b;
dbms_object *db;
if (!PyArg_ParseTuple(args, "O!u#", Dbms_type, &db, &b, &l))
return NULL;
// This is essentially ASSERT_DBOPEN but we can't use that here
// because the name self refers to the view object, not the database
// object.
if (!db->db_obj->dbOpen) {
PyErr_SetString(PyExc_RuntimeError, "Database not open");
return NULL;
}
// If this view has already been prepared to refer to some database,
// decrease the reference count of that old database object.
if (self->dbms_obj)
Py_DECREF(self->dbms_obj);
self->dbms_obj=db;
// Once we prepare a view to some database, that view refers to
// the original database and thus the database object must not be
// destroyed before the view is destroyed. Increase the reference
// count of the database object to tell the Python interpreter of
// this C-level dependency.
Py_INCREF(self->dbms_obj);
TPtrC query((TUint16 *)b, l);
error = self->view_obj->view.Prepare(db->db_obj->dbname, (TDbQuery)query, RDbView::EReadOnly);
if (error == KErrNone)
error = self->view_obj->view.EvaluateAll();
if (error == KErrNone) {
TRAP(error, (self->view_obj->view.FirstL() ));
}
self->view_obj->isPrepared=(error == KErrNone);
RETURN_ERROR_OR_PYNONE(error);
}
extern "C" PyObject *
dbview_first_line(dbview_object *self)
{
ASSERT_ISPREPARED;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -