--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.sql.execute.AutoincrementCounter\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.sql.execute;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+import org.apache.derby.iapi.store.access.TransactionController;\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.catalog.UUID;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+\r
+/**\r
+ * AutoincrementCounter is a not so general counter for the specific purposes\r
+ * of autoincrement columns. It can be thought of as an in-memory autoincrement\r
+ * column.\r
+ * The counting or incrementing is done in fashion identical to the\r
+ * AUTOINCREMENTVALUE in SYSCOLUMNS.\r
+ * <p>\r
+ * To create a counter, the user must call the constructor with a start value,\r
+ * increment and optionally a final value. In addition the caller must specify\r
+ * the schema name, table name and column name uniquely identifying the\r
+ * counter. \r
+ * <p>\r
+ * When a counter is created it is in an invalid state-- to initialize it, the\r
+ * user must call either <i>update</i> or <i>reset(false)</i>. The value of a\r
+ * counter can be changed by either calling reset or update. \r
+\r
+ */\r
+public class AutoincrementCounter \r
+{\r
+\r
+ private Long start;\r
+ private long increment;\r
+ private String identity;\r
+ private long finalValue;\r
+ private String schemaName;\r
+ private String tableName;\r
+ private String columnName;\r
+ // maintains state.\r
+ private long counter;\r
+ private int columnPosition;\r
+ private boolean initialized = false;\r
+\r
+ /**\r
+ * constructor \r
+ * @param start The start value of the counter; is a java object as\r
+ * it can also be null.\r
+ * @param increment how much to increment the counter by.\r
+ * @param finalValue the finalvalue of the counter. used by reset\r
+ * @param s\r
+ * @param t\r
+ * @param c\r
+ */\r
+ public AutoincrementCounter(Long start, long increment, long finalValue,\r
+ String s, String t, String c, int position)\r
+ {\r
+ this.increment = increment;\r
+ this.start = start;\r
+ this.initialized = false;\r
+ this.identity = makeIdentity(s,t,c);\r
+ this.finalValue = finalValue;\r
+ this.schemaName = s;\r
+ this.tableName = t;\r
+ this.columnName = c;\r
+ this.columnPosition = position;\r
+ // System.out.println("aic created with " + this);\r
+ }\r
+\r
+ /**\r
+ * make a unique key for the counter.\r
+ */\r
+ public static String makeIdentity(String s, String t, String c)\r
+ {\r
+ return s + "." + t + "." + c;\r
+ }\r
+\r
+ /**\r
+ * make a unique key for the counter.\r
+ */\r
+ public static String makeIdentity(TableDescriptor td, ColumnDescriptor cd)\r
+ {\r
+ return td.getSchemaName() + "." + td.getName() + \r
+ "." + cd.getColumnName();\r
+ }\r
+\r
+ /**\r
+ * reset to the counter to the beginning or the end.\r
+ * \r
+ * @param begin if TRUE reset to beginning and mark it uninitialized.\r
+ */\r
+ public void reset(boolean begin)\r
+ {\r
+ if (begin == true)\r
+ initialized = false;\r
+ else\r
+ {\r
+ counter = finalValue;\r
+ initialized = true;\r
+ }\r
+ // System.out.println("counter reset to " + this);\r
+\r
+ }\r
+\r
+ /**\r
+ * update the counter.\r
+ * \r
+ * @param t update the counter to this value.\r
+ */\r
+ public long update(long t)\r
+ {\r
+ counter = t;\r
+ // System.out.println("counter updated to " + this);\r
+ initialized = true;\r
+ return counter;\r
+ }\r
+\r
+ /**\r
+ * update the counter to its next value.\r
+ * \r
+ * @exception StandardException if the counter has not yet been\r
+ * initialized and the Start value is NULL.\r
+ */\r
+ public long update() throws StandardException\r
+ {\r
+ long counterVal;\r
+\r
+ if (initialized == false)\r
+ {\r
+ // The first time around, counter simply gets the start\r
+ // value. \r
+ initialized = true;\r
+ \r
+ if (start == null)\r
+ {\r
+ throw StandardException.newException(\r
+ SQLState.LANG_AI_COUNTER_ERROR);\r
+ }\r
+ counter = start.longValue(); \r
+ } \r
+ else\r
+ {\r
+ counter = counter + increment;\r
+ }\r
+ // System.out.println("counter updated to " + this);\r
+ return counter;\r
+ }\r
+\r
+ /**\r
+ * get the current value of the counter. An uninitialized counter means the\r
+ * current value is NULL.\r
+ */\r
+ public Long getCurrentValue()\r
+ {\r
+ if (initialized == false)\r
+ return null;\r
+ return new Long(counter);\r
+ }\r
+ \r
+ /**\r
+ * return the identity of the counter.\r
+ */\r
+ public String getIdentity()\r
+ {\r
+ return identity;\r
+ }\r
+\r
+ /**\r
+ * flush a counter to disk; i.e write the current value of the counter into\r
+ * the row in SYSCOLUMNS.\r
+ * \r
+ * @param tc TransactionController to use\r
+ * @param dd DataDictionary to use.\r
+ * @param tableUUID I might have the table name but I need more\r
+ * information \r
+ * @exception StandardException standard Derby exception.\r
+ */\r
+ public void flushToDisk(TransactionController tc, DataDictionary dd,\r
+ UUID tableUUID)\r
+ throws StandardException\r
+ {\r
+ dd.setAutoincrementValue(tc, tableUUID, columnName, counter, true);\r
+ }\r
+\r
+ /**\r
+ * get the column position in the table for which this counter has been\r
+ * created. \r
+ * @return the position of the corresponding column in the table (1-based)\r
+ */\r
+ public int getColumnPosition()\r
+ {\r
+ return columnPosition;\r
+ }\r
+\r
+ /**\r
+ * get the start value\r
+ * @return the initial value of the counter\r
+ */\r
+ public Long getStartValue()\r
+ {\r
+ return start;\r
+ }\r
+\r
+ public String toString()\r
+ {\r
+ return "counter: " + identity + " current: " + counter \r
+ + " start: " + start + \r
+ " increment: " + increment + " final: " + finalValue;\r
+ } \r
+} \r
+\r
+\r