diff options
author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
---|---|---|
committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/lib/libnisdb/db_scheme.cc | |
download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz |
OpenSolaris Launch
Diffstat (limited to 'usr/src/lib/libnisdb/db_scheme.cc')
-rw-r--r-- | usr/src/lib/libnisdb/db_scheme.cc | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/usr/src/lib/libnisdb/db_scheme.cc b/usr/src/lib/libnisdb/db_scheme.cc new file mode 100644 index 0000000000..9032fa0fb6 --- /dev/null +++ b/usr/src/lib/libnisdb/db_scheme.cc @@ -0,0 +1,243 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * db_scheme.cc + * + * Copyright (c) 1988-2000 Sun Microsystems, Inc. + * All Rights Reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <string.h> +#include "db_headers.h" +#include "db_scheme.h" + +#include "nisdb_mt.h" + +/* + * Constructor: create new scheme by making copy of 'orig'. + * All items within old scheme are also copied (i.e. no shared pointers). +*/ +db_scheme::db_scheme(db_scheme* orig) +{ + int numkeys, i; + keys.keys_len = 0; + keys.keys_val = NULL; + + if (orig == NULL) { + WARNING("db_scheme::db_scheme: null original db_scheme"); + return; + } + + READLOCKV(orig, "r orig db_scheme::db_scheme"); + + numkeys = this->keys.keys_len = orig->keys.keys_len; + db_key_desc * descols = this->keys.keys_val = new db_key_desc[numkeys]; + db_key_desc * srccols = orig->keys.keys_val; + + if (descols == NULL) { + clear_columns(0); + READUNLOCKV(orig, "ru orig db_scheme::db_scheme"); + FATAL("db_scheme::db_scheme: cannot allocate space for columns", + DB_MEMORY_LIMIT); + } + + for (i = 0; i < numkeys; i++) { + if (srccols[i].key_name == NULL) { + clear_columns(i); + WARNING("db_scheme::db_scheme: null column name"); + READUNLOCKV(orig, "ru orig db_scheme::db_scheme"); + return; + } + descols[i].key_name = new item(srccols[i].key_name); + if (descols[i].key_name == NULL) { + clear_columns(i); + READUNLOCKV(orig, "ru orig db_scheme::db_scheme"); + FATAL( + "db_scheme::db_scheme: cannot allocate space for column names", + DB_MEMORY_LIMIT); + } + descols[i].key_flags = srccols[i].key_flags; + descols[i].where = srccols[i].where; + descols[i].store_type = srccols[i].store_type; + descols[i].column_number = srccols[i].column_number; + } + this->max_columns = orig->max_columns; + this->data = orig->data; + READUNLOCKV(orig, "ru orig db_scheme::db_scheme"); + INITRW(scheme); +} + +/* Constructor: create new sheme by using information in 'zdesc'. */ +db_scheme::db_scheme(table_obj *zdesc) +{ + keys.keys_len = 0; + keys.keys_val = NULL; + + if (zdesc == NULL) { + WARNING("db_scheme::db_scheme: null table obj"); + return; + } + + max_columns = zdesc->ta_maxcol; + + /* find out how many searchable columns */ + int total_cols = zdesc->ta_cols.ta_cols_len; + table_col * zcols = zdesc->ta_cols.ta_cols_val; + int count = 0, i; + + if (zcols == NULL) { + WARNING("db_scheme::db_scheme: no columns in nis table obj"); + return; + } + + /* find out number of indices */ + for (i = 0; i < total_cols; i++) { + if (zcols[i].tc_flags&TA_SEARCHABLE) + ++count; + } + if (count == 0) { + WARNING( + "db_scheme::db_scheme: no searchable columns in nis table obj"); + return; + } + + keys.keys_len = count; + db_key_desc * scols = keys.keys_val = new db_key_desc[count]; + if (scols == NULL) { + clear_columns(0); + FATAL("db_scheme::db_scheme: cannot allocate space for keys", + DB_MEMORY_LIMIT); + } + int keynum = 0; + + for (i = 0; i < total_cols; i++) { + if (zcols[i].tc_flags&TA_SEARCHABLE) { + if (zcols[i].tc_name == NULL) { + clear_columns(keynum); + WARNING( + "db_scheme::db_scheme: searchable column cannot have null name"); + return; + } + scols[keynum].key_name = new item(zcols[i].tc_name, + strlen(zcols[i].tc_name)); + if (scols[keynum].key_name == NULL) { + clear_columns(keynum); + FATAL( + "db_scheme::db_scheme: cannot allocate space for key names", + DB_MEMORY_LIMIT); + } + scols[keynum].key_flags = zcols[i].tc_flags; + scols[keynum].column_number = i; + scols[keynum].where.max_len = NIS_MAXATTRVAL; + scols[keynum].where.start_column = 0; + /* don't care about position information for now */ + ++keynum; /* advance to next key number */ + } + } + if (keynum != count) { /* something is wrong */ + clear_columns(keynum); + WARNING( + "db_scheme::db_scheme: incorrect number of searchable columns"); + } + INITRW(scheme); +} + +void +db_scheme::clear_columns(int numkeys) +{ + int j; + + WRITELOCKV(this, "w db_scheme::clear_columns"); + + db_key_desc * cols = keys.keys_val; + + if (cols) { + for (j = 0; j < numkeys; j++) { + if (cols[j].key_name) + delete cols[j].key_name; + } + delete cols; + keys.keys_val = NULL; + } + keys.keys_len = 0; + + WRITEUNLOCKV(this, "wu db_scheme::clear_columns"); +} + +/* Destructor: delete all keys associated with scheme and scheme itself. */ +db_scheme::~db_scheme() +{ + WRITELOCKV(this, "w db_scheme::~db_scheme"); + clear_columns(keys.keys_len); + DESTROYRW(scheme); +} + +/* + * Predicate: return whether given string is one of the index names + * this scheme. If so, return in 'result' the index's number. +*/ +bool_t +db_scheme::find_index(char *purportedname, int *result) +{ + if (purportedname) { + int i; + int plen; + plen = strlen(purportedname); + + READLOCK(this, FALSE, "r db_scheme::find_index"); + for (i = 0; i < keys.keys_len; i++) { + if (keys.keys_val[i].key_name->equal(purportedname, + plen, TRUE)) { + if (result) *result = i; + READUNLOCK(this, TRUE, + "ru db_scheme::find_index"); + return (TRUE); + } + } + READUNLOCK(this, FALSE, "ru db_scheme::find_index"); + } + return (FALSE); +} + +/* Print out description of table. */ +void +db_scheme::print() +{ + int i; + + READLOCKV(this, "r db_scheme::print"); + for (i = 0; i < keys.keys_len; i++) { + keys.keys_val[i].key_name->print(); + printf( + "\tcolumn=%d, flags=0x%x, key record position=%d, max length=%d\n", + keys.keys_val[i].column_number, + keys.keys_val[i].key_flags, + keys.keys_val[i].where.start_column, + keys.keys_val[i].where.max_len); + printf("\tdata record position=%d, max length=%d\n", + data.where.start_column, data.where.max_len); + } + printf("\tmaximum number of columns=%d\n", max_columns); + READUNLOCKV(this, "ru db_scheme::print"); +} |