/* * Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com) * Licensed under the Apache License, Version 2.0 (the "License") * $Id: org_apache_derby_jdbc_EmbeddedDriver.java 3918 2008-04-14 17:35:35Z gbevin $ */ package com.uwyn.rife.cmf.dam.contentmanagers.databasedrivers; import com.uwyn.rife.cmf.Content; import com.uwyn.rife.cmf.ContentRepository; import com.uwyn.rife.cmf.dam.ContentStore; import com.uwyn.rife.cmf.dam.contentmanagers.DatabaseContentInfo; import com.uwyn.rife.cmf.dam.contentmanagers.exceptions.InstallContentErrorException; import com.uwyn.rife.cmf.dam.contentmanagers.exceptions.RemoveContentErrorException; import com.uwyn.rife.cmf.dam.contentmanagers.exceptions.UnknownContentRepositoryException; import com.uwyn.rife.cmf.dam.contentmanagers.exceptions.UnsupportedMimeTypeException; import com.uwyn.rife.cmf.dam.exceptions.ContentManagerException; import com.uwyn.rife.cmf.transform.ContentTransformer; import com.uwyn.rife.config.RifeConfig; import com.uwyn.rife.database.Datasource; import com.uwyn.rife.database.DbConnection; import com.uwyn.rife.database.DbPreparedStatement; import com.uwyn.rife.database.DbPreparedStatementHandler; import com.uwyn.rife.database.DbTransactionUser; import com.uwyn.rife.database.exceptions.DatabaseException; import com.uwyn.rife.database.queries.CreateTable; import com.uwyn.rife.database.queries.Insert; import com.uwyn.rife.database.queries.Query; import com.uwyn.rife.database.queries.Select; import com.uwyn.rife.datastructures.Pair; import com.uwyn.rife.tools.exceptions.InnerClassException; import java.sql.Statement; import java.sql.Types; import java.util.Map; public class org_apache_derby_jdbc_EmbeddedDriver extends generic { public org_apache_derby_jdbc_EmbeddedDriver(Datasource datasource) { super(datasource); mCreateTableContentRepository = new CreateTable(getDatasource()) .table(RifeConfig.Cmf.getTableContentRepository()) .columns(ContentRepository.class) .column("repositoryId", int.class) .customAttribute("repositoryId", "GENERATED ALWAYS AS IDENTITY") .primaryKey("PK_CONTENTREP", "repositoryId"); mCreateTableContentInfo = new CreateTable(getDatasource()) .table(RifeConfig.Cmf.getTableContentInfo()) .columns(DatabaseContentInfo.class) .column("repositoryId", int.class, CreateTable.NOTNULL) .defaultFunction("created", "CURRENT_TIMESTAMP") .customAttribute("contentId", "GENERATED ALWAYS AS IDENTITY") .unique(("UQ_"+RifeConfig.Cmf.getTableContentInfo()).toUpperCase(), new String[] {"repositoryId", "path", "version"}) .foreignKey("FK_"+RifeConfig.Cmf.getTableContentInfo(), RifeConfig.Cmf.getTableContentRepository(), "repositoryId", "repositoryId"); mCreateTableContentAttribute = new CreateTable(getDatasource()) .table(RifeConfig.Cmf.getTableContentAttribute()) .column("contentId", int.class, CreateTable.NOTNULL) .column("name", String.class, 255, CreateTable.NOTNULL) .column(getValueColumnName(), String.class, 255, CreateTable.NOTNULL) .foreignKey("FK_CONTENTATTR", RifeConfig.Cmf.getTableContentInfo(), "contentId", "contentId"); mCreateTableContentProperty = new CreateTable(getDatasource()) .table(RifeConfig.Cmf.getTableContentProperty()) .column("contentId", int.class, CreateTable.NOTNULL) .column("name", String.class, 255, CreateTable.NOTNULL) .column(getValueColumnName(), String.class, 255, CreateTable.NOTNULL) .foreignKey("FK_CONTENTPROP", RifeConfig.Cmf.getTableContentInfo(), "contentId", "contentId"); mCreateContentInfoPathNameIndex = "CREATE INDEX "+RifeConfig.Cmf.getTableContentInfo()+"_pathnm ON "+RifeConfig.Cmf.getTableContentInfo()+" (path, name)"; mDropContentInfoPathNameIndex = "DROP INDEX "+RifeConfig.Cmf.getTableContentInfo()+"_pathnm"; mGetVersion = new Select(getDatasource()) .from(RifeConfig.Cmf.getTableContentInfo()) .field("CASE WHEN MAX(version) IS NULL THEN 0 ELSE MAX(version)+1 END") .whereParameter("repositoryId", "=") .whereParameterAnd("path", "="); mStoreContentRepository = new Insert(getDatasource()) .into(RifeConfig.Cmf.getTableContentRepository()) .fieldsParameters(ContentRepository.class); mStoreContentInfo = new Insert(getDatasource()) .into(RifeConfig.Cmf.getTableContentInfo()) .fieldsParametersExcluded(DatabaseContentInfo.class, new String[] {"contentId"}) .fieldParameter("repositoryId") .field("version", mGetVersion); mGetLatestContentInfo = new Select(getDatasource()) .from(RifeConfig.Cmf.getTableContentInfo()) .join(RifeConfig.Cmf.getTableContentRepository()) .field(RifeConfig.Cmf.getTableContentInfo()+".*") .where(RifeConfig.Cmf.getTableContentInfo()+".repositoryId = "+RifeConfig.Cmf.getTableContentRepository()+".repositoryId") .whereParameterAnd(RifeConfig.Cmf.getTableContentRepository()+".name", "repository", "=") .startWhereAnd() .whereParameter("path", "=") .startWhereOr() .whereParameter("path", "pathpart", "=") .whereParameterAnd(RifeConfig.Cmf.getTableContentInfo()+".name", "namepart", "=") .end() .end() .orderBy("version", Select.DESC); } public boolean install() throws ContentManagerException { try { executeUpdate(mCreateTableContentRepository); executeUpdate(mCreateTableContentInfo); executeUpdate(mCreateTableContentAttribute); executeUpdate(mCreateTableContentProperty); createRepository(ContentRepository.DEFAULT); for (ContentStore store : mStores) { store.install(); } executeUpdate(mCreateContentInfoPathIndex); executeUpdate(mCreateContentInfoPathNameIndex); } catch (DatabaseException e) { throw new InstallContentErrorException(e); } return true; } public boolean remove() throws ContentManagerException { try { executeUpdate(mDropContentInfoPathNameIndex); executeUpdate(mDropContentInfoPathIndex); for (ContentStore store : mStores) { store.remove(); } executeUpdate(mDropTableContentProperties); executeUpdate(mDropTableContentAttribute); executeUpdate(mDropTableContentInfo); executeUpdate(mDropTableContentRepository); } catch (DatabaseException e) { throw new RemoveContentErrorException(e); } return true; } public boolean createRepository(final String name) throws ContentManagerException { if (null == name) throw new IllegalArgumentException("name can't be null"); if (0 == name.length()) throw new IllegalArgumentException("name can't be empty"); Boolean result = null; try { result = inTransaction(new DbTransactionUser() { public Boolean useTransaction() throws InnerClassException { // store the content return executeUpdate(mStoreContentRepository, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setString("name", name); } }) > 0; } }); } catch (InnerClassException e) { throw (ContentManagerException)e.getCause(); } return result != null && result.booleanValue(); } public boolean storeContent(String location, final Content content, final ContentTransformer transformer) throws ContentManagerException { if (null == content) throw new IllegalArgumentException("content can't be null"); final Pair<String, String> split_location = splitLocation(location); final ContentStore store = mMimeMapping.get(content.getMimeType()); if (null == store) { throw new UnsupportedMimeTypeException(content.getMimeType()); } Boolean result = null; try { result = inTransaction(new DbTransactionUser() { public Boolean useTransaction() throws InnerClassException { // get repository id final int repository_id = executeGetFirstInt(mGetContentRepositoryId, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setString("repository", split_location.getFirst()); } }); // verify the existance of the repository if (-1 == repository_id) { throwException(new UnknownContentRepositoryException(split_location.getFirst())); } // store the content final int[] ids_array = new int[1]; if (executeUpdate(mStoreContentInfo, new DbPreparedStatementHandler() { public DbPreparedStatement getPreparedStatement(Query query, DbConnection connection) { return connection.getPreparedStatement(query, Statement.RETURN_GENERATED_KEYS); } public int performUpdate(DbPreparedStatement statement) { statement .setInt("repositoryId", repository_id) .setString("path", split_location.getSecond()) .setString("mimeType", content.getMimeType().toString()) .setBoolean("fragment", content.isFragment()); if (content.hasName()) { statement .setString("name", content.getName()); } else { statement .setNull("name", Types.VARCHAR); } int query_result = statement.executeUpdate(); ids_array[0] = statement.getFirstGeneratedIntKey(); return query_result; } }) > 0) { // store the attributes if there are some if (content.hasAttributes()) { for (Map.Entry<String, String> attribute : content.getAttributes().entrySet()) { final String name = attribute.getKey(); final String value = attribute.getValue(); executeUpdate(mStoreContentAttribute, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setInt("contentId", ids_array[0]) .setString("name", name) .setString(getValueColumnName(), value); } }); } } // put the actual content data in the content store try { if (!store.storeContentData(ids_array[0], content, transformer)) { rollback(); } } catch (ContentManagerException e) { throwException(e); } // store the content data properties if there are some if (content.hasProperties()) { for (Map.Entry<String, String> property : content.getProperties().entrySet()) { final String name = property.getKey(); final String value = property.getValue(); executeUpdate(mStoreContentProperty, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setInt("contentId", ids_array[0]) .setString("name", name) .setString(getValueColumnName(), value); } }); } } return true; } return false; } }); } catch (InnerClassException e) { throw (ContentManagerException)e.getCause(); } return result != null && result.booleanValue(); } }