Listing 4

// Listing 4. Structures and methods for the Database type

typedef struct
{
  /* Header */
  PyObject_HEAD

  /* Database specific information */
  ORJDatabase_holder  *dbh;
  ORJDatabase const   *database;
  char                *path;
  openrj_RecordObject **records;
} openrj_Database;

static openrj_Database  *
  openrj_Database_alloc(PyObject *self, ORJDatabase const *database
                      , char const *path);
static void     openrj_Database_dealloc(openrj_Database *self);
static int      openrj_Database_print(openrj_Database *self
                                    , FILE *file, int flags);
static PyObject *openrj_Database_getattr( openrj_Database *self
                                        , char const *name);
static PyObject *openrj_Database_path(openrj_Database *self);
static PyObject *openrj_Database_records(openrj_Database *self);
static PyObject *openrj_Database_numRecords(openrj_Database *self);
static PyObject *openrj_Database_numFields(openrj_Database *self);
static PyObject *openrj_Database_numLines(openrj_Database *self);
static int      openrj_Database_length(openrj_Database *self);
static PyObject *openrj_Database_item(openrj_Database *self, int index);
static PyObject *openrj_Database_slice(openrj_Database *self,int from,int to);
static struct PyMethodDef openrj_Database_methods[] =
{
    { "path",       openrj_Database_path
    , METH_NOARGS,  "The path of the database"                    }
  , { "records",    openrj_Database_records
    , METH_NOARGS,  "A tuple of all the records in the database"   }
  , { "numRecords", openrj_Database_numRecords
    , METH_NOARGS,  "The number of records in the database"        }
  , { "numFields",  openrj_Database_numFields
    , METH_NOARGS,  "The number of fields in the database"         }
  , { "numLines",   openrj_Database_numLines
    , METH_NOARGS,  "The number of lines in the database"          }
  , { NULL,         NULL
    , 0,            NULL                                        }
};
static PySequenceMethods openrj_Database_as_sequence =
{
    (inquiry)openrj_Database_length       /* sq_length "len(x)"      */
  , (binaryfunc)0                        /* sq_concat "x + y"        */
  , (intargfunc)0                        /* sq_repeat "x * n"        */
  , (intargfunc)openrj_Database_item      /* sq_item   "x[i], in"    */
  , (intintargfunc)openrj_Database_slice  /* sq_slice  "x[i:j]"      */
  , (intobjargproc)0                     /* sq_ass_item  "x[i] = v"  */
  , (intintobjargproc)0                  /* sq_ass_slice "x[i:j]=v"  */
  , (objobjproc)0                        /* sq_contains              */
  , (binaryfunc)0                        /* sq_inplace_concat        */
  , (intargfunc)0                        /* sq_inplace_repeat        */
};
static PyTypeObject openrj_Database_Type =
{
    PyObject_HEAD_INIT(NULL)
    0
  , "Database"
  , sizeof(openrj_Database)
  , 0
  , (destructor)  openrj_Database_dealloc   /* tp_dealloc      */
  , (printfunc)   openrj_Database_print     /* tp_print        */
  , (getattrfunc) openrj_Database_getattr   /* tp_getattr      */
  , 0                                     /* tp_setattr        */
  , 0                                     /* tp_compare        */
  , 0                                     /* tp_repr           */
  , 0                                     /* tp_as_number      */
  , &openrj_Database_as_sequence           /* tp_as_sequence   */
  , 0                                     /* tp_as_mapping     */
  , 0                                     /* tp_hash           */
  , 0                                     /* tp_call           */
  , 0                                     /* tp_str            */
  , 0                                     /* tp_getattro       */
  , 0                                     /* tp_setattro       */
  , 0                                     /* tp_as_buffer      */
  , 0                                     /* tp_flags          */
  , 0                                     /* tp_doc            */
  , 0                                     /* tp_traverse       */
  , 0                                     /* tp_clear          */
  , 0                                     /* tp_richcompare    */
  , 0                                     /* tp_weaklistoffset */
  , 0                                     /* tp_iter           */
  , 0                                     /* tp_iternext       */
  , 0                                     /* tp_methods        */
  , 0                                     /* tp_members        */
  , 0                                     /* tp_getset         */
  , 0                                     /* tp_base           */
  , 0                                     /* tp_dict           */
  , 0                                     /* tp_descr_get      */
  , 0                                     /* tp_descr_set      */
  , 0                                     /* tp_dictoffset     */
  , 0                                     /* tp_init           */
  , 0                                     /* tp_alloc          */
  , 0                                     /* tp_new            */
  , 0                                     /* tp_free           */
  , 0                                     /* tp_is_gc          */
  , 0                                     /* tp_bases          */
  , 0                                     /* tp_mro            */
  , 0                                     /* tp_cache          */
  , 0                                     /* tp_subclasses     */
  , 0                                     /* tp_weaklist       */
#ifdef COUNT_ALLOCS
  , 0                                     /* tp_allocs         */
  , 0                                     /* tp_frees          */
  , 0                                     /* tp_maxalloc       */
  , 0                                     /* tp_next           */
#endif /* COUNT_ALLOCS */
};