001: /*
002: * Copyright 2004 (C) TJDO.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the TJDO License version 1.0.
006: * See the terms of the TJDO License in the documentation provided with this software.
007: *
008: * $Id: NormalMapStore.java,v 1.6 2004/01/25 20:44:33 jackknifebarber Exp $
009: */
010:
011: package com.triactive.jdo.store;
012:
013: import com.triactive.jdo.PersistenceManager;
014: import com.triactive.jdo.StateManager;
015: import java.sql.Connection;
016: import java.sql.PreparedStatement;
017: import java.sql.SQLException;
018: import java.util.NoSuchElementException;
019: import javax.jdo.JDODataStoreException;
020: import org.apache.log4j.Category;
021:
022: class NormalMapStore extends AbstractMapStore {
023: private static final Category LOG = Category
024: .getInstance(AbstractMapStore.class);
025:
026: private final MapTable mapTable;
027: private final String putNewStmt;
028: private final String putUpdStmt;
029: private final String removeStmt;
030: private final String removeEntryStmt;
031:
032: public NormalMapStore(MapTable mapTable) {
033: this .mapTable = mapTable;
034:
035: storeMgr = mapTable.getStoreManager();
036: dba = storeMgr.getDatabaseAdapter();
037:
038: ownerMapping = mapTable.getOwnerMapping();
039: keyMapping = mapTable.getKeyMapping();
040: valueMapping = mapTable.getValueMapping();
041:
042: ownerColumn = ownerMapping.getColumn();
043: keyColumn = keyMapping.getColumn();
044: valueColumn = valueMapping.getColumn();
045:
046: keyType = keyColumn.getType();
047: valueType = valueColumn.getType();
048:
049: keysAreEmbedded = !(keyMapping instanceof OIDMapping);
050: valuesAreEmbedded = !(valueMapping instanceof OIDMapping);
051:
052: loadStmt = "SELECT " + keyColumn.getName() + ','
053: + valueColumn.getName() + " FROM " + mapTable.getName()
054: + " WHERE " + ownerColumn.getName() + " = ?";
055: getStmt = "SELECT " + valueColumn.getName() + " FROM "
056: + mapTable.getName() + " WHERE "
057: + ownerColumn.getName() + " = ? AND "
058: + keyColumn.getName() + " = ?";
059: sizeStmt = "SELECT COUNT(*)" + " FROM " + mapTable.getName()
060: + " WHERE " + ownerColumn.getName() + " = ?";
061: containsValueStmt = "SELECT " + ownerColumn.getName()
062: + " FROM " + mapTable.getName() + " WHERE "
063: + ownerColumn.getName() + " = ? AND "
064: + valueColumn.getName() + " = ?";
065: containsEntryStmt = "SELECT " + ownerColumn.getName()
066: + " FROM " + mapTable.getName() + " WHERE "
067: + ownerColumn.getName() + " = ? AND "
068: + keyColumn.getName() + " = ? AND "
069: + valueColumn.getName() + " = ?";
070: putNewStmt = "INSERT INTO " + mapTable.getName() + " ("
071: + valueColumn.getName() + "," + ownerColumn.getName()
072: + "," + keyColumn.getName() + ")" + " VALUES (?,?,?)";
073: putUpdStmt = "UPDATE " + mapTable.getName() + " SET "
074: + valueColumn.getName() + " = ?" + " WHERE "
075: + ownerColumn.getName() + " = ? AND "
076: + keyColumn.getName() + " = ?";
077: removeStmt = "DELETE FROM " + mapTable.getName() + " WHERE "
078: + ownerColumn.getName() + " = ? AND "
079: + keyColumn.getName() + " = ?";
080: removeEntryStmt = "DELETE FROM " + mapTable.getName()
081: + " WHERE " + ownerColumn.getName() + " = ? AND "
082: + keyColumn.getName() + " = ? AND "
083: + valueColumn.getName() + " = ?";
084: clearStmt = "DELETE FROM " + mapTable.getName() + " WHERE "
085: + ownerColumn.getName() + " = ?";
086: }
087:
088: public boolean allowsNullValues() {
089: return valueColumn.isNullable();
090: }
091:
092: public Object put(StateManager sm, Object key, Object value) {
093: validateKeyForWriting(sm, key);
094: validateValueForWriting(sm, value);
095:
096: PersistenceManager pm = sm.getPersistenceManager();
097: Object oldValue;
098: String stmt;
099:
100: try {
101: oldValue = get0(sm, key);
102: stmt = putUpdStmt;
103: } catch (NoSuchElementException e) {
104: oldValue = null;
105: stmt = putNewStmt;
106: }
107:
108: if (oldValue != value) {
109: try {
110: Connection conn = pm.getConnection(true);
111:
112: try {
113: PreparedStatement ps = conn.prepareStatement(stmt);
114:
115: try {
116: valueMapping.setObject(pm, ps, 1, value);
117: ownerMapping.setObject(pm, ps, 2, sm
118: .getObject());
119: keyMapping.setObject(pm, ps, 3, key);
120:
121: long startTime = System.currentTimeMillis();
122:
123: ps.executeUpdate();
124:
125: if (LOG.isDebugEnabled())
126: LOG
127: .debug("Time = "
128: + (System
129: .currentTimeMillis() - startTime)
130: + " ms: " + stmt);
131: } finally {
132: ps.close();
133: }
134: } finally {
135: pm.releaseConnection(conn);
136: }
137: } catch (SQLException e) {
138: throw dba.newDataStoreException("Put request failed: "
139: + stmt, e);
140: }
141: }
142:
143: return oldValue;
144: }
145:
146: public Object remove(StateManager sm, Object key) {
147: if (!validateKeyForReading(sm, key))
148: return null;
149:
150: PersistenceManager pm = sm.getPersistenceManager();
151: Object oldValue;
152: boolean exists;
153:
154: try {
155: oldValue = get0(sm, key);
156: exists = true;
157: } catch (NoSuchElementException e) {
158: oldValue = null;
159: exists = false;
160: }
161:
162: if (exists) {
163: try {
164: Connection conn = pm.getConnection(true);
165:
166: try {
167: PreparedStatement ps = conn
168: .prepareStatement(removeStmt);
169:
170: try {
171: ownerMapping.setObject(pm, ps, 1, sm
172: .getObject());
173: keyMapping.setObject(pm, ps, 2, key);
174:
175: long startTime = System.currentTimeMillis();
176:
177: ps.executeUpdate();
178:
179: if (LOG.isDebugEnabled())
180: LOG
181: .debug("Time = "
182: + (System
183: .currentTimeMillis() - startTime)
184: + " ms: " + removeStmt);
185: } finally {
186: ps.close();
187: }
188: } finally {
189: pm.releaseConnection(conn);
190: }
191: } catch (SQLException e) {
192: throw dba.newDataStoreException(
193: "Remove request failed: " + removeStmt, e);
194: }
195: }
196:
197: return oldValue;
198: }
199:
200: public boolean removeEntry(StateManager sm, Object key, Object value) {
201: if (!validateKeyForReading(sm, key))
202: return false;
203: if (!validateValueForReading(sm, value))
204: return false;
205:
206: boolean modified;
207: PersistenceManager pm = sm.getPersistenceManager();
208:
209: try {
210: Connection conn = pm.getConnection(true);
211:
212: try {
213: PreparedStatement ps = conn
214: .prepareStatement(removeEntryStmt);
215:
216: try {
217: ownerMapping.setObject(pm, ps, 1, sm.getObject());
218: keyMapping.setObject(pm, ps, 2, key);
219: valueMapping.setObject(pm, ps, 3, key);
220:
221: long startTime = System.currentTimeMillis();
222:
223: int rowsDeleted = ps.executeUpdate();
224:
225: if (LOG.isDebugEnabled())
226: LOG
227: .debug("Time = "
228: + (System.currentTimeMillis() - startTime)
229: + " ms: " + removeEntryStmt);
230:
231: modified = rowsDeleted == 1;
232: } finally {
233: ps.close();
234: }
235: } finally {
236: pm.releaseConnection(conn);
237: }
238: } catch (SQLException e) {
239: throw dba.newDataStoreException(
240: "Remove entry request failed: " + removeEntryStmt,
241: e);
242: }
243:
244: return modified;
245: }
246: }
|