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