001: /**
002: * com.mckoi.database.interpret.Sequence 07 Apr 2003
003: *
004: * Mckoi SQL Database ( http://www.mckoi.com/database )
005: * Copyright (C) 2000, 2001, 2002 Diehl and Associates, Inc.
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * Version 2 as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License Version 2 for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * Version 2 along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: * Change Log:
021: *
022: *
023: */package com.mckoi.database.interpret;
024:
025: import com.mckoi.database.*;
026: import com.mckoi.debug.*;
027:
028: /**
029: * A statement tree for creating and dropping sequence generators.
030: *
031: * @author Tobias Downer
032: */
033:
034: public class Sequence extends Statement {
035:
036: String type;
037:
038: TableName seq_name;
039:
040: Expression increment;
041: Expression min_value;
042: Expression max_value;
043: Expression start_value;
044: Expression cache_value;
045: boolean cycle;
046:
047: // ----------- Implemented from Statement ----------
048:
049: public void prepare() throws DatabaseException {
050: type = (String) cmd.getObject("type");
051: String sname = (String) cmd.getObject("seq_name");
052: String schema_name = database.getCurrentSchema();
053: seq_name = TableName.resolve(schema_name, sname);
054: seq_name = database.tryResolveCase(seq_name);
055:
056: if (type.equals("create")) {
057: // Resolve the function name into a TableName object.
058: increment = (Expression) cmd.getObject("increment");
059: min_value = (Expression) cmd.getObject("min_value");
060: max_value = (Expression) cmd.getObject("max_value");
061: start_value = (Expression) cmd.getObject("start");
062: cache_value = (Expression) cmd.getObject("cache");
063: cycle = cmd.getObject("cycle") != null;
064: }
065:
066: }
067:
068: public Table evaluate() throws DatabaseException {
069:
070: DatabaseQueryContext context = new DatabaseQueryContext(
071: database);
072:
073: // Does the schema exist?
074: boolean ignore_case = database.isInCaseInsensitiveMode();
075: SchemaDef schema = database.resolveSchemaCase(seq_name
076: .getSchema(), ignore_case);
077: if (schema == null) {
078: throw new DatabaseException("Schema '"
079: + seq_name.getSchema() + "' doesn't exist.");
080: } else {
081: seq_name = new TableName(schema.getName(), seq_name
082: .getName());
083: }
084:
085: if (type.equals("create")) {
086:
087: // Does the user have privs to create this sequence generator?
088: if (!database.getDatabase().canUserCreateSequenceObject(
089: context, user, seq_name)) {
090: throw new UserAccessException(
091: "User not permitted to create sequence: "
092: + seq_name);
093: }
094:
095: // Does a table already exist with this name?
096: if (database.tableExists(seq_name)) {
097: throw new DatabaseException(
098: "Database object with name '" + seq_name
099: + "' already exists.");
100: }
101:
102: // Resolve the expressions,
103: long v_start_value = 0;
104: if (start_value != null) {
105: v_start_value = start_value.evaluate(null, null,
106: context).toBigNumber().longValue();
107: }
108: long v_increment_by = 1;
109: if (increment != null) {
110: v_increment_by = increment
111: .evaluate(null, null, context).toBigNumber()
112: .longValue();
113: }
114: long v_min_value = 0;
115: if (min_value != null) {
116: v_min_value = min_value.evaluate(null, null, context)
117: .toBigNumber().longValue();
118: }
119: long v_max_value = Long.MAX_VALUE;
120: if (max_value != null) {
121: v_max_value = max_value.evaluate(null, null, context)
122: .toBigNumber().longValue();
123: }
124: long v_cache = 16;
125: if (cache_value != null) {
126: v_cache = cache_value.evaluate(null, null, context)
127: .toBigNumber().longValue();
128: if (v_cache <= 0) {
129: throw new DatabaseException(
130: "Cache size can not be <= 0");
131: }
132: }
133:
134: if (v_min_value >= v_max_value) {
135: throw new DatabaseException(
136: "Min value can not be >= the max value.");
137: }
138: if (v_start_value < v_min_value
139: || v_start_value >= v_max_value) {
140: throw new DatabaseException(
141: "Start value is outside the min/max sequence bounds.");
142: }
143:
144: database.createSequenceGenerator(seq_name, v_start_value,
145: v_increment_by, v_min_value, v_max_value, v_cache,
146: cycle);
147:
148: // The initial grants for a sequence is to give the user who created it
149: // full access.
150: database.getGrantManager().addGrant(
151: Privileges.PROCEDURE_ALL_PRIVS, GrantManager.TABLE,
152: seq_name.toString(), user.getUserName(), true,
153: Database.INTERNAL_SECURE_USERNAME);
154:
155: } else if (type.equals("drop")) {
156:
157: // Does the user have privs to create this sequence generator?
158: if (!database.getDatabase().canUserDropSequenceObject(
159: context, user, seq_name)) {
160: throw new UserAccessException(
161: "User not permitted to drop sequence: "
162: + seq_name);
163: }
164:
165: database.dropSequenceGenerator(seq_name);
166:
167: // Drop the grants for this object
168: database.getGrantManager().revokeAllGrantsOnObject(
169: GrantManager.TABLE, seq_name.toString());
170:
171: } else {
172: throw new RuntimeException("Unknown type: " + type);
173: }
174:
175: // Return an update result table.
176: return FunctionTable.resultTable(context, 0);
177:
178: }
179:
180: }
|