/* * 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. */ #include #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"); }