/* teamtrack-server.cpp -- Python wrapper round TSServer class Gareth Rees, Ravenbrook Limited, 2000-08-08 $Id: //info.ravenbrook.com/project/p4dti/branch/2000-09-05/interface-debugging/python-teamtrack-interface/teamtrack-server.cpp#1 $ */ #include "teamtrack-module.h" #include "teamtrack-server.h" #include "teamtrack-record.h" #include "da.h" /* Debugging allocator -- GDR 2000-09-01 */ /* teamtrack_server_new(s, delete_p) returns a Python wrapper for the TSServer object s, or 0 if there is an error. Iff delete_p is true, then the TSServer object will be deleted when the Python wrapper is deleted. */ PyObject * teamtrack_server_new(TSServer *s, int delete_p) { teamtrack_server *self = PyObject_NEW(teamtrack_server, &teamtrack_server_type); if (!self) return 0; self->s = s; self->delete_p = delete_p; return (PyObject *)self; } /* Instance methods */ static PyObject * teamtrack_server_delete_record(PyObject *self, PyObject *args) { teamtrack_check_type(teamtrack_server, self, 0); teamtrack_server *tts = (teamtrack_server *)self; int table_id, record_id; if (!PyArg_ParseTuple(args, "ii", &table_id, &record_id)) return 0; teamtrack_try(tts->s->DeleteRecord(table_id, record_id), tts->s, 0); Py_INCREF(Py_None); return Py_None; } static PyObject * teamtrack_server_new_record(PyObject *self, PyObject *args) { teamtrack_check_type(teamtrack_server, self, 0); teamtrack_server *tts = (teamtrack_server *)self; int table_id; if (!PyArg_ParseTuple(args, "i", &table_id)) return 0; TSRecord *r = new TSRecord(table_id, tts->s); teamtrack_assert(r, 0); return teamtrack_record_new(r, tts, 1); } static PyObject * teamtrack_server_query(PyObject *self, PyObject *args) { teamtrack_check_type(teamtrack_server, self, 0); teamtrack_server *tts = (teamtrack_server *)self; int table_id; char *where_clause; if (!PyArg_ParseTuple(args, "is", &table_id, &where_clause)) return 0; TSRecordList ts_records; teamtrack_try(tts->s->ReadRecordListWithWhere(&ts_records, table_id, where_clause), tts->s, 0); int n_records = ts_records.Length(); PyObject *py_records = PyList_New(n_records); if (!py_records) return 0; int i; /* Position in Python list */ TSPosition *p; /* Position in TSRecordList */ for (i = 0, p = ts_records.GetFirst(); i < n_records && p; ++i, p = ts_records.GetNext(p)) { TSRecord *ts_record = ts_records.GetAt(p); if (!ts_record) { teamtrack_set_error(tts->s); break; } /* I believe it's safe to pass ownership of the TSRecord objects to Python, because the TSRecordList class doesn't actually delete the records in it unless you call TSList::EmptyAndDestroyList. See TSList.C. */ PyObject *py_record = teamtrack_record_new(ts_record, tts, 1); if (!py_record) { break; } PyList_SetItem(py_records, i, py_record); /* No need to decref py_record since PyList_SetItem doesn't incref it */ } if (PyErr_Occurred()) { Py_DECREF(py_records); /* Delete. */ return 0; } return py_records; } static PyObject * teamtrack_server_read_record(PyObject *self, PyObject *args) { teamtrack_check_type(teamtrack_server, self, 0); teamtrack_server *tts = (teamtrack_server *)self; int table_id, record_id; if (!PyArg_ParseTuple(args, "ii", &table_id, &record_id)) return 0; TSRecord *r = new TSRecord(table_id, tts->s); teamtrack_assert(r, 0); if (tts->s->ReadRecord(r, record_id) != TS_OK) { teamtrack_set_error(tts->s); delete r; return 0; } return teamtrack_record_new(r, tts, 1); } static struct PyMethodDef teamtrack_server_methods[] = { { "delete_record", teamtrack_server_delete_record, 1 }, { "new_record", teamtrack_server_new_record, 1 }, { "query", teamtrack_server_query, 1 }, { "read_record", teamtrack_server_read_record, 1 }, { NULL, NULL } /* End of methods */ }; /* Basic Python operators */ static void teamtrack_server_dealloc(PyObject *self) { if (!teamtrack_server_p(self)) Py_FatalError("teamtrack_server_dealloc called on object that's not a teamtrack_server."); teamtrack_server *tts = (teamtrack_server *)self; if (tts->delete_p) delete tts->s; PyMem_DEL(self); } static PyObject * teamtrack_server_repr(PyObject *self) { teamtrack_check_type(teamtrack_server, self, 0); teamtrack_server *tts = (teamtrack_server *)self; return PyString_FromString(""); } static PyObject * teamtrack_server_getattr(PyObject *self, char *name) { teamtrack_check_type(teamtrack_server, self, 0); return Py_FindMethod(teamtrack_server_methods, self, name); } /* Create the teamtrack.server class */ PyTypeObject teamtrack_server_type = { /* Type header */ PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */ "server", /* tp_name */ sizeof(teamtrack_server), /* tp_basicsize */ 0, /* tp_itemsize */ /* Basic methods */ teamtrack_server_dealloc, 0, /* print */ teamtrack_server_getattr, 0, /* setatts */ 0, /* compare */ teamtrack_server_repr, /* Type categories */ 0, /* number operators */ 0, /* sequence operators */ 0, /* mapping operators */ /* Other methods are 0: see Python's object.h for details */ };