summaryrefslogtreecommitdiff
path: root/usr/src/lib/libnisdb/db_scheme.cc
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/lib/libnisdb/db_scheme.cc
downloadillumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/lib/libnisdb/db_scheme.cc')
-rw-r--r--usr/src/lib/libnisdb/db_scheme.cc243
1 files changed, 243 insertions, 0 deletions
diff --git a/usr/src/lib/libnisdb/db_scheme.cc b/usr/src/lib/libnisdb/db_scheme.cc
new file mode 100644
index 0000000000..9032fa0fb6
--- /dev/null
+++ b/usr/src/lib/libnisdb/db_scheme.cc
@@ -0,0 +1,243 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * db_scheme.cc
+ *
+ * Copyright (c) 1988-2000 Sun Microsystems, Inc.
+ * All Rights Reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <string.h>
+#include "db_headers.h"
+#include "db_scheme.h"
+
+#include "nisdb_mt.h"
+
+/*
+ * Constructor: create new scheme by making copy of 'orig'.
+ * All items within old scheme are also copied (i.e. no shared pointers).
+*/
+db_scheme::db_scheme(db_scheme* orig)
+{
+ int numkeys, i;
+ keys.keys_len = 0;
+ keys.keys_val = NULL;
+
+ if (orig == NULL) {
+ WARNING("db_scheme::db_scheme: null original db_scheme");
+ return;
+ }
+
+ READLOCKV(orig, "r orig db_scheme::db_scheme");
+
+ numkeys = this->keys.keys_len = orig->keys.keys_len;
+ db_key_desc * descols = this->keys.keys_val = new db_key_desc[numkeys];
+ db_key_desc * srccols = orig->keys.keys_val;
+
+ if (descols == NULL) {
+ clear_columns(0);
+ READUNLOCKV(orig, "ru orig db_scheme::db_scheme");
+ FATAL("db_scheme::db_scheme: cannot allocate space for columns",
+ DB_MEMORY_LIMIT);
+ }
+
+ for (i = 0; i < numkeys; i++) {
+ if (srccols[i].key_name == NULL) {
+ clear_columns(i);
+ WARNING("db_scheme::db_scheme: null column name");
+ READUNLOCKV(orig, "ru orig db_scheme::db_scheme");
+ return;
+ }
+ descols[i].key_name = new item(srccols[i].key_name);
+ if (descols[i].key_name == NULL) {
+ clear_columns(i);
+ READUNLOCKV(orig, "ru orig db_scheme::db_scheme");
+ FATAL(
+ "db_scheme::db_scheme: cannot allocate space for column names",
+ DB_MEMORY_LIMIT);
+ }
+ descols[i].key_flags = srccols[i].key_flags;
+ descols[i].where = srccols[i].where;
+ descols[i].store_type = srccols[i].store_type;
+ descols[i].column_number = srccols[i].column_number;
+ }
+ this->max_columns = orig->max_columns;
+ this->data = orig->data;
+ READUNLOCKV(orig, "ru orig db_scheme::db_scheme");
+ INITRW(scheme);
+}
+
+/* Constructor: create new sheme by using information in 'zdesc'. */
+db_scheme::db_scheme(table_obj *zdesc)
+{
+ keys.keys_len = 0;
+ keys.keys_val = NULL;
+
+ if (zdesc == NULL) {
+ WARNING("db_scheme::db_scheme: null table obj");
+ return;
+ }
+
+ max_columns = zdesc->ta_maxcol;
+
+ /* find out how many searchable columns */
+ int total_cols = zdesc->ta_cols.ta_cols_len;
+ table_col * zcols = zdesc->ta_cols.ta_cols_val;
+ int count = 0, i;
+
+ if (zcols == NULL) {
+ WARNING("db_scheme::db_scheme: no columns in nis table obj");
+ return;
+ }
+
+ /* find out number of indices */
+ for (i = 0; i < total_cols; i++) {
+ if (zcols[i].tc_flags&TA_SEARCHABLE)
+ ++count;
+ }
+ if (count == 0) {
+ WARNING(
+ "db_scheme::db_scheme: no searchable columns in nis table obj");
+ return;
+ }
+
+ keys.keys_len = count;
+ db_key_desc * scols = keys.keys_val = new db_key_desc[count];
+ if (scols == NULL) {
+ clear_columns(0);
+ FATAL("db_scheme::db_scheme: cannot allocate space for keys",
+ DB_MEMORY_LIMIT);
+ }
+ int keynum = 0;
+
+ for (i = 0; i < total_cols; i++) {
+ if (zcols[i].tc_flags&TA_SEARCHABLE) {
+ if (zcols[i].tc_name == NULL) {
+ clear_columns(keynum);
+ WARNING(
+ "db_scheme::db_scheme: searchable column cannot have null name");
+ return;
+ }
+ scols[keynum].key_name = new item(zcols[i].tc_name,
+ strlen(zcols[i].tc_name));
+ if (scols[keynum].key_name == NULL) {
+ clear_columns(keynum);
+ FATAL(
+ "db_scheme::db_scheme: cannot allocate space for key names",
+ DB_MEMORY_LIMIT);
+ }
+ scols[keynum].key_flags = zcols[i].tc_flags;
+ scols[keynum].column_number = i;
+ scols[keynum].where.max_len = NIS_MAXATTRVAL;
+ scols[keynum].where.start_column = 0;
+ /* don't care about position information for now */
+ ++keynum; /* advance to next key number */
+ }
+ }
+ if (keynum != count) { /* something is wrong */
+ clear_columns(keynum);
+ WARNING(
+ "db_scheme::db_scheme: incorrect number of searchable columns");
+ }
+ INITRW(scheme);
+}
+
+void
+db_scheme::clear_columns(int numkeys)
+{
+ int j;
+
+ WRITELOCKV(this, "w db_scheme::clear_columns");
+
+ db_key_desc * cols = keys.keys_val;
+
+ if (cols) {
+ for (j = 0; j < numkeys; j++) {
+ if (cols[j].key_name)
+ delete cols[j].key_name;
+ }
+ delete cols;
+ keys.keys_val = NULL;
+ }
+ keys.keys_len = 0;
+
+ WRITEUNLOCKV(this, "wu db_scheme::clear_columns");
+}
+
+/* Destructor: delete all keys associated with scheme and scheme itself. */
+db_scheme::~db_scheme()
+{
+ WRITELOCKV(this, "w db_scheme::~db_scheme");
+ clear_columns(keys.keys_len);
+ DESTROYRW(scheme);
+}
+
+/*
+ * Predicate: return whether given string is one of the index names
+ * this scheme. If so, return in 'result' the index's number.
+*/
+bool_t
+db_scheme::find_index(char *purportedname, int *result)
+{
+ if (purportedname) {
+ int i;
+ int plen;
+ plen = strlen(purportedname);
+
+ READLOCK(this, FALSE, "r db_scheme::find_index");
+ for (i = 0; i < keys.keys_len; i++) {
+ if (keys.keys_val[i].key_name->equal(purportedname,
+ plen, TRUE)) {
+ if (result) *result = i;
+ READUNLOCK(this, TRUE,
+ "ru db_scheme::find_index");
+ return (TRUE);
+ }
+ }
+ READUNLOCK(this, FALSE, "ru db_scheme::find_index");
+ }
+ return (FALSE);
+}
+
+/* Print out description of table. */
+void
+db_scheme::print()
+{
+ int i;
+
+ READLOCKV(this, "r db_scheme::print");
+ for (i = 0; i < keys.keys_len; i++) {
+ keys.keys_val[i].key_name->print();
+ printf(
+ "\tcolumn=%d, flags=0x%x, key record position=%d, max length=%d\n",
+ keys.keys_val[i].column_number,
+ keys.keys_val[i].key_flags,
+ keys.keys_val[i].where.start_column,
+ keys.keys_val[i].where.max_len);
+ printf("\tdata record position=%d, max length=%d\n",
+ data.where.start_column, data.where.max_len);
+ }
+ printf("\tmaximum number of columns=%d\n", max_columns);
+ READUNLOCKV(this, "ru db_scheme::print");
+}