[New] Initial commit

This commit is contained in:
Robert von Burg 2013-12-18 16:29:45 +01:00
parent 8a88e367df
commit 0ea999d921
21 changed files with 1298 additions and 6 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
target/
.project
.settings
.classpath

View File

@ -1,4 +1,5 @@
Apache License
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
@ -178,7 +179,7 @@ Apache License
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
@ -186,7 +187,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -199,4 +200,3 @@ Apache License
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,4 +1,54 @@
li.strolch.persistence.postgresql
=================================
=======================================================================
PostgreSQL persistence implementation for Strolch
PostgreSQL Persistence Implementation for Strolch
Setup
=======================================================================
1. Install PostgreSQL version with at least version 9.1:
$ sudo aptitude install postgresql postgresql-client
2. Set a password for user 'postgres'
$ sudo -u postgres psql postgres
postgres=# \password postgres
3. Create the user and DB:
$ sudo su - postgres
postgres=# create user testUser with password 'test';
postgres=# create database testdb;
postgres=# GRANT ALL PRIVILEGES ON DATABASE testdb to testuser;
postgres=# GRANT CONNECT ON DATABASE testdb TO testuser ;
4. Added new component, setting properties for PostgreSQL DB:
<Component>
<name>PersistenceHandler</name>
<api>li.strolch.persistence.api.StrolchPersistenceHandler</api>
<impl>li.strolch.persistence.postgresql.PostgreSqlPersistenceHandler</impl>
<Properties>
<allowSchemaCreation>false</allowSchemaCreation>
<db.url>jdbc:postgresql://localhost/testdb</db.url>
<db.username>testUser</db.username>
<db.password>test</db.password>
</Properties>
</Component>
5. Create tables, or allow strolch to due it for you.
Appendix
=======================================================================
1. To drop the user and DB:
postgres=# revoke ALL PRIVILEGES ON DATABASE testdb from testuser;
postgres=# drop user testuser;
postgres=# drop database testdb;
2. Create a database:
$ createdb -p 5432 -O drupal -U drupal -E UTF8 testingsiteone -T template0
3. Dropping the database
$ dropdb -p 5432 -U drupal testingsiteone
4. Dumping the database
$ pg_dump -p 5432 -h localhost -Fc -U drupal --no-owner testingsiteone > /tmp/testingsiteone_$(date +"%Y-%m-%d_%s").pgdump
5. Restoring the database
$ pg_restore -p 5432 -h localhost -Fc -d testingsiteone -U drupal --no-owner < /tmp/path-to-the-file.pgdump
References
=======================================================================
http://www.pixelite.co.nz/article/installing-and-configuring-postgresql-91-ubuntu-1204-local-drupal-development

86
pom.xml Normal file
View File

@ -0,0 +1,86 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>li.strolch</groupId>
<artifactId>li.strolch.parent</artifactId>
<version>0.1.0-SNAPSHOT</version>
<relativePath>../li.strolch.parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>li.strolch.persistence.postgresql</artifactId>
<name>Reference Persistence Implementation for Strolch</name>
<description>Reference Persistence Implementation for Strolch</description>
<url>https://github.com/eitch/li.strolch.persistence.postgresql</url>
<inceptionYear>2011</inceptionYear>
<issueManagement>
<system>Github Issues</system>
<url>https://github.com/eitch/li.strolch.persistence.postgresql/issues</url>
</issueManagement>
<scm>
<connection>scm:git:https://github.com/eitch/li.strolch.persistence.postgresql.git</connection>
<developerConnection>scm:git:git@github.com:eitch/li.strolch.persistence.postgresql.git</developerConnection>
<url>https://github.com/eitch/li.strolch.persistence.postgresql</url>
</scm>
<dependencies>
<dependency>
<groupId>li.strolch</groupId>
<artifactId>li.strolch.model</artifactId>
</dependency>
<dependency>
<groupId>li.strolch</groupId>
<artifactId>li.strolch.runtime</artifactId>
</dependency>
<dependency>
<groupId>li.strolch</groupId>
<artifactId>li.strolch.persistence.api</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.3-1100-jdbc41</version>
</dependency>
<dependency>
<groupId>li.strolch</groupId>
<artifactId>li.strolch.testbase</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,96 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.persistence.postgresql;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import li.strolch.model.StrolchElement;
import li.strolch.persistence.api.StrolchDao;
import li.strolch.persistence.api.StrolchTransaction;
public abstract class AbstractDao<T extends StrolchElement> implements StrolchDao<T> {
protected AbstractDao(StrolchTransaction tx) {
PostgreSqlStrolchTransaction strolchTx = (PostgreSqlStrolchTransaction) tx;
}
protected abstract String getClassType();
@Override
public Set<String> queryKeySet() {
Set<String> keys = new HashSet<>();
Set<String> types = queryTypes();
for (String type : types) {
keys.addAll(queryKeySet(type));
}
return keys;
}
@Override
public Set<String> queryKeySet(String type) {
return null;
}
@Override
public Set<String> queryTypes() {
return null;
}
@Override
public T queryBy(String type, String id) {
return null;
}
@Override
public List<T> queryAll() {
return null;
}
@Override
public List<T> queryAll(String type) {
return null;
}
@Override
public void save(T object) {
}
@Override
public void saveAll(List<T> objects) {
}
@Override
public void update(T object) {
}
@Override
public void updateAll(List<T> objects) {
}
@Override
public void remove(T object) {
}
@Override
public void removeAll(List<T> objects) {
}
@Override
public void remove(String type, String id) {
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.persistence.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import li.strolch.persistence.api.DbConnectionInfo;
import li.strolch.runtime.configuration.StrolchConfigurationException;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public class DbConnectionCheck {
private static final Logger logger = LoggerFactory.getLogger(DbConnectionCheck.class);
private Map<String, DbConnectionInfo> connetionInfoMap;
/**
* @param connetionInfoMap
*/
public DbConnectionCheck(Map<String, DbConnectionInfo> connetionInfoMap) {
this.connetionInfoMap = connetionInfoMap;
}
public void checkConnections() {
Collection<DbConnectionInfo> values = this.connetionInfoMap.values();
for (DbConnectionInfo connectionInfo : values) {
String url = connectionInfo.getUrl();
String username = connectionInfo.getUsername();
String password = connectionInfo.getPassword();
try (Connection con = DriverManager.getConnection(url, username, password);
Statement st = con.createStatement();) {
try (ResultSet rs = st.executeQuery("SELECT VERSION()")) {
if (rs.next()) {
logger.info("Connected to: " + rs.getString(1));
}
}
} catch (SQLException e) {
String msg = "Failed to open DB connection to URL {0} due to: {1}"; //$NON-NLS-1$
msg = MessageFormat.format(msg, url, e.getMessage());
throw new StrolchConfigurationException(msg, e);
}
}
}
}

View File

@ -0,0 +1,201 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.persistence.postgresql;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.Map;
import java.util.Properties;
import li.strolch.exception.StrolchException;
import li.strolch.persistence.api.DbConnectionInfo;
import li.strolch.runtime.configuration.ComponentConfiguration;
import li.strolch.runtime.configuration.StrolchConfigurationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.eitchnet.utils.dbc.DBC;
import ch.eitchnet.utils.helper.FileHelper;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
@SuppressWarnings(value = "nls")
public class DbSchemaVersionCheck {
private static final String RESOURCE_DB_VERSION = "/db_version.properties";
private static final String PROP_DB_VERSION = "db_version";
private static final String PROP_ALLOW_SCHEMA_CREATION = "allowSchemaCreation";
private static final String PROP_ALLOW_SCHEMA_DROP = "allowSchemaDrop";
private static final Logger logger = LoggerFactory.getLogger(DbSchemaVersionCheck.class);
private Map<String, DbConnectionInfo> connetionInfoMap;
private boolean allowSchemaCreation;
private boolean allowSchemaDrop;
/**
* @param connetionInfoMap
* @param componentConfiguration
*/
public DbSchemaVersionCheck(Map<String, DbConnectionInfo> connetionInfoMap,
ComponentConfiguration componentConfiguration) {
this.connetionInfoMap = connetionInfoMap;
this.allowSchemaCreation = componentConfiguration.getBoolean(PROP_ALLOW_SCHEMA_CREATION, Boolean.FALSE);
this.allowSchemaDrop = componentConfiguration.getBoolean(PROP_ALLOW_SCHEMA_DROP, Boolean.FALSE);
}
public void checkSchemaVersion() {
Collection<DbConnectionInfo> values = this.connetionInfoMap.values();
for (DbConnectionInfo connectionInfo : values) {
String realm = connectionInfo.getRealm();
String url = connectionInfo.getUrl();
String username = connectionInfo.getUsername();
String password = connectionInfo.getPassword();
logger.info("Checking Schema version for realm " + realm + "...");
try (Connection con = DriverManager.getConnection(url, username, password);
Statement st = con.createStatement();) {
String expectedDbVersion = getExpectedDbVersion();
// first see if we have any schema
String checkSchemaExistsSql = MessageFormat
.format("select table_schema, table_name, table_type from information_schema.tables where table_name=''{0}'';",
PROP_DB_VERSION);
try (ResultSet rs = st.executeQuery(checkSchemaExistsSql)) {
if (!rs.next()) {
createSchema(realm, expectedDbVersion, st);
} else {
checkCurrentVersion(realm, st, expectedDbVersion);
}
}
} catch (SQLException e) {
String msg = "Failed to open DB connection to URL {0} due to: {1}"; //$NON-NLS-1$
msg = MessageFormat.format(msg, url, e.getMessage());
throw new StrolchConfigurationException(msg, e);
}
}
}
private void checkCurrentVersion(String realm, Statement st, String expectedDbVersion) throws SQLException {
try (ResultSet rs = st.executeQuery("select id, version from db_version order by id desc;")) {
if (!rs.next()) {
createSchema(realm, expectedDbVersion, st);
} else {
String currentVersion = rs.getString(2);
if (expectedDbVersion.equals(currentVersion)) {
logger.info("Schema version " + currentVersion + " is the current version. No changes needed.");
} else {
logger.warn("Schema version is not current. Need to upgrade from " + currentVersion + " to "
+ expectedDbVersion);
upgradeSchema(realm, expectedDbVersion, st);
}
}
}
}
private String getExpectedDbVersion() {
Properties dbVersionProps = new Properties();
try (InputStream stream = getClass().getResourceAsStream(RESOURCE_DB_VERSION);) {
DBC.PRE.assertNotNull(
MessageFormat.format("Resource file with name {0} does not exist!", RESOURCE_DB_VERSION), stream);
dbVersionProps.load(stream);
} catch (IOException e) {
throw new StrolchException("Expected resource file " + RESOURCE_DB_VERSION
+ " does not exist or is not a valid properties file: " + e.getMessage(), e);
}
String dbVersion = dbVersionProps.getProperty(PROP_DB_VERSION);
String msg = "Missing property {0} in resource file {1}";
DBC.PRE.assertNotEmpty(MessageFormat.format(msg, PROP_DB_VERSION, RESOURCE_DB_VERSION), dbVersion);
return dbVersion;
}
private String getSql(String dbVersion, String type) {
String schemaResourceS = "/db_schema_" + dbVersion + "_" + type + ".sql";
try (InputStream stream = getClass().getResourceAsStream(schemaResourceS);) {
DBC.PRE.assertNotNull(
MessageFormat.format("Schema Resource file with name {0} does not exist!", schemaResourceS), stream);
return FileHelper.readStreamToString(stream);
} catch (IOException e) {
throw new StrolchException("Schema creation resource file is missing or could not be read: "
+ schemaResourceS, e);
}
}
/**
* @param realm
* @param st
*/
private void createSchema(String realm, String dbVersion, Statement st) {
if (!this.allowSchemaCreation) {
throw new StrolchConfigurationException("[" + realm
+ "] No schema exists, or is not valid. Schema generation is disabled, thus can not continue!");
}
logger.info("[" + realm + "] Creating initial schema...");
String sql = getSql(dbVersion, "initial");
try {
st.execute(sql);
} catch (SQLException e) {
logger.error("Failed to execute schema creation SQL: \n" + sql);
throw new StrolchException("Failed to execute schema generation SQL: " + e.getMessage(), e);
}
logger.info("[" + realm + "] Successfully created schema for version " + dbVersion);
}
private void dropSchema(String realm, String dbVersion, Statement st) {
if (!this.allowSchemaDrop) {
throw new StrolchConfigurationException("[" + realm
+ "] Dropping Schema is disabled, but is required to upgrade current schema...");
}
logger.info("[" + realm + "] Dropping existing schema...");
String sql = getSql(dbVersion, "drop");
try {
st.execute(sql);
} catch (SQLException e) {
logger.error("Failed to execute schema drop SQL: \n" + sql);
throw new StrolchException("Failed to execute schema drop SQL: " + e.getMessage(), e);
}
}
/**
* @param st
*/
private void upgradeSchema(String realm, String dbVersion, Statement st) {
dropSchema(realm, dbVersion, st);
createSchema(realm, dbVersion, st);
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.persistence.postgresql;
import java.util.ArrayList;
import java.util.List;
public class ModificationResult {
private final String key;
private final List<?> created;
private final List<?> updated;
private final List<?> deleted;
public ModificationResult(String key) {
this.key = key;
this.created = new ArrayList<>();
this.updated = new ArrayList<>();
this.deleted = new ArrayList<>();
}
public ModificationResult(String key, List<?> created, List<?> updated, List<?> deleted) {
this.key = key;
this.created = created;
this.updated = updated;
this.deleted = deleted;
}
public String getKey() {
return this.key;
}
@SuppressWarnings("unchecked")
public <T> List<T> getCreated() {
return (List<T>) this.created;
}
@SuppressWarnings("unchecked")
public <T> List<T> getUpdated() {
return (List<T>) this.updated;
}
@SuppressWarnings("unchecked")
public <T> List<T> getDeleted() {
return (List<T>) this.deleted;
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.persistence.postgresql;
import li.strolch.model.Order;
import li.strolch.model.Tags;
import li.strolch.persistence.api.OrderDao;
import li.strolch.persistence.api.StrolchTransaction;
public class PostgreSqlOrderDao extends AbstractDao<Order> implements OrderDao {
protected PostgreSqlOrderDao(StrolchTransaction tx) {
super(tx);
}
@Override
protected String getClassType() {
return Tags.ORDER;
}
}

View File

@ -0,0 +1,122 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.persistence.postgresql;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import li.strolch.persistence.api.DbConnectionInfo;
import li.strolch.persistence.api.OrderDao;
import li.strolch.persistence.api.ResourceDao;
import li.strolch.persistence.api.StrolchPersistenceHandler;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.runtime.component.ComponentContainer;
import li.strolch.runtime.component.StrolchComponent;
import li.strolch.runtime.configuration.ComponentConfiguration;
import li.strolch.runtime.configuration.StrolchConfigurationException;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class PostgreSqlPersistenceHandler extends StrolchComponent implements StrolchPersistenceHandler {
private static final String PROP_DB_URL = "db.url";
private static final String PROP_DB_USERNAME = "db.username";
private static final String PROP_DB_PASSWORD = "db.password";
private ComponentConfiguration componentConfiguration;
private Map<String, DbConnectionInfo> connetionInfoMap;
public PostgreSqlPersistenceHandler(ComponentContainer container, String componentName) {
super(container, componentName);
}
@Override
public void initialize(ComponentConfiguration componentConfiguration) {
this.componentConfiguration = componentConfiguration;
this.connetionInfoMap = new HashMap<>();
String dbUrl = componentConfiguration.getString(PROP_DB_URL, null);
String username = componentConfiguration.getString(PROP_DB_USERNAME, null);
String password = componentConfiguration.getString(PROP_DB_PASSWORD, null);
Driver driver;
try {
driver = DriverManager.getDriver(dbUrl);
} catch (SQLException e) {
String msg = "Failed to load DB driver for URL {0} due to: {1}"; //$NON-NLS-1$
msg = MessageFormat.format(msg, dbUrl, e.getMessage());
throw new StrolchConfigurationException(msg, e);
}
DbConnectionInfo connectionInfo = new DbConnectionInfo(StrolchTransaction.DEFAULT_REALM, dbUrl);
connectionInfo.setUsername(username);
connectionInfo.setPassword(password);
this.connetionInfoMap.put(StrolchTransaction.DEFAULT_REALM, connectionInfo);
String compliant = driver.jdbcCompliant() ? "" : "non"; //$NON-NLS-1$ //$NON-NLS-2$
String msg = "Using {0} JDBC compliant Driver {1}.{2}"; //$NON-NLS-1$
msg = MessageFormat.format(msg, compliant, driver.getMajorVersion(), driver.getMinorVersion());
logger.info(msg);
super.initialize(componentConfiguration);
}
@Override
public void start() {
// test all connections
DbConnectionCheck connectionCheck = new DbConnectionCheck(this.connetionInfoMap);
connectionCheck.checkConnections();
DbSchemaVersionCheck schemaVersionCheck = new DbSchemaVersionCheck(this.connetionInfoMap,
componentConfiguration);
schemaVersionCheck.checkSchemaVersion();
super.start();
}
public StrolchTransaction openTx() {
return openTx(StrolchTransaction.DEFAULT_REALM);
}
@SuppressWarnings("resource")
// caller will/must close
public StrolchTransaction openTx(String realm) {
// PersistenceTransaction tx = this.persistenceManager.openTx(realm);
// XmlStrolchTransaction strolchTx = new XmlStrolchTransaction(tx);
// if (getContainer().hasComponent(ObserverHandler.class)) {
// strolchTx.setObserverHandler(getContainer().getComponent(ObserverHandler.class));
// }
// return strolchTx;
return null;
}
@Override
public OrderDao getOrderDao(StrolchTransaction tx) {
return new PostgreSqlOrderDao(tx);
}
@Override
public ResourceDao getResourceDao(StrolchTransaction tx) {
return new PostgreSqlResourceDao(tx);
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.persistence.postgresql;
import li.strolch.model.Resource;
import li.strolch.model.Tags;
import li.strolch.persistence.api.ResourceDao;
import li.strolch.persistence.api.StrolchTransaction;
public class PostgreSqlResourceDao extends AbstractDao<Resource> implements ResourceDao {
protected PostgreSqlResourceDao(StrolchTransaction tx) {
super(tx);
}
@Override
protected String getClassType() {
return Tags.RESOURCE;
}
}

View File

@ -0,0 +1,102 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.persistence.postgresql;
import li.strolch.persistence.api.StrolchPersistenceException;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.persistence.api.TransactionCloseStrategy;
import li.strolch.runtime.observer.ObserverHandler;
public class PostgreSqlStrolchTransaction implements StrolchTransaction {
private ObserverHandler observerHandler;
private boolean suppressUpdates;
private TransactionCloseStrategy closeStrategy;
// private TransactionResult txResult;
public PostgreSqlStrolchTransaction(/*PersistenceTransaction tx*/) {
this.suppressUpdates = false;
// this.tx = tx;
this.closeStrategy = TransactionCloseStrategy.COMMIT;
}
/**
* @param observerHandler
* the observerHandler to set
*/
public void setObserverHandler(ObserverHandler observerHandler) {
this.observerHandler = observerHandler;
}
/**
* @param suppressUpdates
* the suppressUpdates to set
*/
public void setSuppressUpdates(boolean suppressUpdates) {
this.suppressUpdates = suppressUpdates;
}
/**
* @return the suppressUpdates
*/
public boolean isSuppressUpdates() {
return this.suppressUpdates;
}
@Override
public void setCloseStrategy(TransactionCloseStrategy closeStrategy) {
this.closeStrategy = closeStrategy;
}
@Override
public void autoCloseableCommit() {
if (!this.suppressUpdates && this.observerHandler != null) {
// this.txResult = new TransactionResult();
// this.tx.setTransactionResult(this.txResult);
}
// this.tx.autoCloseableCommit();
if (!this.suppressUpdates && this.observerHandler != null) {
// Set<String> keys = this.txResult.getKeys();
// for (String key : keys) {
// ModificationResult modificationResult = this.txResult.getModificationResult(key);
//
// this.observerHandler.add(key, modificationResult.<StrolchElement> getCreated());
// this.observerHandler.update(key, modificationResult.<StrolchElement> getUpdated());
// this.observerHandler.remove(key, modificationResult.<StrolchElement> getDeleted());
// }
}
}
@Override
public void autoCloseableRollback() {
// this.tx.autoCloseableRollback();
}
@Override
public void close() throws StrolchPersistenceException {
this.closeStrategy.close(this);
}
@Override
public boolean isOpen() {
// return this.tx.isOpen();
return true;
}
}

View File

@ -0,0 +1,5 @@
DROP TABLE IF EXISTS resources, orders, db_version;
DROP TYPE IF EXISTS order_state;

View File

@ -0,0 +1,33 @@
CREATE TABLE IF NOT EXISTS db_version (
id SERIAL PRIMARY KEY,
version varchar(255),
description varchar(255),
created timestamp with time zone
);
CREATE TABLE IF NOT EXISTS resources (
id varchar(255) PRIMARY KEY,
name VARCHAR(255),
type VARCHAR(255),
asxml xml
);
CREATE TYPE order_state AS ENUM ('CREATED', 'OPEN', 'EXECUTION', 'CLOSED');
CREATE TABLE IF NOT EXISTS orders (
id varchar(255) PRIMARY KEY,
name VARCHAR(255),
type VARCHAR(255),
state order_state,
date timestamp with time zone,
asxml xml
);
INSERT INTO db_version
(version, description, created)
values(
'0.1.0',
'Initial schema version',
CURRENT_TIMESTAMP
);

View File

@ -0,0 +1,2 @@
# Property file defining what the currently expected version is supposed to be
db_version=0.1.0

View File

@ -0,0 +1,54 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.persistence.postgresql.dao.test;
import java.io.File;
import li.strolch.persistence.api.StrolchPersistenceHandler;
import li.strolch.testbase.runtime.RuntimeMock;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public abstract class AbstractDaoImplTest extends RuntimeMock {
private static final String RUNTIME_PATH = "target/strolchRuntime/"; //$NON-NLS-1$
private static final String DB_STORE_PATH_DIR = "dbStore"; //$NON-NLS-1$
private static final String CONFIG_SRC = "src/test/resources/runtime/config"; //$NON-NLS-1$
protected static StrolchPersistenceHandler persistenceHandler;
@BeforeClass
public static void beforeClass() {
File rootPath = new File(RUNTIME_PATH);
File configSrc = new File(CONFIG_SRC);
RuntimeMock.mockRuntime(rootPath, configSrc);
new File(rootPath, DB_STORE_PATH_DIR).mkdir();
RuntimeMock.startContainer(rootPath);
// initialize the component configuration
persistenceHandler = getContainer().getComponent(StrolchPersistenceHandler.class);
}
@AfterClass
public static void afterClass() {
RuntimeMock.destroyRuntime();
}
}

View File

@ -0,0 +1,98 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.persistence.postgresql.dao.test;
import static li.strolch.model.ModelGenerator.createOrder;
import static li.strolch.model.ModelGenerator.createResource;
import static org.junit.Assert.assertEquals;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import li.strolch.model.Order;
import li.strolch.model.Resource;
import li.strolch.model.State;
import li.strolch.model.StrolchElement;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.persistence.postgresql.ModificationResult;
import li.strolch.runtime.observer.Observer;
import li.strolch.runtime.observer.ObserverHandler;
import org.junit.Test;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public class ObserverUpdateTest extends AbstractDaoImplTest {
public final class ElementAddedObserver implements Observer {
Map<String, ModificationResult> results = new HashMap<>();
private ModificationResult getModificationResult(String key) {
ModificationResult result = this.results.get(key);
if (result == null) {
result = new ModificationResult(key);
this.results.put(key, result);
}
return result;
}
@Override
public void update(String key, List<StrolchElement> elements) {
getModificationResult(key).getUpdated().addAll(elements);
}
@Override
public void remove(String key, List<StrolchElement> elements) {
getModificationResult(key).getDeleted().addAll(elements);
}
@Override
public void add(String key, List<StrolchElement> elements) {
getModificationResult(key).getCreated().addAll(elements);
}
}
@Test
public void shouldReceiveUpdates() {
// register an observer for orders and resources
ElementAddedObserver observer = new ElementAddedObserver();
getContainer().getComponent(ObserverHandler.class).registerObserver("Order", observer); //$NON-NLS-1$
getContainer().getComponent(ObserverHandler.class).registerObserver("Resource", observer); //$NON-NLS-1$
// create order
Order newOrder = createOrder("MyTestOrder", "Test Name", "TestType", new Date(), State.CREATED); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getOrderDao(tx).save(newOrder);
}
// create resource
Resource newResource = createResource("MyTestResource", "Test Name", "TestType"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getResourceDao(tx).save(newResource);
}
assertEquals(2, observer.results.size());
assertEquals(1, observer.results.get("Order").getCreated().size()); //$NON-NLS-1$
assertEquals(1, observer.results.get("Resource").getCreated().size()); //$NON-NLS-1$
}
}

View File

@ -0,0 +1,92 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.persistence.postgresql.dao.test;
import static li.strolch.model.ModelGenerator.BAG_ID;
import static li.strolch.model.ModelGenerator.PARAM_STRING_ID;
import static li.strolch.model.ModelGenerator.createOrder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import li.strolch.model.Order;
import li.strolch.model.parameter.Parameter;
import li.strolch.persistence.api.StrolchTransaction;
import org.junit.Test;
public class PostgreSqlOrderDaoTest extends AbstractDaoImplTest {
private static final String ID = "@testOrder"; //$NON-NLS-1$
private static final String NAME = "Test Order"; //$NON-NLS-1$
private static final String TYPE = "ToStock"; //$NON-NLS-1$
@Test
public void shouldCreateOrder() {
// create
Order newOrder = createOrder("MyTestOrder", "Test Name", "TestType"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getOrderDao(tx).save(newOrder);
}
}
@Test
public void shouldCrud() {
// create
Order newOrder = createOrder(ID, NAME, TYPE);
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getOrderDao(tx).save(newOrder);
}
// read
Order readOrder = null;
try (StrolchTransaction tx = persistenceHandler.openTx();) {
readOrder = persistenceHandler.getOrderDao(tx).queryBy(TYPE, ID);
}
assertNotNull("Should read Order with id " + ID, readOrder); //$NON-NLS-1$
// update
Parameter<String> sParam = readOrder.getParameter(BAG_ID, PARAM_STRING_ID);
String newStringValue = "Giddiya!"; //$NON-NLS-1$
sParam.setValue(newStringValue);
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getOrderDao(tx).update(readOrder);
}
// read updated
Order updatedOrder = null;
try (StrolchTransaction tx = persistenceHandler.openTx();) {
updatedOrder = persistenceHandler.getOrderDao(tx).queryBy(TYPE, ID);
}
assertNotNull("Should read Order with id " + ID, updatedOrder); //$NON-NLS-1$
assertFalse("Objects can't be the same reference after re-reading!", readOrder == updatedOrder); //$NON-NLS-1$
Parameter<String> updatedParam = readOrder.getParameter(BAG_ID, PARAM_STRING_ID);
assertEquals(newStringValue, updatedParam.getValue());
// delete
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getOrderDao(tx).remove(readOrder);
}
// fail to re-read
try (StrolchTransaction tx = persistenceHandler.openTx();) {
Order order = persistenceHandler.getOrderDao(tx).queryBy(TYPE, ID);
assertNull("Should no read Order with id " + ID, order); //$NON-NLS-1$
}
}
}

View File

@ -0,0 +1,92 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.persistence.postgresql.dao.test;
import static li.strolch.model.ModelGenerator.BAG_ID;
import static li.strolch.model.ModelGenerator.PARAM_STRING_ID;
import static li.strolch.model.ModelGenerator.createResource;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import li.strolch.model.Resource;
import li.strolch.model.parameter.Parameter;
import li.strolch.persistence.api.StrolchTransaction;
import org.junit.Test;
public class PostgreSqlResourceDaoTest extends AbstractDaoImplTest {
private static final String ID = "@testResource"; //$NON-NLS-1$
private static final String NAME = "Test Resource"; //$NON-NLS-1$
private static final String TYPE = "Box"; //$NON-NLS-1$
@Test
public void shouldCreateResource() {
// create
Resource newResource = createResource("MyTestResource", "Test Name", "TestType"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getResourceDao(tx).save(newResource);
}
}
@Test
public void shouldCrud() {
// create
Resource newResource = createResource(ID, NAME, TYPE);
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getResourceDao(tx).save(newResource);
}
// read
Resource readResource = null;
try (StrolchTransaction tx = persistenceHandler.openTx();) {
readResource = persistenceHandler.getResourceDao(tx).queryBy(TYPE, ID);
}
assertNotNull("Should read Resource with id " + ID, readResource); //$NON-NLS-1$
// update
Parameter<String> sParam = readResource.getParameter(BAG_ID, PARAM_STRING_ID);
String newStringValue = "Giddiya!"; //$NON-NLS-1$
sParam.setValue(newStringValue);
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getResourceDao(tx).update(readResource);
}
// read updated
Resource updatedResource = null;
try (StrolchTransaction tx = persistenceHandler.openTx();) {
updatedResource = persistenceHandler.getResourceDao(tx).queryBy(TYPE, ID);
}
assertNotNull("Should read Resource with id " + ID, updatedResource); //$NON-NLS-1$
assertFalse("Objects can't be the same reference after re-reading!", readResource == updatedResource); //$NON-NLS-1$
Parameter<String> updatedParam = readResource.getParameter(BAG_ID, PARAM_STRING_ID);
assertEquals(newStringValue, updatedParam.getValue());
// delete
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getResourceDao(tx).remove(readResource);
}
// fail to re-read
try (StrolchTransaction tx = persistenceHandler.openTx();) {
Resource resource = persistenceHandler.getResourceDao(tx).queryBy(TYPE, ID);
assertNull("Should no read Resource with id " + ID, resource); //$NON-NLS-1$
}
}
}

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration debug="false" xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %5p [%t] %C{1} %M - %m%n" />
</layout>
</appender>
<appender name="FILE" class="org.apache.log4j.FileAppender">
<param name="File" value="sample.log"/>
<param name="BufferedIO" value="true" />
<param name="Append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %5p [%t] %C{1} %M - %m%n" />
</layout>
</appender>
<logger name="ch.eitchnet">
<level value="info" />
</logger>
<root>
<priority value="info" />
<appender-ref ref="CONSOLE" />
<!-- appender-ref ref="FILE" / -->
</root>
</log4j:configuration>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<StrolchConfiguration>
<Runtime>
<applicationName>StrolchPersistenceTest</applicationName>
<Properties>
<dataStoreMode>EMPTY</dataStoreMode>
<verbose>true</verbose>
</Properties>
</Runtime>
<Component>
<name>PersistenceHandler</name>
<api>li.strolch.persistence.api.StrolchPersistenceHandler</api>
<impl>li.strolch.persistence.postgresql.PostgreSqlPersistenceHandler</impl>
<Properties>
<allowSchemaCreation>true</allowSchemaCreation>
<allowSchemaDrop>true</allowSchemaDrop>
<db.url>jdbc:postgresql://localhost/testdb</db.url>
<db.username>testuser</db.username>
<db.password>test</db.password>
</Properties>
</Component>
<Component>
<name>ObserverHandler</name>
<api>li.strolch.runtime.observer.ObserverHandler</api>
<impl>li.strolch.runtime.observer.DefaultObserverHandler</impl>
</Component>
</StrolchConfiguration>