static rc_t copy_metadata_attribs ( const KMDataNode *snode, KMDataNode *dnode, const char *node_path, const bool show_meta ) { KNamelist *attrs; uint32_t i, count; rc_t rc = KMDataNodeListAttr ( snode, & attrs ); DISP_RC( rc, "copy_metadata_child:KMDataNodeListAttr(src) failed" ); if ( rc != 0 ) return rc; rc = KNamelistCount ( attrs, & count ); for ( i = 0; rc == 0 && i < count; ++ i ) { const char *attr; rc = KNamelistGet ( attrs, i, & attr ); if ( rc == 0 ) { char buffer [ 1024 ]; size_t bytes; /* test for attr existence */ rc = KMDataNodeReadAttr ( dnode, attr, buffer, sizeof buffer, & bytes ); if ( rc != 0 ) { rc = KMDataNodeReadAttr ( snode, attr, buffer, sizeof buffer, & bytes ); if ( rc == 0 ) { if ( show_meta ) KOutMsg( "copy atr %s : %s\n", node_path, attr ); rc = KMDataNodeWriteAttr ( dnode, attr, buffer ); } } } DISP_RC( rc, "copy_metadata_child:failed to copy attribute" ); } KNamelistRelease ( attrs ); return rc; }
static rc_t enter_version( KMDataNode *node, const char * key ) { char buff[ 32 ]; rc_t rc; rc = string_printf ( buff, sizeof( buff ), NULL, "%.3V", VDB_COPY_VERS ); assert ( rc == 0 ); rc = KMDataNodeWriteAttr ( node, key, buff ); DISP_RC( rc, "enter_version:KMDataNodeWriteAttr() failed" ); return rc; }
static rc_t enter_time( KMDataNode *node, const char * key ) { char timestring[ 160 ]; rc_t rc = fill_timestring( timestring, sizeof timestring ); if ( rc == 0 ) { rc = KMDataNodeWriteAttr ( node, key, timestring ); DISP_RC( rc, "enter_time:KMDataNodeWriteAttr( timestring ) failed" ); } return rc; }
static rc_t enter_date_name_vers( KMDataNode *node ) { rc_t rc = enter_time( node, "run" ); DISP_RC( rc, "enter_date_name_vers:enter_time() failed" ); if ( rc == 0 ) { rc = KMDataNodeWriteAttr ( node, "tool", "vdb-copy" ); DISP_RC( rc, "enter_date_name_vers:KMDataNodeWriteAttr(tool=vdb-copy) failed" ); if ( rc == 0 ) { rc = enter_version ( node, "vers" ); DISP_RC( rc, "enter_date_name_vers:enter_version() failed" ); if ( rc == 0 ) { rc = KMDataNodeWriteAttr ( node, "build", __DATE__ ); DISP_RC( rc, "enter_date_name_vers:KMDataNodeWriteAttr(build=_DATE_) failed" ); } } } return rc; }
static rc_t group_stats_write_name(KMDataNode *const node, unsigned const namelen, char const name[/* namelen */]) { char sbuf[4096]; char *const hbuf = (namelen + 1) < sizeof(sbuf) ? NULL : malloc(namelen + 1); char *const buffer = (namelen + 1) < sizeof(sbuf) ? sbuf : hbuf; if (buffer == NULL) return RC(rcXF, rcFunction, rcExecuting, rcMemory, rcExhausted); memcpy(buffer, name, namelen); buffer[namelen] = '\0'; { rc_t const rc = KMDataNodeWriteAttr(node, STATS_NODE_NAME_ATTR, buffer); free(hbuf); return rc; } }
/* StoreSchema */ rc_t VDatabaseStoreSchema ( VDatabase *self ) { /* open schema node */ KMDataNode *node; rc_t rc = KMetadataOpenNodeUpdate ( self -> meta, & node, "schema" ); if ( rc == 0 ) { size_t num_writ; char expr [ 256 ]; rc = VSchemaToText ( self -> schema, expr, sizeof expr - 1, & num_writ, "%N%V", self -> sdb -> name, self -> sdb -> version ); if ( rc != 0 ) LOGERR ( klogInt, rc, "failed to determine database schema" ); else { expr [ num_writ ] = 0; rc = KMDataNodeWriteAttr ( node, "name", expr ); if ( rc != 0 ) PLOGERR (klogInt, ( klogInt, rc, "failed to write database type '$(expr)'", "expr=%s", expr )); else { /* truncate existing schema */ rc = KMDataNodeWrite ( node, "", 0 ); if ( rc == 0 ) { rc = VSchemaDump ( self -> schema, sdmCompact, expr, ( rc_t ( CC * ) ( void*, const void*, size_t ) ) KMDataNodeAppend, node ); } if ( rc != 0 ) PLOGERR (klogInt, ( klogInt, rc, "failed to write database schema '$(expr)'", "expr=%s", expr )); } } KMDataNodeRelease ( node ); } return rc; }
/* StoreSchema * stores schema definition in metadata * * <schema name="">...</schema> */ LIB_EXPORT rc_t VTableStoreSchema ( VTable *self ) { /* open schema node */ KMDataNode *node; rc_t rc = KMetadataOpenNodeUpdate ( self -> meta, & node, "schema" ); if ( rc == 0 ) { size_t num_writ; char expr [ 256 ]; rc = VSchemaToText ( self -> schema, expr, sizeof expr - 1, & num_writ, "%N%V", self -> stbl -> name, self -> stbl -> version ); if ( rc != 0 ) LOGERR ( klogInt, rc, "failed to determine table schema" ); else { expr [ num_writ ] = 0; /* if table has a default view declaration, store the table information under a new attribute */ if ( self -> stbl -> dflt_view != NULL ) { uint32_t type; const SNameOverload *name; const STable *view = VSchemaFind ( self -> schema, & name, & type, self -> stbl -> dflt_view-> addr, __func__, false ); if ( view == NULL ) { rc = RC ( rcVDB, rcTable, rcUpdating, rcSchema, rcNotFound ); PLOGERR ( klogInt, ( klogInt, rc, "failed to locate default view schema '$(expr)'", "expr=%S", self -> stbl -> dflt_view )); } else { rc = KMDataNodeWriteAttr ( node, "table", expr ); if ( rc != 0 ) PLOGERR ( klogInt, ( klogInt, rc, "failed to write table type '$(expr)'", "expr=%s", expr )); else { rc = VSchemaToText ( self -> schema, expr, sizeof expr - 1, & num_writ, "%N%V", view -> name, view -> version ); if ( rc != 0 ) LOGERR ( klogInt, rc, "failed to determine table default view schema" ); else expr [ num_writ ] = 0; } } } if ( rc == 0 ) { rc = KMDataNodeWriteAttr ( node, "name", expr ); if ( rc != 0 ) PLOGERR ( klogInt, ( klogInt, rc, "failed to write table name '$(expr)'", "expr=%s", expr )); } if ( rc == 0 ) { /* truncate existing schema */ rc = KMDataNodeWrite ( node, "", 0 ); if ( rc == 0 ) { rc = VSchemaDump ( self -> schema, sdmCompact, expr, ( rc_t ( CC * ) ( void*, const void*, size_t ) ) KMDataNodeAppend, node ); } if ( rc != 0 ) PLOGERR ( klogInt, ( klogInt, rc, "failed to write table schema '$(expr)'", "expr=%s", expr )); } } KMDataNodeRelease ( node ); } return rc; }
static rc_t CC sra_meta_stats_update(sra_meta_stats_data* self, const int64_t spot_id, const uint32_t spot_len, const uint32_t bio_spot_len, const uint32_t cmp_spot_len, bool has_grp, const char* grp, uint64_t grp_len) { rc_t rc = 0; const uint32_t max_grp_qty = 10000; assert(self != NULL); rc = sra_meta_stats_node_group_update(&self->table, spot_id, spot_len, bio_spot_len, cmp_spot_len); if( has_grp && self->grp_qty <= max_grp_qty && rc == 0 ) { /* an empty group is considered default */ if( grp_len == 0 || grp == NULL || grp[0] == '\0' || (grp_len == 7 && strncasecmp("default", grp, grp_len) == 0 ) ) { rc = sra_meta_stats_node_group_update(&self->dflt_grp, spot_id, spot_len, bio_spot_len, cmp_spot_len); } else { size_t i; KMDataNode* n; const KMDataNode *cn; bool new_group, unsafe; /* look for cached node */ if ( self->last_grp_name != NULL && self->last_grp_name_len == grp_len && strncmp(self->last_grp_name, grp, grp_len) == 0 ) { return sra_meta_stats_node_group_update(&self->last_grp, spot_id, spot_len, bio_spot_len, cmp_spot_len); } /* release cached group */ sra_meta_stats_node_group_release(&self->last_grp); /* realloc cached name */ if ( self->last_grp_name == NULL || grp_len >= self->last_grp_name_sz ) { char *p = realloc ( self -> last_grp_name, grp_len + 1 ); if ( p == NULL ) return RC ( rcXF, rcFunction, rcExecuting, rcMemory, rcExhausted ); self -> last_grp_name = p; self -> last_grp_name_sz = grp_len + 1; } /* sanitize name */ for ( unsafe = false, i = 0; i < grp_len; ++ i ) { if ( ( self -> last_grp_name [ i ] = grp [ i ] ) == '/' ) { unsafe = true; self -> last_grp_name [ i ] = '\\'; } } self -> last_grp_name_len = i; self -> last_grp_name [ i ] = 0; /* look for new group */ new_group = true; rc = KMetadataOpenNodeRead(self->meta, &cn, "STATS/SPOT_GROUP/%s", self->last_grp_name ); if ( rc == 0 ) { new_group = false; KMDataNodeRelease ( cn ); } /* detect abusive quantity of nodes */ if ( new_group && ++self->grp_qty > max_grp_qty ) { rc = KMetadataOpenNodeUpdate(self->meta, &n, "STATS"); if( rc == 0 ) { sra_meta_stats_node_group_release(&self->dflt_grp); KMDataNodeDropChild(n, "SPOT_GROUP"); KMDataNodeRelease(n); free(self->last_grp_name); self->last_grp_name = NULL; } return rc; } /* create new or cache existing group */ rc = KMetadataOpenNodeUpdate(self->meta, &n, "STATS/SPOT_GROUP/%s", self->last_grp_name ); if ( rc == 0 ) { rc = sra_meta_stats_node_group_open(n, &self->last_grp, self->compressed); if (rc == 0 && new_group) { if (unsafe) { char value [ 512 ], *v = value; if ( grp_len >= sizeof value ) v = malloc ( grp_len + 1 ); if ( v == NULL ) rc = RC ( rcXF, rcFunction, rcExecuting, rcMemory, rcExhausted ); else { rc = string_printf ( v, grp_len + 1, NULL, "%.*s", ( uint32_t ) grp_len, grp ); assert ( rc == 0 ); rc = KMDataNodeWriteAttr(n, "name", v); if ( rc == 0 ) memcpy ( self->last_grp_name, grp, grp_len ); if ( v != value ) free ( v ); } } if ( rc == 0 ) rc = sra_meta_stats_node_group_update(&self->last_grp, 0, 0, 0, 0); } KMDataNodeRelease(n); if( rc == 0 ) rc = sra_meta_stats_node_group_update(&self->last_grp, spot_id, spot_len, bio_spot_len, cmp_spot_len); } } } return rc; }
/* WriteAttr * writes NUL-terminated string * * "name" [ IN ] - NUL terminated attribute name * * "value" [ IN ] - NUL terminated attribute value */ inline rc_t WriteAttr ( const char *name, const char *value ) throw() { return KMDataNodeWriteAttr ( this, name, value ); }