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 #include <string.h> 30 #include "db_headers.h" 31 #include "db_scheme.h" 32 33 #include "nisdb_mt.h" 34 35 /* 36 * Constructor: create new scheme by making copy of 'orig'. 37 * All items within old scheme are also copied (i.e. no shared pointers). 38 */ 39 db_scheme::db_scheme(db_scheme* orig) 40 { 41 int numkeys, i; 42 keys.keys_len = 0; 43 keys.keys_val = NULL; 44 45 if (orig == NULL) { 46 WARNING("db_scheme::db_scheme: null original db_scheme"); 47 return; 48 } 49 50 READLOCKV(orig, "r orig db_scheme::db_scheme"); 51 52 numkeys = this->keys.keys_len = orig->keys.keys_len; 53 db_key_desc * descols = this->keys.keys_val = new db_key_desc[numkeys]; 54 db_key_desc * srccols = orig->keys.keys_val; 55 56 if (descols == NULL) { 57 clear_columns(0); 58 READUNLOCKV(orig, "ru orig db_scheme::db_scheme"); 59 FATAL("db_scheme::db_scheme: cannot allocate space for columns", 60 DB_MEMORY_LIMIT); 61 } 62 63 for (i = 0; i < numkeys; i++) { 64 if (srccols[i].key_name == NULL) { 65 clear_columns(i); 66 WARNING("db_scheme::db_scheme: null column name"); 67 READUNLOCKV(orig, "ru orig db_scheme::db_scheme"); 68 return; 69 } 70 descols[i].key_name = new item(srccols[i].key_name); 71 if (descols[i].key_name == NULL) { 72 clear_columns(i); 73 READUNLOCKV(orig, "ru orig db_scheme::db_scheme"); 74 FATAL( 75 "db_scheme::db_scheme: cannot allocate space for column names", 76 DB_MEMORY_LIMIT); 77 } 78 descols[i].key_flags = srccols[i].key_flags; 79 descols[i].where = srccols[i].where; 80 descols[i].store_type = srccols[i].store_type; 81 descols[i].column_number = srccols[i].column_number; 82 } 83 this->max_columns = orig->max_columns; 84 this->data = orig->data; 85 READUNLOCKV(orig, "ru orig db_scheme::db_scheme"); 86 INITRW(scheme); 87 } 88 89 /* Constructor: create new sheme by using information in 'zdesc'. */ 90 db_scheme::db_scheme(table_obj *zdesc) 91 { 92 keys.keys_len = 0; 93 keys.keys_val = NULL; 94 95 if (zdesc == NULL) { 96 WARNING("db_scheme::db_scheme: null table obj"); 97 return; 98 } 99 100 max_columns = zdesc->ta_maxcol; 101 102 /* find out how many searchable columns */ 103 int total_cols = zdesc->ta_cols.ta_cols_len; 104 table_col * zcols = zdesc->ta_cols.ta_cols_val; 105 int count = 0, i; 106 107 if (zcols == NULL) { 108 WARNING("db_scheme::db_scheme: no columns in nis table obj"); 109 return; 110 } 111 112 /* find out number of indices */ 113 for (i = 0; i < total_cols; i++) { 114 if (zcols[i].tc_flags&TA_SEARCHABLE) 115 ++count; 116 } 117 if (count == 0) { 118 WARNING( 119 "db_scheme::db_scheme: no searchable columns in nis table obj"); 120 return; 121 } 122 123 keys.keys_len = count; 124 db_key_desc * scols = keys.keys_val = new db_key_desc[count]; 125 if (scols == NULL) { 126 clear_columns(0); 127 FATAL("db_scheme::db_scheme: cannot allocate space for keys", 128 DB_MEMORY_LIMIT); 129 } 130 int keynum = 0; 131 132 for (i = 0; i < total_cols; i++) { 133 if (zcols[i].tc_flags&TA_SEARCHABLE) { 134 if (zcols[i].tc_name == NULL) { 135 clear_columns(keynum); 136 WARNING( 137 "db_scheme::db_scheme: searchable column cannot have null name"); 138 return; 139 } 140 scols[keynum].key_name = new item(zcols[i].tc_name, 141 strlen(zcols[i].tc_name)); 142 if (scols[keynum].key_name == NULL) { 143 clear_columns(keynum); 144 FATAL( 145 "db_scheme::db_scheme: cannot allocate space for key names", 146 DB_MEMORY_LIMIT); 147 } 148 scols[keynum].key_flags = zcols[i].tc_flags; 149 scols[keynum].column_number = i; 150 scols[keynum].where.max_len = NIS_MAXATTRVAL; 151 scols[keynum].where.start_column = 0; 152 /* don't care about position information for now */ 153 ++keynum; /* advance to next key number */ 154 } 155 } 156 if (keynum != count) { /* something is wrong */ 157 clear_columns(keynum); 158 WARNING( 159 "db_scheme::db_scheme: incorrect number of searchable columns"); 160 } 161 INITRW(scheme); 162 } 163 164 void 165 db_scheme::clear_columns(int numkeys) 166 { 167 int j; 168 169 WRITELOCKV(this, "w db_scheme::clear_columns"); 170 171 db_key_desc * cols = keys.keys_val; 172 173 if (cols) { 174 for (j = 0; j < numkeys; j++) { 175 if (cols[j].key_name) 176 delete cols[j].key_name; 177 } 178 delete cols; 179 keys.keys_val = NULL; 180 } 181 keys.keys_len = 0; 182 183 WRITEUNLOCKV(this, "wu db_scheme::clear_columns"); 184 } 185 186 /* Destructor: delete all keys associated with scheme and scheme itself. */ 187 db_scheme::~db_scheme() 188 { 189 WRITELOCKV(this, "w db_scheme::~db_scheme"); 190 clear_columns(keys.keys_len); 191 DESTROYRW(scheme); 192 } 193 194 /* 195 * Predicate: return whether given string is one of the index names 196 * this scheme. If so, return in 'result' the index's number. 197 */ 198 bool_t 199 db_scheme::find_index(char *purportedname, int *result) 200 { 201 if (purportedname) { 202 int i; 203 int plen; 204 plen = strlen(purportedname); 205 206 READLOCK(this, FALSE, "r db_scheme::find_index"); 207 for (i = 0; i < keys.keys_len; i++) { 208 if (keys.keys_val[i].key_name->equal(purportedname, 209 plen, TRUE)) { 210 if (result) *result = i; 211 READUNLOCK(this, TRUE, 212 "ru db_scheme::find_index"); 213 return (TRUE); 214 } 215 } 216 READUNLOCK(this, FALSE, "ru db_scheme::find_index"); 217 } 218 return (FALSE); 219 } 220 221 /* Print out description of table. */ 222 void 223 db_scheme::print() 224 { 225 int i; 226 227 READLOCKV(this, "r db_scheme::print"); 228 for (i = 0; i < keys.keys_len; i++) { 229 keys.keys_val[i].key_name->print(); 230 printf( 231 "\tcolumn=%d, flags=0x%x, key record position=%d, max length=%d\n", 232 keys.keys_val[i].column_number, 233 keys.keys_val[i].key_flags, 234 keys.keys_val[i].where.start_column, 235 keys.keys_val[i].where.max_len); 236 printf("\tdata record position=%d, max length=%d\n", 237 data.where.start_column, data.where.max_len); 238 } 239 printf("\tmaximum number of columns=%d\n", max_columns); 240 READUNLOCKV(this, "ru db_scheme::print"); 241 } 242