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 */
db_scheme(db_scheme * orig)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'. */
db_scheme(table_obj * 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
clear_columns(int numkeys)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. */
~db_scheme()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
find_index(char * purportedname,int * result)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
print()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