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