Mercurial > dive4elements > framework
diff artifact-database/src/main/java/de/intevation/artifactdatabase/Backend.java @ 14:0d16d1bb2df0
Initial checkin of artigact persistents back by database.
artifacts/trunk@29 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Mon, 07 Sep 2009 08:41:05 +0000 |
parents | 0d6badf6af42 |
children | 9ad6ec2d09c3 |
line wrap: on
line diff
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/Backend.java Sun Sep 06 16:16:54 2009 +0000 +++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/Backend.java Mon Sep 07 08:41:05 2009 +0000 @@ -1,5 +1,23 @@ package de.intevation.artifactdatabase; +import org.w3c.dom.Document; + +import java.util.UUID; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.PreparedStatement; +import java.sql.Types; +import java.sql.ResultSet; + +import javax.sql.DataSource; + +import java.io.IOException; +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; + +import java.util.zip.GZIPOutputStream; + import de.intevation.artifacts.ArtifactFactory; import de.intevation.artifacts.Artifact; @@ -8,6 +26,118 @@ */ public class Backend { + public static final String SQL_NEXT_ID = + SQL.get("artifacts.id.nextval"); + + public static final String SQL_INSERT = + SQL.get("artifacts.insert"); + + public static final String SQL_UPDATE = + SQL.get("artifacts.update"); + + public static final String SQL_TOUCH = + SQL.get("artifacts.touch"); + + /** + * Used to wrap the calls to invole database actions. + */ + public class ArtifactProxy + implements Artifact + { + protected Artifact original; + protected int id; + protected boolean unwritten; + + public ArtifactProxy() { + } + + public ArtifactProxy(Artifact original, int id, boolean unwritten) { + this.original = original; + this.id = id; + this.unwritten = unwritten; + } + + public Artifact getOriginal() { + return original; + } + + public int getId() { + return id; + } + + public boolean isUnwritten() { + return unwritten; + } + + public String identifier() { + return original.identifier(); + } + + public String hash() { + return original.hash(); + } + + public Document describe(Object context) { + try { + return original.describe(context); + } + finally { + touch(this); + } + } + + public Document advance(Document target, Object context) { + try { + return original.advance(target, context); + } + finally { + store(this); + } + } + + public Document feed(Document data, Object context) { + try { + return original.feed(data, context); + } + finally { + store(this); + } + } + + public byte [] out(Document format, Object context) { + try { + return original.out(format, context); + } + finally { + touch(this); + } + } + + public void setup(String identifier, Object context) { + original.setup(identifier, context); + } + + public void endOfLife(Object context) { + original.endOfLife(context); + } + + public byte [] toBytes() { + try { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + GZIPOutputStream gos = new GZIPOutputStream(bos); + ObjectOutputStream oos = new ObjectOutputStream(gos); + + oos.writeObject(original); + oos.flush(); + + return bos.toByteArray(); + } + catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } + } // class ArtifactProxy + public Backend() { } @@ -18,7 +148,155 @@ public Artifact createArtifactWithFactory( ArtifactFactory factory, Object context ) { - return null; + UUID uuid = UUID.randomUUID(); + Artifact artifact = factory.createArtifact( + uuid.toString(), context); + + Long ttl = factory.timeToLiveUntouched( + artifact, context); + + int id = insertDatabase(uuid, ttl); + + return new ArtifactProxy(artifact, id, true); } + + protected int insertDatabase(UUID uuid, Long ttl) { + Connection connection = null; + PreparedStatement stmnt_next_id = null; + PreparedStatement stmnt_insert = null; + ResultSet res_id = null; + + DataSource dataSource = DBConnection.getDataSource(); + try { + connection = dataSource.getConnection(); + try { + connection.setAutoCommit(false); + + stmnt_next_id = connection.prepareStatement(SQL_NEXT_ID); + stmnt_insert = connection.prepareStatement(SQL_INSERT); + + res_id = stmnt_next_id.executeQuery(); + + if (!res_id.next()) { + throw new RuntimeException("No id generated"); + } + + int id = res_id.getInt(1); + + stmnt_insert.setInt(1, id); + stmnt_insert.setString(2, uuid.toString()); + if (ttl == null) { + stmnt_insert.setNull(3, Types.BIGINT); + } + else { + stmnt_insert.setLong(3, ttl.longValue()); + } + + stmnt_insert.execute(); + + connection.commit(); + + return id; + } + catch (SQLException sqle) { + connection.rollback(); + throw sqle; + } + } + catch (SQLException sqle) { + sqle.printStackTrace(System.err); + } + finally { + if (res_id != null) { + try { res_id.close(); } + catch (SQLException sqle) {} + } + if (stmnt_insert != null) { + try { stmnt_insert.close(); } + catch (SQLException sqle) {} + } + if (stmnt_next_id != null) { + try { stmnt_next_id.close(); } + catch (SQLException sqle) {} + } + if (connection != null) { + try { connection.close(); } + catch (SQLException sqle) {} + } + } + throw new RuntimeException("failed insert artifact into database"); + } + + public void touch(ArtifactProxy proxy) { + System.err.println("touch: " + proxy); + if (proxy.isUnwritten()) { + store(proxy); + return; + } + Connection connection = null; + PreparedStatement stmnt_touch = null; + DataSource dataSource = DBConnection.getDataSource(); + try { + connection = dataSource.getConnection(); + try { + connection.setAutoCommit(false); + stmnt_touch = connection.prepareStatement(SQL_UPDATE); + stmnt_touch.setInt(1, proxy.getId()); + stmnt_touch.execute(); + connection.commit(); + } + catch (SQLException sqle) { + connection.rollback(); + } + } + catch (SQLException sqle) { + sqle.printStackTrace(System.err); + } + finally { + if (stmnt_touch != null) { + try { stmnt_touch.close(); } + catch (SQLException sqle) {} + } + if (connection != null) { + try { connection.close(); } + catch (SQLException sqle) {} + } + } + } + + public void store(ArtifactProxy proxy) { + System.err.println("store: " + proxy); + Connection connection = null; + PreparedStatement stmnt_update = null; + DataSource dataSource = DBConnection.getDataSource(); + try { + connection = dataSource.getConnection(); + try { + connection.setAutoCommit(false); + stmnt_update = connection.prepareStatement(SQL_UPDATE); + stmnt_update.setInt(1, proxy.getId()); + stmnt_update.setBytes(2, proxy.toBytes()); + stmnt_update.execute(); + connection.commit(); + } + catch (SQLException sqle) { + connection.rollback(); + } + } + catch (SQLException sqle) { + sqle.printStackTrace(System.err); + } + finally { + if (stmnt_update != null) { + try { stmnt_update.close(); } + catch (SQLException sqle) {} + } + if (connection != null) { + try { connection.close(); } + catch (SQLException sqle) {} + } + } + } + } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: