001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.command.dml;
007:
008: import java.sql.SQLException;
009: import java.text.Collator;
010:
011: import org.h2.command.Prepared;
012: import org.h2.compress.Compressor;
013: import org.h2.constant.ErrorCode;
014: import org.h2.constant.SysProperties;
015: import org.h2.engine.Database;
016: import org.h2.engine.DbObject;
017: import org.h2.engine.Mode;
018: import org.h2.engine.Session;
019: import org.h2.engine.Setting;
020: import org.h2.expression.Expression;
021: import org.h2.expression.ValueExpression;
022: import org.h2.message.Message;
023: import org.h2.result.LocalResult;
024: import org.h2.schema.Schema;
025: import org.h2.table.Table;
026: import org.h2.tools.CompressTool;
027: import org.h2.util.ObjectArray;
028: import org.h2.util.StringUtils;
029: import org.h2.value.CompareMode;
030: import org.h2.value.ValueInt;
031:
032: /**
033: * This class represents the statement
034: * SET
035: */
036: public class Set extends Prepared {
037:
038: private int type;
039: private Expression expression;
040: private String stringValue;
041: private String[] stringValueList;
042:
043: public Set(Session session, int type) {
044: super (session);
045: this .type = type;
046: }
047:
048: public void setString(String v) {
049: this .stringValue = v;
050: }
051:
052: public boolean isTransactional() {
053: return false;
054: }
055:
056: public int update() throws SQLException {
057: // Value v = expr.getValue();
058: Database database = session.getDatabase();
059: String name = SetTypes.getTypeName(type);
060: switch (type) {
061: case SetTypes.MAX_LOG_SIZE:
062: session.getUser().checkAdmin();
063: session.getDatabase().setMaxLogSize(
064: (long) getIntValue() * 1024 * 1024);
065: addOrUpdateSetting(name, null, getIntValue());
066: break;
067: case SetTypes.LOCK_TIMEOUT:
068: session.setLockTimeout(getIntValue());
069: break;
070: case SetTypes.LOCK_MODE:
071: session.getUser().checkAdmin();
072: database.setLockMode(getIntValue());
073: addOrUpdateSetting(name, null, getIntValue());
074: break;
075: case SetTypes.DEFAULT_LOCK_TIMEOUT:
076: session.getUser().checkAdmin();
077: addOrUpdateSetting(name, null, getIntValue());
078: break;
079: case SetTypes.DEFAULT_TABLE_TYPE:
080: session.getUser().checkAdmin();
081: addOrUpdateSetting(name, null, getIntValue());
082: break;
083: case SetTypes.TRACE_LEVEL_SYSTEM_OUT:
084: session.getUser().checkAdmin();
085: database.getTraceSystem().setLevelSystemOut(getIntValue());
086: addOrUpdateSetting(name, null, getIntValue());
087: break;
088: case SetTypes.TRACE_LEVEL_FILE:
089: session.getUser().checkAdmin();
090: database.getTraceSystem().setLevelFile(getIntValue());
091: addOrUpdateSetting(name, null, getIntValue());
092: break;
093: case SetTypes.TRACE_MAX_FILE_SIZE: {
094: session.getUser().checkAdmin();
095: int size = getIntValue() * 1024 * 1024;
096: database.getTraceSystem().setMaxFileSize(size);
097: addOrUpdateSetting(name, null, getIntValue());
098: break;
099: }
100: case SetTypes.CACHE_SIZE:
101: session.getUser().checkAdmin();
102: database.setCacheSize(getIntValue());
103: addOrUpdateSetting(name, null, getIntValue());
104: break;
105: case SetTypes.MODE:
106: session.getUser().checkAdmin();
107: Mode mode = Mode.getInstance(stringValue);
108: if (mode == null) {
109: throw Message.getSQLException(ErrorCode.UNKNOWN_MODE_1,
110: stringValue);
111: }
112: database.setMode(mode);
113: break;
114: case SetTypes.COLLATION: {
115: session.getUser().checkAdmin();
116: ObjectArray array = database
117: .getAllSchemaObjects(DbObject.TABLE_OR_VIEW);
118: for (int i = 0; i < array.size(); i++) {
119: Table table = (Table) array.get(i);
120: if (table.getCreateSQL() != null) {
121: throw Message
122: .getSQLException(
123: ErrorCode.COLLATION_CHANGE_WITH_DATA_TABLE_1,
124: table.getSQL());
125: }
126: }
127: CompareMode compareMode;
128: StringBuffer buff = new StringBuffer(stringValue);
129: if (stringValue.equals(CompareMode.OFF)) {
130: compareMode = new CompareMode(null, null, 0);
131: } else {
132: Collator coll = CompareMode.getCollator(stringValue);
133: compareMode = new CompareMode(coll, stringValue,
134: SysProperties.getCollatorCacheSize());
135: buff.append(" STRENGTH ");
136: if (getIntValue() == Collator.IDENTICAL) {
137: buff.append("IDENTICAL");
138: } else if (getIntValue() == Collator.PRIMARY) {
139: buff.append("PRIMARY");
140: } else if (getIntValue() == Collator.SECONDARY) {
141: buff.append("SECONDARY");
142: } else if (getIntValue() == Collator.TERTIARY) {
143: buff.append("TERTIARY");
144: }
145: coll.setStrength(getIntValue());
146: }
147: addOrUpdateSetting(name, buff.toString(), 0);
148: database.setCompareMode(compareMode);
149: break;
150: }
151: case SetTypes.IGNORECASE:
152: session.getUser().checkAdmin();
153: session.getDatabase().setIgnoreCase(getIntValue() == 1);
154: addOrUpdateSetting(name, null, getIntValue());
155: break;
156: case SetTypes.CLUSTER: {
157: session.getUser().checkAdmin();
158: database
159: .setCluster(StringUtils.quoteStringSQL(stringValue));
160: addOrUpdateSetting(name, StringUtils
161: .quoteStringSQL(stringValue), 0);
162: break;
163: }
164: case SetTypes.WRITE_DELAY: {
165: session.getUser().checkAdmin();
166: database.setWriteDelay(getIntValue());
167: addOrUpdateSetting(name, null, getIntValue());
168: break;
169: }
170: case SetTypes.DATABASE_EVENT_LISTENER: {
171: session.getUser().checkAdmin();
172: database.setEventListener(stringValue);
173: break;
174: }
175: case SetTypes.MAX_MEMORY_ROWS: {
176: session.getUser().checkAdmin();
177: database.setMaxMemoryRows(getIntValue());
178: addOrUpdateSetting(name, null, getIntValue());
179: break;
180: }
181: case SetTypes.MULTI_THREADED: {
182: session.getUser().checkAdmin();
183: database.setMultiThreaded(getIntValue() == 1);
184: break;
185: }
186: case SetTypes.DB_CLOSE_DELAY: {
187: session.getUser().checkAdmin();
188: database.setCloseDelay(getIntValue());
189: addOrUpdateSetting(name, null, getIntValue());
190: break;
191: }
192: case SetTypes.LOG: {
193: int value = getIntValue();
194: if (value < 0 || value > 2) {
195: throw Message.getInvalidValueException(""
196: + getIntValue(), "LOG");
197: }
198: if (value == 0) {
199: session.getUser().checkAdmin();
200: }
201: database.setLog(value);
202: break;
203: }
204: case SetTypes.THROTTLE: {
205: if (getIntValue() < 0) {
206: throw Message.getInvalidValueException(""
207: + getIntValue(), "THROTTLE");
208: }
209: session.setThrottle(getIntValue());
210: break;
211: }
212: case SetTypes.MAX_MEMORY_UNDO: {
213: if (getIntValue() < 0) {
214: throw Message.getInvalidValueException(""
215: + getIntValue(), "MAX_MEMORY_UNDO");
216: }
217: session.getUser().checkAdmin();
218: database.setMaxMemoryUndo(getIntValue());
219: addOrUpdateSetting(name, null, getIntValue());
220: break;
221: }
222: case SetTypes.MAX_LENGTH_INPLACE_LOB: {
223: if (getIntValue() < 0) {
224: throw Message.getInvalidValueException(""
225: + getIntValue(), "MAX_LENGTH_INPLACE_LOB");
226: }
227: session.getUser().checkAdmin();
228: database.setMaxLengthInplaceLob(getIntValue());
229: addOrUpdateSetting(name, null, getIntValue());
230: break;
231: }
232: case SetTypes.COMPRESS_LOB: {
233: session.getUser().checkAdmin();
234: int algo = CompressTool.getInstance().getCompressAlgorithm(
235: stringValue);
236: database
237: .setLobCompressionAlgorithm(algo == Compressor.NO ? null
238: : stringValue);
239: addOrUpdateSetting(name, stringValue, 0);
240: break;
241: }
242: case SetTypes.ALLOW_LITERALS: {
243: session.getUser().checkAdmin();
244: int value = getIntValue();
245: if (value < 0 || value > 2) {
246: throw Message.getInvalidValueException(""
247: + getIntValue(), "ALLOW_LITERALS");
248: }
249: database.setAllowLiterals(value);
250: addOrUpdateSetting(name, null, value);
251: break;
252: }
253: case SetTypes.SCHEMA: {
254: Schema schema = database.getSchema(stringValue);
255: session.setCurrentSchema(schema);
256: break;
257: }
258: case SetTypes.OPTIMIZE_REUSE_RESULTS: {
259: session.getUser().checkAdmin();
260: database.setOptimizeReuseResults(getIntValue() != 0);
261: break;
262: }
263: case SetTypes.SCHEMA_SEARCH_PATH: {
264: session.setSchemaSearchPath(stringValueList);
265: break;
266: }
267: case SetTypes.UNDO_LOG: {
268: int value = getIntValue();
269: if (value < 0 || value > 1) {
270: throw Message.getInvalidValueException(""
271: + getIntValue(), "UNDO_LOG");
272: }
273: session.setUndoLogEnabled(value == 1);
274: break;
275: }
276: case SetTypes.REFERENTIAL_INTEGRITY: {
277: session.getUser().checkAdmin();
278: int value = getIntValue();
279: if (value < 0 || value > 1) {
280: throw Message.getInvalidValueException(""
281: + getIntValue(), "REFERENTIAL_INTEGRITY");
282: }
283: database.setReferentialIntegrity(value == 1);
284: break;
285: }
286: case SetTypes.MVCC: {
287: if (database.isMultiVersion() != (getIntValue() == 1)) {
288: throw Message.getSQLException(
289: ErrorCode.CANNOT_CHANGE_SETTING_WHEN_OPEN_1,
290: "MVCC");
291: }
292: break;
293: }
294: case SetTypes.MAX_OPERATION_MEMORY: {
295: session.getUser().checkAdmin();
296: int value = getIntValue();
297: database.setMaxOperationMemory(value);
298: break;
299: }
300: case SetTypes.EXCLUSIVE: {
301: session.getUser().checkAdmin();
302: int value = getIntValue();
303: database.setExclusiveSession(value == 1 ? session : null);
304: break;
305: }
306: case SetTypes.CREATE_BUILD: {
307: session.getUser().checkAdmin();
308: if (database.isStarting()) {
309: // just ignore the command if not starting
310: // this avoids problems when running recovery scripts
311: int value = getIntValue();
312: addOrUpdateSetting(name, null, value);
313: }
314: break;
315: }
316: case SetTypes.VARIABLE: {
317: Expression expr = expression.optimize(session);
318: session.setVariable(stringValue, expr.getValue(session));
319: break;
320: }
321: case SetTypes.QUERY_TIMEOUT: {
322: int value = getIntValue();
323: session.setQueryTimeout(value);
324: break;
325: }
326: default:
327: throw Message.getInternalError("type=" + type);
328: }
329: // the meta data information has changed
330: database.getNextModificationDataId();
331: return 0;
332: }
333:
334: private int getIntValue() throws SQLException {
335: expression = expression.optimize(session);
336: return expression.getValue(session).getInt();
337: }
338:
339: public void setInt(int value) {
340: this .expression = ValueExpression.get(ValueInt.get(value));
341: }
342:
343: public void setExpression(Expression expression) {
344: this .expression = expression;
345: }
346:
347: private void addOrUpdateSetting(String name, String s, int v)
348: throws SQLException {
349: Database database = session.getDatabase();
350: if (database.getReadOnly()) {
351: return;
352: }
353: Setting setting = database.findSetting(name);
354: boolean addNew = false;
355: if (setting == null) {
356: addNew = true;
357: int id = getObjectId(false, true);
358: setting = new Setting(database, id, name);
359: }
360: if (s != null) {
361: if (!addNew && setting.getStringValue().equals(s)) {
362: return;
363: }
364: setting.setStringValue(s);
365: } else {
366: if (!addNew && setting.getIntValue() == v) {
367: return;
368: }
369: setting.setIntValue(v);
370: }
371: if (addNew) {
372: database.addDatabaseObject(session, setting);
373: } else {
374: database.update(session, setting);
375: }
376: }
377:
378: public boolean needRecompile() {
379: return false;
380: }
381:
382: public LocalResult queryMeta() {
383: return null;
384: }
385:
386: public void setStringArray(String[] list) {
387: this.stringValueList = list;
388: }
389:
390: }
|