Home | History | Annotate | Download | only in libnisdb
      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 */
     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'. */
     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
    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. */
    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
    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
    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