001: /*
002: * (c) Copyright 2007 by Volker Bergmann. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, is permitted under the terms of the
006: * GNU General Public License.
007: *
008: * For redistributing this software or a derivative work under a license other
009: * than the GPL-compatible Free Software License as defined by the Free
010: * Software Foundation or approved by OSI, you must first obtain a commercial
011: * license to this software product from Volker Bergmann.
012: *
013: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
014: * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
015: * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
016: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
017: * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
018: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
019: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
020: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
021: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
022: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
023: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
024: * POSSIBILITY OF SUCH DAMAGE.
025: */
026:
027: package org.databene.platform.db;
028:
029: import java.sql.Connection;
030: import java.sql.PreparedStatement;
031: import java.sql.SQLException;
032:
033: import org.apache.commons.logging.Log;
034: import org.apache.commons.logging.LogFactory;
035: import org.databene.commons.ConfigurationError;
036: import org.databene.id.IdProvider;
037:
038: /**
039: * Creates Unique keys efficiently by connecting a database, retrieving a (unique) sequence value
040: * and building sub keys of it.
041: * @since 0.4.0
042: * @author Volker Bergmann
043: */
044: public class SeqHiLoIdProvider implements IdProvider<Long> {
045:
046: protected static final int DEFAULT_MAX_LO = 100;
047:
048: private PreparedStatement statement;
049:
050: private String selector;
051: private long maxLo;
052:
053: private int lo;
054: private long hi;
055:
056: // constructors -----------------------------------------------------------------------------------
057:
058: public SeqHiLoIdProvider(Connection connection, String selector) {
059: this (connection, selector, DEFAULT_MAX_LO);
060: }
061:
062: public SeqHiLoIdProvider(Connection connection, String selector,
063: long maxLo) {
064: if (logger.isDebugEnabled())
065: logger.debug("Instantiating " + getClass().getSimpleName()
066: + '[' + selector + ']');
067: try {
068: this .selector = selector;
069: this .maxLo = maxLo;
070: this .statement = connection.prepareStatement(selector);
071: this .hi = -1;
072: this .lo = -1;
073: } catch (SQLException e) {
074: throw new ConfigurationError("Statement creation failed: "
075: + selector, e);
076: }
077: }
078:
079: // IdProvider interface --------------------------------------------------------------------------------------------
080:
081: public Class<Long> getType() {
082: return Long.class;
083: }
084:
085: public boolean hasNext() {
086: return (statement != null);
087: }
088:
089: public Long next() {
090: if (hi == -1 || lo >= maxLo) {
091: hi = nextHi();
092: lo = 0;
093: } else
094: lo++;
095: return hi * (maxLo + 1) + lo;
096: }
097:
098: public void remove() {
099: throw new UnsupportedOperationException(
100: "Removal is not supported.");
101: }
102:
103: public void close() {
104: DBUtil.close(statement);
105: this .statement = null;
106: }
107:
108: // java.lang.Object overrides --------------------------------------------------------------------------------------
109:
110: @Override
111: public String toString() {
112: return getClass().getSimpleName() + '[' + selector + ','
113: + maxLo + ']';
114: }
115:
116: // implementation --------------------------------------------------------------------------------------------------
117:
118: private long nextHi() {
119: if (sqlLogger.isDebugEnabled())
120: sqlLogger.debug(selector);
121: return Long.parseLong(DBUtil.queryWithOneCellResult(statement));
122: }
123:
124: private static final Log logger = LogFactory
125: .getLog(SeqHiLoIdProvider.class);
126: private static final Log sqlLogger = LogFactory
127: .getLog("org.databene.benerator.SQL");
128: }
|