1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * db_scheme.cc 24*7c478bd9Sstevel@tonic-gate * 25*7c478bd9Sstevel@tonic-gate * Copyright (c) 1988-2000 Sun Microsystems, Inc. 26*7c478bd9Sstevel@tonic-gate * All Rights Reserved. 27*7c478bd9Sstevel@tonic-gate */ 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #include <string.h> 32*7c478bd9Sstevel@tonic-gate #include "db_headers.h" 33*7c478bd9Sstevel@tonic-gate #include "db_scheme.h" 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #include "nisdb_mt.h" 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate /* 38*7c478bd9Sstevel@tonic-gate * Constructor: create new scheme by making copy of 'orig'. 39*7c478bd9Sstevel@tonic-gate * All items within old scheme are also copied (i.e. no shared pointers). 40*7c478bd9Sstevel@tonic-gate */ 41*7c478bd9Sstevel@tonic-gate db_scheme::db_scheme(db_scheme* orig) 42*7c478bd9Sstevel@tonic-gate { 43*7c478bd9Sstevel@tonic-gate int numkeys, i; 44*7c478bd9Sstevel@tonic-gate keys.keys_len = 0; 45*7c478bd9Sstevel@tonic-gate keys.keys_val = NULL; 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate if (orig == NULL) { 48*7c478bd9Sstevel@tonic-gate WARNING("db_scheme::db_scheme: null original db_scheme"); 49*7c478bd9Sstevel@tonic-gate return; 50*7c478bd9Sstevel@tonic-gate } 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate READLOCKV(orig, "r orig db_scheme::db_scheme"); 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate numkeys = this->keys.keys_len = orig->keys.keys_len; 55*7c478bd9Sstevel@tonic-gate db_key_desc * descols = this->keys.keys_val = new db_key_desc[numkeys]; 56*7c478bd9Sstevel@tonic-gate db_key_desc * srccols = orig->keys.keys_val; 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate if (descols == NULL) { 59*7c478bd9Sstevel@tonic-gate clear_columns(0); 60*7c478bd9Sstevel@tonic-gate READUNLOCKV(orig, "ru orig db_scheme::db_scheme"); 61*7c478bd9Sstevel@tonic-gate FATAL("db_scheme::db_scheme: cannot allocate space for columns", 62*7c478bd9Sstevel@tonic-gate DB_MEMORY_LIMIT); 63*7c478bd9Sstevel@tonic-gate } 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate for (i = 0; i < numkeys; i++) { 66*7c478bd9Sstevel@tonic-gate if (srccols[i].key_name == NULL) { 67*7c478bd9Sstevel@tonic-gate clear_columns(i); 68*7c478bd9Sstevel@tonic-gate WARNING("db_scheme::db_scheme: null column name"); 69*7c478bd9Sstevel@tonic-gate READUNLOCKV(orig, "ru orig db_scheme::db_scheme"); 70*7c478bd9Sstevel@tonic-gate return; 71*7c478bd9Sstevel@tonic-gate } 72*7c478bd9Sstevel@tonic-gate descols[i].key_name = new item(srccols[i].key_name); 73*7c478bd9Sstevel@tonic-gate if (descols[i].key_name == NULL) { 74*7c478bd9Sstevel@tonic-gate clear_columns(i); 75*7c478bd9Sstevel@tonic-gate READUNLOCKV(orig, "ru orig db_scheme::db_scheme"); 76*7c478bd9Sstevel@tonic-gate FATAL( 77*7c478bd9Sstevel@tonic-gate "db_scheme::db_scheme: cannot allocate space for column names", 78*7c478bd9Sstevel@tonic-gate DB_MEMORY_LIMIT); 79*7c478bd9Sstevel@tonic-gate } 80*7c478bd9Sstevel@tonic-gate descols[i].key_flags = srccols[i].key_flags; 81*7c478bd9Sstevel@tonic-gate descols[i].where = srccols[i].where; 82*7c478bd9Sstevel@tonic-gate descols[i].store_type = srccols[i].store_type; 83*7c478bd9Sstevel@tonic-gate descols[i].column_number = srccols[i].column_number; 84*7c478bd9Sstevel@tonic-gate } 85*7c478bd9Sstevel@tonic-gate this->max_columns = orig->max_columns; 86*7c478bd9Sstevel@tonic-gate this->data = orig->data; 87*7c478bd9Sstevel@tonic-gate READUNLOCKV(orig, "ru orig db_scheme::db_scheme"); 88*7c478bd9Sstevel@tonic-gate INITRW(scheme); 89*7c478bd9Sstevel@tonic-gate } 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate /* Constructor: create new sheme by using information in 'zdesc'. */ 92*7c478bd9Sstevel@tonic-gate db_scheme::db_scheme(table_obj *zdesc) 93*7c478bd9Sstevel@tonic-gate { 94*7c478bd9Sstevel@tonic-gate keys.keys_len = 0; 95*7c478bd9Sstevel@tonic-gate keys.keys_val = NULL; 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate if (zdesc == NULL) { 98*7c478bd9Sstevel@tonic-gate WARNING("db_scheme::db_scheme: null table obj"); 99*7c478bd9Sstevel@tonic-gate return; 100*7c478bd9Sstevel@tonic-gate } 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate max_columns = zdesc->ta_maxcol; 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate /* find out how many searchable columns */ 105*7c478bd9Sstevel@tonic-gate int total_cols = zdesc->ta_cols.ta_cols_len; 106*7c478bd9Sstevel@tonic-gate table_col * zcols = zdesc->ta_cols.ta_cols_val; 107*7c478bd9Sstevel@tonic-gate int count = 0, i; 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate if (zcols == NULL) { 110*7c478bd9Sstevel@tonic-gate WARNING("db_scheme::db_scheme: no columns in nis table obj"); 111*7c478bd9Sstevel@tonic-gate return; 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate /* find out number of indices */ 115*7c478bd9Sstevel@tonic-gate for (i = 0; i < total_cols; i++) { 116*7c478bd9Sstevel@tonic-gate if (zcols[i].tc_flags&TA_SEARCHABLE) 117*7c478bd9Sstevel@tonic-gate ++count; 118*7c478bd9Sstevel@tonic-gate } 119*7c478bd9Sstevel@tonic-gate if (count == 0) { 120*7c478bd9Sstevel@tonic-gate WARNING( 121*7c478bd9Sstevel@tonic-gate "db_scheme::db_scheme: no searchable columns in nis table obj"); 122*7c478bd9Sstevel@tonic-gate return; 123*7c478bd9Sstevel@tonic-gate } 124*7c478bd9Sstevel@tonic-gate 125*7c478bd9Sstevel@tonic-gate keys.keys_len = count; 126*7c478bd9Sstevel@tonic-gate db_key_desc * scols = keys.keys_val = new db_key_desc[count]; 127*7c478bd9Sstevel@tonic-gate if (scols == NULL) { 128*7c478bd9Sstevel@tonic-gate clear_columns(0); 129*7c478bd9Sstevel@tonic-gate FATAL("db_scheme::db_scheme: cannot allocate space for keys", 130*7c478bd9Sstevel@tonic-gate DB_MEMORY_LIMIT); 131*7c478bd9Sstevel@tonic-gate } 132*7c478bd9Sstevel@tonic-gate int keynum = 0; 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate for (i = 0; i < total_cols; i++) { 135*7c478bd9Sstevel@tonic-gate if (zcols[i].tc_flags&TA_SEARCHABLE) { 136*7c478bd9Sstevel@tonic-gate if (zcols[i].tc_name == NULL) { 137*7c478bd9Sstevel@tonic-gate clear_columns(keynum); 138*7c478bd9Sstevel@tonic-gate WARNING( 139*7c478bd9Sstevel@tonic-gate "db_scheme::db_scheme: searchable column cannot have null name"); 140*7c478bd9Sstevel@tonic-gate return; 141*7c478bd9Sstevel@tonic-gate } 142*7c478bd9Sstevel@tonic-gate scols[keynum].key_name = new item(zcols[i].tc_name, 143*7c478bd9Sstevel@tonic-gate strlen(zcols[i].tc_name)); 144*7c478bd9Sstevel@tonic-gate if (scols[keynum].key_name == NULL) { 145*7c478bd9Sstevel@tonic-gate clear_columns(keynum); 146*7c478bd9Sstevel@tonic-gate FATAL( 147*7c478bd9Sstevel@tonic-gate "db_scheme::db_scheme: cannot allocate space for key names", 148*7c478bd9Sstevel@tonic-gate DB_MEMORY_LIMIT); 149*7c478bd9Sstevel@tonic-gate } 150*7c478bd9Sstevel@tonic-gate scols[keynum].key_flags = zcols[i].tc_flags; 151*7c478bd9Sstevel@tonic-gate scols[keynum].column_number = i; 152*7c478bd9Sstevel@tonic-gate scols[keynum].where.max_len = NIS_MAXATTRVAL; 153*7c478bd9Sstevel@tonic-gate scols[keynum].where.start_column = 0; 154*7c478bd9Sstevel@tonic-gate /* don't care about position information for now */ 155*7c478bd9Sstevel@tonic-gate ++keynum; /* advance to next key number */ 156*7c478bd9Sstevel@tonic-gate } 157*7c478bd9Sstevel@tonic-gate } 158*7c478bd9Sstevel@tonic-gate if (keynum != count) { /* something is wrong */ 159*7c478bd9Sstevel@tonic-gate clear_columns(keynum); 160*7c478bd9Sstevel@tonic-gate WARNING( 161*7c478bd9Sstevel@tonic-gate "db_scheme::db_scheme: incorrect number of searchable columns"); 162*7c478bd9Sstevel@tonic-gate } 163*7c478bd9Sstevel@tonic-gate INITRW(scheme); 164*7c478bd9Sstevel@tonic-gate } 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate void 167*7c478bd9Sstevel@tonic-gate db_scheme::clear_columns(int numkeys) 168*7c478bd9Sstevel@tonic-gate { 169*7c478bd9Sstevel@tonic-gate int j; 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate WRITELOCKV(this, "w db_scheme::clear_columns"); 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate db_key_desc * cols = keys.keys_val; 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate if (cols) { 176*7c478bd9Sstevel@tonic-gate for (j = 0; j < numkeys; j++) { 177*7c478bd9Sstevel@tonic-gate if (cols[j].key_name) 178*7c478bd9Sstevel@tonic-gate delete cols[j].key_name; 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate delete cols; 181*7c478bd9Sstevel@tonic-gate keys.keys_val = NULL; 182*7c478bd9Sstevel@tonic-gate } 183*7c478bd9Sstevel@tonic-gate keys.keys_len = 0; 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate WRITEUNLOCKV(this, "wu db_scheme::clear_columns"); 186*7c478bd9Sstevel@tonic-gate } 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate /* Destructor: delete all keys associated with scheme and scheme itself. */ 189*7c478bd9Sstevel@tonic-gate db_scheme::~db_scheme() 190*7c478bd9Sstevel@tonic-gate { 191*7c478bd9Sstevel@tonic-gate WRITELOCKV(this, "w db_scheme::~db_scheme"); 192*7c478bd9Sstevel@tonic-gate clear_columns(keys.keys_len); 193*7c478bd9Sstevel@tonic-gate DESTROYRW(scheme); 194*7c478bd9Sstevel@tonic-gate } 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate /* 197*7c478bd9Sstevel@tonic-gate * Predicate: return whether given string is one of the index names 198*7c478bd9Sstevel@tonic-gate * this scheme. If so, return in 'result' the index's number. 199*7c478bd9Sstevel@tonic-gate */ 200*7c478bd9Sstevel@tonic-gate bool_t 201*7c478bd9Sstevel@tonic-gate db_scheme::find_index(char *purportedname, int *result) 202*7c478bd9Sstevel@tonic-gate { 203*7c478bd9Sstevel@tonic-gate if (purportedname) { 204*7c478bd9Sstevel@tonic-gate int i; 205*7c478bd9Sstevel@tonic-gate int plen; 206*7c478bd9Sstevel@tonic-gate plen = strlen(purportedname); 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate READLOCK(this, FALSE, "r db_scheme::find_index"); 209*7c478bd9Sstevel@tonic-gate for (i = 0; i < keys.keys_len; i++) { 210*7c478bd9Sstevel@tonic-gate if (keys.keys_val[i].key_name->equal(purportedname, 211*7c478bd9Sstevel@tonic-gate plen, TRUE)) { 212*7c478bd9Sstevel@tonic-gate if (result) *result = i; 213*7c478bd9Sstevel@tonic-gate READUNLOCK(this, TRUE, 214*7c478bd9Sstevel@tonic-gate "ru db_scheme::find_index"); 215*7c478bd9Sstevel@tonic-gate return (TRUE); 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate } 218*7c478bd9Sstevel@tonic-gate READUNLOCK(this, FALSE, "ru db_scheme::find_index"); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate return (FALSE); 221*7c478bd9Sstevel@tonic-gate } 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate /* Print out description of table. */ 224*7c478bd9Sstevel@tonic-gate void 225*7c478bd9Sstevel@tonic-gate db_scheme::print() 226*7c478bd9Sstevel@tonic-gate { 227*7c478bd9Sstevel@tonic-gate int i; 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gate READLOCKV(this, "r db_scheme::print"); 230*7c478bd9Sstevel@tonic-gate for (i = 0; i < keys.keys_len; i++) { 231*7c478bd9Sstevel@tonic-gate keys.keys_val[i].key_name->print(); 232*7c478bd9Sstevel@tonic-gate printf( 233*7c478bd9Sstevel@tonic-gate "\tcolumn=%d, flags=0x%x, key record position=%d, max length=%d\n", 234*7c478bd9Sstevel@tonic-gate keys.keys_val[i].column_number, 235*7c478bd9Sstevel@tonic-gate keys.keys_val[i].key_flags, 236*7c478bd9Sstevel@tonic-gate keys.keys_val[i].where.start_column, 237*7c478bd9Sstevel@tonic-gate keys.keys_val[i].where.max_len); 238*7c478bd9Sstevel@tonic-gate printf("\tdata record position=%d, max length=%d\n", 239*7c478bd9Sstevel@tonic-gate data.where.start_column, data.where.max_len); 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate printf("\tmaximum number of columns=%d\n", max_columns); 242*7c478bd9Sstevel@tonic-gate READUNLOCKV(this, "ru db_scheme::print"); 243*7c478bd9Sstevel@tonic-gate } 244