CUBRID Engine  latest
db_object.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * db_object.c -
21  */
22 
23 #include "config.h"
24 #include <assert.h>
25 #include <stdlib.h>
26 #include "dbi.h"
27 #include "db_stub.h"
28 #include "api_util.h"
29 
34 
36 {
39 };
40 
42 {
45 };
46 
48 {
53  int deleted;
56  int nattrs;
61 };
62 
64 {
69 };
70 
71 /* result set meta api */
72 static int rm_api_get_count (API_RESULTSET_META * impl, int *count);
73 static int rm_api_get_info (API_RESULTSET_META * impl, int index, CI_RMETA_INFO_TYPE type, void *arg, size_t size);
74 static void or_rm_bind_destroyf (BH_BIND * bind);
75 static int or_rm_bind_create (OBJECT_RESULTSET * or, OBJECT_RM_BIND ** rrm_bind);
76 static void or_rm_bind_destroy (OBJECT_RM_BIND * rm_bind);
77 
78 /* result set api */
80 static int res_api_fetch (API_RESULTSET * impl, int offset, CI_FETCH_POSITION pos);
81 static int res_api_tell (API_RESULTSET * impl, int *offset);
82 static int res_api_clear_updates (API_RESULTSET * impl);
83 static int res_api_delete_row (API_RESULTSET * impl);
84 static int res_api_get_value (API_RESULTSET * impl, int index, CI_TYPE type, void *addr, size_t len, size_t * outlen,
85  bool * is_null);
86 static int res_api_get_value_by_name (API_RESULTSET * impl, const char *name, CI_TYPE type, void *addr, size_t len,
87  size_t * outlen, bool * isnull);
88 static int res_api_update_value (API_RESULTSET * impl, int index, CI_TYPE type, void *addr, size_t len);
89 static int res_api_apply_update (API_RESULTSET * impl);
90 static void res_api_destroy (API_RESULTSET * impl);
91 static void or_res_bind_destroyf (BH_BIND * bind);
92 static int or_res_bind_create (OBJECT_RESULTSET * or, OBJECT_RES_BIND ** rres_bind);
93 static void or_res_bind_destroy (OBJECT_RES_BIND * res_bind);
94 
95 /* value bind table interface */
96 static int vt_api_get_index_by_name (void *impl, const char *name, int *ri);
97 static int vt_api_get_db_value (void *impl, int index, DB_VALUE * dbval);
98 static int vt_api_set_db_value (void *impl, int index, DB_VALUE * dbval);
99 static int vt_api_init_domain (void *impl, int index, DB_VALUE * value);
100 /* object resultset */
101 static void or_destroy (OBJECT_RESULTSET * or);
102 static int or_create (OID * oid, BIND_HANDLE conn, BH_INTERFACE * bh_ifs, OBJECT_RESULTSET ** ror);
103 
104 /* object result set pool */
105 static int orp_ht_comparef (void *key1, void *key2, int *r);
106 static int orp_ht_hashf (void *key, unsigned int *rv);
107 static int orp_ht_keyf (void *elem, void **rk);
108 static int orp_api_get_object_resultset (API_OBJECT_RESULTSET_POOL * pool, CI_OID * oid, API_RESULTSET ** rref);
109 static int orp_oid_delete (API_OBJECT_RESULTSET_POOL * pool, CI_OID * oid);
110 static int orp_oid_get_classname (API_OBJECT_RESULTSET_POOL * pool, CI_OID * xoid, char *name, size_t size);
111 static void orp_api_destroy (API_OBJECT_RESULTSET_POOL * pool);
112 
113 
114 /*
115  * rm_api_get_count -
116  * return:
117  * impl():
118  * count():
119  */
120 static int
122 {
124  assert (impl != NULL);
125  assert (count != NULL);
126 
127  or = ((OBJECT_RM_BIND *) impl)->or;
128  *count = or->nattrs;
129  return NO_ERROR;
130 }
131 
132 /*
133  * rm_api_get_info -
134  * return:
135  * impl():
136  * index():
137  * type():
138  * arg():
139  * size():
140  */
141 static int
142 rm_api_get_info (API_RESULTSET_META * impl, int index, CI_RMETA_INFO_TYPE type, void *arg, size_t size)
143 {
145  DB_ATTRIBUTE *attr;
146  DB_DOMAIN *domain;
147  int res;
148 
149  assert (impl != NULL);
150 
151  /* convert to zero based index */
152  index--;
153 
154  or = ((OBJECT_RM_BIND *) impl)->or;
155  if (index < 0 || index >= or->nattrs)
156  {
157  return ER_INTERFACE_INVALID_ARGUMENT; /* index out of range */
158  }
159  if (arg == NULL || size <= 0)
160  {
162  }
163  attr = or->attr_index[index];
164 
165  assert (attr != NULL);
166 
167  switch (type)
168  {
169  case CI_RMETA_INFO_COL_LABEL:
170  /* col label is not defined. return null string */
171  *(char *) arg = '\0';
172  return NO_ERROR;
173 
174  case CI_RMETA_INFO_COL_NAME:
175  {
176  size_t namelen;
177  const char *attr_name;
178 
179  attr_name = db_attribute_name (attr);
180 
181  assert (attr_name != NULL);
182 
183  namelen = strlen (attr_name) + 1;
184  if (namelen > size)
185  {
186  return ER_INTERFACE_INVALID_ARGUMENT; /* size insufficient */
187  }
188  strcpy ((char *) arg, attr_name);
189  return NO_ERROR;
190  }
191  case CI_RMETA_INFO_COL_TYPE:
192  if (size < sizeof (CI_TYPE))
193  {
195  }
196 
197  domain = db_attribute_domain (attr);
198  if (domain == NULL)
199  {
200  return ER_INTERFACE_GENERIC;
201  }
202 
203  res = db_type_to_type (TP_DOMAIN_TYPE (domain), (CI_TYPE *) arg);
204  return res;
205 
206  case CI_RMETA_INFO_PRECISION:
207  if (size < sizeof (int))
208  {
210  }
211 
212  domain = db_attribute_domain (attr);
213  if (domain == NULL)
214  {
215  return ER_INTERFACE_GENERIC;
216  }
217 
218  *(int *) arg = db_domain_precision (domain);
219  return NO_ERROR;
220 
221  case CI_RMETA_INFO_SCALE:
222  if (size < sizeof (int))
223  {
225  }
226 
227  domain = db_attribute_domain (attr);
228  if (domain == NULL)
229  {
230  return ER_INTERFACE_GENERIC;
231  }
232 
233  *(int *) arg = db_domain_scale (domain);
234  return NO_ERROR;
235 
236  case CI_RMETA_INFO_TABLE_NAME:
237  {
238  const char *tbl_name;
239  size_t sz;
240 
241  assert (or->clz != NULL);
242 
243  tbl_name = db_get_class_name (or->clz);
244  if (tbl_name == NULL)
245  {
246  return ER_INTERFACE_GENERIC;
247  }
248 
249  sz = strlen (tbl_name) + 1;
250  if (sz > size)
251  {
253  }
254  strcpy ((char *) arg, tbl_name);
255  return NO_ERROR;
256  }
257  case CI_RMETA_INFO_IS_AUTO_INCREMENT:
258  if (size < sizeof (int))
259  {
261  }
262 
263  *(int *) arg = db_attribute_is_auto_increment (attr);
264  return NO_ERROR;
265 
266  case CI_RMETA_INFO_IS_NULLABLE:
267  if (size < sizeof (int))
268  {
270  }
271 
272  *(int *) arg = db_attribute_is_non_null (attr) ? 0 : 1;
273  return NO_ERROR;
274 
275  case CI_RMETA_INFO_IS_WRITABLE:
276  if (size < sizeof (int))
277  {
279  }
280 
281  if (or->obj->lock == X_LOCK || or->obj->lock == U_LOCK)
282  {
283  *(int *) arg = 1;
284  }
285  else
286  {
287  *(int *) arg = 0;
288  }
289  return NO_ERROR;
290 
291  default:
293  }
294 
295  assert (0);
296  return ER_INTERFACE_GENERIC;
297 }
298 
302 };
303 
304 /*
305  * or_rm_bind_destroyf -
306  * return:
307  * bind():
308  */
309 static void
311 {
312  OBJECT_RM_BIND *rm_bind = (OBJECT_RM_BIND *) bind;
313  assert (rm_bind != NULL);
314  assert (rm_bind->or->rm_bind == rm_bind);
315  rm_bind->or->rm_bind = NULL;
316  or_rm_bind_destroy (rm_bind);
317 }
318 
319 /*
320  * or_rm_bind_create -
321  * return:
322  * or():
323  * rrm_bind():
324  */
325 static int
327 {
328  OBJECT_RM_BIND *rm_bind;
329  assert (or != NULL);
330  assert (rrm_bind != NULL);
331  rm_bind = API_MALLOC (sizeof (*rm_bind));
332  if (rm_bind == NULL)
334  rm_bind->rm.bind.dtor = or_rm_bind_destroyf;
335  rm_bind->rm.handle_type = HANDLE_TYPE_RMETA;
336  rm_bind->rm.ifs = &RM_IFS_;
337  rm_bind->or = or;
338  *rrm_bind = rm_bind;
339  return NO_ERROR;
340 }
341 
342 /*
343  * or_rm_bind_destroy -
344  * return:
345  * rm_bind():
346  */
347 static void
349 {
350  assert (rm_bind != NULL);
351  API_FREE (rm_bind);
352 }
353 
354 /* ------------------------------------------------------------------------- */
355 /* OBJECT RESULTSET IMPLEMENTATION */
356 
357 /*
358  * res_api_get_resultset_metadata -
359  * return:
360  * impl():
361  * rimpl():
362  */
363 static int
365 {
367  assert (impl != NULL);
368  assert (rimpl != NULL);
369  or = ((OBJECT_RES_BIND *) impl)->or;
370  *rimpl = (API_RESULTSET_META *) or->rm_bind;
371  return NO_ERROR;
372 }
373 
374 /*
375  * res_api_fetch -
376  * return:
377  * impl():
378  * offset():
379  * pos():
380  */
381 static int
382 res_api_fetch (API_RESULTSET * impl, int offset, CI_FETCH_POSITION pos)
383 {
385  int idx;
386  assert (impl != NULL);
387  or = ((OBJECT_RES_BIND *) impl)->or;
388  if (pos == CI_FETCH_POSITION_CURRENT || pos == CI_FETCH_POSITION_FIRST)
389  idx = offset;
390  else if (pos == CI_FETCH_POSITION_LAST)
391  idx = or->nattrs + offset;
392  else
394  if (idx != 0)
395  return ER_INTERFACE_INVALID_ARGUMENT; /* index out of range */
396 
397  if (or->deleted == 1)
398  return ER_INTERFACE_GENERIC; /* already deleted */
399  return NO_ERROR;
400 }
401 
402 /*
403  * res_api_tell -
404  * return:
405  * impl():
406  * offset():
407  */
408 static int
409 res_api_tell (API_RESULTSET * impl, int *offset)
410 {
412  assert (impl != NULL);
413  assert (offset != NULL);
414  or = ((OBJECT_RES_BIND *) impl)->or;
415  *offset = 1;
416  return NO_ERROR;
417 }
418 
419 /*
420  * res_api_clear_updates -
421  * return:
422  * impl():
423  */
424 static int
426 {
428  int res;
429 
430  assert (impl != NULL);
431  or = ((OBJECT_RES_BIND *) impl)->or;
432 
433  if (or->deleted == 1)
434  return ER_INTERFACE_GENERIC; /* already deleted */
435  res = or->vt->ifs->reset (or->vt);
436  return res;
437 }
438 
439 /*
440  * res_api_delete_row -
441  * return:
442  * impl():
443  */
444 static int
446 {
448  int res;
449 
450  assert (impl != NULL);
451  or = ((OBJECT_RES_BIND *) impl)->or;
452  if (or->deleted == 1)
453  return ER_INTERFACE_GENERIC; /* already deleted */
454  res = db_drop (or->obj);
455  if (res != NO_ERROR)
456  return ER_INTERFACE_GENERIC;
457  or->vt->ifs->destroy (or->vt);
458  or->vt = NULL;
459  or->deleted = 1;
460  return NO_ERROR;
461 }
462 
463 /*
464  * res_api_get_value -
465  * return:
466  * impl():
467  * index():
468  * type():
469  * addr():
470  * len():
471  * outlen():
472  * is_null():
473  */
474 static int
475 res_api_get_value (API_RESULTSET * impl, int index, CI_TYPE type, void *addr, size_t len, size_t * outlen,
476  bool * is_null)
477 {
479  int res;
480 
481  assert (impl != NULL);
482 
483  /* convert to zero based index */
484  index--;
485 
486  or = ((OBJECT_RES_BIND *) impl)->or;
487  if (index < 0 || index >= or->nattrs)
489  if (or->deleted)
490  return ER_INTERFACE_GENERIC; /* value table deleted */
491  res = or->vt->ifs->get_value (or->vt, index, type, addr, len, outlen, is_null);
492  return res;
493 }
494 
495 /*
496  * res_api_get_value_by_name -
497  * return:
498  * impl():
499  * name():
500  * type():
501  * addr():
502  * len():
503  * outlen():
504  * isnull():
505  */
506 static int
507 res_api_get_value_by_name (API_RESULTSET * impl, const char *name, CI_TYPE type, void *addr, size_t len,
508  size_t * outlen, bool * isnull)
509 {
511  int res;
512 
513  assert (impl != NULL);
514  or = ((OBJECT_RES_BIND *) impl)->or;
515  if (name == NULL)
517  if (or->deleted)
518  return ER_INTERFACE_GENERIC; /* value table deleted */
519  res = or->vt->ifs->get_value_by_name (or->vt, name, type, addr, len, outlen, isnull);
520  return res;
521 }
522 
523 /*
524  * res_api_update_value -
525  * return:
526  * impl():
527  * index():
528  * type():
529  * addr():
530  * len():
531  */
532 static int
533 res_api_update_value (API_RESULTSET * impl, int index, CI_TYPE type, void *addr, size_t len)
534 {
536  int res;
537 
538  assert (impl != NULL);
539 
540  /* convert to zero based index */
541  index--;
542 
543  or = ((OBJECT_RES_BIND *) impl)->or;
544  if (index < 0 || index >= or->nattrs)
546  if (or->deleted)
547  return ER_INTERFACE_GENERIC; /* value table deleted */
548  res = or->vt->ifs->set_value (or->vt, index, type, addr, len);
549  return res;
550 }
551 
552 /*
553  * res_api_apply_update -
554  * return:
555  * impl():
556  */
557 static int
559 {
561  int res;
562 
563  assert (impl != NULL);
564  or = ((OBJECT_RES_BIND *) impl)->or;
565  if (or->deleted)
566  return ER_INTERFACE_GENERIC; /* value table deleted */
567  res = or->vt->ifs->apply_updates (or->vt);
568  return res;
569 }
570 
571 /*
572  * res_api_destroy -
573  * return:
574  * impl():
575  */
576 static void
578 {
580  assert (impl != NULL);
581  or = ((OBJECT_RES_BIND *) impl)->or;
582  or_destroy (or);
583 }
584 
588  res_api_tell,
596 };
597 
598 /*
599  * or_res_bind_destroyf -
600  * return:
601  * bind():
602  */
603 static void
605 {
606  OBJECT_RES_BIND *res_bind = (OBJECT_RES_BIND *) bind;
607  assert (res_bind != NULL);
608  assert (res_bind->or->res_bind == res_bind);
609  res_bind->or->res_bind = NULL;
610  or_res_bind_destroy (res_bind);
611 }
612 
613 
614 /*
615  * or_res_bind_create -
616  * return:
617  * or():
618  * rres_bind():
619  */
620 static int
622 {
623  OBJECT_RES_BIND *res_bind;
624 
625  assert (or != NULL);
626  assert (rres_bind != NULL);
627  res_bind = API_MALLOC (sizeof (*res_bind));
628  if (res_bind == NULL)
630  res_bind->res.bind.dtor = or_res_bind_destroyf;
631  res_bind->res.handle_type = HANDLE_TYPE_RESULTSET;
632  res_bind->res.ifs = &RES_IFS_;
633  res_bind->or = or;
634  *rres_bind = res_bind;
635  return NO_ERROR;
636 }
637 
638 /*
639  * or_res_bind_destroy -
640  * return:
641  * res_bind():
642  */
643 static void
645 {
646  assert (res_bind != NULL);
647  API_FREE (res_bind);
648 }
649 
650 /*
651  * vt_api_get_index_by_name -
652  * return:
653  * impl():
654  * name():
655  * ri():
656  */
657 static int
658 vt_api_get_index_by_name (void *impl, const char *name, int *ri)
659 {
661  int i;
662  for (i = 0; i < or->nattrs; i++)
663  {
664  const char *attr_name = db_attribute_name (or->attr_index[i]);
665  assert (attr_name != NULL);
666  if (strcmp (name, attr_name) == 0)
667  {
668  assert (ri != NULL);
669  *ri = i;
670  return NO_ERROR;
671  }
672  }
673  return ER_INTERFACE_GENERIC; /* NO SUCH ATTRIBUTE */
674 }
675 
676 /*
677  * vt_api_get_db_value -
678  * return:
679  * impl():
680  * index():
681  * dbval():
682  */
683 static int
684 vt_api_get_db_value (void *impl, int index, DB_VALUE * dbval)
685 {
687  DB_ATTRIBUTE *attr;
688  int res;
689  assert (or != NULL);
690  attr = or->attr_index[index];
691  assert (attr != NULL);
692  res = db_get (or->obj, attr->header.name, dbval);
693  if (res != NO_ERROR)
694  return ER_INTERFACE_GENERIC;
695  return NO_ERROR;
696 }
697 
698 /*
699  * vt_api_set_db_value -
700  * return:
701  * impl():
702  * index():
703  * dbval():
704  */
705 static int
706 vt_api_set_db_value (void *impl, int index, DB_VALUE * dbval)
707 {
709  DB_ATTRIBUTE *attr;
710  int res;
711 
712  assert (or != NULL);
713 
714  attr = or->attr_index[index];
715  assert (attr != NULL);
716 
717  res = db_put (or->obj, attr->header.name, dbval);
718  if (res != NO_ERROR)
719  {
720  return ER_INTERFACE_GENERIC;
721  }
722 
723  return NO_ERROR;
724 }
725 
726 /*
727  * vt_api_init_domain -
728  * return:
729  * impl():
730  * index():
731  * value():
732  */
733 static int
734 vt_api_init_domain (void *impl, int index, DB_VALUE * value)
735 {
737  DB_ATTRIBUTE *attr;
738  DB_DOMAIN *domain;
739  DB_TYPE dbt;
740  int p, s;
741  int res;
742  assert (or != NULL);
743  attr = or->attr_index[index];
744  assert (attr != NULL);
745  domain = db_attribute_domain (attr);
746  assert (domain != NULL);
747  dbt = TP_DOMAIN_TYPE (domain);
748  p = db_domain_precision (domain);
749  s = db_domain_scale (domain);
750  res = db_value_domain_init (value, dbt, p, s);
751  return NO_ERROR;
752 }
753 
754 /*
755  * or_destroy -
756  * return:
757  * or():
758  */
759 static void
761 {
762  BIND_HANDLE res_h;
763  int res;
764 
765  assert (or != NULL);
766  assert (or->res_bind != NULL);
767  assert (or->rm_bind != NULL);
768  res = or->bh_ifs->bind_to_handle (or->bh_ifs, (BH_BIND *) or->res_bind, &res_h);
769  assert (res == NO_ERROR);
770  res = or->bh_ifs->destroy_handle (or->bh_ifs, res_h);
771  assert (res == NO_ERROR);
772  assert (or->res_bind == NULL);
773  assert (or->rm_bind == NULL);
774  if (or->attr_index != NULL)
775  {
776  API_FREE (or->attr_index);
777  }
778  if (or->vt != NULL)
779  {
780  or->vt->ifs->destroy (or->vt);
781  }
782  API_FREE (or);
783 }
784 
785 /*
786  * or_create -
787  * return:
788  * oid():
789  * conn():
790  * bh_ifs():
791  * ror():
792  */
793 static int
794 or_create (OID * oid, BIND_HANDLE conn, BH_INTERFACE * bh_ifs, OBJECT_RESULTSET ** ror)
795 {
797  int res = NO_ERROR;
798  BIND_HANDLE res_h, rm_h;
799 
800  assert (oid != NULL);
801  assert (ror != NULL);
802 
803  /* create structure */
804  or = API_CALLOC (1, sizeof (*or));
805  if (or == NULL)
806  {
808  }
809  or->oid = *oid;
810  or->bh_ifs = bh_ifs;
811  res = or_res_bind_create (or, &or->res_bind);
812  if (res != NO_ERROR)
813  {
814  API_FREE (or);
815  return res;
816  }
817  res = or_rm_bind_create (or, &or->rm_bind);
818  if (res != NO_ERROR)
819  {
821  API_FREE (or);
822  return res;
823  }
824  /* realize handles and setup dependency between them */
825  res = bh_ifs->alloc_handle (bh_ifs, (BH_BIND *) or->res_bind, &res_h);
826  if (res != NO_ERROR)
827  {
830  API_FREE (or);
831  return res;
832  }
833  res = bh_ifs->alloc_handle (bh_ifs, (BH_BIND *) or->rm_bind, &rm_h);
834  if (res != NO_ERROR)
835  {
836  bh_ifs->destroy_handle (bh_ifs, res_h);
838  API_FREE (or);
839  return res;
840  }
841  res = bh_ifs->bind_graft (bh_ifs, (BH_BIND *) or->rm_bind, (BH_BIND *) or->res_bind);
842  if (res != NO_ERROR)
843  {
844  bh_ifs->destroy_handle (bh_ifs, res_h);
845  bh_ifs->destroy_handle (bh_ifs, rm_h);
846  API_FREE (or);
847  return res;
848  }
849 
850  or->obj = db_object (oid);
851  if (or->obj == NULL)
852  {
853  or_destroy (or);
854  return ER_INTERFACE_GENERIC;
855  }
856  or->clz = db_get_class (or->obj);
857  if (or->clz == NULL)
858  {
859  or_destroy (or);
860  return ER_INTERFACE_GENERIC;
861  }
862  /* create object value bind table */
863  do
864  {
865  int i = 0;
866  DB_ATTRIBUTE *attrs;
867 
868  or->deleted = 0;
869  attrs = db_get_attributes (or->obj);
870  if (attrs == NULL)
871  {
872  or_destroy (or);
873  return ER_INTERFACE_GENERIC;
874  }
875  or->attrs = attrs;
876 
877  while (attrs)
878  {
879  i++;
880  attrs = db_attribute_next (attrs);
881  }
882  or->nattrs = i;
883  or->attr_index = API_CALLOC (i, sizeof (DB_ATTRIBUTE *));
884  if (or->attr_index == NULL)
885  {
886  or_destroy (or);
888  }
889  attrs = or->attrs;
890 
891  i = 0;
892  while (attrs)
893  {
894  or->attr_index[i] = attrs;
895  attrs = db_attribute_next (attrs);
896  i++;
897  }
898  or->conn = conn;
899  res =
901  vt_api_init_domain, &or->vt);
902  if (res != NO_ERROR)
903  {
904  or_destroy (or);
905  return res;
906  }
907  }
908  while (0);
909 
910  *ror = or;
911  return NO_ERROR;
912 }
913 
914 /*
915  * orp_ht_comparef -
916  * return:
917  * key1():
918  * key2():
919  * r():
920  */
921 static int
922 orp_ht_comparef (void *key1, void *key2, int *r)
923 {
924  OID *oid1 = (OID *) key1;
925  OID *oid2 = (OID *) key2;
926 
927  assert (oid1 != NULL);
928  assert (oid2 != NULL);
929  *r = OID_EQ (oid1, oid2) ? 0 : OID_GT (oid1, oid2) ? 1 : -1;
930  return NO_ERROR;
931 }
932 
933 /*
934  * orp_ht_hashf -
935  * return:
936  * key():
937  * rv():
938  */
939 static int
940 orp_ht_hashf (void *key, unsigned int *rv)
941 {
942  OID *oid = (OID *) key;
943 
944  assert (oid != NULL);
945  assert (rv != NULL);
946  *rv = OID_PSEUDO_KEY (oid);
947  return NO_ERROR;
948 }
949 
950 /*
951  * orp_ht_keyf -
952  * return:
953  * elem():
954  * rk():
955  */
956 static int
957 orp_ht_keyf (void *elem, void **rk)
958 {
960  assert (or != NULL);
961  assert (rk != NULL);
962  *rk = &or->oid;
963  return NO_ERROR;
964 }
965 
966 /*
967  * orp_api_get_object_resultset -
968  * return:
969  * pool():
970  * xoid():
971  * rref():
972  */
973 static int
975 {
977  void *r;
978  int res;
979  OID oid;
981 
982  assert (pool != NULL);
983  assert (xoid != NULL);
984  assert (rref != NULL);
985 
986  p = (OBJECT_RESULTSET_POOL *) pool;
987  r = NULL;
988  xoid2oid (xoid, &oid);
989  res = hash_lookup (p->ht, &oid, &r);
990  if (res != NO_ERROR)
991  return res;
992  if (r)
993  {
994  *rref = (API_RESULTSET *) r;
995  return NO_ERROR;
996  }
997  res = or_create (&oid, p->conn, p->bh_ifs, &or);
998  if (res != NO_ERROR)
999  return res;
1000  *rref = (API_RESULTSET *) or->res_bind;
1001  return NO_ERROR;
1002 }
1003 
1004 /*
1005  * orp_oid_delete -
1006  * return:
1007  * pool():
1008  * xoid():
1009  */
1010 static int
1012 {
1014  OID oid;
1015  int res;
1016  void *r;
1017 
1018  assert (pool != NULL);
1019  assert (xoid != NULL);
1020  p = (OBJECT_RESULTSET_POOL *) pool;
1021  /* delete object resultset */
1022  xoid2oid (xoid, &oid);
1023  res = hash_lookup (p->ht, &oid, &r);
1024  if (res != NO_ERROR)
1025  return res;
1026  if (r)
1027  {
1029  DB_OBJECT *obj = or->obj;
1030  assert (obj != NULL);
1031  assert (or->res_bind != NULL);
1032  or->res_bind->res.ifs->destroy ((API_RESULTSET *) or->res_bind);
1033  (void) db_drop (obj);
1034  return NO_ERROR;
1035  }
1037 }
1038 
1039 /*
1040  * orp_oid_get_classname -
1041  * return:
1042  * pool():
1043  * xoid():
1044  * name():
1045  * size():
1046  */
1047 static int
1048 orp_oid_get_classname (API_OBJECT_RESULTSET_POOL * pool, CI_OID * xoid, char *name, size_t size)
1049 {
1051  OID oid;
1052  int res;
1053  void *r;
1054  DB_OBJECT *obj;
1055 
1056  assert (pool != NULL);
1057  assert (xoid != NULL);
1058  p = (OBJECT_RESULTSET_POOL *) pool;
1059  /* delete object resultset */
1060  xoid2oid (xoid, &oid);
1061  res = hash_lookup (p->ht, &oid, &r);
1062  if (res != NO_ERROR)
1063  return res;
1064 
1065  obj = ws_mop (&oid, NULL);
1066  if (obj)
1067  {
1068  char *tmp;
1069  tmp = (char *) db_get_class_name (obj);
1070  if (tmp)
1071  {
1072  strncpy (name, tmp, size);
1073  return NO_ERROR;
1074  }
1075  }
1076 
1077  strncpy (name, "NULL", size);
1078 
1079  return NO_ERROR;
1080 }
1081 
1082 /*
1083  * orp_api_destroy -
1084  * return:
1085  * pool():
1086  */
1087 static void
1089 {
1091  assert (pool != NULL);
1092  p = (OBJECT_RESULTSET_POOL *) pool;
1093  hash_destroy (p->ht, NULL);
1094  API_FREE (p);
1095 }
1096 
1097 /*
1098  * apif_tell -
1099  * return:
1100  * obj():
1101  * pos():
1102  */
1103 static int
1104 apif_tell (DB_OBJECT * obj, int *pos)
1105 {
1106  DB_VALUE ret;
1107  int res;
1108 
1109  assert (obj != NULL);
1110  assert (pos != NULL);
1111 
1112  res = db_send (obj, "data_pos", &ret);
1113  if (res == NO_ERROR)
1114  {
1115  *pos = db_get_int (&ret);
1116  return NO_ERROR;
1117  }
1118 
1119  return res;
1120 }
1121 
1122 /*
1123  * apif_last_pos -
1124  * return:
1125  * obj():
1126  * pos():
1127  */
1128 static int
1129 apif_last_pos (DB_OBJECT * obj, int *pos)
1130 {
1131  DB_VALUE ret;
1132  int res;
1133 
1134  assert (obj != NULL);
1135  assert (pos != NULL);
1136 
1137  res = db_send (obj, "data_size", &ret);
1138  if (res == NO_ERROR)
1139  {
1140  *pos = db_get_int (&ret);
1141  return NO_ERROR;
1142  }
1143 
1144  return res;
1145 }
1146 
1147 /* ------------------------------------------------------------------------- */
1148 /* EXPORTED FUNCTION */
1149 
1150 
1151 /*
1152  * api_object_resultset_pool_create -
1153  * return:
1154  * ifs():
1155  * conn():
1156  * rpool():
1157  */
1158 int
1160 {
1161  OBJECT_RESULTSET_POOL *pool;
1162  hash_table *ht;
1163  int res;
1164 
1165  assert (ifs != NULL);
1166  assert (rpool != NULL);
1167 
1168  pool = API_MALLOC (sizeof (*pool));
1169  if (pool == NULL)
1170  {
1172  }
1173 
1174  ht = NULL;
1175 
1176  res = hash_new (64, orp_ht_hashf, orp_ht_keyf, orp_ht_comparef, &ht);
1177  if (res != NO_ERROR)
1178  {
1179  API_FREE (pool);
1181  }
1182 
1183  pool->pool.destroy = orp_api_destroy;
1184  pool->pool.oid_delete = orp_oid_delete;
1187  pool->bh_ifs = ifs;
1188  pool->conn = conn;
1189  pool->ht = ht;
1190  *rpool = (API_OBJECT_RESULTSET_POOL *) pool;
1191 
1192  return NO_ERROR;
1193 }
#define NO_ERROR
Definition: error_code.h:46
static void or_rm_bind_destroyf(BH_BIND *bind)
Definition: db_object.c:310
static int apif_last_pos(DB_OBJECT *obj, int *pos)
Definition: db_object.c:1129
static int vt_api_init_domain(void *impl, int index, DB_VALUE *value)
Definition: db_object.c:734
static int res_api_fetch(API_RESULTSET *impl, int offset, CI_FETCH_POSITION pos)
Definition: db_object.c:382
#define OID_GT(oidp1, oidp2)
Definition: oid.h:97
void(* destroy)(VALUE_BIND_TABLE *tbl)
Definition: api_common.h:250
const char * db_get_class_name(DB_OBJECT *class_)
Definition: db_info.c:608
BIND_HANDLE conn
Definition: db_object.c:59
int(* bind_graft)(BH_INTERFACE *ifs, BH_BIND *bind, BH_BIND *on_bind)
Definition: api_handle.h:66
void hash_destroy(hash_table *ht, ht_destroyf dtor)
Definition: api_util.c:198
int db_domain_scale(const DB_DOMAIN *domain)
Definition: db_macro.c:4098
MOP ws_mop(const OID *oid, MOP class_mop)
Definition: work_space.c:614
void xoid2oid(CI_OID *xoid, OID *oid)
DB_ATTRIBUTE * db_get_attributes(DB_OBJECT *obj)
Definition: db_info.c:908
DB_OBJECT * db_object(DB_IDENTIFIER *oid)
Definition: db_admin.c:2641
static int res_api_tell(API_RESULTSET *impl, int *offset)
Definition: db_object.c:409
static int orp_ht_keyf(void *elem, void **rk)
Definition: db_object.c:957
static int res_api_delete_row(API_RESULTSET *impl)
Definition: db_object.c:445
int db_domain_precision(const DB_DOMAIN *domain)
Definition: db_macro.c:4079
VALUE_BIND_TABLE * vt
Definition: db_object.c:60
int hash_lookup(hash_table *ht, void *key, void **relem)
Definition: api_util.c:233
int db_get_int(const DB_VALUE *value)
DB_TYPE
Definition: dbtype_def.h:670
static int res_api_get_resultset_metadata(API_RESULTSET *impl, API_RESULTSET_META **rimpl)
Definition: db_object.c:364
#define API_CALLOC(n, s)
Definition: api_util.h:110
static int rm_api_get_info(API_RESULTSET_META *impl, int index, CI_RMETA_INFO_TYPE type, void *arg, size_t size)
Definition: db_object.c:142
OBJECT_RM_BIND * rm_bind
Definition: db_object.c:52
int(* get_value_by_name)(VALUE_BIND_TABLE *tbl, const char *name, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *isnull)
Definition: api_common.h:245
static int res_api_get_value(API_RESULTSET *impl, int index, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *is_null)
Definition: db_object.c:475
static int res_api_clear_updates(API_RESULTSET *impl)
Definition: db_object.c:425
static int orp_oid_get_classname(API_OBJECT_RESULTSET_POOL *pool, CI_OID *xoid, char *name, size_t size)
Definition: db_object.c:1048
DB_OBJECT * obj
Definition: db_object.c:54
int(* reset)(VALUE_BIND_TABLE *tbl)
Definition: api_common.h:249
static int orp_ht_comparef(void *key1, void *key2, int *r)
Definition: db_object.c:922
static void or_rm_bind_destroy(OBJECT_RM_BIND *rm_bind)
Definition: db_object.c:348
const char * db_attribute_name(DB_ATTRIBUTE *attribute)
Definition: db_info.c:1065
API_RESULTSET_META rm
Definition: db_object.c:37
int db_attribute_is_non_null(DB_ATTRIBUTE *attribute)
Definition: db_info.c:1355
static void or_res_bind_destroyf(BH_BIND *bind)
Definition: db_object.c:604
int db_send(MOP obj, const char *name, DB_VALUE *returnval,...)
Definition: db_obj.c:381
OBJECT_RES_BIND * res_bind
Definition: db_object.c:51
static API_RESULTSET_IFS RES_IFS_
Definition: db_object.c:585
#define OID_PSEUDO_KEY(oidp)
Definition: oid.h:130
int(* oid_delete)(API_OBJECT_RESULTSET_POOL *pool, CI_OID *oid)
Definition: api_common.h:171
static int or_rm_bind_create(OBJECT_RESULTSET *or, OBJECT_RM_BIND **rrm_bind)
Definition: db_object.c:326
#define assert(x)
#define ER_INTERFACE_GENERIC
Definition: error_code.h:1179
int db_type_to_type(DB_TYPE dt, CI_TYPE *xt)
static int or_create(OID *oid, BIND_HANDLE conn, BH_INTERFACE *bh_ifs, OBJECT_RESULTSET **ror)
Definition: db_object.c:794
static int or_res_bind_create(OBJECT_RESULTSET *or, OBJECT_RES_BIND **rres_bind)
Definition: db_object.c:621
int(* bind_to_handle)(BH_INTERFACE *ifs, BH_BIND *bind, BIND_HANDLE *bh)
Definition: api_handle.h:63
static API_RESULTSET_META_IFS RM_IFS_
Definition: db_object.c:299
BH_INTERFACE * bh_ifs
Definition: db_object.c:50
static int orp_api_get_object_resultset(API_OBJECT_RESULTSET_POOL *pool, CI_OID *oid, API_RESULTSET **rref)
Definition: db_object.c:974
static int vt_api_get_db_value(void *impl, int index, DB_VALUE *dbval)
Definition: db_object.c:684
int api_object_resultset_pool_create(BH_INTERFACE *ifs, BIND_HANDLE conn, API_OBJECT_RESULTSET_POOL **rpool)
Definition: db_object.c:1159
int db_put(DB_OBJECT *obj, const char *name, DB_VALUE *value)
Definition: db_obj.c:318
static int orp_oid_delete(API_OBJECT_RESULTSET_POOL *pool, CI_OID *oid)
Definition: db_object.c:1011
DB_ATTRIBUTE * db_attribute_next(DB_ATTRIBUTE *attribute)
Definition: db_info.c:1020
#define OID_EQ(oidp1, oidp2)
Definition: oid.h:92
DB_OBJECT * clz
Definition: db_object.c:55
#define TP_DOMAIN_TYPE(dom)
static int rv
Definition: area_alloc.c:52
#define NULL
Definition: freelistheap.h:34
DB_OBJECT * db_get_class(MOP obj)
Definition: db_info.c:589
int db_drop(DB_OBJECT *obj)
Definition: db_obj.c:190
int(* oid_get_classname)(API_OBJECT_RESULTSET_POOL *pool, CI_OID *oid, char *name, size_t size)
Definition: api_common.h:172
int db_attribute_is_auto_increment(DB_ATTRIBUTE *attribute)
Definition: db_info.c:1309
LOCK lock
Definition: work_space.h:134
#define API_FREE(p)
Definition: api_util.h:112
int count(int &result, const cub_regex_object &reg, const std::string &src, const int position, const INTL_CODESET codeset)
static int res_api_get_value_by_name(API_RESULTSET *impl, const char *name, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *isnull)
Definition: db_object.c:507
DB_DOMAIN * db_attribute_domain(DB_ATTRIBUTE *attribute)
Definition: db_info.c:1165
BH_INTERFACE * bh_ifs
Definition: db_object.c:66
API_RESULTSET res
Definition: db_object.c:43
static int vt_api_get_index_by_name(void *impl, const char *name, int *ri)
Definition: db_object.c:658
static int orp_ht_hashf(void *key, unsigned int *rv)
Definition: db_object.c:940
VALUE_BIND_TABLE_IFS * ifs
Definition: api_common.h:233
static int vt_api_set_db_value(void *impl, int index, DB_VALUE *dbval)
Definition: db_object.c:706
static int res_api_update_value(API_RESULTSET *impl, int index, CI_TYPE type, void *addr, size_t len)
Definition: db_object.c:533
API_OBJECT_RESULTSET_POOL pool
Definition: db_object.c:65
#define strlen(s1)
Definition: intl_support.c:43
int(* get_object_resultset)(API_OBJECT_RESULTSET_POOL *pool, CI_OID *oid, API_RESULTSET **rres)
Definition: api_common.h:170
SM_COMPONENT header
Definition: class_object.h:441
DB_ATTRIBUTE * attrs
Definition: db_object.c:58
int db_get(DB_OBJECT *object, const char *attpath, DB_VALUE *value)
Definition: db_obj.c:233
int create_db_value_bind_table(int nvalue, void *impl, int auto_apply, BIND_HANDLE conn_handle, int(*get_index_by_name)(void *, const char *, int *ri), int(*get_db_value)(void *, int, DB_VALUE *), int(*set_db_value)(void *, int, DB_VALUE *), int(*init_domain)(void *, int, DB_VALUE *), VALUE_BIND_TABLE **rtable)
static int res_api_apply_update(API_RESULTSET *impl)
Definition: db_object.c:558
int(* get_value)(VALUE_BIND_TABLE *tbl, int index, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *isnull)
Definition: api_common.h:242
int(* set_value)(VALUE_BIND_TABLE *tbl, int index, CI_TYPE type, void *addr, size_t len)
Definition: api_common.h:244
OBJECT_RESULTSET * or
Definition: db_object.c:38
static int apif_tell(DB_OBJECT *obj, int *pos)
Definition: db_object.c:1104
void(* destroy)(API_OBJECT_RESULTSET_POOL *pool)
Definition: api_common.h:173
int(* apply_updates)(VALUE_BIND_TABLE *tbl)
Definition: api_common.h:248
int i
Definition: dynamic_load.c:954
#define API_MALLOC(s)
Definition: api_util.h:111
const char * name
Definition: class_object.h:385
int(* destroy_handle)(BH_INTERFACE *ifs, BIND_HANDLE bh)
Definition: api_handle.h:61
int(* alloc_handle)(BH_INTERFACE *ifs, BH_BIND *bind, BIND_HANDLE *bh)
Definition: api_handle.h:60
static int rm_api_get_count(API_RESULTSET_META *impl, int *count)
Definition: db_object.c:121
UINT64 BIND_HANDLE
Definition: api_handle.h:28
static void orp_api_destroy(API_OBJECT_RESULTSET_POOL *pool)
Definition: db_object.c:1088
DB_ATTRIBUTE ** attr_index
Definition: db_object.c:57
#define ER_INTERFACE_INVALID_ARGUMENT
Definition: error_code.h:1174
static void or_res_bind_destroy(OBJECT_RES_BIND *res_bind)
Definition: db_object.c:644
OBJECT_RESULTSET * or
Definition: db_object.c:44
#define ER_INTERFACE_INVALID_HANDLE
Definition: error_code.h:1176
static void or_destroy(OBJECT_RESULTSET *or)
Definition: db_object.c:760
const char ** p
Definition: dynamic_load.c:945
int hash_new(int bucket_sz, ht_hashf hashf, ht_keyf keyf, ht_comparef comparef, hash_table **rht)
Definition: api_util.c:166
int db_value_domain_init(DB_VALUE *value, const DB_TYPE type, const int precision, const int scale)
Definition: db_macro.c:153
#define ER_INTERFACE_NO_MORE_MEMORY
Definition: error_code.h:1198
static void res_api_destroy(API_RESULTSET *impl)
Definition: db_object.c:577