CUBRID Engine  latest
db_collection.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_collection.c -
21  */
22 
23 #include <assert.h>
24 #include "db_stub.h"
25 #include "api_util.h"
26 #include "dbi.h"
27 
28 typedef struct collection_s_ COLLECTION_;
30 {
34 };
35 
36 static int col_api_length (API_COLLECTION * col, int *len);
37 static int col_api_insert (API_COLLECTION * col, long pos, CI_TYPE type, void *ptr, size_t size);
38 static int col_api_update (API_COLLECTION * col, long pos, CI_TYPE type, void *ptr, size_t size);
39 static int col_api_delete (API_COLLECTION * col, long pos);
40 static int col_api_get_elem_domain_info (API_COLLECTION * col, long pos, CI_TYPE * type, int *precision, int *scale);
41 static int col_api_get_elem (API_COLLECTION * col, long pos, CI_TYPE type, void *addr, size_t len, size_t * outlen,
42  bool * isnull);
43 static void col_dtorf (VALUE_AREA * va, API_VALUE * val);
44 static void col_api_destroy (API_COLLECTION * col);
45 
46 static int apif_collection_create (BIND_HANDLE conn, COLLECTION_ ** rc);
47 static int fill_collection (COLLECTION_ * co, DB_SET * set);
48 
49 
50 /*
51  * col_api_length -
52  * return:
53  * col():
54  * len():
55  */
56 static int
58 {
59  COLLECTION_ *co = (COLLECTION_ *) col;
60  int res;
61  assert (co != NULL);
62  assert (len != NULL);
63  res = co->indexer->ifs->length (co->indexer, len);
64  return res;
65 }
66 
67 /*
68  * col_api_insert -
69  * return:
70  * col():
71  * pos():
72  * type():
73  * ptr():
74  * size():
75  */
76 static int
77 col_api_insert (API_COLLECTION * col, long pos, CI_TYPE type, void *ptr, size_t size)
78 {
79  COLLECTION_ *co;
80  DB_VALUE *val;
81  int res;
82 
83  co = (COLLECTION_ *) col;
84  assert (co != NULL);
85 
86  res = co->indexer->ifs->check (co->indexer, (int) pos, CHECK_FOR_INSERT);
87  if (res != NO_ERROR)
88  {
89  return res;
90  }
91 
92  val = db_value_create ();
93  if (val == NULL)
95 
96  res = coerce_value_to_db_value (type, ptr, size, val, false);
97  if (res != NO_ERROR)
98  return res;
99 
100  res = co->indexer->ifs->insert (co->indexer, (int) pos, NULL, (API_VALUE *) val);
101  if (res != NO_ERROR)
102  (void) db_value_free (val);
103 
104  return NO_ERROR;
105 }
106 
107 /*
108  * col_api_update -
109  * return:
110  * col():
111  * pos():
112  * type():
113  * ptr():
114  * size():
115  */
116 static int
117 col_api_update (API_COLLECTION * col, long pos, CI_TYPE type, void *ptr, size_t size)
118 {
119  COLLECTION_ *co = (COLLECTION_ *) col;
120  int res;
121  VALUE_AREA *va;
122  DB_VALUE *val;
123 
124  assert (co != NULL);
125  res = co->indexer->ifs->check (co->indexer, (int) pos, CHECK_FOR_GET | CHECK_FOR_SET);
126  if (res != NO_ERROR)
127  return res;
128  res = co->indexer->ifs->get (co->indexer, (int) pos, &va, (API_VALUE **) (&val));
129  if (res != NO_ERROR)
130  return res;
131  res = coerce_value_to_db_value (type, ptr, size, val, true);
132  if (res != NO_ERROR)
133  return res;
134  return NO_ERROR;
135 }
136 
137 /*
138  * col_api_delete -
139  * return:
140  * col():
141  * pos():
142  */
143 static int
145 {
146  COLLECTION_ *co = (COLLECTION_ *) col;
147  int res;
148  VALUE_AREA *va;
149  DB_VALUE *val;
150 
151  assert (co != NULL);
152  res = co->indexer->ifs->check (co->indexer, (int) pos, CHECK_FOR_DELETE);
153  if (res != NO_ERROR)
154  return res;
155  res = co->indexer->ifs->delete (co->indexer, (int) pos, &va, (API_VALUE **) (&val));
156  if (res != NO_ERROR)
157  return res;
158  assert (va == NULL);
159  if (val)
160  (void) db_value_free (val);
161  return NO_ERROR;
162 }
163 
164 /*
165  * col_api_get_elem_domain_info -
166  * return:
167  * col():
168  * pos():
169  * type():
170  */
171 static int
172 col_api_get_elem_domain_info (API_COLLECTION * col, long pos, CI_TYPE * type, int *precision, int *scale)
173 {
174  COLLECTION_ *co = (COLLECTION_ *) col;
175  int res;
176  VALUE_AREA *va;
177  DB_VALUE *val;
178 
179  assert (co != NULL);
180  res = co->indexer->ifs->check (co->indexer, (int) pos, CHECK_FOR_GET);
181  if (res != NO_ERROR)
182  {
183  return res;
184  }
185  res = co->indexer->ifs->get (co->indexer, (int) pos, &va, (API_VALUE **) (&val));
186  if (res != NO_ERROR)
187  {
188  return res;
189  }
190 
191  if (precision)
192  {
193  *precision = db_value_precision (val);
194  }
195  if (scale)
196  {
197  *scale = db_value_scale (val);
198  }
199 
200  return db_type_to_type (DB_VALUE_DOMAIN_TYPE (val), type);
201 }
202 
203 /*
204  * col_api_get_elem -
205  * return:
206  * col():
207  * pos():
208  * type():
209  * addr():
210  * len():
211  * outlen():
212  * isnull():
213  */
214 static int
215 col_api_get_elem (API_COLLECTION * col, long pos, CI_TYPE type, void *addr, size_t len, size_t * outlen, bool * isnull)
216 {
217  COLLECTION_ *co = (COLLECTION_ *) col;
218  int res;
219  VALUE_AREA *va;
220  DB_VALUE *val;
221 
222  assert (co != NULL);
223  res = co->indexer->ifs->check (co->indexer, (int) pos, CHECK_FOR_GET);
224  if (res != NO_ERROR)
225  return res;
226  res = co->indexer->ifs->get (co->indexer, (int) pos, &va, (API_VALUE **) (&val));
227  if (res != NO_ERROR)
228  return res;
229  assert (val != NULL);
230  res = coerce_db_value_to_value (val, co->col.conn, type, addr, len, outlen, isnull);
231  return res;
232 }
233 
234 /*
235  * col_dtorf -
236  * return:
237  * va():
238  * aval():
239  */
240 static void
242 {
243  DB_VALUE *val = (DB_VALUE *) aval;
244  assert (va == NULL);
245  if (val)
246  db_value_free (val);
247 }
248 
249 /*
250  * col_api_destroy -
251  * return:
252  * col():
253  */
254 static void
256 {
257  COLLECTION_ *co = (COLLECTION_ *) col;
258  assert (co != NULL);
259  co->indexer->ifs->destroy (co->indexer, col_dtorf);
260  API_FREE (co);
261 }
262 
271 };
272 
273 /*
274  * apif_collection_create -
275  * return:
276  * conn():
277  * rc():
278  */
279 static int
281 {
282  COLLECTION_ *col;
283  int res;
284  assert (rc != NULL);
285  col = API_MALLOC (sizeof (*col));
286  if (col == NULL)
288  col->col.ifs = &COL_IFS_;
289  col->col.conn = conn;
290  res = list_indexer_create (&col->indexer);
291  if (res != NO_ERROR)
292  {
293  API_FREE (col);
294  }
295  *rc = col;
296  return res;
297 }
298 
299 /*
300  * fill_collection -
301  * return:
302  * co():
303  * set():
304  */
305 static int
307 {
308  int set_size;
309  int i, res;
310  DB_VALUE *val;
311 
312  assert (co != NULL);
313  if (set == NULL)
315 
316  set_size = db_col_size (set);
317  for (i = 0; i < set_size; i++)
318  {
319  int li_idx = i - 1;
320 
321  res = co->indexer->ifs->check (co->indexer, li_idx, CHECK_FOR_INSERT);
322  if (res != NO_ERROR)
323  return res;
324  val = db_value_create ();
325  if (!val)
327  res = db_col_get (set, i, val);
328  if (res != NO_ERROR)
329  {
330  db_value_free (val);
331  return ER_INTERFACE_GENERIC;
332  }
333  res = co->indexer->ifs->insert (co->indexer, li_idx, NULL, (API_VALUE *) val);
334  if (res != NO_ERROR)
335  {
336  db_value_free (val);
337  }
338  }
339  return NO_ERROR;
340 }
341 
342 /* ------------------------------------------------------------------------- */
343 /* EXPORTED FUNCTION */
344 
345 /*
346  * api_collection_create_from_db_value -
347  * return:
348  * conn():
349  * val():
350  * rc():
351  */
352 int
354 {
355  DB_TYPE dt;
356  COLLECTION_ *co;
357  int res;
358 
359  if (val == NULL || rc == NULL)
360  {
362  }
363  dt = DB_VALUE_DOMAIN_TYPE (val);
364  if (!TP_IS_SET_TYPE (dt))
365  {
366  return ER_INTERFACE_INVALID_ARGUMENT; /* not collection type */
367  }
368  res = apif_collection_create (conn, &co);
369  if (res != NO_ERROR)
370  {
371  return res;
372  }
373 
374  res = fill_collection (co, db_get_set (val));
375  if (res != NO_ERROR)
376  {
377  co->col.ifs->destroy ((API_COLLECTION *) co);
378  }
379  *rc = (API_COLLECTION *) co;
380 
381  return res;
382 }
383 
384 /*
385  * set_to_db_value_mapf -
386  * return:
387  * arg():
388  * idx():
389  * va():
390  * aval():
391  */
392 static int
393 set_to_db_value_mapf (void *arg, int idx, VALUE_AREA * va, API_VALUE * aval)
394 {
395  int res;
396  DB_VALUE *val = (DB_VALUE *) aval;
397  DB_COLLECTION *col = (DB_COLLECTION *) arg;
398 
399  assert (col != NULL);
400 
401  res = db_col_put (col, idx, val);
402  if (res != NO_ERROR)
403  {
404  return ER_INTERFACE_GENERIC;
405  }
406 
407  return NO_ERROR;
408 }
409 
410 /*
411  * api_collection_set_to_db_value -
412  * return:
413  * col():
414  * val():
415  */
416 int
418 {
419  DB_TYPE dt;
420  COLLECTION_ *co;
421  DB_COLLECTION *dbcol;
422  int size, res;
423 
424  if (col == NULL || val == NULL)
425  {
427  }
428  co = (COLLECTION_ *) col;
429  dt = DB_VALUE_DOMAIN_TYPE (val);
430  if (!TP_IS_SET_TYPE (dt))
431  {
433  }
434  res = co->indexer->ifs->length (co->indexer, &size);
435  if (res != NO_ERROR)
436  {
437  return res;
438  }
439  dbcol = db_col_create (dt, size, NULL);
440  if (dbcol == NULL)
441  {
442  return ER_INTERFACE_GENERIC;
443  }
444  res = co->indexer->ifs->map (co->indexer, set_to_db_value_mapf, dbcol);
445  if (res != NO_ERROR)
446  {
447  db_col_free (dbcol);
448  return ER_INTERFACE_GENERIC;
449  }
450  res = db_value_put (val, DB_TYPE_C_SET, &dbcol, sizeof (DB_COLLECTION **));
451  if (res != NO_ERROR)
452  {
453  db_col_free (dbcol);
454  return ER_INTERFACE_GENERIC;
455  }
456 
457  return NO_ERROR;
458 }
459 
460 /*
461  * api_collection_create -
462  * return:
463  * conn():
464  * rc():
465  */
466 int
468 {
469  COLLECTION_ *co;
470  int res;
471 
472  if (rc == NULL)
474 
475  res = apif_collection_create (conn, &co);
476  if (res == NO_ERROR)
477  {
478  *rc = (API_COLLECTION *) co;
479  }
480  return res;
481 }
int api_collection_set_to_db_value(API_COLLECTION *col, DB_VALUE *val)
static int col_api_get_elem(API_COLLECTION *col, long pos, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *isnull)
int db_col_put(DB_COLLECTION *col, int element_index, DB_VALUE *value)
Definition: db_set.c:1249
#define NO_ERROR
Definition: error_code.h:46
DB_COLLECTION * db_get_set(const DB_VALUE *value)
int db_value_scale(const DB_VALUE *value)
static int col_api_insert(API_COLLECTION *col, long pos, CI_TYPE type, void *ptr, size_t size)
Definition: db_collection.c:77
static int col_api_delete(API_COLLECTION *col, long pos)
#define TP_IS_SET_TYPE(typenum)
DB_TYPE
Definition: dbtype_def.h:670
void(* destroy)(API_COLLECTION *col)
Definition: api_common.h:275
void(* destroy)(VALUE_INDEXER *indexer, void(*df)(VALUE_AREA *va, API_VALUE *db))
Definition: api_common.h:225
int db_col_get(DB_COLLECTION *col, int element_index, DB_VALUE *value)
Definition: db_set.c:1222
API_COLLECTION_IFS * ifs
Definition: api_common.h:259
int set_size(DB_COLLECTION *set)
Definition: set_object.c:3036
struct VALUE_AREA VALUE_AREA
Definition: api_common.h:42
BIND_HANDLE conn
Definition: api_common.h:258
int api_collection_create_from_db_value(BIND_HANDLE conn, const DB_VALUE *val, API_COLLECTION **rc)
Definition: db_set.h:35
#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 fill_collection(COLLECTION_ *co, DB_SET *set)
#define DB_VALUE_DOMAIN_TYPE(value)
Definition: dbtype.h:70
int db_value_free(DB_VALUE *value)
Definition: db_macro.c:1610
int db_col_free(DB_COLLECTION *col)
Definition: db_set.c:998
struct API_VALUE API_VALUE
Definition: api_common.h:43
DB_VALUE * db_value_create(void)
Definition: db_macro.c:1517
int(* map)(VALUE_INDEXER *indexer, int(*mapf)(void *, int, VALUE_AREA *, API_VALUE *), void *arg)
Definition: api_common.h:222
static void col_api_destroy(API_COLLECTION *col)
#define NULL
Definition: freelistheap.h:34
static int apif_collection_create(BIND_HANDLE conn, COLLECTION_ **rc)
API_COLLECTION col
Definition: db_collection.c:31
int db_col_size(DB_COLLECTION *col)
Definition: db_set.c:1167
#define API_FREE(p)
Definition: api_util.h:112
int(* check)(VALUE_INDEXER *indexer, int index, CHECK_PURPOSE pup)
Definition: api_common.h:218
static int col_api_length(API_COLLECTION *col, int *len)
Definition: db_collection.c:57
int(* delete)(VALUE_INDEXER *indexer, int index, VALUE_AREA **rva, API_VALUE **rval)
Definition: api_common.h:224
static void col_dtorf(VALUE_AREA *va, API_VALUE *val)
static int rc
Definition: serial.c:50
VALUE_INDEXER * indexer
Definition: db_collection.c:33
static API_COLLECTION_IFS COL_IFS_
DB_COLLECTION * db_col_create(DB_TYPE type, int size, DB_DOMAIN *domain)
Definition: db_set.c:949
int(* get)(VALUE_INDEXER *indexer, int index, VALUE_AREA **rva, API_VALUE **rv)
Definition: api_common.h:220
int api_collection_create(BIND_HANDLE conn, API_COLLECTION **rc)
int list_indexer_create(VALUE_INDEXER **rvi)
int db_value_precision(const DB_VALUE *value)
static int col_api_get_elem_domain_info(API_COLLECTION *col, long pos, CI_TYPE *type, int *precision, int *scale)
int(* insert)(VALUE_INDEXER *indexer, int index, VALUE_AREA *va, API_VALUE *dval)
Definition: api_common.h:223
int db_value_put(DB_VALUE *value, const DB_TYPE_C c_type, void *input, const int input_length)
Definition: db_macro.c:1256
int coerce_db_value_to_value(const DB_VALUE *dbval, BIND_HANDLE conn, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *isnull)
static int col_api_update(API_COLLECTION *col, long pos, CI_TYPE type, void *ptr, size_t size)
int i
Definition: dynamic_load.c:954
#define API_MALLOC(s)
Definition: api_util.h:111
UINT64 BIND_HANDLE
Definition: api_handle.h:28
int coerce_value_to_db_value(CI_TYPE type, void *addr, size_t len, DB_VALUE *dbval, bool domain_initialized)
VALUE_INDEXER_IFS * ifs
Definition: api_common.h:208
#define ER_INTERFACE_INVALID_ARGUMENT
Definition: error_code.h:1174
int(* length)(VALUE_INDEXER *indexer, int *len)
Definition: api_common.h:219
static int set_to_db_value_mapf(void *arg, int idx, VALUE_AREA *va, API_VALUE *aval)
#define ER_INTERFACE_NO_MORE_MEMORY
Definition: error_code.h:1198