001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.execute.AutoincrementCounter
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.execute;
023:
024: import org.apache.derby.iapi.services.sanity.SanityManager;
025: import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
026: import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
027: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
028: import org.apache.derby.iapi.store.access.TransactionController;
029: import org.apache.derby.iapi.error.StandardException;
030: import org.apache.derby.catalog.UUID;
031: import org.apache.derby.iapi.reference.SQLState;
032:
033: /**
034: * AutoincrementCounter is a not so general counter for the specific purposes
035: * of autoincrement columns. It can be thought of as an in-memory autoincrement
036: * column.
037: * The counting or incrementing is done in fashion identical to the
038: * AUTOINCREMENTVALUE in SYSCOLUMNS.
039: * <p>
040: * To create a counter, the user must call the constructor with a start value,
041: * increment and optionally a final value. In addition the caller must specify
042: * the schema name, table name and column name uniquely identifying the
043: * counter.
044: * <p>
045: * When a counter is created it is in an invalid state-- to initialize it, the
046: * user must call either <i>update</i> or <i>reset(false)</i>. The value of a
047: * counter can be changed by either calling reset or update.
048:
049: * @author manish
050: */
051: public class AutoincrementCounter {
052:
053: private Long start;
054: private long increment;
055: private String identity;
056: private long finalValue;
057: private String schemaName;
058: private String tableName;
059: private String columnName;
060: // maintains state.
061: private long counter;
062: private int columnPosition;
063: private boolean initialized = false;
064:
065: /**
066: * constructor
067: * @param start The start value of the counter; is a java object as
068: * it can also be null.
069: * @param increment how much to increment the counter by.
070: * @param finalValue the finalvalue of the counter. used by reset
071: * @param s
072: * @param t
073: * @param c
074: */
075: public AutoincrementCounter(Long start, long increment,
076: long finalValue, String s, String t, String c, int position) {
077: this .increment = increment;
078: this .start = start;
079: this .initialized = false;
080: this .identity = makeIdentity(s, t, c);
081: this .finalValue = finalValue;
082: this .schemaName = s;
083: this .tableName = t;
084: this .columnName = c;
085: this .columnPosition = position;
086: // System.out.println("aic created with " + this);
087: }
088:
089: /**
090: * make a unique key for the counter.
091: */
092: public static String makeIdentity(String s, String t, String c) {
093: return s + "." + t + "." + c;
094: }
095:
096: /**
097: * make a unique key for the counter.
098: */
099: public static String makeIdentity(TableDescriptor td,
100: ColumnDescriptor cd) {
101: return td.getSchemaName() + "." + td.getName() + "."
102: + cd.getColumnName();
103: }
104:
105: /**
106: * reset to the counter to the beginning or the end.
107: *
108: * @param begin if TRUE reset to beginning and mark it uninitialized.
109: */
110: public void reset(boolean begin) {
111: if (begin == true)
112: initialized = false;
113: else {
114: counter = finalValue;
115: initialized = true;
116: }
117: // System.out.println("counter reset to " + this);
118:
119: }
120:
121: /**
122: * update the counter.
123: *
124: * @param t update the counter to this value.
125: */
126: public long update(long t) {
127: counter = t;
128: // System.out.println("counter updated to " + this);
129: initialized = true;
130: return counter;
131: }
132:
133: /**
134: * update the counter to its next value.
135: *
136: * @exception StandardException if the counter has not yet been
137: * initialized and the Start value is NULL.
138: */
139: public long update() throws StandardException {
140: long counterVal;
141:
142: if (initialized == false) {
143: // The first time around, counter simply gets the start
144: // value.
145: initialized = true;
146:
147: if (start == null) {
148: throw StandardException
149: .newException(SQLState.LANG_AI_COUNTER_ERROR);
150: }
151: counter = start.longValue();
152: } else {
153: counter = counter + increment;
154: }
155: // System.out.println("counter updated to " + this);
156: return counter;
157: }
158:
159: /**
160: * get the current value of the counter. An uninitialized counter means the
161: * current value is NULL.
162: */
163: public Long getCurrentValue() {
164: if (initialized == false)
165: return null;
166: return new Long(counter);
167: }
168:
169: /**
170: * return the identity of the counter.
171: */
172: public String getIdentity() {
173: return identity;
174: }
175:
176: /**
177: * flush a counter to disk; i.e write the current value of the counter into
178: * the row in SYSCOLUMNS.
179: *
180: * @param tc TransactionController to use
181: * @param dd DataDictionary to use.
182: * @param tableUUID I might have the table name but I need more
183: * information
184: * @exception StandardException standard cloudscape exception.
185: */
186: public void flushToDisk(TransactionController tc,
187: DataDictionary dd, UUID tableUUID) throws StandardException {
188: dd.setAutoincrementValue(tc, tableUUID, columnName, counter,
189: true);
190: }
191:
192: /**
193: * get the column position in the table for which this counter has been
194: * created.
195: * @return the position of the corresponding column in the table (1-based)
196: */
197: public int getColumnPosition() {
198: return columnPosition;
199: }
200:
201: /**
202: * get the start value
203: * @return the initial value of the counter
204: */
205: public Long getStartValue() {
206: return start;
207: }
208:
209: public String toString() {
210: return "counter: " + identity + " current: " + counter
211: + " start: " + start + " increment: " + increment
212: + " final: " + finalValue;
213: }
214: }
|