table: astro_object - added union for char designation.
[libastrodb.git] / src / table.c
blob27baeff80afe5614303324cadaadccbd0a496c3e
1 /*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) any later version.
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * Copyright (C) 2008 Liam Girdwood
19 #define _GNU_SOURCE /* for strtof and NAN */
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <math.h>
27 #include <dirent.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <sys/wait.h>
31 #include <errno.h>
33 #include <libastrodb/db.h>
34 #include <libastrodb/table.h>
35 #include <libastrodb/wget.h>
36 #include <libastrodb/gunzip.h>
37 #include <libastrodb/adbstdio.h>
40 #define FLOAT_SIZE '6' /* CDS F string size and below for float else double */
41 #define FILE_LEN 1024
43 /*! \fn static int init_table(astrodb_table * table, int ra_stride, int dec_stride, int mag_stride)
44 * \brief Initialise a dataset
46 static int init_table(struct astrodb_table *table,
47 int ra_stride, int dec_stride, int mag_stride)
49 struct astrodb_slist **slist, **hash_object;
50 struct astrodb_tile_status *status;
51 int i = 0;
53 table->ra.stride = ra_stride;
54 table->dec.stride = dec_stride;
55 table->mag.stride = mag_stride;
57 table->array_size = table->ra.stride * table->dec.stride *
58 table->mag.stride * sizeof(struct astrodb_slist *);
59 table->status_size = table->ra.stride * table->dec.stride *
60 table->mag.stride * sizeof(struct astrodb_tile_status);
61 table->no_tiles = table->ra.stride * table->dec.stride *
62 table->mag.stride;
64 table->ra.stride_size =
65 fabs((table->db->ra_max - table->db->ra_min) / table->ra.stride);
66 table->dec.stride_size =
67 fabs((table->db->dec_max - table->db->dec_min) / table->dec.stride);
68 table->mag.stride_size =
69 fabs((table->db->mag_bright - table->db->mag_faint) / table->mag.stride);
71 slist = (struct astrodb_slist **) calloc(1, table->array_size);
72 if (slist == 0) {
73 free(table);
74 return -ENOMEM;
76 table->objects = slist;
78 status = (struct astrodb_tile_status *) calloc(1, table->status_size);
79 if (status == 0) {
80 free(slist);
81 free(table);
82 return -ENOMEM;
84 table->status = status;
86 for (i = 0; i < table->num_hmaps; i++) {
87 hash_object = (struct astrodb_slist **) calloc(1, table->array_size);
88 if (hash_object == NULL) {
89 free(slist);
90 free(status);
91 while(i--)
92 free(table->hmaps[i-1].hobjects);
94 free(table);
95 return -ENOMEM;
97 table->hmaps[i].hobjects = hash_object;
100 return 0;
103 /*! \fn static astrodb_table* create_table(astrodb_db*db, astrodb_dlist* desc, astrodb_dlist* files)
104 * \brief Create a object dataset and populate fields
106 static struct astrodb_table *create_table(struct astrodb_db *db,
107 struct astrodb_dlist *desc, struct astrodb_dlist *files)
109 struct astrodb_table *table;
111 table = calloc(1, sizeof(struct astrodb_table));
112 if (table == NULL)
113 return NULL;
115 bzero(table, sizeof(struct astrodb_table));
116 table->byte_description =
117 ((struct astrodb_table_info *) files->data)->byte_description;
118 table->file = ((struct astrodb_table_info *) files->data)->name;
119 table->table_size = ((struct astrodb_table_info *) files->data)->records;
120 table->record_size = ((struct astrodb_table_info *) files->data)->length;
121 table->db = db;
122 db->num_tables++;
123 return table;
128 /*! \fn astrodb_table *astrodb_table_create(astrodb_db *db, char *table_name, unsigned int flags)
129 * \param db Catalog
130 * \param table_name Dataset name (dataset file name in ReadMe)
131 * \param flags Dataset creation flags.
132 * \return A astrodb_table* for success or NULL on error
134 * Creates a dataset object.
136 struct astrodb_table *astrodb_table_create(struct astrodb_db *db,
137 char *table_name, unsigned int flags)
139 struct astrodb_dlist *files = db->info->files;
140 struct astrodb_table *table = NULL;
141 astrodb_info("Scanning for key fields in table: %s\n", table_name);
143 while (files) {
144 struct astrodb_table_info *table_info =
145 (struct astrodb_table_info *) files->data;
146 struct astrodb_dlist *byte_desc = table_info->byte_description;
148 /* create a tile array per file for files that have a byte desc */
149 if (byte_desc &&
150 !strncmp(table_name, table_info->name, strlen(table_name))) {
152 table = create_table(db, byte_desc, files);
153 table->init_flags = flags;
154 astrodb_info(" scan: %s\n", table_info->name);
156 db->tables = astrodb_dlist_append(db->tables,
157 (char *) table);
158 return table;
160 files = files->tail;
163 return NULL;
166 /*! \fn int astrodb_table_open(astrodb_table * table, astrodb_progress progress, int ra, int dec, int mag)
167 * \param table dataset
168 * \param progress Progress callback
169 * \param ra RA stride
170 * \param dec Dec stride
171 * \param mag Magnitude stride
173 * Initialise a dataset. This will download and import the raw data if necessary.
175 int astrodb_table_open(struct astrodb_table *table, int ra, int dec, int mag)
177 struct stat stat_info;
178 char file[FILE_LEN];
179 char pstr[FILE_LEN];
180 int ret;
182 sprintf(pstr, "Initialising table %s", table->file);
184 /* do we have to delete existing dataset */
185 //if (flags & ADB_REFRESH)
186 // delete_table(astrodb_table* table);
188 table_get_object_insert(table);
190 ret = init_table(table, ra, dec, mag);
191 if (ret < 0) {
192 astrodb_error("failed to initialise table %d\n", ret);
193 return ret;
196 /* check for local binary copy */
197 sprintf(file, "%s%s%s", table->db->local_path, table->file, ".idx");
198 ret = stat(file, &stat_info);
199 if (ret == 0) {
200 ret = table_load_hdr(table);
201 if (ret < 0) {
202 astrodb_error("failed to load binary header %s %d\n",
203 file, ret);
204 return ret;
206 ret = table_uncache_tiles(table);
207 if (ret < 0)
208 astrodb_error("failed to uncache table tiles %d\n",
209 ret);
210 return ret;
213 /* check for local ASCII copy */
214 sprintf(file, "%s%s", table->db->local_path, table->file);
215 ret = stat(file, &stat_info);
216 if (ret == 0)
217 goto import;
219 /* check for local */
221 /* local binary or ASCII not available, so download ASCII */
222 if (!(strncmp("http://", table->db->lib->remote, 7)) ||
223 !(strncmp("ftp://", table->db->lib->remote, 6))) {
224 ret = table_get_remote_dataset(table);
225 if (ret < 0) {
226 astrodb_error("failed to get remote table %d\n", ret);
227 return ret;
230 import:
231 if (table->init_flags & ADB_MEM) {
232 ret = table_import(table, file);
233 if (ret < 0) {
234 astrodb_error("failed to import table %s %d\n", file,
235 ret);
236 return ret;
239 if (table->init_flags & ADB_FILE) {
240 ret = table_save_hdr(table);
241 if (ret < 0) {
242 astrodb_error("failed to save table schema %d\n", ret);
243 return ret;
245 ret = table_cache_tiles(table);
247 return ret;
250 /*! \fn void astrodb_table_close(astrodb_table* table)
251 * \param table dataset
253 * Free dataset resources
255 void astrodb_table_close(struct astrodb_table *table)
257 int i, j;
258 struct astrodb_db *db = table->db;
260 /* free hash maps */
261 for (i = 0; i < table->num_hmaps; i++) {
262 for (j = 0; j < table->no_tiles; j++) {
264 struct astrodb_slist *slist, *slist_;
265 slist_ = *(table->hmaps[i].hobjects + j);
267 while (slist_) {
268 slist = slist_;
269 slist_ = slist_->tail;
270 free(slist);
273 /* free array */
274 free(table->hmaps[i].hobjects);
277 if (table->objects) {
278 /* free objects in array */
279 for (i = 0; i < table->no_tiles; i++)
280 astrodb_slist_foreach_free(*(table->objects + i), NULL, 0);
281 /* free array */
282 free(table->objects);
285 if (table->status)
286 free(table->status);
288 db->tables = astrodb_dlist_free_object(db->tables, table);
291 /*! \fn void astrodb_table_put_objects(astrodb_slist *results)
292 * \param results Results from astrodb_table_get_objects()
294 * Releases resources held by the results from astrodb_table_get_objects().
296 void astrodb_table_put_objects(struct astrodb_slist *results)
298 struct astrodb_slist *slist;
300 while (results) {
301 slist = results;
302 results = results->tail;
303 free(slist);
307 /*! \fn int astrodb_table_alt_column(astrodb_table* table, char* field, char* alt, int flags)
308 * \param table dataset
309 * \param field Primary field
310 * \param alt Alternative field
311 * \param flags flags
313 * Set an alternative import field if the primary field is blank.
315 int astrodb_table_alt_column(struct astrodb_table *table, char *field,
316 char *alt, int flags)
318 int idx, err;
320 if (table->alt_fields >= TABLE_MAX_AIDX) {
321 astrodb_error("too many alt fields %s\n", field);
322 return -EINVAL;
325 idx = table_find_field(table, field);
326 if (idx < 0) {
327 astrodb_error("field not found %s\n", field);
328 return -EINVAL;
331 err = table_add_alt_field(table, alt, idx);
332 if (err < 0) {
333 astrodb_error("failed to add field %s at idx %d\n", field, idx);
334 return -EINVAL;
337 return 0;
340 /*! \fn void astrodb_table_clip_on_position (astrodb_table* table, double min_ra, double min_dec, double max_ra, double max_dec, double faint_mag,double bright_mag)
341 * \param table dataset
342 * \param min_ra Min RA
343 * \param min_dec Min Dec
344 * \param max_ra Max RA
345 * \param max_dec Max Dec
346 * \param faint_mag Faint Magnitude
347 * \param bright_mag Bright Magnitude
349 * Clips the dataset to the within the given position range. Note: Clipping
350 * boundaries are not exact and depend on the granularity of the
351 * dataset position strides.
353 void astrodb_table_clip_on_position(struct astrodb_table *table,
354 double min_ra, double min_dec,
355 double max_ra, double max_dec,
356 double faint_mag, double bright_mag)
358 /* check ra,deg & mag boundaries */
359 if (min_ra < table->db->ra_min)
360 min_ra = table->db->ra_min;
361 if (max_ra > table->db->ra_max)
362 max_ra = table->db->ra_max;
363 if (min_dec < table->db->dec_min)
364 min_dec = table->db->dec_min;
365 if (max_dec > table->db->dec_max)
366 max_dec = table->db->dec_max;
367 if (faint_mag > table->db->mag_faint)
368 faint_mag = table->db->mag_faint;
369 if (bright_mag < table->db->mag_bright)
370 bright_mag = table->db->mag_bright;
372 /* normalise boundaries */
373 min_ra -= table->db->ra_min;
374 max_ra -= table->db->ra_min;
375 min_dec -= table->db->dec_min;
376 max_dec -= table->db->dec_min;
377 faint_mag -= table->db->mag_bright;
378 bright_mag -= table->db->mag_bright;
380 table->fov = 0;
382 /* convert to stride boundaries */
383 table->ra.clip_min = floor(min_ra / table->ra.stride_size);
384 table->ra.clip_max = floor(max_ra / table->ra.stride_size);
385 table->dec.clip_min = floor(min_dec / table->dec.stride_size);
386 table->dec.clip_max = floor(max_dec / table->dec.stride_size);
388 table->mag.clip_max = floor(bright_mag / table->mag.stride_size);
389 table->mag.clip_min = floor(faint_mag / table->mag.stride_size);
392 /*! \fn void astrodb_table_clip_on_distance (astrodb_table* table, double min_AU, double max_AU)
393 * \param table dataset
394 * \param min_AU Min AU
395 * \param max_AU Max AU
397 * Clips the dataset to the within the given distance range. Note: Clipping
398 * boundaries are not exact and depend on the granularity of the
399 * dataset distance stride.
401 void astrodb_table_clip_on_distance(struct astrodb_table *table,
402 double min_AU, double max_AU)
404 /* check AU boundaries */
405 if (min_AU < table->db->ra_min)
406 min_AU = table->db->ra_min;
407 if (max_AU > table->db->ra_max)
408 max_AU = table->db->ra_max;
410 /* normalise boundaries */
411 min_AU -= table->db->ra_min;
412 max_AU -= table->db->ra_min;
414 table->fov = 0;
416 /* convert to stride boundaries */
417 table->ra.clip_min = (int) min_AU / table->ra.stride_size;
418 table->ra.clip_max = ((int) max_AU / table->ra.stride_size) + 1;
421 /*! \fn void astrodb_table_clip_on_fov (astrodb_table* table, double ra, double dec, double radius,
422 double faint_mag, double bright_mag);
423 * \brief Set dataset clipping area based on field of view
424 * \ingroup dataset
426 void astrodb_table_clip_on_fov (struct astrodb_table *table,
427 double ra, double dec, double fov,
428 double faint_mag, double bright_mag)
430 /* check boundaries */
431 table->fov = fov;
432 if (ra < table->db->ra_min)
433 ra = table->db->ra_min;
434 if (ra > table->db->ra_max)
435 ra = table->db->ra_max;
436 if (dec < table->db->dec_min)
437 dec = table->db->dec_min;
438 if (dec > table->db->dec_max)
439 dec = table->db->dec_max;
440 if (faint_mag > table->db->mag_faint)
441 faint_mag = table->db->mag_faint;
442 if (bright_mag < table->db->mag_bright)
443 bright_mag = table->db->mag_bright;
445 table->clip_centre_ra = ra;
446 table->clip_centre_dec = dec;
448 /* normalise boundaries */
449 faint_mag -= table->db->mag_bright;
450 bright_mag -= table->db->mag_bright;
452 /* convert to stride boundaries */
453 table->mag.clip_max = (int) bright_mag / table->mag.stride_size;
454 table->mag.clip_min = ((int) faint_mag / table->mag.stride_size) + 1;
457 /*! \fn void astrodb_table_unclip (astrodb_table* table)
458 * \param table dataset
460 * Unclip the dataset to it's full boundaries
462 void astrodb_table_unclip(struct astrodb_table *table)
464 int i,j,k, offset;
466 /* in stride */
467 table->ra.clip_min = 0;
468 table->dec.clip_min = 0;
469 table->ra.clip_max = table->ra.stride - 1;
470 table->dec.clip_max = table->dec.stride - 1;
471 table->mag.clip_min = table->mag.stride - 1;
472 table->mag.clip_max = 0;
473 table->fov = 0;
475 for (i = 0; i <= table->ra.clip_max; i++) {
476 for (j = 0; j <= table->dec.clip_max; j++) {
477 for (k = 0; k <= table->mag.clip_min; k++) {
478 offset = table_calc_offset(table, i, j, k);
479 (table->status + offset)->flags &= ~ADB_SUSED;
485 /*! int astrodb_table_get_objects (astrodb_table* table, astrodb_progress progress, astrodb_slist **result, unsigned int src)
486 * \param table dataset
487 * \param progress Progress callback
488 * \param results dataset objects
489 * \param src Get objects flags
490 * \return number of objects, or negative for failed
492 * Get objects from dataset based on clipping area. Results must be released
493 * with astrodb_table_put_objects() after use.
495 int astrodb_table_get_objects(struct astrodb_table *table,
496 struct astrodb_slist **result,
497 unsigned int src)
499 if (table->fov) {
500 switch (src) {
501 case ADB_SMEM:
502 return table_get_objects_memc(table, result);
503 case ADB_SCACHE:
504 return table_get_objects_cachec(table, result);
505 case ADB_SLOCAL:
506 return table_get_objects_rawc(table, result);
507 case ADB_SONLINE:
508 return table_get_objects_onlinec(table, result);
509 default:
510 return ADB_ENOGET;
512 } else {
513 switch (src) {
514 case ADB_SMEM:
515 return table_get_objects_mem(table, result);
516 case ADB_SCACHE:
517 return table_get_objects_cache(table, result);
518 case ADB_SLOCAL:
519 return table_get_objects_raw(table, result);
520 case ADB_SONLINE:
521 return table_get_objects_online(table, result);
522 default:
523 return ADB_ENOGET;
528 /*! \fn int astrodb_table_prune(astrodb_table* table)
529 * \param table dataset
530 * \return bytes free'd
532 * Free's oldest unused object tiles.
534 int astrodb_table_prune(struct astrodb_table *table)
536 return 0;
539 /*! \fn int astrodb_table_get_size(astrodb_table* table)
540 * \param table dataset
541 * \return size in bytes
543 * Get dataset memory usage.
545 int astrodb_table_get_size(struct astrodb_table *table)
547 return table->object_size * table->db->db_size;
550 /*! \fn void astrodb_table_set_status_posn (astrodb_table* table, double min_ra, double min_dec, double max_ra, double max_dec, double faint_mag,double bright_mag, unsigned int status)
551 * \param table dataset
552 * \param min_ra Min RA
553 * \param min_dec Min Dec
554 * \param max_ra Max RA
555 * \param max_dec Max Dec
556 * \param faint_mag Faint Magnitude
557 * \param bright_mag Bright Magnitude
558 * \param status Object status
560 * Set the status of objects within a given position range.
562 void astrodb_table_set_status_posn(struct astrodb_table *table,
563 double min_ra, double min_dec,
564 double max_ra, double max_dec,
565 double faint_mag, double bright_mag,
566 unsigned int status)
568 int i, j, k;
569 int clip_min_ra, clip_max_ra, clip_min_dec, clip_max_dec,
570 clip_bright_mag, clip_faint_mag;
572 clip_min_ra = table->ra.clip_min;
573 clip_max_ra = table->ra.clip_max;
574 clip_min_dec = table->dec.clip_min;
575 clip_max_dec = table->dec.clip_max;
576 clip_bright_mag = table->mag.clip_max;
577 clip_faint_mag = table->mag.clip_min;
579 astrodb_table_clip_on_position(table, min_ra, min_dec,
580 max_ra, max_dec, bright_mag, faint_mag);
582 for (i = table->ra.clip_min; i < table->ra.clip_max; i++) {
583 for (j = table->dec.clip_min; j < table->dec.clip_max; j++) {
584 for (k = table->mag.clip_max;
585 k < table->mag.clip_min; k++) {
592 /*! \fn void astrodb_table_set_status_dist (astrodb_table* table, double min_AU, double max_AU, unsigned int status)
593 * \param table Dataset
594 * \param min_AU Minimum distance in AU
595 * \param max_AU Maximum distance in AU
596 * \param status Status flags to set
598 * Set the status of objects within a given distance range.
600 void astrodb_table_set_status_dist(struct astrodb_table *table,
601 double min_AU, double max_AU,
602 unsigned int status)
604 int min_offset = (min_AU - table->db->ra_min) / table->ra.stride_size;
605 int max_offset = (max_AU - table->db->ra_min) / table->ra.stride_size;
607 for (; min_offset < max_offset; min_offset++) {
608 ((struct astrodb_tile_status*)
609 (table->status + min_offset))->flags = status;
613 /*! \fn astrodb_tile_status astrodb_table_get_status_posn (astrodb_table* table, double ra, double dec, double mag)
614 * \param table Dataset
615 * \param ra RA in degrees
616 * \param dec DEC in dergrees
617 * \param mag Magnitude
619 * Get the status of objects within a tile at a give (ra,dec,mag) offset.
621 struct astrodb_tile_status
622 astrodb_table_get_status_posn(struct astrodb_table *table,
623 double ra, double dec, double mag)
625 int x, y, z, offset;
627 x = floor((ra - table->db->ra_min) / table->ra.stride_size);
628 y = floor((dec - table->db->dec_min) / table->dec.stride_size);
629 z = floor((mag - table->db->mag_bright) / table->mag.stride_size);
630 offset = table_calc_offset(table, x, y, z);
632 return *(table->status + offset);
635 /*! \fn astrodb_tile_status astrodb_table_get_status_dist (astrodb_table* table, double AU)
636 * \param table Dataset
637 * \param AU Distance in AU
638 * \returns Status
640 * Get the status of objects within a tile at a give distance offset.
642 struct astrodb_tile_status
643 astrodb_table_get_status_dist(struct astrodb_table *table, double AU)
645 int offset = floor((AU - table->db->ra_min) / table->ra.stride_size);
646 return *(table->status + offset);
649 /*! \fn astrodb_ctype astrodb_table_get_column_type(astrodb_table* table, char* field)
650 * \param table Dataset
651 * \param field Dataset field name
652 * \return C type
654 * Get the C type for a field within a dataset.
656 astrodb_ctype astrodb_table_get_column_type(struct astrodb_table *table,
657 char *field)
659 int i;
661 for (i = 0; i < table->object_fields; i++) {
662 if (!strcmp(table->idx[i].symbol, field))
663 return table->idx[i].type;
666 return CT_NULL;
669 /*! \fn int astrodb_table_get_column_offset(astrodb_table* table, char* field)
670 * \param table Dataset
671 * \param field Dataset field name
672 * \return Field offset in bytes
674 * Gets the offset in bytes for a field within a dataset.
676 int astrodb_table_get_column_offset(struct astrodb_table *table, char *field)
678 int i;
680 /* check custom fields */
681 for (i = 0; i < table->object_fields; i++) {
682 if (!strcmp(table->idx[i].symbol, field)) {
683 return table->idx[i].s_offset;
687 astrodb_error("failed to find field %s\n", field);
688 return -EINVAL;
691 /*! \fn int astrodb_table_for_search_results_do(astrodb_slist* res, void(*func)(void* object, void* data), void* data)
692 * \param res Results from get_objects
693 * \param func Function to call per object in res
694 * \param data Pointer to pass to func
695 * \return 0 for success, negative for error
697 * Calls func for every object in res.
700 int astrodb_table_for_search_results_do(struct astrodb_slist *results,
701 void (*func) (void *object, void *data),
702 void *data)
704 if (func == NULL)
705 return -EINVAL;
707 while (results) {
708 struct astrodb_slist *slist = results->data;
709 while (slist) {
710 func(slist->data, data);
711 slist = slist->tail;
713 results = results->tail;
716 return 0;
720 /*! \fn int astrodb_table_get_row_size(astrodb_table* table);
722 int astrodb_table_get_row_size(struct astrodb_table *table)
724 return table->object_size;
728 /*! \fn void* astrodb_table_get_object (astrodb_table* table, char* id, char* field);
729 * \param table dataset
730 * \param id object id
731 * \param field dataset field
732 * \return object or NULL if not found
734 * Get an object based on it' ID
736 void* astrodb_table_get_object (struct astrodb_table *table, char *id,
737 char *field)
739 struct astrodb_slist *slist = NULL;
740 int offset, i;
742 for (i = 0; i < table->num_hmaps; i++) {
743 if (!strncmp(field, table->hmaps[i].field,
744 strlen(table->hmaps[i].field))) {
745 goto get_object;
748 astrodb_error("failed to find field %s\n", field);
749 return NULL;
751 get_object:
752 offset = table_calc_hash_str(id, strlen(id), table->no_tiles);
753 slist = *(table->hmaps[i].hobjects + offset);
755 while (slist) {
756 char* object_id = slist->data + table->hmaps[i].offset;
757 if (!strstr(object_id, id))
758 return slist->data;
759 slist = slist->tail;
762 astrodb_error("failed to find id %s\n", id);
763 return NULL;
766 /*! \fn int astrodb_table_hash_key(astrodb_table* table, char* field)
767 * \param table dataset
768 * \param field Field to be hashed.
769 * \return 0 on success
771 * Add a field to be hashed for fast lookups.
773 int astrodb_table_hash_key(struct astrodb_table* table, char* key)
775 if (table->num_hmaps == HASH_MAPS) {
776 astrodb_error("too many hashed keys %s\n", key);
777 return -EINVAL;
780 table->hmaps[table->num_hmaps].offset =
781 astrodb_table_get_column_offset(table, key);
782 if (table->hmaps[table->num_hmaps].offset < 0) {
783 astrodb_error("invalid column offset %s\n", key);
784 return -EINVAL;
787 strncpy(table->hmaps[table->num_hmaps].field, key, 8);
788 table->num_hmaps++;
789 return 0;
792 /*! \fn int astrodb_table_register_schema(astrodb_table* table, astrodb_schema_object* idx, int idx_size);
793 * \param table dataset
794 * \param idx Object field index
795 * \param idx_size Number of fields in index
796 * \return 0 on success
798 * Register a new custom object type
800 int astrodb_table_register_schema(struct astrodb_table *table,
801 struct astrodb_schema_object *idx,
802 int idx_size, int object_size)
804 int n, i;
806 for (i = 0, n = 0; i < idx_size; i++) {
807 if (!table_add_custom_struct_field(table, &idx[i]))
808 n++;
810 table->object_size = object_size;
812 return n;