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