001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.db.table;
031:
032: import com.caucho.db.index.BTree;
033: import com.caucho.db.index.KeyCompare;
034: import com.caucho.db.sql.Expr;
035: import com.caucho.db.sql.QueryContext;
036: import com.caucho.db.sql.SelectResult;
037: import com.caucho.db.store.Transaction;
038: import com.caucho.log.Log;
039:
040: import java.sql.SQLException;
041: import java.util.logging.Logger;
042:
043: abstract public class Column {
044: protected final static Logger log = Logger.getLogger(Column.class
045: .getName());
046:
047: public final static int NONE = 0;
048: public final static int VARCHAR = 1;
049: public final static int INT = 2;
050: public final static int LONG = 3;
051: public final static int DOUBLE = 4;
052: public final static int DATE = 5;
053: public final static int BLOB = 6;
054: public final static int NUMERIC = 7;
055: public final static int VARBINARY = 8;
056:
057: private final Row _row;
058: private final String _name;
059:
060: protected final int _columnOffset;
061: protected final int _nullOffset;
062: protected final byte _nullMask;
063:
064: private Table _table;
065:
066: private boolean _isPrimaryKey;
067: private boolean _isUnique;
068: private boolean _isNotNull;
069: private int _autoIncrementMin = -1;
070: private Expr _defaultExpr;
071:
072: private BTree _index;
073:
074: Column(Row row, String name) {
075: _row = row;
076: _name = name;
077:
078: _columnOffset = _row.getLength();
079: _nullOffset = _row.getNullOffset();
080: _nullMask = _row.getNullMask();
081: }
082:
083: /**
084: * Returns the column's name.
085: */
086: public String getName() {
087: return _name;
088: }
089:
090: /**
091: * Sets the table.
092: */
093: void setTable(Table table) {
094: _table = table;
095: }
096:
097: /**
098: * Gets the table.
099: */
100: public Table getTable() {
101: return _table;
102: }
103:
104: /**
105: * Returns the column offset.
106: */
107: int getColumnOffset() {
108: return _columnOffset;
109: }
110:
111: /**
112: * Returns the column's code.
113: */
114: abstract public int getTypeCode();
115:
116: /**
117: * Returns the java type.
118: */
119: public Class getJavaType() {
120: return Object.class;
121: }
122:
123: /**
124: * Returns true if the column is a primary key
125: */
126: public boolean isPrimaryKey() {
127: return _isPrimaryKey;
128: }
129:
130: /**
131: * Returns true if the column is a primary key
132: */
133: public void setPrimaryKey(boolean primaryKey) {
134: _isPrimaryKey = primaryKey;
135: }
136:
137: /**
138: * Returns true if the column is unique.
139: */
140: public boolean isUnique() {
141: return _isUnique;
142: }
143:
144: /**
145: * Set if the column is unique.
146: */
147: public void setUnique() {
148: _isUnique = true;
149: }
150:
151: /**
152: * Returns the index.
153: */
154: public BTree getIndex() {
155: return _index;
156: }
157:
158: /**
159: * Sets the index.
160: */
161: public void setIndex(BTree index) {
162: _index = index;
163: }
164:
165: /**
166: * Returns the key compare for the column.
167: */
168: public KeyCompare getIndexKeyCompare() {
169: return null;
170: }
171:
172: /**
173: * Set true if the column is NOT NULL.
174: */
175: public void setNotNull() {
176: _isNotNull = true;
177: }
178:
179: /**
180: * Returns true if the column is NOT NULL.
181: */
182: public boolean isNotNull() {
183: return _isNotNull;
184: }
185:
186: /**
187: * Sets the default expression
188: */
189: public void setDefault(Expr expr) {
190: _defaultExpr = expr;
191: }
192:
193: /**
194: * Gets the default expression
195: */
196: public Expr getDefault() {
197: return _defaultExpr;
198: }
199:
200: /**
201: * Returns true if the column is auto increment
202: */
203: public void setAutoIncrement(int min) {
204: _autoIncrementMin = min;
205: }
206:
207: /**
208: * Set if the column is unique.
209: */
210: public int getAutoIncrement() {
211: return _autoIncrementMin;
212: }
213:
214: /**
215: * Returns the column's size (from the decl).
216: */
217: abstract public int getDeclarationSize();
218:
219: abstract int getLength();
220:
221: /**
222: * Returns true if the column is null.
223: *
224: * @param block the block's buffer
225: * @param rowOffset the offset of the row in the block
226: */
227: public final boolean isNull(byte[] block, int rowOffset) {
228: return (block[rowOffset + _nullOffset] & _nullMask) == 0;
229: }
230:
231: /**
232: * Sets the column null.
233: *
234: * @param block the block's buffer
235: * @param rowOffset the offset of the row in the block
236: */
237: public final void setNull(byte[] block, int rowOffset) {
238: block[rowOffset + _nullOffset] &= ~_nullMask;
239: }
240:
241: /**
242: * Sets the column non-null.
243: *
244: * @param block the block's buffer
245: * @param rowOffset the offset of the row in the block
246: */
247: protected final void setNonNull(byte[] block, int rowOffset) {
248: block[rowOffset + _nullOffset] |= _nullMask;
249: }
250:
251: /**
252: * Gets a string value from the column.
253: *
254: * @param block the block's buffer
255: * @param rowOffset the offset of the row in the block
256: */
257: public abstract String getString(byte[] block, int rowOffset)
258: throws SQLException;
259:
260: /**
261: * Sets a string value in the column.
262: *
263: * @param block the block's buffer
264: * @param rowOffset the offset of the row in the block
265: * @param value the value to store
266: */
267: abstract void setString(Transaction xa, byte[] block,
268: int rowOffset, String value) throws SQLException;
269:
270: /**
271: * Sets an integer value in the column.
272: *
273: * @param block the block's buffer
274: * @param rowOffset the offset of the row in the block
275: * @param value the value to store
276: */
277: public int getInteger(byte[] block, int rowOffset)
278: throws SQLException {
279: String str = getString(block, rowOffset);
280:
281: if (str == null)
282: return 0;
283:
284: return Integer.parseInt(str);
285: }
286:
287: /**
288: * Sets an integer value in the column.
289: *
290: * @param block the block's buffer
291: * @param rowOffset the offset of the row in the block
292: * @param value the value to store
293: */
294: void setInteger(Transaction xa, byte[] block, int rowOffset,
295: int value) throws SQLException {
296: setString(xa, block, rowOffset, String.valueOf(value));
297: }
298:
299: /**
300: * Sets a long value in the column.
301: *
302: * @param block the block's buffer
303: * @param rowOffset the offset of the row in the block
304: * @param value the value to store
305: */
306: public long getLong(byte[] block, int rowOffset)
307: throws SQLException {
308: String str = getString(block, rowOffset);
309:
310: if (str == null)
311: return 0;
312:
313: return Long.parseLong(str);
314: }
315:
316: /**
317: * Sets a long value in the column.
318: *
319: * @param block the block's buffer
320: * @param rowOffset the offset of the row in the block
321: * @param value the value to store
322: */
323: void setLong(Transaction xa, byte[] block, int rowOffset, long value)
324: throws SQLException {
325: setString(xa, block, rowOffset, String.valueOf(value));
326: }
327:
328: /**
329: * Sets a double value in the column.
330: *
331: * @param block the block's buffer
332: * @param rowOffset the offset of the row in the block
333: * @param value the value to store
334: */
335: public double getDouble(byte[] block, int rowOffset)
336: throws SQLException {
337: String str = getString(block, rowOffset);
338:
339: if (str == null)
340: return 0;
341:
342: return Double.parseDouble(str);
343: }
344:
345: /**
346: * Sets a double value in the column.
347: *
348: * @param block the block's buffer
349: * @param rowOffset the offset of the row in the block
350: * @param value the value to store
351: */
352: void setDouble(Transaction xa, byte[] block, int rowOffset,
353: double value) throws SQLException {
354: setString(xa, block, rowOffset, String.valueOf(value));
355: }
356:
357: /**
358: * Sets the column based on an expression.
359: *
360: * @param block the block's buffer
361: * @param rowOffset the offset of the row in the block
362: * @param expr the expression to store
363: */
364: void setExpr(Transaction xa, byte[] block, int rowOffset,
365: Expr expr, QueryContext context) throws SQLException {
366: if (expr.isNull(context))
367: setNull(block, rowOffset);
368: else
369: setString(xa, block, rowOffset, expr.evalString(context));
370: }
371:
372: /**
373: * Gets a double value in the column.
374: *
375: * @param block the block's buffer
376: * @param rowOffset the offset of the row in the block
377: */
378: public long getDate(byte[] block, int rowOffset)
379: throws SQLException {
380: throw new UnsupportedOperationException();
381: }
382:
383: /**
384: * Sets a date value in the column.
385: *
386: * @param block the block's buffer
387: * @param rowOffset the offset of the row in the block
388: * @param value the value to store
389: */
390: void setDate(Transaction xa, byte[] block, int rowOffset,
391: double value) throws SQLException {
392: throw new UnsupportedOperationException();
393: }
394:
395: /**
396: * Evaluate to a buffer.
397: *
398: * @param block the block's buffer
399: * @param rowOffset the offset of the row in the block
400: * @param buffer the result buffer
401: * @param buffer the result buffer offset
402: *
403: * @return the length of the value
404: */
405: int evalToBuffer(byte[] block, int rowOffset, byte[] buffer,
406: int bufferOffset) throws SQLException {
407: throw new UnsupportedOperationException(getClass().getName());
408: }
409:
410: /**
411: * Returns true if the bytes are equal.
412: */
413: public boolean isEqual(byte[] block, int rowOffset, byte[] buffer,
414: int offset, int length) {
415: return false;
416: }
417:
418: /**
419: * Returns true if the bytes are equal.
420: */
421: public boolean isEqual(byte[] buffer1, int rowOffset1,
422: byte[] buffer2, int rowOffset2) {
423: throw new UnsupportedOperationException();
424: }
425:
426: /**
427: * Returns true if the string is equal.
428: */
429: public boolean isEqual(byte[] block, int rowOffset, String string) {
430: return false;
431: }
432:
433: /**
434: * Evaluates the column to the result.
435: */
436: public void evalToResult(byte[] block, int rowOffset,
437: SelectResult result) throws SQLException {
438: throw new UnsupportedOperationException(getClass().getName());
439: }
440:
441: /**
442: * Sets based on an iterator.
443: */
444: public void set(Transaction xa, TableIterator iter, Expr expr,
445: QueryContext context) throws SQLException {
446: setString(xa, iter.getBuffer(), iter.getRowOffset(), expr
447: .evalString(context));
448:
449: iter.setDirty();
450: }
451:
452: /**
453: * Sets any index for the column.
454: *
455: * @param block the block's buffer
456: * @param rowOffset the offset of the row in the block
457: * @param rowAddr the address of the row
458: */
459: void setIndex(Transaction xa, byte[] block, int rowOffset,
460: long rowAddr, QueryContext context) throws SQLException {
461: }
462:
463: /**
464: * Deleting the row, based on the column.
465: *
466: * @param block the block's buffer
467: * @param rowOffset the offset of the row in the block
468: * @param expr the expression to store
469: */
470: void delete(Transaction xa, byte[] block, int rowOffset)
471: throws SQLException {
472: }
473:
474: /**
475: * Cleanup of the column on table shutdown.
476: */
477: public void close() {
478: BTree index = _index;
479:
480: if (index != null)
481: index.close();
482: }
483:
484: public String toString() {
485: if (getIndex() != null)
486: return getClass().getName() + "[" + _name + ",index]";
487: else
488: return getClass().getName() + "[" + _name + "]";
489: }
490: }
|