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