CUBRID Engine  latest
elo.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  * elo.c - ELO interface
21  *
22  * MEMOERY MANAGEMENT
23  * db_private_alloc/db_private_free
24 
25  * ERROR HANDLING
26  * Every exported function sets error code if error occurred
27  * Assume argument checking is already done.
28  *
29  * LOCATOR FORMAT: <scheme name>:<scheme specific data>
30  * <scheme name>
31  * inline : data is encoded in locator
32  * <other>: for server side BLOB/CLOB storage extension.
33  *
34  * <scheme specific data>
35  * inline : 2byte hexa decimal code encoding
36  * <other>: scheme_name specific part (EXTERNAL STORAGE)
37  *
38  * META DATA
39  * - simple key, value pair
40  * - format: <key>=<value>[,<key>=<value>[...]]
41  * key, value should not contain '=', or ',' character
42  */
43 
44 #ident "$Id$"
45 
46 #include "config.h"
47 
48 #include <stdio.h>
49 #include <string.h>
50 #include <assert.h>
51 #include <stddef.h>
52 #include <errno.h>
53 #include <fcntl.h>
54 #include <sys/stat.h>
55 
56 #include "elo.h"
57 
58 #include "boot.h"
59 #include "dbtype.h"
60 #include "error_manager.h"
61 #include "es.h"
62 #include "lob_locator.hpp"
63 #include "object_primitive.h"
64 #include "object_representation.h"
65 #include "storage_common.h"
66 
67 static const DB_ELO elo_Initializer = { -1LL, NULL, NULL, ELO_NULL, ES_NONE };
68 
69 #define ELO_NEEDS_TRANSACTION(e) \
70  ((e)->es_type == ES_OWFS || (e)->es_type == ES_POSIX)
71 
72 /* ========================================================================== */
73 /* EXPORTED FUNCTIONS */
74 /* ========================================================================== */
75 
76 /*
77  * elo_create () - create a new file
78  * return: NO_ERROR if successful, error code otherwise
79  * DB_ELO(in): DB_ELO
80  * type(in): DB_ELO_TYPE
81  */
82 int
84 {
85  ES_URI out_uri;
86  char *uri = NULL;
87  int ret = NO_ERROR;
88 
89  assert (elo != NULL);
90 
91 
92  ret = es_create_file (out_uri);
93  if (ret < NO_ERROR)
94  {
95  ASSERT_ERROR ();
96  return ret;
97  }
98 
99  uri = db_private_strdup (NULL, out_uri);
100  if (uri == NULL)
101  {
104  }
105 
106  elo_init_structure (elo);
107  elo->size = 0;
108  elo->locator = uri;
109  elo->type = ELO_FBO;
110  elo->es_type = es_get_type (uri);
111 
112  if (ELO_NEEDS_TRANSACTION (elo))
113  {
115  if (ret != NO_ERROR)
116  {
117  ASSERT_ERROR ();
118  }
119  }
120  return ret;
121 }
122 
123 /*
124  * elo_init_structure () - init. ELO structure
125  */
126 void
128 {
129  if (elo != NULL)
130  {
131  *elo = elo_Initializer;
132  }
133 }
134 
135 /*
136  * elo_copy_structure () - Copy elo instance
137  * return:
138  * elo(in):
139  * dest(out):
140  */
141 int
142 elo_copy_structure (const DB_ELO * elo, DB_ELO * dest)
143 {
144  char *locator = NULL;
145  char *meta_data = NULL;
146 
147  assert (elo != NULL);
148  assert (dest != NULL);
149 
150  if (elo->locator != NULL)
151  {
152  locator = db_private_strdup (NULL, elo->locator);
153  if (locator == NULL)
154  {
156  }
157  }
158 
159  if (elo->meta_data != NULL)
160  {
161  meta_data = db_private_strdup (NULL, elo->meta_data);
162  if (meta_data == NULL)
163  {
164  if (locator != NULL)
165  {
166  db_private_free_and_init (NULL, locator);
167  }
169  }
170  }
171 
172  *dest = *elo;
173  dest->locator = locator;
174  dest->meta_data = meta_data;
175 
176  return NO_ERROR;
177 }
178 
179 /*
180  * elo_free_structure () - free DB_ELO structure
181  *
182  * return:
183  * elo(in):
184  */
185 void
187 {
188  if (elo != NULL)
189  {
190  if (elo->locator != NULL)
191  {
193  }
194 
195  if (elo->meta_data != NULL)
196  {
198  }
199 
200  elo_init_structure (elo);
201  }
202 }
203 
204 /*
205  * elo_copy () - Create new elo instance and copy the file located by elo.
206  * return:
207  * elo(in):
208  * dest(out):
209  */
210 int
211 elo_copy (DB_ELO * elo, DB_ELO * dest)
212 {
213  int ret;
214  ES_URI out_uri;
215  char *locator = NULL;
216  char *meta_data = NULL;
217 
218  assert (elo != NULL);
219  assert (dest != NULL);
220  assert (elo->type == ELO_FBO);
221  assert (elo->locator != NULL);
222 
223  /* create elo instance and copy file */
224  if (elo->meta_data != NULL)
225  {
226  meta_data = db_private_strdup (NULL, elo->meta_data);
227  if (meta_data == NULL)
228  {
229  assert (er_errid () != NO_ERROR);
230  return er_errid ();
231  }
232  }
233 
234  /* if it uses external storage, do transaction work */
235  elo->es_type = es_get_type (elo->locator);
236  if (!ELO_NEEDS_TRANSACTION (elo))
237  {
238  ret = es_copy_file (elo->locator, elo->meta_data, out_uri);
239  if (ret != NO_ERROR)
240  {
241  goto error_return;
242  }
243 
244  locator = db_private_strdup (NULL, out_uri);
245  if (locator == NULL)
246  {
247  es_delete_file (out_uri);
248  goto error_return;
249  }
250  }
251  else
252  {
253  LOB_LOCATOR_STATE state;
254  ES_URI real_locator;
255 
256  state = lob_locator_find (elo->locator, real_locator);
257  switch (state)
258  {
261  {
262  ret = es_rename_file (real_locator, elo->meta_data, out_uri);
263  if (ret != NO_ERROR)
264  {
265  goto error_return;
266  }
267  locator = db_private_strdup (NULL, out_uri);
268  if (locator == NULL)
269  {
270  assert (er_errid () != NO_ERROR);
271  ret = er_errid ();
272  goto error_return;
273  }
275  if (ret != NO_ERROR)
276  {
277  goto error_return;
278  }
279  }
280  break;
281 
283  {
284  locator = db_private_strdup (NULL, elo->locator);
285  if (locator == NULL)
286  {
287  assert (er_errid () != NO_ERROR);
288  ret = er_errid ();
289  goto error_return;
290  }
291  ret = lob_locator_drop (elo->locator);
292  if (ret != NO_ERROR)
293  {
294  goto error_return;
295  }
296  }
297  break;
298 
300  case LOB_NOT_FOUND:
301  {
302  ret = es_copy_file (real_locator, elo->meta_data, out_uri);
303  if (ret != NO_ERROR)
304  {
305  goto error_return;
306  }
307  locator = db_private_strdup (NULL, out_uri);
308  if (locator == NULL)
309  {
310  es_delete_file (out_uri);
311  goto error_return;
312  }
313  ret = lob_locator_add (locator, LOB_PERMANENT_CREATED);
314  if (ret != NO_ERROR)
315  {
316  goto error_return;
317  }
318  }
319  break;
320 
321  case LOB_UNKNOWN:
322  assert (er_errid () != NO_ERROR);
323  ret = er_errid ();
324  goto error_return;
325 
326  default:
327  assert (0);
328  return ER_FAILED;
329  }
330  }
331 
332  *dest = *elo;
333  dest->locator = locator;
334  dest->meta_data = meta_data;
335 
336  return NO_ERROR;
337 
338 error_return:
339  if (locator != NULL)
340  {
341  db_private_free_and_init (NULL, locator);
342  }
343 
344  if (meta_data != NULL)
345  {
346  db_private_free_and_init (NULL, meta_data);
347  }
348  return ret;
349 }
350 
351 /*
352  * elo_delete () - delete the file located by elo and the structure itself.
353  * return: NO_ERROR if successful, error code otherwise
354  * elo(in):
355  */
356 int
357 elo_delete (DB_ELO * elo, bool force_delete)
358 {
359  int ret = NO_ERROR;
360 
361  assert (elo != NULL);
362  assert (elo->type == ELO_FBO);
363  assert (elo->locator != NULL);
364 
365  /* if it uses external storage, do transaction work */
366  elo->es_type = es_get_type (elo->locator);
367  if (!ELO_NEEDS_TRANSACTION (elo) || force_delete)
368  {
369  ret = es_delete_file (elo->locator);
370  }
371  else
372  {
373  LOB_LOCATOR_STATE state;
374  ES_URI real_locator;
375 
376  state = lob_locator_find (elo->locator, real_locator);
377  switch (state)
378  {
380  ret = es_delete_file (real_locator);
381  if (ret != NO_ERROR)
382  {
383  return ret;
384  }
385 
386  ret = lob_locator_drop (elo->locator);
387  break;
388 
392  break;
393 
395  break;
396 
397  case LOB_NOT_FOUND:
399  break;
400 
401  case LOB_UNKNOWN:
402  assert (er_errid () != NO_ERROR);
403  ret = er_errid ();
404  break;
405 
406  default:
407  assert (0);
408  return ER_FAILED;
409  }
410  }
411 
412  return ret;
413 }
414 
415 /*
416  * elo_size () - get the size of file located by elo
417  * return: non-negative integer if successful, -1 if error.
418  * elo(in):
419  */
420 off_t
422 {
423  off_t ret;
424 
425  assert (elo != NULL);
426  assert (elo->type == ELO_FBO);
427  assert (elo->locator != NULL);
428 
429  if (elo->size >= 0)
430  {
431  return elo->size;
432  }
433 
434  ret = es_get_file_size (elo->locator);
435  if (ret < 0)
436  {
437  return ret;
438  }
439 
440  elo->size = ret;
441  return ret;
442 }
443 
444 /*
445  * elo_read () - read data from elo
446  * return: bytes read if successful, -1 if error
447  * elo(in): ELO instance
448  * buf(out): output buffer
449  * count(in): bytes to read
450  *
451  */
452 ssize_t
453 elo_read (const DB_ELO * elo, off_t pos, void *buf, size_t count)
454 {
455  ssize_t ret;
456 
457  assert (elo != NULL);
458  assert (pos >= 0);
459  assert (buf != NULL);
460  assert (elo->type == ELO_FBO);
461  assert (elo->locator != NULL);
462 
463  ret = es_read_file (elo->locator, buf, count, pos);
464  if (ret < NO_ERROR)
465  {
466  ASSERT_ERROR ();
467  }
468  return ret;
469 }
470 
471 /*
472  * elo_write () - write data to elo
473  * return: bytes written if successful, -1 if error
474  * elo(in): ELO instance
475  * buf(out): data buffer
476  * count(in): bytes to write
477  */
478 ssize_t
479 elo_write (DB_ELO * elo, off_t pos, const void *buf, size_t count)
480 {
481  ssize_t ret;
482 
483  assert (elo != NULL);
484  assert (pos >= 0);
485  assert (buf != NULL);
486  assert (count > 0);
487  assert (elo->type == ELO_FBO);
488  assert (elo->locator != NULL);
489 
490  ret = es_write_file (elo->locator, buf, count, pos);
491  if (ret < 0)
492  {
493  ASSERT_ERROR ();
494  return ret;
495  }
496 
497  /* adjust size field */
498  if ((INT64) (pos + count) > elo->size)
499  {
500  elo->size = pos + count;
501  }
502  return ret;
503 }
static const DB_ELO elo_Initializer
Definition: elo.c:67
int elo_create(DB_ELO *elo)
Definition: elo.c:83
#define NO_ERROR
Definition: error_code.h:46
#define ASSERT_ERROR()
off_t es_get_file_size(const char *uri)
Definition: es.c:479
int lob_locator_change_state(const char *locator, const char *new_locator, LOB_LOCATOR_STATE state)
#define ER_FAILED
Definition: error_code.h:47
DB_ELO_TYPE type
Definition: dbtype_def.h:950
int er_errid(void)
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
#define assert(x)
ssize_t es_read_file(const char *uri, void *buf, size_t count, off_t offset)
Definition: es.c:243
char * db_private_strdup(THREAD_ENTRY *thrd, const char *s)
Definition: memory_alloc.c:675
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
ssize_t es_write_file(const char *uri, const void *buf, size_t count, off_t offset)
Definition: es.c:187
int es_rename_file(const char *in_uri, const char *metaname, char *out_uri)
Definition: es.c:417
int elo_delete(DB_ELO *elo, bool force_delete)
Definition: elo.c:357
#define NULL
Definition: freelistheap.h:34
int es_delete_file(const char *uri)
Definition: es.c:301
LOB_LOCATOR_STATE lob_locator_find(const char *locator, char *real_locator)
Definition: lob_locator.cpp:72
int es_create_file(char *out_uri)
Definition: es.c:140
#define db_private_free_and_init(thrd, ptr)
Definition: memory_alloc.h:141
int lob_locator_add(const char *locator, LOB_LOCATOR_STATE state)
Definition: lob_locator.cpp:88
ssize_t elo_read(const DB_ELO *elo, off_t pos, void *buf, size_t count)
Definition: elo.c:453
int count(int &result, const cub_regex_object &reg, const std::string &src, const int position, const INTL_CODESET codeset)
int es_copy_file(const char *in_uri, const char *metaname, char *out_uri)
Definition: es.c:353
#define ARG_FILE_LINE
Definition: error_manager.h:44
off_t elo_size(DB_ELO *elo)
Definition: elo.c:421
#define ELO_NEEDS_TRANSACTION(e)
Definition: elo.c:69
ssize_t elo_write(DB_ELO *elo, off_t pos, const void *buf, size_t count)
Definition: elo.c:479
char * locator
Definition: dbtype_def.h:948
#define strlen(s1)
Definition: intl_support.c:43
int es_type
Definition: dbtype_def.h:951
void elo_free_structure(DB_ELO *elo)
Definition: elo.c:186
int64_t size
Definition: dbtype_def.h:947
void elo_init_structure(DB_ELO *elo)
Definition: elo.c:127
char ES_URI[ES_MAX_URI_LEN]
Definition: es.h:35
enum lob_locator_state LOB_LOCATOR_STATE
Definition: lob_locator.hpp:62
char * meta_data
Definition: dbtype_def.h:949
int elo_copy_structure(const DB_ELO *elo, DB_ELO *dest)
Definition: elo.c:142
int elo_copy(DB_ELO *elo, DB_ELO *dest)
Definition: elo.c:211
ES_TYPE es_get_type(const char *uri)
Definition: es_common.c:43
int lob_locator_drop(const char *locator)