/usr/local/Hypy
view estraiernative.c @ 139:d0a738aea316
Added tag 0.8.4.1 for changeset bbc3e3a3c4fb
| author | Cory Dodt <corymercurial@spam.goonmill.org> |
|---|---|
| date | Fri Oct 09 10:32:45 2009 -0700 (2009-10-09) |
| parents | |
| children |
line source
1 /*
2 hyperestraier.c - HyperEstraier wrapper for Python
3 Copyright (c) 2007, SOUNDBOARD Co.,Ltd.
4 All rights reserved.
5 Written by Yusuke YOSHIDA <usk.yos_at_gmail.com>
6 $Id: estraiernative.c,v 1.11 2007/04/15 05:52:47 yosida Exp $
7 */
9 #include <Python.h>
10 #include <structmember.h>
11 #include <estraier.h>
12 #include <estmtdb.h>
13 #include <cabin.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <assert.h>
19 #ifdef DEBUG
20 static void debug(char *msg) {
21 char dmsg[BUFSIZ];
22 sprintf(dmsg, "DEBUG : %s\n", msg);
23 fputs(dmsg, stderr);
24 }
26 static void refcount(PyObject *o, char *tag) {
27 char buf[BUFSIZ];
28 sprintf(buf, "REFCOUNT - %s : %d", tag, (o)->ob_refcnt);
29 debug(buf);
30 }
31 #else
32 static void debug(char *msg) {
33 }
34 static void refcount(PyObject *o, char *tag) {
35 }
36 #endif
38 /* --------------------------------------------------------------------- */
40 /* ==================== type definition ==================== */
41 static PyObject *EST_Error;
43 typedef struct {
44 PyObject_HEAD;
45 ESTDOC *doc;
46 } PyESTDOC;
47 static PyTypeObject PyESTDOC_Type;
48 #define PyESTDOCObject_Check(v) ((v)->ob_type == &PyESTDOC_Type)
50 typedef struct {
51 PyObject_HEAD;
52 int ecode;
53 ESTMTDB *db;
54 } PyESTDB;
55 static PyTypeObject PyESTDB_Type;
56 #define PyESTDBObject_Check(v) ((v)->ob_type == &PyESTDB_Type)
58 typedef struct {
59 PyObject_HEAD;
60 ESTCOND *cond;
61 } PyESTCOND;
62 static PyTypeObject PyESTCOND_Type;
63 #define PyESTCONDObject_Check(v) ((v)->ob_type == &PyESTCOND_Type)
65 typedef struct {
66 PyObject_HEAD;
67 int *ids;
68 int *dbidxs;
69 int num;
70 CBMAP *hints;
71 } PyESTRES;
72 static PyTypeObject PyESTRES_Type;
73 #define PyESTRESObject_Check(v) ((v)->ob_type == &PyESTRES_Type)
75 static PyESTRES* estres_factory(void);
77 /* ==================== utility functions ==================== */
78 #define define_const(dic, key, val) do { \
79 PyDict_SetItemString(dic, key, PyInt_FromLong(val)); \
80 } while (0)
82 #define define_const_fmt(dic, key, val, fmt) do { \
83 PyObject* o = Py_BuildValue(fmt, val); \
84 PyDict_SetItemString(dic, key, o); \
85 } while (0)
87 #define null_check(o, msg) do { \
88 if (o == NULL) { \
89 if (msg != NULL) \
90 PyErr_SetString(EST_Error, msg); \
91 return NULL; \
92 } \
93 } while (0)
95 /* python dict object -> CBMAP */
96 static CBMAP*
97 dic2CBMAP(PyObject *dic)
98 {
99 CBMAP *map;
100 PyListObject *items;
101 int items_len, i;
102 PyObject *key_o, *score_o;
103 char *key, *score;
105 if (!PyDict_Check(dic)) {
106 PyErr_SetString(PyExc_TypeError, "dict is expected");
107 return NULL;
108 }
110 map = cbmapopen();
111 null_check(map, "dic2CBMAP() - cbmapopen()");
112 items = (PyListObject*)PyDict_Items(dic);
113 items_len = PyList_GET_SIZE(items);
115 for(i = 0; i < items_len; i++) {
116 key_o = PyTuple_GET_ITEM(PyList_GET_ITEM(items, i), 0);
117 score_o = PyTuple_GET_ITEM(PyList_GET_ITEM(items, i), 1);
119 if (!(PyString_Check(key_o) && PyString_Check(score_o))) {
120 PyErr_SetString(PyExc_TypeError, "dic2CBMAP() - str is expected");
121 return NULL;
122 }
123 key = PyString_AS_STRING(key_o);
124 score = PyString_AS_STRING(score_o);
125 //key = strdup(PyString_AS_STRING(key_o));
126 //score = strdup(PyString_AS_STRING(score_o));
127 null_check(key, "dic2CBMAP() - strdup()");
128 null_check(score, "dic2CBMAP() - strdup()");
130 cbmapput(map, key, -1, score, -1, 1);
131 refcount(key_o, "key_o");
132 }
133 debug("before decref");
134 Py_DECREF(items);
135 debug("after decref");
136 return map;
137 }
139 /* CBMAP -> python dict object */
140 static PyObject*
141 CBMAP2dic(CBMAP *map)
142 {
143 const char *key, *v;
144 int ksp, vsp;
145 PyObject *dic;
147 dic = PyDict_New();
148 null_check(dic, "CBMAP2dic() - PyDict_New()");
149 refcount(dic, "dic");
150 if (map == NULL) {
151 return dic;
152 }
154 assert(map != NULL);
155 cbmapiterinit(map);
156 debug("c 0");
157 while ((key = cbmapiternext(map, &ksp)) != NULL) {
158 v = cbmapget(map, key, -1, &vsp);
159 null_check(v, "CBMAP2dic() - cbmapget()");
160 PyDict_SetItemString(dic, key, PyString_FromString(v));
161 }
162 return dic;
163 }
165 /* python list object -> CBLIST */
166 static CBLIST*
167 list2CBLIST(PyObject *list)
168 {
169 CBLIST *cblist;
170 int size, idx;
171 PyObject *item;
173 if (!PyList_Check(list)) {
174 PyErr_SetString(PyExc_TypeError, "list2CBLIST() - list is expected");
175 return NULL;
176 }
178 cblist = cblistopen();
179 null_check(cblist, "cblistopen()");
181 size = PyList_GET_SIZE(list);
182 for (idx = 0; idx < size; idx++) {
183 item = PyList_GET_ITEM(list, idx);
184 cblistpush(cblist, PyString_AS_STRING(item), -1);
185 }
186 return cblist;
187 }
189 static PyObject*
190 CBLIST2list(CBLIST *cblist)
191 {
192 PyObject *list;
193 int size, idx;
194 const char *item;
196 if (cblist == NULL) {
197 return PyList_New(0);
198 }
199 size = cblistnum(cblist);
200 list = PyList_New(size);
201 null_check(list, "CBLIST2list - PyList_New()");
203 for (idx = 0; idx < size; idx++) {
204 item = cblistval(cblist, idx, NULL);
205 PyList_SetItem(list, idx, PyString_FromString(item));
206 }
207 return list;
208 }
211 /* =============== ESTDOC ==================*/
213 static PyObject*
214 PyESTDOC_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
215 {
216 PyESTDOC *pdoc = NULL;
218 pdoc = (PyESTDOC*)type->tp_alloc(type, 0);
219 if (pdoc == NULL) {
220 return NULL;
221 }
222 debug("PyESTDOC_new ");
223 return (PyObject*)pdoc;
224 }
226 static int
227 PyESTDOC_init(PyObject* self, PyObject *args, PyObject *kwds)
228 {
229 PyESTDOC* pdoc = (PyESTDOC*)self;
230 ESTDOC *doc;
231 const char* draft = NULL;
232 static char* keywords[] = {"draft", 0};
234 assert(args != NULL);
235 assert(pdoc != NULL);
236 if(!PyArg_ParseTuple(args, "|s", &draft)) {
237 return -1;
238 }
240 if (draft == NULL) {
241 doc = est_doc_new();
242 debug("PyESTDOC_init() : est_doc_new()");
243 } else {
244 doc = est_doc_new_from_draft(draft);
245 debug("PyESTDOC_init() : est_doc_new_from_draft()");
246 }
248 if (doc == NULL) {
249 return -1;
250 }
251 pdoc->doc = doc;
252 debug("PyESTDOC_init : ESTDOC allocate");
253 return 0;
254 }
256 static void
257 PyESTDOC_dealloc(PyESTDOC *self)
258 {
259 debug("PyESTDOC_dealloc");
260 if (self->doc != NULL) {
261 est_doc_delete(self->doc);
262 self->doc = NULL;
263 }
264 PyObject_Del(self);
265 }
267 /* ==== Document methods ==== */
268 static PyObject*
269 _est_doc_add_attr(PyObject *self, PyObject *args)
270 {
271 PyESTDOC *pdoc = (PyESTDOC*)self;
272 const char *name, *value;
274 if (!PyArg_ParseTuple(args, "sz", &name, &value))
275 return NULL;
276 null_check(pdoc->doc, "this is deleted document");
278 est_doc_add_attr(pdoc->doc, name, value);
279 Py_INCREF(Py_None);
280 return Py_None;
281 }
283 static PyObject*
284 _est_doc_add_text(PyObject *self, PyObject *args)
285 {
286 PyESTDOC *pdoc = (PyESTDOC*)self;
287 const char *text;
289 if (!PyArg_ParseTuple(args, "s", &text))
290 return NULL;
291 null_check(pdoc->doc, "this is deleted document");
293 est_doc_add_text(pdoc->doc, text);
294 Py_INCREF(Py_None);
295 return Py_None;
296 }
299 static PyObject*
300 _est_doc_add_hidden_text(PyObject *self, PyObject *args)
301 {
302 PyESTDOC *pdoc = (PyESTDOC*)self;
303 const char *text;
305 if (!PyArg_ParseTuple(args, "s", &text))
306 return NULL;
307 null_check(pdoc->doc, "this is deleted document");
309 est_doc_add_hidden_text(pdoc->doc, text);
310 Py_INCREF(Py_None);
311 return Py_None;
312 }
314 static PyObject*
315 _est_doc_set_keywords(PyObject *self, PyObject *args)
316 {
317 PyESTDOC *pdoc = (PyESTDOC*)self;
318 PyObject *keyword;
319 CBMAP *map;
321 if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &keyword))
322 return NULL;
323 null_check(pdoc->doc, "this is deleted document");
325 map = dic2CBMAP(keyword);
326 null_check(map, NULL);
327 debug("k 0");
328 est_doc_set_keywords(pdoc->doc, map);
329 debug("k 1");
330 cbmapclose(map);
331 debug("k 2");
332 Py_INCREF(Py_None);
333 debug("k 3");
334 return Py_None;
335 }
337 static PyObject*
338 _est_doc_set_score(PyObject *self, PyObject *args)
339 {
340 #if (_EST_LIBVER > 814)
341 PyESTDOC *pdoc = (PyESTDOC*)self;
342 ESTDOC *doc;
343 int score;
345 if (!PyArg_ParseTuple(args, "i", &score))
346 return NULL;
347 null_check(pdoc->doc, "this is deleted document");
349 est_doc_set_score(pdoc->doc, score);
351 Py_INCREF(Py_None);
352 return Py_None;
353 #else
354 PyErr_SetString(PyExc_NotImplementedError, "_est_doc_set_score");
355 return NULL;
356 #endif
357 }
360 static PyObject*
361 _est_doc_id(PyObject *self, PyObject *args)
362 {
363 PyESTDOC *pdoc = (PyESTDOC*)self;
364 int id;
366 null_check(pdoc->doc, "this is deleted document");
367 debug("doc_id - 2");
369 id = est_doc_id(pdoc->doc);
370 debug("doc_id - 3");
371 return PyInt_FromLong(id);
372 }
374 static PyObject*
375 _est_doc_attr_names(PyObject *self, PyObject *args)
376 {
377 PyESTDOC *pdoc = (PyESTDOC*)self;
378 CBLIST *cbl;
379 PyObject *list;
381 null_check(pdoc->doc, "this is deleted document");
383 cbl = est_doc_attr_names(pdoc->doc);
384 list = CBLIST2list(cbl);
385 cblistclose(cbl);
386 return list;
387 }
389 static PyObject*
390 _est_doc_score(PyObject *self, PyObject *args)
391 {
392 PyESTDOC *pdoc = (PyESTDOC*)self;
393 long score;
394 PyObject *rv;
396 null_check(pdoc->doc, "this is deleted document");
398 score = est_doc_score(pdoc->doc);
399 if (score) {
400 rv = PyInt_FromLong(score);
401 } else {
402 rv = Py_None;
403 Py_INCREF(rv);
404 }
405 return rv;
406 }
408 static PyObject*
409 _est_doc_attr(PyObject *self, PyObject *args)
410 {
411 PyESTDOC *pdoc = (PyESTDOC*)self;
412 const char *name, *attr;
413 PyObject *rv;
415 if (!PyArg_ParseTuple(args, "s", &name))
416 return NULL;
417 null_check(pdoc->doc, "this is deleted document");
419 attr = est_doc_attr(pdoc->doc, name);
420 if (attr) {
421 rv = PyString_FromString(attr);
422 } else {
423 rv = Py_None;
424 Py_INCREF(rv);
425 }
426 return rv;
427 }
429 static PyObject*
430 _est_doc_texts(PyObject *self, PyObject *args)
431 {
432 PyESTDOC *pdoc = (PyESTDOC*)self;
433 CBLIST *cbl;
434 PyObject *rv;
436 null_check(pdoc->doc, "this is deleted document");
438 // donot cblistclose(), because a life span of cbl syncs pdoc->doc.
439 cbl = (CBLIST*)est_doc_texts(pdoc->doc);
440 rv = CBLIST2list(cbl);
442 return rv;
443 }
445 static PyObject*
446 _est_doc_cat_texts(PyObject *self, PyObject *args)
447 {
448 PyESTDOC *pdoc = (PyESTDOC*)self;
449 PyObject *rv;
450 char *ret = NULL;
452 null_check(pdoc->doc, "this is deleted document");
453 debug("null_check 0");
454 ret = est_doc_cat_texts(pdoc->doc);
455 debug("est_doc_cat_texts 1");
456 debug(ret);
457 null_check(ret, "cat_texts return NULL");
458 rv = PyString_FromString(ret);
459 debug("PyString_FromString 2");
460 free(ret);
461 return rv;
462 }
464 static PyObject*
465 _est_doc_keywords(PyObject *self, PyObject *args)
466 {
467 PyESTDOC *pdoc = (PyESTDOC*)self;
468 CBMAP *map;
469 PyObject *rv;
471 null_check(pdoc->doc, "this is deleted document");
472 debug("est_doc_keywods 0");
473 map = est_doc_keywords(pdoc->doc);
474 debug("est_doc_keywods 1");
475 rv = CBMAP2dic(map);
476 debug("est_doc_keywods 2");
477 //cbmapclose(map);
478 debug("est_doc_keywods 3");
479 return rv;
480 }
482 static PyObject*
483 _est_doc_dump_draft(PyObject *self, PyObject *args)
484 {
485 PyESTDOC *pdoc = (PyESTDOC*)self;
486 char *draft;
487 PyObject *rv;
489 null_check(pdoc->doc, "this is deleted document");
491 draft = est_doc_dump_draft(pdoc->doc);
492 rv = PyString_FromString(draft);
493 free(draft);
494 return rv;
495 }
497 static PyObject*
498 _est_doc_make_snippet(PyObject *self, PyObject *args)
499 {
500 PyESTDOC *pdoc = (PyESTDOC*)self;
501 PyObject *words, *rv;
502 int ww, hw, aw;
503 CBLIST *cbl;
504 char *snippet;
506 if (!PyArg_ParseTuple(args, "O!iii", &PyList_Type, &words, &ww, &hw, &aw))
507 return NULL;
508 null_check(pdoc->doc, "this is deleted document");
510 cbl = list2CBLIST(words);
511 null_check(cbl, NULL);
512 snippet = est_doc_make_snippet(pdoc->doc, cbl, ww, hw, aw);
513 rv = PyString_FromString(snippet);
514 free(snippet);
515 return rv;
516 }
518 static PyMethodDef PyESTDOC_methods[] = {
519 {"add_attr", _est_doc_add_attr, METH_VARARGS, NULL},
520 {"add_text", _est_doc_add_text, METH_VARARGS, NULL},
521 {"add_hidden_text", _est_doc_add_hidden_text, METH_VARARGS, NULL},
522 {"set_keywords", _est_doc_set_keywords, METH_VARARGS, NULL},
523 {"set_score", _est_doc_set_score, METH_VARARGS, NULL},
524 {"id", _est_doc_id, METH_NOARGS, NULL},
525 {"attr_names", _est_doc_attr_names, METH_NOARGS, NULL},
526 {"attr", _est_doc_attr, METH_VARARGS, NULL},
527 {"score", _est_doc_score, METH_NOARGS, NULL},
528 {"texts", _est_doc_texts, METH_NOARGS, NULL},
529 {"cat_texts", _est_doc_cat_texts, METH_NOARGS, NULL},
530 {"keywords", _est_doc_keywords, METH_NOARGS, NULL},
531 {"dump_draft", _est_doc_dump_draft, METH_NOARGS, NULL},
532 {"make_snippet", _est_doc_make_snippet, METH_VARARGS, NULL},
533 {NULL, NULL}
534 };
536 static PyTypeObject PyESTDOC_Type = {
537 /* The ob_type field must be initialized in the module init function
538 * to be portable to Windows without using C++. */
539 PyObject_HEAD_INIT(NULL)
540 0, /*ob_size*/
541 "_estraiernative.PyESTDOC", /*tp_name*/
542 sizeof(PyESTDOC), /*tp_basicsize*/
543 0, /*tp_itemsize*/
544 (destructor)PyESTDOC_dealloc, /*tp_dealloc*/
545 0, /*tp_print*/
546 0, /*tp_getattr*/
547 0, /*tp_setattr*/
548 0, /*tp_compare*/
549 0, /*tp_repr*/
550 0, /*tp_as_number*/
551 0, /*tp_as_sequence*/
552 0, /*tp_as_mapping*/
553 0, /*tp_hash*/
554 0, /*tp_call*/
555 0, /*tp_str*/
556 0, /*tp_getattro*/
557 0, /*tp_setattro*/
558 0, /*tp_as_buffer*/
559 Py_TPFLAGS_DEFAULT, /*tp_flags*/
560 0, /*tp_doc*/
561 0, /* tp_traverse */
562 0, /* tp_clear */
563 0, /* tp_richcompare */
564 0, /* tp_weaklistoffset */
565 0, /* tp_iter */
566 0, /* tp_iternext */
567 PyESTDOC_methods, /* tp_methods */
568 0, /* tp_members */
569 0, /* tp_getset */
570 0, /* tp_base */
571 0, /* tp_dict */
572 0, /* tp_descr_get */
573 0, /* tp_descr_set */
574 0, /* tp_dictoffset */
575 PyESTDOC_init, /* tp_init */
576 0, /* tp_alloc */
577 PyESTDOC_new, /* tp_new */
578 0, /* tp_free */
579 };
582 /* =============== ESTMTDB ==================*/
584 static PyObject *
585 PyESTDB_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
586 {
587 PyESTDB *pdb = NULL;
588 pdb = (PyESTDB*)type->tp_alloc(type, 0);
590 if (pdb != NULL) {
591 pdb->db = NULL;
592 pdb->ecode = ESTENOERR;
593 }
595 return (PyObject*)pdb;
596 }
598 static void
599 PyESTDB_dealloc(PyESTDB *self)
600 {
601 debug("PyESTDB_dealloc bgn");
602 assert(self != NULL);
603 assert(PyESTDBObject_Check(self));
604 if (self->db != NULL) {
605 int ret;
606 debug("est_mtdb_close() pre");
607 ret = est_mtdb_close(self->db, &(self->ecode));
608 if (ret) {
609 debug("est_mtdb_close() post");
610 self->db = NULL;
611 } else {
612 debug("est_mtdb_close() is failed");
613 }
614 }
615 PyObject_Del(self);
616 debug("PyESTDB_dealloc fin.");
617 }
620 /* ==== Database methods ==== */
621 static PyObject*
622 _est_err_msg(PyObject *self, PyObject *args)
623 {
624 int ecode;
625 char errmsg[BUFSIZ];
626 PyObject *rv;
628 if (!PyArg_ParseTuple(args, "i:err_msg", &ecode))
629 return NULL;
631 strcpy(errmsg, est_err_msg(ecode)); // len(est_err_msg()) < BUFSIZ
632 rv = PyString_FromString(errmsg);
634 if (rv == NULL) {
635 Py_INCREF(Py_None);
636 return Py_None;
637 } else {
638 return rv;
639 }
640 }
642 static PyObject*
643 _est_db_open(PyObject *self, PyObject *args)
644 {
645 char *name;
646 int omode, ecp;
647 ESTMTDB *db;
648 PyESTDB *pdb = (PyESTDB*)self;
650 if (pdb->db != NULL && !est_mtdb_close(pdb->db, &(pdb->ecode))) {
651 pdb->db = NULL;
652 Py_INCREF(Py_False);
653 return Py_False;
654 }
656 if (!PyArg_ParseTuple(args, "si", &name, &omode))
657 return NULL;
659 db = est_mtdb_open(name, omode, &(pdb->ecode));
660 if (db != NULL) {
661 pdb->db = db;
662 Py_INCREF(Py_True);
663 return Py_True;
664 } else {
665 Py_INCREF(Py_False);
666 return Py_False;
667 }
668 }
670 static PyObject*
671 _est_db_close(PyObject *self, PyObject *args)
672 {
673 PyESTDB *pdb = (PyESTDB*)self;
674 int ecp, ret;
675 PyObject *rv;
677 null_check(pdb->db, "db is closed");
678 ret = est_mtdb_close(pdb->db, &(pdb->ecode));
679 pdb->db = NULL;
680 if (ret) {
681 rv = Py_True;
682 } else {
683 //pdb->ecode = est_mtdb_error(pdb->db);
684 rv = Py_False;
685 }
686 Py_INCREF(rv);
687 return rv;
688 }
690 static PyObject*
691 _est_db_error(PyObject *self, PyObject *args)
692 {
693 PyObject *po;
694 PyESTDB *pdb = (PyESTDB*)self;
696 //null_check(pdb->db, "db is closed");
697 //pdb->ecode = est_mtdb_error(pdb->db);
698 return PyInt_FromLong(pdb->ecode);
699 }
701 static PyObject*
702 _est_db_fatal(PyObject *self, PyObject *args)
703 {
704 PyESTDB *pdb = (PyESTDB*)self;
705 int ret;
706 PyObject *rv;
708 null_check(pdb->db, "db is closed");
710 ret = est_mtdb_error(pdb->db);
711 if (ret) {
712 rv = Py_True;
713 } else {
714 rv = Py_False;
715 }
716 Py_INCREF(rv);
717 return rv;
718 }
720 static PyObject*
721 _est_db_add_attr_index(PyObject *self, PyObject *args)
722 {
723 #if (_EST_LIBVER > 805)
724 PyESTDB *pdb = (PyESTDB*)self;
725 char *name;
726 int type, ret;
727 PyObject *rv;
729 if (!PyArg_ParseTuple(args, "si", &name, &type))
730 return NULL;
731 null_check(pdb->db, "db is closed");
733 ret = est_mtdb_add_attr_index(pdb->db, name, type);
734 if (ret) {
735 rv = Py_True;
736 } else {
737 rv = Py_False;
738 pdb->ecode = est_mtdb_error(pdb->db);
739 }
740 Py_INCREF(rv);
741 return rv;
742 #else
743 PyErr_SetString(PyExc_NotImplementedError, "add_attr_index");
744 return NULL;
745 #endif
746 }
748 static PyObject*
749 _est_db_flush(PyObject *self, PyObject *args)
750 {
751 PyESTDB *pdb = (PyESTDB*)self;
752 int max, ret;
753 PyObject *rv;
755 if (!PyArg_ParseTuple(args, "i", &max))
756 return NULL;
757 null_check(pdb->db, "db is closed");
759 ret = est_mtdb_flush(pdb->db, max);
760 if (ret) {
761 rv = Py_True;
762 } else {
763 rv = Py_False;
764 pdb->ecode = est_mtdb_error(pdb->db);
765 }
766 Py_INCREF(rv);
767 return rv;
768 }
770 static PyObject*
771 _est_db_sync(PyObject *self, PyObject *args)
772 {
773 PyESTDB *pdb = (PyESTDB*)self;
774 int ret;
775 PyObject *rv;
777 null_check(pdb->db, "db is closed");
779 ret = est_mtdb_sync(pdb->db);
780 if (ret) {
781 rv = Py_True;
782 } else {
783 rv = Py_False;
784 pdb->ecode = est_mtdb_error(pdb->db);
785 }
786 Py_INCREF(rv);
787 return rv;
788 }
790 static PyObject*
791 _est_db_optimize(PyObject *self, PyObject *args)
792 {
793 PyESTDB *pdb = (PyESTDB*)self;
794 int opts, ret;
795 PyObject *rv;
797 if (!PyArg_ParseTuple(args, "i", &opts))
798 return NULL;
799 null_check(pdb->db, "db is closed");
801 ret = est_mtdb_optimize(pdb->db, opts);
802 if (ret) {
803 rv = Py_True;
804 } else {
805 rv = Py_False;
806 pdb->ecode = est_mtdb_error(pdb->db);
807 }
808 Py_INCREF(rv);
809 return rv;
810 }
812 static PyObject*
813 _est_db_merge(PyObject *self, PyObject *args)
814 {
815 #if (_EST_LIBVER > 814)
816 PyESTDB *pdb = (PyESTDB*)self;
817 char *name;
818 int opts, ret;
819 PyObject *rv;
821 if (!PyArg_ParseTuple(args, "si", &name, &opts))
822 return NULL;
823 null_check(pdb->db, "db is closed");
825 ret = est_mtdb_merge(pdb->db, name, opts);
826 if (ret) {
827 rv = Py_True;
828 } else {
829 rv = Py_False;
830 pdb->ecode = est_mtdb_error(pdb->db);
831 }
832 Py_INCREF(rv);
833 return rv;
834 #else
835 PyErr_SetString(PyExc_NotImplementedError, "_est_db_merge");
836 return NULL;
837 #endif
838 }
840 static PyObject*
841 _est_db_put_doc(PyObject *self, PyObject *args)
842 {
843 PyESTDB *pdb = (PyESTDB*)self;
844 PyESTDOC *pdoc;
845 int opts, ret;
846 PyObject *rv;
848 if (!PyArg_ParseTuple(args, "O!i", &PyESTDOC_Type, &pdoc, &opts))
849 return NULL;
850 null_check(pdb->db, "db is closed");
851 null_check(pdoc->doc, "this is deleted document");
853 ret = est_mtdb_put_doc(pdb->db, pdoc->doc, opts);
854 if (ret) {
855 rv = Py_True;
856 } else {
857 rv = Py_False;
858 pdb->ecode = est_mtdb_error(pdb->db);
859 }
860 Py_INCREF(rv);
861 return rv;
862 }
864 static PyObject*
865 _est_db_out_doc(PyObject *self, PyObject *args)
866 {
867 PyESTDB *pdb = (PyESTDB*)self;
868 int id, opts, ret;
869 PyObject *rv;
871 if (!PyArg_ParseTuple(args, "ii", &id, &opts))
872 return NULL;
873 null_check(pdb->db, "db is closed");
875 ret = est_mtdb_out_doc(pdb->db, id, opts);
876 if (ret) {
877 rv = Py_True;
878 } else {
879 rv = Py_False;
880 pdb->ecode = est_mtdb_error(pdb->db);
881 }
882 Py_INCREF(rv);
883 return rv;
884 }
886 static PyObject*
887 _est_db_edit_doc(PyObject *self, PyObject *args)
888 {
889 PyESTDB *pdb = (PyESTDB*)self;
890 PyESTDOC *pdoc;
891 int ret;
892 PyObject *rv;
894 if (!PyArg_ParseTuple(args, "O!", &PyESTDOC_Type, &pdoc))
895 return NULL;
896 null_check(pdb->db, "db is closed");
897 null_check(pdoc->doc, "this is deleted document");
899 ret = est_mtdb_edit_doc(pdb->db, pdoc->doc);
900 if (ret) {
901 rv = Py_True;
902 } else {
903 rv = Py_False;
904 pdb->ecode = est_mtdb_error(pdb->db);
905 }
906 Py_INCREF(rv);
907 return rv;
908 }
910 static PyObject*
911 _est_db_get_doc(PyObject *self, PyObject *args)
912 {
913 PyESTDB *pdb = (PyESTDB*)self;
914 int id, opts;
915 PyESTDOC *pdoc;
916 ESTDOC *doc;
918 if (!PyArg_ParseTuple(args, "ii", &id, &opts))
919 return NULL;
921 null_check(pdb->db, "db is closed");
923 doc = est_mtdb_get_doc(pdb->db, id, opts);
924 if (doc) {
925 pdoc = PyObject_New(PyESTDOC, &PyESTDOC_Type);
926 pdoc->doc = doc;
927 return (PyObject*)pdoc;
928 } else {
929 Py_INCREF(Py_None);
930 pdb->ecode = est_mtdb_error(pdb->db);
931 return Py_None;
932 }
933 }
935 static PyObject*
936 _est_db_get_doc_attr(PyObject *self, PyObject *args)
937 {
938 PyESTDB *pdb = (PyESTDB*)self;
939 int id;
940 char *name, *attr;
941 PyObject *rv;
943 if (!PyArg_ParseTuple(args, "is", &id, &name))
944 return NULL;
946 null_check(pdb->db, "db is closed");
948 attr = est_mtdb_get_doc_attr(pdb->db, id, name);
949 if (attr) {
950 rv = PyString_FromString(attr);
951 free(attr);
952 return rv;
953 } else {
954 Py_INCREF(Py_None);
955 pdb->ecode = est_mtdb_error(pdb->db);
956 return Py_None;
957 }
958 }
960 static PyObject*
961 _est_db_uri_to_id(PyObject *self, PyObject *args)
962 {
963 PyESTDB *pdb = (PyESTDB*)self;
964 char *uri;
965 int id;
967 if(!PyArg_ParseTuple(args, "s", &uri))
968 return NULL;
970 null_check(pdb->db, "db is closed");
972 id = est_mtdb_uri_to_id(pdb->db, uri);
973 if (id == -1) {
974 pdb->ecode = est_mtdb_error(pdb->db);
975 }
976 return PyInt_FromLong(id);
977 }
979 static PyObject*
980 _est_db_name(PyObject *self, PyObject *args)
981 {
982 PyESTDB *pdb = (PyESTDB*)self;
983 const char *name;
985 null_check(pdb->db, "db is closed");
987 name = est_mtdb_name(pdb->db);
988 return PyString_FromString(name);
989 }
991 static PyObject*
992 _est_db_doc_num(PyObject *self, PyObject *args)
993 {
994 PyESTDB *pdb = (PyESTDB*)self;
995 int docnum;
997 null_check(pdb->db, "db is closed");
999 docnum = est_mtdb_doc_num(pdb->db);
1000 return PyInt_FromLong(docnum);
1001 }
1004 static PyObject*
1005 _est_db_word_num(PyObject *self, PyObject *args)
1006 {
1007 PyESTDB *pdb = (PyESTDB*)self;
1008 int wordnum;
1010 null_check(pdb->db, "db is closed");
1012 wordnum = est_mtdb_word_num(pdb->db);
1013 return PyInt_FromLong(wordnum);
1014 }
1017 static PyObject*
1018 _est_db_size(PyObject *self, PyObject *args)
1019 {
1020 PyESTDB *pdb = (PyESTDB*)self;
1021 double dbsize;
1023 null_check(pdb->db, "db is closed");
1025 dbsize = est_mtdb_size(pdb->db);
1026 return PyFloat_FromDouble(dbsize);
1027 }
1029 static PyObject*
1030 _est_db_search(PyObject *self, PyObject *args)
1031 {
1032 PyESTDB *pdb = (PyESTDB*)self;
1033 PyESTCOND *pcond;
1034 PyESTRES *res;
1035 int nump, *ret, i;
1036 PyObject *hints, *list;
1037 CBMAP *map;
1039 if (!PyArg_ParseTuple(args, "O!", &PyESTCOND_Type, &pcond))
1040 return NULL;
1041 null_check(pdb->db, "db is closed");
1042 null_check(pcond->cond, "this is deleted condition");
1043 debug("null_check");
1045 res = estres_factory();
1046 null_check(res, "_est_db_search() - estres_factory()");
1047 map = cbmapopen();
1048 debug("_est_db_search() - cbmapopen()");
1050 ret = est_mtdb_search(pdb->db, pcond->cond, &nump, map);
1051 debug("_est_db_search() - est_mtdb_search()");
1053 res->ids = ret;
1054 res->num = nump;
1055 res->hints = map;
1056 debug("_est_db_search() - ids, num, hints");
1057 refcount(res, "db_search");
1058 return (PyObject*)res;
1059 }
1061 static PyObject*
1062 _est_db_search_meta(PyObject *self, PyObject *args)
1063 {
1064 PyErr_SetString(PyExc_NotImplementedError, "_est_db_search_meta");
1065 return NULL;
1066 }
1068 static PyObject*
1069 _est_db_scan_doc(PyObject *self, PyObject *args)
1070 {
1071 PyESTDB *pdb = (PyESTDB*)self;
1072 PyESTDOC *pdoc;
1073 PyESTCOND *pcond;
1074 int ret;
1075 PyObject *rv;
1077 if (!PyArg_ParseTuple(args, "O!O!",
1078 &PyESTDOC_Type, &pdoc,
1079 &PyESTCOND_Type, &pcond))
1080 return NULL;
1081 null_check(pdb->db, "db is closed");
1082 null_check(pdoc->doc, "this is deleted document");
1083 null_check(pcond->cond, "this is deleted condition");
1085 ret = est_mtdb_scan_doc(pdb->db, pdoc->doc, pcond->cond);
1086 if (ret) {
1087 rv = Py_True;
1088 } else {
1089 rv = Py_False;
1090 }
1091 Py_INCREF(rv);
1092 return rv;
1093 }
1095 static PyObject*
1096 _est_db_set_cache_size(PyObject *self, PyObject *args, PyObject* kwargs)
1097 {
1098 PyESTDB *pdb = (PyESTDB*)self;
1099 size_t sz = -1;
1100 int anum = -1, tnum = -1, rnum = -1;
1101 static char* keywords[] = {"size", "anum", "tnum", "rnum", NULL};
1103 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iiii", keywords,
1104 &sz, &anum, &tnum, &rnum))
1105 return NULL;
1107 null_check(pdb->db, "db is closed");
1109 if ( sz != -1 || anum != -1 || tnum != -1 || rnum != -1) {
1110 est_mtdb_set_cache_size(pdb->db, sz, anum, tnum, rnum);
1111 }
1112 Py_INCREF(Py_None);
1113 return Py_None;
1114 }
1115 #ifdef DEBUG
1116 static PyObject*
1117 _dic2dic(PyObject *self, PyObject *args)
1118 {
1119 PyObject *dic, *rv;
1120 CBMAP *map;
1121 debug("d 0");
1122 if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dic))
1123 return NULL;
1124 debug("d 1");
1125 map = dic2CBMAP(dic);
1126 debug("d 2");
1127 rv = CBMAP2dic(map);
1128 debug("d 3");
1129 return rv;
1130 }
1131 #endif
1133 static PyMethodDef PyESTDB_methods[] = {
1134 /* Database functions */
1135 {"err_msg", _est_err_msg, METH_VARARGS, NULL},
1136 {"open", _est_db_open, METH_VARARGS, NULL},
1137 {"close", _est_db_close, METH_NOARGS, NULL},
1138 {"error", _est_db_error, METH_NOARGS, NULL},
1139 {"fatal", _est_db_fatal, METH_NOARGS, NULL},
1140 {"add_attr_index", _est_db_add_attr_index, METH_VARARGS, NULL},
1141 {"flush", _est_db_flush, METH_VARARGS, NULL},
1142 {"sync", _est_db_sync, METH_NOARGS, NULL},
1143 {"optimize", _est_db_optimize, METH_VARARGS, NULL},
1144 {"merge", _est_db_merge, METH_VARARGS, NULL},
1145 {"put_doc", _est_db_put_doc, METH_VARARGS, NULL},
1146 {"out_doc", _est_db_out_doc, METH_VARARGS, NULL},
1147 {"edit_doc", _est_db_edit_doc, METH_VARARGS, NULL},
1148 {"get_doc", _est_db_get_doc, METH_VARARGS, NULL},
1149 {"get_doc_attr", _est_db_get_doc_attr, METH_VARARGS, NULL},
1150 {"uri_to_id", _est_db_uri_to_id, METH_VARARGS, NULL},
1151 {"name", _est_db_name, METH_NOARGS, NULL},
1152 {"doc_num", _est_db_doc_num, METH_NOARGS, NULL},
1153 {"word_num", _est_db_word_num, METH_NOARGS, NULL},
1154 {"size", _est_db_size, METH_NOARGS, NULL},
1155 {"search", _est_db_search, METH_VARARGS, NULL},
1156 {"search_meta", _est_db_search_meta, METH_VARARGS, NULL},
1157 {"scan_doc", _est_db_scan_doc, METH_VARARGS, NULL},
1158 {"cache_size", (PyCFunction)_est_db_set_cache_size,
1159 METH_VARARGS | METH_KEYWORDS, NULL},
1160 #ifdef DEBUG
1161 {"dic2dic", _dic2dic, METH_VARARGS, NULL},
1162 #endif
1163 {NULL, NULL}
1164 };
1166 static PyTypeObject PyESTDB_Type = {
1167 /* The ob_type field must be initialized in the module init function
1168 * to be portable to Windows without using C++. */
1169 PyObject_HEAD_INIT(NULL)
1170 0, /*ob_size*/
1171 "_estraiernative.PyESTDB", /*tp_name*/
1172 sizeof(PyESTDB), /*tp_basicsize*/
1173 0, /*tp_itemsize*/
1174 (destructor)PyESTDB_dealloc, /*tp_dealloc*/
1175 0, /*tp_print*/
1176 0, /*tp_getattr*/
1177 0, /*tp_setattr*/
1178 0, /*tp_compare*/
1179 0, /*tp_repr*/
1180 0, /*tp_as_number*/
1181 0, /*tp_as_sequence*/
1182 0, /*tp_as_mapping*/
1183 0, /*tp_hash*/
1184 0, /*tp_call*/
1185 0, /*tp_str*/
1186 0, /*tp_getattro*/
1187 0, /*tp_setattro*/
1188 0, /*tp_as_buffer*/
1189 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1190 0, /*tp_doc*/
1191 0, /* tp_traverse */
1192 0, /* tp_clear */
1193 0, /* tp_richcompare */
1194 0, /* tp_weaklistoffset */
1195 0, /* tp_iter */
1196 0, /* tp_iternext */
1197 PyESTDB_methods, /* tp_methods */
1198 0, /* tp_members */
1199 0, /* tp_getset */
1200 0, /* tp_base */
1201 0, /* tp_dict */
1202 0, /* tp_descr_get */
1203 0, /* tp_descr_set */
1204 0, /* tp_dictoffset */
1205 0, /* tp_init */
1206 0, /* tp_alloc */
1207 PyESTDB_new, /* tp_new */
1208 0, /* tp_free */
1209 };
1211 /* --------------------------------------------------------------------- */
1214 /* =============== ESTCOND ==================*/
1216 static PyObject*
1217 PyESTCOND_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1218 {
1219 PyESTCOND *pcond;
1221 pcond = (PyESTCOND*)type->tp_alloc(type, 0);
1222 if (pcond != NULL) {
1223 pcond->cond = NULL;
1224 }
1225 return (PyObject*)pcond;
1226 }
1228 static int
1229 PyESTCOND_init(PyObject* self, PyObject *args, PyObject *kwds) {
1230 PyESTCOND *pcond = (PyESTCOND*)self;
1231 ESTCOND *cond;
1233 cond = est_cond_new();
1234 if (cond == NULL) {
1235 return -1;
1236 }
1238 pcond->cond = cond;
1239 debug("PyESTCOND_init");
1240 return 0;
1242 }
1244 static void
1245 PyESTCOND_dealloc(PyESTCOND *self)
1246 {
1247 debug("PyESTCOND_dealloc");
1248 if (self->cond != NULL) {
1249 est_cond_delete(self->cond);
1250 self->cond = NULL;
1251 }
1252 PyObject_Del(self);
1253 }
1255 /* ==== Condition functions ==== */
1257 static PyObject*
1258 _est_cond_set_phrase(PyObject *self, PyObject *args)
1259 {
1260 PyESTCOND *pcond = (PyESTCOND*)self;
1261 const char *phrase;
1263 if (!PyArg_ParseTuple(args, "s", &phrase))
1264 return NULL;
1266 if (pcond->cond == NULL) {
1267 PyErr_SetString(EST_Error, "this is deleted condition");
1268 return NULL;
1269 }
1271 est_cond_set_phrase(pcond->cond, phrase);
1272 Py_INCREF(Py_None);
1273 return Py_None;
1274 }
1276 static PyObject*
1277 _est_cond_add_attr(PyObject *self, PyObject *args)
1278 {
1279 PyESTCOND *pcond = (PyESTCOND*)self;
1280 const char *expr;
1282 if (!PyArg_ParseTuple(args, "s", &expr))
1283 return NULL;
1285 null_check(pcond->cond, "this is deleted condition");
1287 est_cond_add_attr(pcond->cond, expr);
1288 Py_INCREF(Py_None);
1289 return Py_None;
1290 }
1292 static PyObject*
1293 _est_cond_set_order(PyObject *self, PyObject *args)
1294 {
1295 PyESTCOND *pcond = (PyESTCOND*)self;
1296 const char *expr;
1298 if (!PyArg_ParseTuple(args, "s", &expr))
1299 return NULL;
1301 null_check(pcond->cond, "this is deleted condition");
1303 est_cond_set_order(pcond->cond, expr);
1304 Py_INCREF(Py_None);
1305 return Py_None;
1306 }
1308 static PyObject*
1309 _est_cond_set_max(PyObject *self, PyObject *args)
1310 {
1311 PyESTCOND *pcond = (PyESTCOND*)self;
1312 int i;
1314 if (!PyArg_ParseTuple(args, "i", &i))
1315 return NULL;
1317 null_check(pcond->cond, "this is deleted condition");
1319 est_cond_set_max(pcond->cond, i);
1320 Py_INCREF(Py_None);
1321 return Py_None;
1322 }
1324 static PyObject*
1325 _est_cond_set_skip(PyObject *self, PyObject *args)
1326 {
1327 PyESTCOND *pcond = (PyESTCOND*)self;
1328 int i;
1330 if (!PyArg_ParseTuple(args, "i", &i))
1331 return NULL;
1333 null_check(pcond->cond, "this is deleted condition");
1335 est_cond_set_skip(pcond->cond, i);
1336 Py_INCREF(Py_None);
1337 return Py_None;
1338 }
1340 static PyObject*
1341 _est_cond_set_options(PyObject *self, PyObject *args)
1342 {
1343 PyESTCOND *pcond = (PyESTCOND*)self;
1344 int i;
1346 if (!PyArg_ParseTuple(args, "i", &i))
1347 return NULL;
1349 null_check(pcond->cond, "this is deleted condition");
1351 est_cond_set_options(pcond->cond, i);
1352 Py_INCREF(Py_None);
1353 return Py_None;
1354 }
1356 static PyObject*
1357 _est_cond_set_auxiliary(PyObject *self, PyObject *args)
1358 {
1359 PyESTCOND *pcond = (PyESTCOND*)self;
1360 int i;
1362 if (!PyArg_ParseTuple(args, "i", &i))
1363 return NULL;
1365 null_check(pcond->cond, "this is deleted condition");
1367 est_cond_set_auxiliary(pcond->cond, i);
1368 Py_INCREF(Py_None);
1369 return Py_None;
1370 }
1372 static PyObject*
1373 _est_cond_set_eclipse(PyObject *self, PyObject *args)
1374 {
1375 PyESTCOND *pcond = (PyESTCOND*)self;
1376 double d;
1378 if (!PyArg_ParseTuple(args, "d", &d))
1379 return NULL;
1381 null_check(pcond->cond, "this is deleted condition");
1383 est_cond_set_auxiliary(pcond->cond, d);
1384 Py_INCREF(Py_None);
1385 return Py_None;
1386 }
1388 static PyObject*
1389 _est_cond_set_distinct(PyObject *self, PyObject *args)
1390 {
1391 #if (_EST_LIBVER > 814)
1392 PyESTCOND *pcond = (PyESTCOND*)self;
1393 char *name;
1395 if (!PyArg_ParseTuple(args, "s", &name))
1396 return NULL;
1398 null_check(pcond->cond, "this is deleted condition");
1400 est_cond_set_distinct(pcond->cond, name);
1401 Py_INCREF(Py_None);
1402 return Py_None;
1403 #else
1404 PyErr_SetString(PyExc_NotImplementedError, "_est_cond_set_distinct");
1405 return NULL;
1406 #endif
1407 }
1409 static PyObject*
1410 _est_cond_set_mask(PyObject *self, PyObject *args)
1411 {
1412 #if (_EST_LIBVER > 814)
1413 PyESTCOND *pcond = (PyESTCOND*)self;
1414 int i;
1416 if (!PyArg_ParseTuple(args, "i", &i))
1417 return NULL;
1419 null_check(pcond->cond, "this is deleted condition");
1421 est_cond_set_mask(pcond->cond, i);
1422 Py_INCREF(Py_None);
1423 return Py_None;
1424 #else
1425 PyErr_SetString(PyExc_NotImplementedError, "_est_cond_set_mask");
1426 return NULL;
1427 #endif
1428 }
1430 static PyObject*
1431 _est_cond_get_phrase(PyObject *self, PyObject *args)
1432 {
1433 PyESTCOND *pcond = (PyESTCOND*)self;
1434 const char *p;
1436 null_check(pcond->cond, "this is deleted condition");
1438 p = est_cond_phrase(pcond->cond);
1439 if (p) {
1440 return PyString_FromString(p);
1441 } else {
1442 Py_INCREF(Py_None);
1443 return Py_None;
1444 }
1445 }
1447 static PyObject*
1448 _est_cond_get_attrs(PyObject *self, PyObject *args)
1449 {
1450 PyESTCOND *pcond = (PyESTCOND*)self;
1451 const CBLIST *cbl;
1452 PyObject *rv;
1454 null_check(pcond->cond, "this is deleted condition");
1456 // donot call cblistclose(), cbl and pcond->cond are in the same boat.
1457 cbl = est_cond_attrs(pcond->cond);
1458 if (cbl) {
1459 return CBLIST2list((CBLIST*)cbl);
1460 } else {
1461 Py_INCREF(Py_None);
1462 return Py_None;
1463 }
1464 }
1466 static PyObject*
1467 _est_cond_get_order(PyObject *self, PyObject *args)
1468 {
1469 PyESTCOND *pcond = (PyESTCOND*)self;
1470 const char *o;
1472 null_check(pcond->cond, "this is deleted condition");
1474 o = est_cond_order(pcond->cond);
1475 if (o) {
1476 return PyString_FromString(o);
1477 } else {
1478 Py_INCREF(Py_None);
1479 return Py_None;
1480 }
1481 }
1483 static PyObject*
1484 _est_cond_get_max(PyObject *self, PyObject *args)
1485 {
1486 PyESTCOND *pcond = (PyESTCOND*)self;
1487 int i;
1489 null_check(pcond->cond, "this is deleted condition");
1491 i = est_cond_max(pcond->cond);
1492 return PyInt_FromLong(i);
1493 }
1495 static PyObject*
1496 _est_cond_get_skip(PyObject *self, PyObject *args)
1497 {
1498 PyESTCOND *pcond = (PyESTCOND*)self;
1499 int i;
1501 null_check(pcond->cond, "this is deleted condition");
1503 i = est_cond_skip(pcond->cond);
1504 return PyInt_FromLong(i);
1505 }
1507 static PyObject*
1508 _est_cond_get_options(PyObject *self, PyObject *args)
1509 {
1510 PyESTCOND *pcond = (PyESTCOND*)self;
1511 int i;
1513 null_check(pcond->cond, "this is deleted condition");
1515 i = est_cond_options(pcond->cond);
1516 return PyInt_FromLong(i);
1517 }
1520 static PyObject*
1521 _est_cond_get_auxiliary(PyObject *self, PyObject *args)
1522 {
1523 PyESTCOND *pcond = (PyESTCOND*)self;
1524 int i;
1526 null_check(pcond->cond, "this is deleted condition");
1528 i = est_cond_auxiliary(pcond->cond);
1529 return PyInt_FromLong(i);
1530 }
1533 static PyObject*
1534 _est_cond_get_distinct(PyObject *self, PyObject *args)
1535 {
1536 PyESTCOND *pcond = (PyESTCOND*)self;
1537 const char *d;
1539 null_check(pcond->cond, "this is deleted condition");
1540 d = est_cond_distinct(pcond->cond);
1541 if (d) {
1542 return PyString_FromString(d);
1543 } else {
1544 Py_INCREF(Py_None);
1545 return Py_None;
1546 }
1547 }
1549 static PyObject*
1550 _est_cond_get_mask(PyObject *self, PyObject *args)
1551 {
1552 PyESTCOND *pcond = (PyESTCOND*)self;
1553 int i;
1555 null_check(pcond->cond, "this is deleted condition");
1557 i = est_cond_mask(pcond->cond);
1558 return PyInt_FromLong(i);
1559 }
1561 static PyMethodDef PyESTCOND_methods[] = {
1562 /* Condition functions */
1563 {"set_phrase", _est_cond_set_phrase, METH_VARARGS, NULL},
1564 {"add_attr", _est_cond_add_attr, METH_VARARGS, NULL},
1565 {"set_order", _est_cond_set_order, METH_VARARGS, NULL},
1566 {"set_max", _est_cond_set_max, METH_VARARGS, NULL},
1567 {"set_skip", _est_cond_set_skip, METH_VARARGS, NULL},
1568 {"set_options", _est_cond_set_options, METH_VARARGS, NULL},
1569 {"set_auxiliary", _est_cond_set_auxiliary, METH_VARARGS, NULL},
1570 {"set_eclipse", _est_cond_set_eclipse, METH_VARARGS, NULL},
1571 {"set_mask", _est_cond_set_mask, METH_VARARGS, NULL},
1572 {"get_phrase", _est_cond_get_phrase, METH_NOARGS, NULL},
1573 {"get_attrs", _est_cond_get_attrs, METH_NOARGS, NULL},
1574 {"get_order", _est_cond_get_order, METH_NOARGS, NULL},
1575 {"get_max", _est_cond_get_max, METH_NOARGS, NULL},
1576 {"get_skip", _est_cond_get_skip, METH_NOARGS, NULL},
1577 {"get_options", _est_cond_get_options, METH_NOARGS, NULL},
1578 {"get_auxliary", _est_cond_get_auxiliary, METH_NOARGS, NULL},
1579 {"get_distinct", _est_cond_get_distinct, METH_NOARGS, NULL},
1580 {"get_mask", _est_cond_get_mask, METH_NOARGS, NULL},
1582 {NULL, NULL} /* sentinel */
1583 };
1585 static PyTypeObject PyESTCOND_Type = {
1586 /* The ob_type field must be initialized in the module init function
1587 * to be portable to Windows without using C++. */
1588 PyObject_HEAD_INIT(NULL)
1589 0, /*ob_size*/
1590 "_estraiernative.PyESTCOND", /*tp_name*/
1591 sizeof(PyESTCOND), /*tp_basicsize*/
1592 0, /*tp_itemsize*/
1593 /* methods */
1594 (destructor)PyESTCOND_dealloc, /*tp_dealloc*/
1595 0, /*tp_print*/
1596 0, /*tp_getattr*/
1597 0, /*tp_setattr*/
1598 0, /*tp_compare*/
1599 0, /*tp_repr*/
1600 0, /*tp_as_number*/
1601 0, /*tp_as_sequence*/
1602 0, /*tp_as_mapping*/
1603 0, /*tp_hash*/
1604 0, /*tp_call*/
1605 0, /*tp_str*/
1606 0, /*tp_getattro*/
1607 0, /*tp_setattro*/
1608 0, /*tp_as_buffer*/
1609 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1610 0, /*tp_doc*/
1611 0, /* tp_traverse */
1612 0, /* tp_clear */
1613 0, /* tp_richcompare */
1614 0, /* tp_weaklistoffset */
1615 0, /* tp_iter */
1616 0, /* tp_iternext */
1617 PyESTCOND_methods, /* tp_methods */
1618 0, /* tp_members */
1619 0, /* tp_getset */
1620 0, /* tp_base */
1621 0, /* tp_dict */
1622 0, /* tp_descr_get */
1623 0, /* tp_descr_set */
1624 0, /* tp_dictoffset */
1625 PyESTCOND_init, /* tp_init */
1626 0, /* tp_alloc */
1627 PyESTCOND_new, /* tp_new */
1628 0, /* tp_free */
1629 };
1630 /* --------------------------------------------------------------------- */
1632 /* =============== ESTRES ==================*/
1633 static PyESTRES*
1634 estres_factory(void)
1635 {
1636 PyESTRES *res;
1637 //res = PyESTRES_Type.tp_alloc(&PyESTRES_Type, 0);
1638 res = PyObject_New(PyESTRES, &PyESTRES_Type);
1639 if (res == NULL) {
1640 return NULL;
1641 }
1642 res->ids = NULL;
1643 res->dbidxs = NULL;
1644 res->num = 0;
1645 res->hints = NULL;
1646 debug("estres_factory");
1647 refcount(res, "estres_factory");
1648 return res;
1649 }
1651 static PyObject*
1652 PyESTRES_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1653 debug("PyESTRES_new");
1654 return (PyObject*)estres_factory();
1655 }
1657 static void
1658 PyESTRES_dealloc(PyESTRES *self)
1659 {
1660 assert(self != NULL);
1661 if (self->ids != NULL) {
1662 free(self->ids);
1663 }
1664 if (self->dbidxs != NULL) {
1665 free(self->dbidxs);
1666 }
1667 if (self->hints != NULL) {
1668 cbmapclose(self->hints);
1669 }
1670 debug("PyESTERS_dealloc");
1671 PyObject_Del(self);
1672 }
1674 /* ==== Result methods ==== */
1675 static PyObject*
1676 _est_res_doc_num(PyObject *self, PyObject *args)
1677 {
1678 PyESTRES* res = (PyESTRES*)self;
1679 assert(res != NULL);
1680 debug("doc_num");
1681 return PyInt_FromLong(res->num);
1682 }
1684 static PyObject*
1685 _est_res_get_doc_id(PyObject *self, PyObject *args)
1686 {
1687 PyESTRES* res = (PyESTRES*)self;
1688 int idx;
1690 if (!PyArg_ParseTuple(args, "i", &idx))
1691 return NULL;
1693 if (!res->ids || idx < 0 || idx >= res->num) {
1694 PyErr_SetString(PyExc_IndexError, "index out of range");
1695 return NULL;
1696 }
1698 return PyInt_FromLong(res->ids[idx]);
1699 }
1701 static PyObject*
1702 _est_res_get_dbidx(PyObject *self, PyObject *args)
1703 {
1704 PyESTRES* res = (PyESTRES*)self;
1705 int idx;
1707 if (!PyArg_ParseTuple(args, "i", &idx))
1708 return NULL;
1710 if (!res->ids || idx < 0 || idx >= res->num) {
1711 PyErr_SetString(PyExc_IndexError, "index out of range");
1712 return NULL;
1713 }
1715 return PyInt_FromLong(res->dbidxs[idx]);
1716 }
1717 static PyObject*
1718 _est_res_hint_words(PyObject *self, PyObject *args)
1719 {
1720 PyESTRES* res = (PyESTRES*)self;
1721 PyObject *rv;
1722 CBLIST *words;
1723 int i;
1724 const char* vbuf;
1726 if (res->hints == NULL) {
1727 return PyList_New(0);
1728 }
1730 words = cbmapkeys(res->hints);
1731 for (i=0; i < CB_LISTNUM(words); i++) {
1732 vbuf = CB_LISTVAL(words, i);
1733 if (vbuf[0] == '\0') {
1734 free(cblistremove(words, i, NULL));
1735 break;
1736 }
1737 }
1738 rv = CBLIST2list(words);
1739 cblistclose(words);
1740 return rv;
1741 }
1743 static PyObject*
1744 _est_res_hint(PyObject *self, PyObject *args)
1745 {
1746 PyESTRES* res = (PyESTRES*)self;
1747 char *word;
1748 const char* vbuf;
1750 if (!PyArg_ParseTuple(args, "s", word)) {
1751 return NULL;
1752 }
1753 if (res->hints != NULL) {
1754 return PyInt_FromLong(0);
1755 }
1756 vbuf = cbmapget(res->hints, word, -1, NULL);
1757 if (vbuf == NULL) {
1758 return PyInt_FromLong(0);
1759 }
1760 return PyInt_FromLong(atoi(vbuf));
1761 }
1763 static PyObject*
1764 _est_res_get_score(PyObject *self, PyObject *args)
1765 {
1766 PyESTRES* res = (PyESTRES*)self;
1767 int idx;
1769 PyErr_SetString(PyExc_NotImplementedError, "_est_cond_set_mask");
1770 return NULL;
1771 }
1772 static PyObject*
1773 _est_res_get_shadows(PyObject *self, PyObject *args)
1774 {
1775 PyESTRES* res = (PyESTRES*)self;
1777 PyErr_SetString(PyExc_NotImplementedError, "_est_cond_set_mask");
1778 return NULL;
1779 }
1781 static PyMethodDef PyESTRES_methods[] = {
1782 {"doc_num", _est_res_doc_num, METH_NOARGS, NULL},
1783 {"get_doc_id", _est_res_get_doc_id, METH_VARARGS, NULL},
1784 {"get_dbidx", _est_res_get_dbidx, METH_VARARGS, NULL},
1785 {"hint_words", _est_res_hint_words, METH_NOARGS, NULL},
1786 {"hint", _est_res_hint, METH_VARARGS, NULL},
1787 {"get_score", _est_res_get_score, METH_VARARGS, NULL},
1788 {"get_shadows", _est_res_doc_num, METH_VARARGS, NULL},
1789 {NULL, NULL}
1790 };
1793 static PyTypeObject PyESTRES_Type = {
1794 /* The ob_type field must be initialized in the module init function
1795 * to be portable to Windows without using C++. */
1796 PyObject_HEAD_INIT(NULL)
1797 0, /*ob_size*/
1798 "_estraiernative.PyESTRES", /*tp_name*/
1799 sizeof(PyESTRES), /*tp_basicsize*/
1800 0, /*tp_itemsize*/
1801 (destructor)PyESTRES_dealloc, /*tp_dealloc*/
1802 0, /*tp_print*/
1803 0, /*tp_getattr*/
1804 0, /*tp_setattr*/
1805 0, /*tp_compare*/
1806 0, /*tp_repr*/
1807 0, /*tp_as_number*/
1808 0, /*tp_as_sequence*/
1809 0, /*tp_as_mapping*/
1810 0, /*tp_hash*/
1811 0, /*tp_call*/
1812 0, /*tp_str*/
1813 0, /*tp_getattro*/
1814 0, /*tp_setattro*/
1815 0, /*tp_as_buffer*/
1816 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1817 0, /*tp_doc*/
1818 0, /* tp_traverse */
1819 0, /* tp_clear */
1820 0, /* tp_richcompare */
1821 0, /* tp_weaklistoffset */
1822 0, /* tp_iter */
1823 0, /* tp_iternext */
1824 PyESTRES_methods, /* tp_methods */
1825 0, /* tp_members */
1826 0, /* tp_getset */
1827 0, /* tp_base */
1828 0, /* tp_dict */
1829 0, /* tp_descr_get */
1830 0, /* tp_descr_set */
1831 0, /* tp_dictoffset */
1832 0, /* tp_init */
1833 0, /* tp_alloc */
1834 PyESTRES_new, /* tp_new */
1835 0, /* tp_free */
1836 };
1839 /* --------------------------------------------------------------------- */
1841 static PyMethodDef hyperest_methods[] = {
1842 {NULL, NULL}
1843 };
1845 PyDoc_STRVAR(module_doc,
1846 "This is a template module just for instruction.");
1848 /* Initialization function for the module (*must* be called initxx) */
1850 PyMODINIT_FUNC
1851 init_estraiernative(void)
1852 {
1853 PyObject *m;
1854 PyObject *d;
1856 if (PyType_Ready(&PyESTDOC_Type) < 0)
1857 return;
1859 if (PyType_Ready(&PyESTCOND_Type) < 0)
1860 return;
1862 if (PyType_Ready(&PyESTDB_Type) < 0)
1863 return;
1865 if (PyType_Ready(&PyESTRES_Type) < 0)
1866 return;
1868 m = Py_InitModule3("_estraiernative", hyperest_methods, module_doc);
1870 // Document
1871 Py_INCREF(&PyESTDOC_Type);
1872 PyModule_AddObject(m, "Document", (PyObject*)&PyESTDOC_Type);
1874 // Condition
1875 d = PyESTCOND_Type.tp_dict;
1876 define_const(d, "SURE", ESTCONDSURE);
1877 define_const(d, "USUAL", ESTCONDUSUAL);
1878 define_const(d, "FAST", ESTCONDFAST);
1879 define_const(d, "AGITO", ESTCONDAGITO);
1880 define_const(d, "NOIDF", ESTCONDNOIDF);
1881 define_const(d, "SIMPLE", ESTCONDSIMPLE);
1882 define_const(d, "ROUGH", ESTCONDROUGH);
1883 define_const(d, "UNION", ESTCONDUNION);
1884 define_const(d, "ISECT", ESTCONDISECT);
1885 Py_INCREF(&PyESTCOND_Type);
1886 PyModule_AddObject(m, "Condition", (PyObject*)&PyESTCOND_Type);
1888 // Database
1889 d = PyESTDB_Type.tp_dict;
1890 define_const_fmt(d, "VERSION", est_version, "s");
1891 define_const(d, "ERRNOERR", ESTENOERR);
1892 define_const(d, "ERRINVAL", ESTEINVAL);
1893 define_const(d, "ERRACCES", ESTEACCES);
1894 define_const(d, "ERRLOCK", ESTELOCK);
1895 define_const(d, "ERRDB", ESTEDB);
1896 define_const(d, "ERRIO", ESTEIO);
1897 define_const(d, "ERRNOITEM", ESTENOITEM);
1898 define_const(d, "ERRMISC", ESTEMISC);
1899 define_const(d, "DBREADER", ESTDBREADER);
1900 define_const(d, "DBWRITER", ESTDBWRITER);
1901 define_const(d, "DBCREAT", ESTDBCREAT);
1902 define_const(d, "DBTRUNC", ESTDBTRUNC);
1903 define_const(d, "DBNOLCK", ESTDBNOLCK);
1904 define_const(d, "DBLCKNB", ESTDBLCKNB);
1905 define_const(d, "DBPERFNG", ESTDBPERFNG);
1906 define_const(d, "DBCHRCAT", ESTDBCHRCAT);
1907 define_const(d, "DBSMALL", ESTDBSMALL);
1908 define_const(d, "DBLARGE", ESTDBLARGE);
1909 define_const(d, "DBHUGE", ESTDBHUGE);
1910 define_const(d, "DBHUGE2", ESTDBHUGE2);
1911 define_const(d, "DBHUGE3", ESTDBHUGE3);
1912 define_const(d, "DBSCVOID", ESTDBSCVOID);
1913 define_const(d, "DBSCINT", ESTDBSCINT);
1914 define_const(d, "DBSCASIS", ESTDBSCASIS);
1915 define_const(d, "IDXATTRSEQ", ESTIDXATTRSEQ);
1916 define_const(d, "IDXATTRSTR", ESTIDXATTRSTR);
1917 define_const(d, "IDXATTRNUM", ESTIDXATTRNUM);
1918 define_const(d, "OPTNOPURGE", ESTOPTNOPURGE);
1919 define_const(d, "OPTNODBOPT", ESTOPTNODBOPT);
1920 define_const(d, "MGCLEAN", ESTMGCLEAN);
1921 define_const(d, "PDCLEAN", ESTPDCLEAN);
1922 define_const(d, "PDWEIGHT", ESTPDWEIGHT);
1923 define_const(d, "ODCLEAN", ESTODCLEAN);
1924 define_const(d, "GDNOATTR", ESTGDNOATTR);
1925 define_const(d, "GDNOTEXT", ESTGDNOTEXT);
1927 Py_INCREF(&PyESTDB_Type);
1928 PyModule_AddObject(m, "Database", (PyObject*)&PyESTDB_Type);
1930 // Result
1931 Py_INCREF(&PyESTRES_Type);
1932 PyModule_AddObject(m, "Result", (PyObject*)&PyESTRES_Type);
1934 /* Add some symbolic constants to the module */
1935 EST_Error = PyErr_NewException("_estraiernative.Error", NULL, NULL);
1936 if (EST_Error == NULL)
1937 return;
1938 PyModule_AddObject(m, "EstError", EST_Error);
1940 debug("init_estraeirnative fin.");
1941 }
