KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > table > Column


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.table;
6
7 import java.sql.SQLException JavaDoc;
8 import java.sql.Time JavaDoc;
9 import java.sql.Timestamp JavaDoc;
10
11 import org.h2.command.Parser;
12 import org.h2.engine.Constants;
13 import org.h2.engine.Mode;
14 import org.h2.engine.Session;
15 import org.h2.expression.ConditionAndOr;
16 import org.h2.expression.Expression;
17 import org.h2.expression.SequenceValue;
18 import org.h2.expression.ValueExpression;
19 import org.h2.message.Message;
20 import org.h2.result.Row;
21 import org.h2.schema.Schema;
22 import org.h2.schema.Sequence;
23 import org.h2.util.StringUtils;
24 import org.h2.value.DataType;
25 import org.h2.value.Value;
26 import org.h2.value.ValueInt;
27 import org.h2.value.ValueNull;
28 import org.h2.value.ValueString;
29 import org.h2.value.ValueTime;
30 import org.h2.value.ValueTimestamp;
31
32 /**
33  * @author Thomas
34  */

35 public class Column {
36     private Table table;
37     private String JavaDoc name;
38     private int type;
39     private long precision;
40     private int scale;
41     private int columnId;
42     private boolean nullable = true;
43     private Expression defaultExpression;
44     private Expression checkConstraint;
45     private String JavaDoc checkConstraintSQL;
46     private String JavaDoc originalSQL;
47     private boolean autoIncrement;
48     private long start;
49     private long increment;
50     private boolean convertNullToDefault;
51     private Sequence sequence;
52     private boolean isComputed;
53     private TableFilter computeTableFilter;
54     private int selectivity;
55     private SingleColumnResolver resolver;
56     private String JavaDoc comment;
57
58     // must be equal to ResultSetMetaData columnNoNulls, columnNullable, columnNullableUnknown
59
public static final int NOT_NULLABLE = 0, NULLABLE = 1, NULLABLE_UNKNOWN = 2;
60
61     public Column(String JavaDoc name, int type, long precision, int scale) {
62         this.name = name;
63         this.type = type;
64         this.precision = precision;
65         this.scale = scale;
66     }
67     
68     public Column getClone() {
69         Column newColumn = new Column(name, type, precision, scale);
70         // table is not set
71
// columnId is not set
72
newColumn.nullable = nullable;
73         newColumn.defaultExpression = defaultExpression;
74         newColumn.originalSQL = originalSQL;
75         // autoIncrement, start, increment is not set
76
newColumn.convertNullToDefault = convertNullToDefault;
77         newColumn.sequence = sequence;
78         newColumn.comment = comment;
79         return newColumn;
80     }
81
82     public boolean getComputed() {
83         return isComputed;
84     }
85
86     public Value computeValue(Session session, Row row) throws SQLException JavaDoc {
87         computeTableFilter.setSession(session);
88         computeTableFilter.set(row);
89         return defaultExpression.getValue(session);
90     }
91
92     public void setComputed(boolean computed, Expression expression) {
93         this.isComputed = computed;
94         this.defaultExpression = expression;
95     }
96
97     void setTable(Table table, int columnId) {
98         this.table = table;
99         this.columnId = columnId;
100     }
101
102     public Table getTable() {
103         return table;
104     }
105
106     public void setDefaultExpression(Session session, Expression defaultExpression) throws SQLException JavaDoc {
107         // also to test that no column names are used
108
if(defaultExpression != null) {
109             defaultExpression = defaultExpression.optimize(session);
110             if(defaultExpression.isConstant()) {
111                 defaultExpression = ValueExpression.get(defaultExpression.getValue(session));
112             }
113         }
114         this.defaultExpression = defaultExpression;
115     }
116
117     public int getColumnId() {
118         return columnId;
119     }
120
121     public String JavaDoc getSQL() {
122         return Parser.quoteIdentifier(name);
123     }
124
125     public String JavaDoc getName() {
126         return name;
127     }
128
129     public int getType() {
130         return type;
131     }
132
133     public long getPrecision() {
134         return precision;
135     }
136
137     public int getScale() {
138         return scale;
139     }
140
141     public void setNullable(boolean b) {
142         nullable = b;
143     }
144
145     public Value validateConvertUpdateSequence(Session session, Value value) throws SQLException JavaDoc {
146         if(value == null) {
147             if(defaultExpression == null) {
148                 value = ValueNull.INSTANCE;
149             } else {
150                 value = defaultExpression.getValue(session).convertTo(type);
151             }
152         }
153         if (value == ValueNull.INSTANCE) {
154             if(convertNullToDefault) {
155                 value = defaultExpression.getValue(session).convertTo(type);
156             }
157             if (value == ValueNull.INSTANCE && !nullable) {
158                 if(Mode.getCurrentMode().convertInsertNullToZero) {
159                     DataType dt = DataType.getDataType(type);
160                     if(dt.decimal) {
161                         value = ValueInt.get(0).convertTo(type);
162                     } else if(dt.type==Value.TIMESTAMP) {
163                         value = ValueTimestamp.getNoCopy(new Timestamp JavaDoc(System.currentTimeMillis()));
164                     } else if(dt.type==Value.TIME) {
165                         // need to normalize
166
value = ValueTime.get(Time.valueOf("0:0:0"));
167                     } else if(dt.type==Value.DATE) {
168                         value = ValueTimestamp.getNoCopy(new Timestamp JavaDoc(System.currentTimeMillis())).convertTo(dt.type);
169                     } else {
170                         value = ValueString.get("").convertTo(type);
171                     }
172                 } else {
173                     throw Message.getSQLException(Message.NULL_NOT_ALLOWED, name);
174                 }
175             }
176         }
177         if(checkConstraint != null) {
178             resolver.setValue(value);
179             Value v = checkConstraint.getValue(session);
180             // Both TRUE and NULL are ok
181
if(Boolean.FALSE.equals(v.getBoolean())) {
182                 throw Message.getSQLException(Message.CHECK_CONSTRAINT_VIOLATED_1, checkConstraint.getSQL());
183             }
184         }
185         value = value.convertScale(Mode.getCurrentMode().convertOnlyToSmallerScale, scale);
186         if (precision > 0 && value.getPrecision() > precision) {
187             throw Message.getSQLException(Message.VALUE_TOO_LONG_1, name);
188         }
189         updateSequenceIfRequired(session, value);
190         return value;
191     }
192
193     private void updateSequenceIfRequired(Session session, Value value) throws SQLException JavaDoc {
194         if(sequence != null) {
195             long current = sequence.getCurrentValue();
196             long increment = sequence.getIncrement();
197             long now = value.getLong();
198             boolean update = false;
199             if(increment > 0 && now > current) {
200                 update = true;
201             } else if(increment < 0 && now < current) {
202                 update = true;
203             }
204             if(update) {
205                 sequence.setStartValue(now + increment);
206                 session.setLastIdentity(now);
207                 sequence.flush();
208             }
209         }
210     }
211
212     public void convertAutoIncrementToSequence(Session session, Schema schema, int id, boolean temporary) throws SQLException JavaDoc {
213         if(!getAutoIncrement()) {
214             throw Message.getInternalError();
215         }
216         if(originalSQL.equals("IDENTITY")) {
217             originalSQL = "BIGINT";
218         }
219         String JavaDoc sequenceName;
220         for(int i=0; ; i++) {
221             sequenceName = "SYSTEM_SEQUENCE_" + i;
222             if(schema.findSequence(sequenceName) == null) {
223                 break;
224             }
225         }
226         Sequence sequence = new Sequence(schema, id, sequenceName, true);
227         sequence.setStartValue(start);
228         sequence.setIncrement(increment);
229         if(!temporary) {
230             session.getDatabase().addSchemaObject(session, sequence);
231         }
232         setAutoIncrement(false, 0, 0);
233         SequenceValue seq = new SequenceValue(sequence);
234         setDefaultExpression(session, seq);
235         setSequence(sequence);
236     }
237
238     public void prepareExpression(Session session) throws SQLException JavaDoc {
239         if(defaultExpression != null) {
240             computeTableFilter = new TableFilter(session, table, null, false);
241             defaultExpression.mapColumns(computeTableFilter, 0);
242             defaultExpression = defaultExpression.optimize(session);
243         }
244     }
245
246     public String JavaDoc getCreateSQL() {
247         StringBuffer JavaDoc buff = new StringBuffer JavaDoc();
248         if(name != null) {
249             buff.append(Parser.quoteIdentifier(name));
250             buff.append(' ');
251         }
252         if(originalSQL != null) {
253             buff.append(originalSQL);
254         } else {
255             buff.append(DataType.getDataType(type).name);
256             switch (type) {
257             case Value.DECIMAL:
258                 buff.append("(");
259                 buff.append(precision);
260                 buff.append(", ");
261                 buff.append(scale);
262                 buff.append(")");
263                 break;
264             case Value.BYTES:
265             case Value.STRING:
266             case Value.STRING_IGNORECASE:
267                 buff.append("(");
268                 buff.append(precision);
269                 buff.append(")");
270                 break;
271             }
272         }
273         if(defaultExpression != null) {
274             String JavaDoc sql = defaultExpression.getSQL();
275             if(sql != null) {
276                 if(isComputed) {
277                     buff.append(" AS ");
278                     buff.append(sql);
279                 } else if(defaultExpression != null) {
280                     buff.append(" DEFAULT ");
281                     buff.append(sql);
282                 }
283             }
284         }
285         if (!nullable) {
286             buff.append(" NOT NULL");
287         }
288         if (convertNullToDefault) {
289             buff.append(" NULL_TO_DEFAULT");
290         }
291         if(sequence != null) {
292             buff.append(" SEQUENCE ");
293             buff.append(sequence.getSQL());
294         }
295         if(selectivity != 0) {
296             buff.append(" SELECTIVITY ");
297             buff.append(selectivity);
298         }
299         if(checkConstraint != null) {
300             buff.append(" CHECK ");
301             buff.append(checkConstraintSQL);
302         }
303         if(comment != null) {
304             buff.append(" COMMENT ");
305             buff.append(StringUtils.quoteStringSQL(comment));
306         }
307         return buff.toString();
308     }
309
310     public boolean getNullable() {
311         return nullable;
312     }
313
314     public void setOriginalSQL(String JavaDoc original) {
315         originalSQL = original;
316     }
317
318     public String JavaDoc getOriginalSQL() {
319         return originalSQL;
320     }
321
322     public Expression getDefaultExpression() {
323         return defaultExpression;
324     }
325
326     public boolean getAutoIncrement() {
327         return autoIncrement;
328     }
329
330     public void setAutoIncrement(boolean autoInc, long start, long increment) {
331         this.autoIncrement = autoInc;
332         this.start = start;
333         this.increment = increment;
334         this.nullable = false;
335         if(autoInc) {
336             convertNullToDefault = true;
337         }
338     }
339
340     public void setConvertNullToDefault(boolean convert) {
341         this.convertNullToDefault = convert;
342     }
343
344     public void rename(String JavaDoc newName) {
345         this.name = newName;
346     }
347
348     public void setSequence(Sequence sequence) {
349         this.sequence = sequence;
350     }
351
352     public Sequence getSequence() {
353         return sequence;
354     }
355
356     public int getSelectivity() {
357         return selectivity == 0 ? Constants.SELECTIVITY_DEFAULT : selectivity;
358     }
359
360     public void setSelectivity(int selectivity) {
361         selectivity = selectivity < 0 ? 0 : (selectivity > 100 ? 100 : selectivity);
362         this.selectivity = selectivity;
363     }
364
365     public void addCheckConstraint(Session session, Expression expr) throws SQLException JavaDoc {
366         resolver = new SingleColumnResolver(this);
367         synchronized(this) {
368             String JavaDoc oldName = name;
369             if(name == null) {
370                 name = "VALUE";
371             }
372             expr.mapColumns(resolver, 0);
373             name = oldName;
374         }
375         expr = expr.optimize(session);
376         resolver.setValue(ValueNull.INSTANCE);
377         // check if the column is mapped
378
expr.getValue(session);
379         if(checkConstraint == null) {
380             checkConstraint = expr;
381         } else {
382             checkConstraint = new ConditionAndOr(ConditionAndOr.AND, checkConstraint, expr);
383         }
384         checkConstraintSQL = getCheckConstraintSQL(session, name);
385     }
386
387     public Expression getCheckConstraint(Session session, String JavaDoc asColumnName) throws SQLException JavaDoc {
388         if(checkConstraint == null) {
389             return null;
390         }
391         Parser parser = new Parser(session);
392         String JavaDoc sql;
393         synchronized(this) {
394             String JavaDoc oldName = name;
395             name = asColumnName;
396             sql = checkConstraint.getSQL();
397             name = oldName;
398         }
399         Expression expr = parser.parseExpression(sql);
400         return expr;
401     }
402
403     public String JavaDoc getDefaultSQL() {
404         return defaultExpression == null ? "" : defaultExpression.getSQL();
405     }
406
407     public int getPrecisionAsInt() {
408         return precision > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)precision;
409     }
410
411     public DataType getDataType() {
412         return DataType.getDataType(type);
413     }
414
415     public String JavaDoc getCheckConstraintSQL(Session session, String JavaDoc name) throws SQLException JavaDoc {
416         Expression constraint = getCheckConstraint(session, name);
417         return constraint == null ? "" : constraint.getSQL();
418     }
419
420     public void setComment(String JavaDoc comment) {
421         this.comment = comment;
422     }
423
424     public String JavaDoc getComment() {
425         return comment;
426     }
427
428 }
429
Popular Tags