From 16b1b727a5be9dadc598dcc4b54d8dbc7ad990a1 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Tue, 17 Nov 2020 15:48:07 +0100 Subject: [PATCH] [New] Added a DataArchiveHandler for archiving objects --- .../persistence/api/DataArchiveHandler.java | 38 ++++ .../persistence/impl/InMemoryActivityDao.java | 123 +++++++++++++ .../impl/InMemoryDataArchiveHandler.java | 46 +++++ .../persistence/impl/InMemoryOrderDao.java | 169 ++++++++++++++++++ .../persistence/impl/InMemoryResourceDao.java | 123 +++++++++++++ .../persistence/impl/InMemoryStrolchDao.java | 145 +++++++++++++++ .../ArchivePostgreSqlActivityDao.java | 20 +++ .../postgresql/ArchivePostgreSqlOrderDao.java | 62 +++++++ .../ArchivePostgreSqlResourceDao.java | 20 +++ .../PostgreSqlDataArchiveHandler.java | 90 ++++++++++ .../archive_db_schema_0.1.0_drop.sql | 2 + .../archive_db_schema_0.1.0_initial.sql | 26 +++ .../archive_db_schema_0.2.0_drop.sql | 2 + .../archive_db_schema_0.2.0_initial.sql | 36 ++++ .../archive_db_schema_0.2.0_migration.sql | 19 ++ .../archive_db_schema_0.3.0_drop.sql | 4 + .../archive_db_schema_0.3.0_initial.sql | 81 +++++++++ .../archive_db_schema_0.3.0_migration.sql | 44 +++++ .../resources/archive_db_version.properties | 2 + 19 files changed, 1052 insertions(+) create mode 100644 li.strolch.agent/src/main/java/li/strolch/persistence/api/DataArchiveHandler.java create mode 100644 li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryActivityDao.java create mode 100644 li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryDataArchiveHandler.java create mode 100644 li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryOrderDao.java create mode 100644 li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryResourceDao.java create mode 100644 li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryStrolchDao.java create mode 100644 li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/ArchivePostgreSqlActivityDao.java create mode 100644 li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/ArchivePostgreSqlOrderDao.java create mode 100644 li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/ArchivePostgreSqlResourceDao.java create mode 100644 li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlDataArchiveHandler.java create mode 100644 li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.1.0_drop.sql create mode 100644 li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.1.0_initial.sql create mode 100644 li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.2.0_drop.sql create mode 100644 li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.2.0_initial.sql create mode 100644 li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.2.0_migration.sql create mode 100644 li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.3.0_drop.sql create mode 100644 li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.3.0_initial.sql create mode 100644 li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.3.0_migration.sql create mode 100644 li.strolch.persistence.postgresql/src/main/resources/archive_db_version.properties diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/api/DataArchiveHandler.java b/li.strolch.agent/src/main/java/li/strolch/persistence/api/DataArchiveHandler.java new file mode 100644 index 000000000..4cb37c8e0 --- /dev/null +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/api/DataArchiveHandler.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013 Robert von Burg + * + * 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.api; + +import java.sql.Connection; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; + +/** + * @author Robert von Burg + */ +public interface DataArchiveHandler { + + void run(StrolchTransaction tx, BiConsumer runnable); + + T runWithResult(StrolchTransaction tx, BiFunction runnable); + + Connection getConnection(StrolchTransaction tx); + + OrderDao getOrderDao(Connection connection, TransactionResult txResult); + + ResourceDao getResourceDao(Connection connection, TransactionResult txResult); + + ActivityDao getActivityDao(Connection connection, TransactionResult txResult); +} diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryActivityDao.java b/li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryActivityDao.java new file mode 100644 index 000000000..69bb9fbe6 --- /dev/null +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryActivityDao.java @@ -0,0 +1,123 @@ +package li.strolch.persistence.impl; + +import java.util.List; +import java.util.Set; + +import li.strolch.model.activity.Activity; +import li.strolch.persistence.api.ActivityDao; +import li.strolch.persistence.api.StrolchPersistenceException; + +public class InMemoryActivityDao implements ActivityDao { + + private static final InMemoryStrolchDao instance = new InMemoryStrolchDao<>(); + + @Override + public boolean supportsPaging() { + return instance.supportsPaging(); + } + + @Override + public long querySize() { + return instance.querySize(); + } + + @Override + public long querySize(String... types) { + return instance.querySize(types); + } + + @Override + public Set queryTypes() throws StrolchPersistenceException { + return instance.queryTypes(); + } + + @Override + public List queryAll() throws StrolchPersistenceException { + return instance.queryAll(); + } + + @Override + public List queryAll(long limit, long offset) throws StrolchPersistenceException { + return instance.queryAll(limit, offset); + } + + @Override + public List queryAll(String... types) throws StrolchPersistenceException { + return instance.queryAll(types); + } + + @Override + public List queryAll(long limit, long offset, String... types) throws StrolchPersistenceException { + return instance.queryAll(limit, offset, types); + } + + @Override + public void save(Activity element) throws StrolchPersistenceException { + instance.save(element); + } + + @Override + public void saveAll(List elements) throws StrolchPersistenceException { + instance.saveAll(elements); + } + + @Override + public void update(Activity element) throws StrolchPersistenceException { + instance.update(element); + } + + @Override + public void updateAll(List elements) throws StrolchPersistenceException { + instance.updateAll(elements); + } + + @Override + public void remove(Activity element) throws StrolchPersistenceException { + instance.remove(element); + } + + @Override + public void removeAll(List elements) throws StrolchPersistenceException { + instance.removeAll(elements); + } + + @Override + public long removeAll() throws StrolchPersistenceException { + return instance.removeAll(); + } + + @Override + public long removeAllBy(String type) throws StrolchPersistenceException { + return instance.removeAllBy(type); + } + + @Override + public Activity queryBy(String type, String id, int version) throws StrolchPersistenceException { + return instance.queryBy(type, id, version); + } + + @Override + public List queryVersionsFor(String type, String id) throws StrolchPersistenceException { + return instance.queryVersionsFor(type, id); + } + + @Override + public int queryLatestVersionFor(String type, String id) throws StrolchPersistenceException { + return instance.queryLatestVersionFor(type, id); + } + + @Override + public long queryVersionsSizeFor(String type, String id) throws StrolchPersistenceException { + return instance.queryVersionsSizeFor(type, id); + } + + @Override + public void removeVersion(Activity element) throws StrolchPersistenceException { + instance.removeVersion(element); + } + + @Override + public void flush() throws StrolchPersistenceException { + instance.flush(); + } +} diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryDataArchiveHandler.java b/li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryDataArchiveHandler.java new file mode 100644 index 000000000..2ff93a709 --- /dev/null +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryDataArchiveHandler.java @@ -0,0 +1,46 @@ +package li.strolch.persistence.impl; + +import java.sql.Connection; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; + +import li.strolch.agent.api.ComponentContainer; +import li.strolch.agent.api.StrolchComponent; +import li.strolch.persistence.api.*; + +public class InMemoryDataArchiveHandler extends StrolchComponent implements DataArchiveHandler { + + public InMemoryDataArchiveHandler(ComponentContainer container, String componentName) { + super(container, componentName); + } + + @Override + public void run(StrolchTransaction tx, BiConsumer runnable) { + runnable.accept(null, null); + } + + @Override + public T runWithResult(StrolchTransaction tx, BiFunction runnable) { + return runnable.apply(null, null); + } + + @Override + public Connection getConnection(StrolchTransaction tx) { + return null; + } + + @Override + public OrderDao getOrderDao(Connection connection, TransactionResult txResult) { + return new InMemoryOrderDao(); + } + + @Override + public ResourceDao getResourceDao(Connection connection, TransactionResult txResult) { + return new InMemoryResourceDao(); + } + + @Override + public ActivityDao getActivityDao(Connection connection, TransactionResult txResult) { + return new InMemoryActivityDao(); + } +} diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryOrderDao.java b/li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryOrderDao.java new file mode 100644 index 000000000..aba8dd857 --- /dev/null +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryOrderDao.java @@ -0,0 +1,169 @@ +package li.strolch.persistence.impl; + +import static java.util.stream.Collectors.toList; + +import java.util.List; +import java.util.Set; + +import li.strolch.model.Order; +import li.strolch.persistence.api.OrderDao; +import li.strolch.persistence.api.StrolchPersistenceException; +import li.strolch.utils.collections.DateRange; + +public class InMemoryOrderDao implements OrderDao { + + private static final InMemoryStrolchDao instance = new InMemoryStrolchDao<>(); + + @Override + public boolean supportsPaging() { + return instance.supportsPaging(); + } + + @Override + public long querySize() { + return instance.querySize(); + } + + @Override + public long querySize(DateRange dateRange) { + return instance.getElements().values().stream().filter(o -> dateRange.contains(o.getDate())).count(); + } + + @Override + public long querySize(String... types) { + return instance.querySize(types); + } + + @Override + public long querySize(DateRange dateRange, String... types) { + return instance.getElements().values().stream().filter(o -> isIn(o, types)) + .filter(o -> dateRange.contains(o.getDate())).count(); + } + + private boolean isIn(Order o, String[] types) { + for (String type : types) { + if (o.getType().equals(type)) + return true; + } + return false; + } + + @Override + public Set queryTypes() throws StrolchPersistenceException { + return instance.queryTypes(); + } + + @Override + public List queryAll() throws StrolchPersistenceException { + return instance.queryAll(); + } + + @Override + public List queryAll(DateRange dateRange) throws StrolchPersistenceException { + return instance.getElements().values().stream().filter(o -> dateRange.contains(o.getDate())).collect(toList()); + } + + @Override + public List queryAll(long limit, long offset) throws StrolchPersistenceException { + return instance.queryAll(limit, offset); + } + + @Override + public List queryAll(DateRange dateRange, long limit, long offset) throws StrolchPersistenceException { + return instance.getElements().values().stream().filter(o -> dateRange.contains(o.getDate())).skip(offset) + .limit(limit).collect(toList()); + } + + @Override + public List queryAll(String... types) throws StrolchPersistenceException { + return instance.queryAll(types); + } + + @Override + public List queryAll(long limit, long offset, String... types) throws StrolchPersistenceException { + return instance.queryAll(limit, offset, types); + } + + @Override + public List queryAll(DateRange dateRange, String... types) throws StrolchPersistenceException { + return instance.getElements().values().stream().filter(o -> isIn(o, types)) + .filter(o -> dateRange.contains(o.getDate())).collect(toList()); + } + + @Override + public List queryAll(DateRange dateRange, long limit, long offset, String... types) + throws StrolchPersistenceException { + return instance.getElements().values().stream().filter(o -> isIn(o, types)) + .filter(o -> dateRange.contains(o.getDate())).skip(offset).limit(limit).collect(toList()); + } + + @Override + public void save(Order element) throws StrolchPersistenceException { + instance.save(element); + } + + @Override + public void saveAll(List elements) throws StrolchPersistenceException { + instance.saveAll(elements); + } + + @Override + public void update(Order element) throws StrolchPersistenceException { + instance.update(element); + } + + @Override + public void updateAll(List elements) throws StrolchPersistenceException { + instance.updateAll(elements); + } + + @Override + public void remove(Order element) throws StrolchPersistenceException { + instance.remove(element); + } + + @Override + public void removeAll(List elements) throws StrolchPersistenceException { + instance.removeAll(elements); + } + + @Override + public long removeAll() throws StrolchPersistenceException { + return instance.removeAll(); + } + + @Override + public long removeAllBy(String type) throws StrolchPersistenceException { + return instance.removeAllBy(type); + } + + @Override + public Order queryBy(String type, String id, int version) throws StrolchPersistenceException { + return instance.queryBy(type, id, version); + } + + @Override + public List queryVersionsFor(String type, String id) throws StrolchPersistenceException { + return instance.queryVersionsFor(type, id); + } + + @Override + public int queryLatestVersionFor(String type, String id) throws StrolchPersistenceException { + return instance.queryLatestVersionFor(type, id); + } + + @Override + public long queryVersionsSizeFor(String type, String id) throws StrolchPersistenceException { + return instance.queryVersionsSizeFor(type, id); + } + + @Override + public void removeVersion(Order element) throws StrolchPersistenceException { + instance.removeVersion(element); + } + + @Override + public void flush() throws StrolchPersistenceException { + instance.flush(); + } +} diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryResourceDao.java b/li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryResourceDao.java new file mode 100644 index 000000000..0deefcd3c --- /dev/null +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryResourceDao.java @@ -0,0 +1,123 @@ +package li.strolch.persistence.impl; + +import java.util.List; +import java.util.Set; + +import li.strolch.model.Resource; +import li.strolch.persistence.api.ResourceDao; +import li.strolch.persistence.api.StrolchPersistenceException; + +public class InMemoryResourceDao implements ResourceDao { + + private static final InMemoryStrolchDao instance = new InMemoryStrolchDao<>(); + + @Override + public boolean supportsPaging() { + return instance.supportsPaging(); + } + + @Override + public long querySize() { + return instance.querySize(); + } + + @Override + public long querySize(String... types) { + return instance.querySize(types); + } + + @Override + public Set queryTypes() throws StrolchPersistenceException { + return instance.queryTypes(); + } + + @Override + public List queryAll() throws StrolchPersistenceException { + return instance.queryAll(); + } + + @Override + public List queryAll(long limit, long offset) throws StrolchPersistenceException { + return instance.queryAll(limit, offset); + } + + @Override + public List queryAll(String... types) throws StrolchPersistenceException { + return instance.queryAll(types); + } + + @Override + public List queryAll(long limit, long offset, String... types) throws StrolchPersistenceException { + return instance.queryAll(limit, offset, types); + } + + @Override + public void save(Resource element) throws StrolchPersistenceException { + instance.save(element); + } + + @Override + public void saveAll(List elements) throws StrolchPersistenceException { + instance.saveAll(elements); + } + + @Override + public void update(Resource element) throws StrolchPersistenceException { + instance.update(element); + } + + @Override + public void updateAll(List elements) throws StrolchPersistenceException { + instance.updateAll(elements); + } + + @Override + public void remove(Resource element) throws StrolchPersistenceException { + instance.remove(element); + } + + @Override + public void removeAll(List elements) throws StrolchPersistenceException { + instance.removeAll(elements); + } + + @Override + public long removeAll() throws StrolchPersistenceException { + return instance.removeAll(); + } + + @Override + public long removeAllBy(String type) throws StrolchPersistenceException { + return instance.removeAllBy(type); + } + + @Override + public Resource queryBy(String type, String id, int version) throws StrolchPersistenceException { + return instance.queryBy(type, id, version); + } + + @Override + public List queryVersionsFor(String type, String id) throws StrolchPersistenceException { + return instance.queryVersionsFor(type, id); + } + + @Override + public int queryLatestVersionFor(String type, String id) throws StrolchPersistenceException { + return instance.queryLatestVersionFor(type, id); + } + + @Override + public long queryVersionsSizeFor(String type, String id) throws StrolchPersistenceException { + return instance.queryVersionsSizeFor(type, id); + } + + @Override + public void removeVersion(Resource element) throws StrolchPersistenceException { + instance.removeVersion(element); + } + + @Override + public void flush() throws StrolchPersistenceException { + instance.flush(); + } +} diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryStrolchDao.java b/li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryStrolchDao.java new file mode 100644 index 000000000..8d4f19df5 --- /dev/null +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/impl/InMemoryStrolchDao.java @@ -0,0 +1,145 @@ +package li.strolch.persistence.impl; + +import static java.util.stream.Collectors.toList; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import li.strolch.model.StrolchRootElement; +import li.strolch.persistence.api.StrolchDao; +import li.strolch.persistence.api.StrolchPersistenceException; +import li.strolch.utils.collections.MapOfLists; + +public class InMemoryStrolchDao implements StrolchDao { + + private final MapOfLists elements; + + public InMemoryStrolchDao() { + this.elements = new MapOfLists<>(); + } + + public MapOfLists getElements() { + return this.elements; + } + + @Override + public boolean supportsPaging() { + return true; + } + + @Override + public long querySize() { + return this.elements.size(); + } + + @Override + public long querySize(String... types) { + long size = 0L; + for (String type : types) { + size += this.elements.size(type); + } + return size; + } + + @Override + public Set queryTypes() throws StrolchPersistenceException { + return this.elements.keySet(); + } + + @Override + public List queryAll() throws StrolchPersistenceException { + return this.elements.values(); + } + + @Override + public List queryAll(long limit, long offset) throws StrolchPersistenceException { + return this.elements.values().stream().skip(offset).limit(limit).collect(toList()); + } + + @Override + public List queryAll(String... types) throws StrolchPersistenceException { + List values = new ArrayList<>(); + for (String type : types) { + values.addAll(this.elements.getList(type)); + } + return values; + } + + @Override + public List queryAll(long limit, long offset, String... types) throws StrolchPersistenceException { + return this.queryAll(types).stream().skip(offset).limit(limit).collect(toList()); + } + + @Override + public void save(T element) throws StrolchPersistenceException { + this.elements.addElement(element.getType(), element); + } + + @Override + public void saveAll(List elements) throws StrolchPersistenceException { + elements.forEach(this::save); + } + + @Override + public void update(T element) throws StrolchPersistenceException { + save(element); + } + + @Override + public void updateAll(List elements) throws StrolchPersistenceException { + saveAll(elements); + } + + @Override + public void remove(T element) throws StrolchPersistenceException { + this.elements.removeElement(element.getType(), element); + } + + @Override + public void removeAll(List elements) throws StrolchPersistenceException { + elements.forEach(this::remove); + } + + @Override + public long removeAll() throws StrolchPersistenceException { + int size = this.elements.size(); + this.elements.clear(); + return size; + } + + @Override + public long removeAllBy(String type) throws StrolchPersistenceException { + return this.elements.removeList(type).size(); + } + + @Override + public T queryBy(String type, String id, int version) throws StrolchPersistenceException { + throw new UnsupportedOperationException("Versioning is not supported!"); + } + + @Override + public List queryVersionsFor(String type, String id) throws StrolchPersistenceException { + throw new UnsupportedOperationException("Versioning is not supported!"); + } + + @Override + public int queryLatestVersionFor(String type, String id) throws StrolchPersistenceException { + throw new UnsupportedOperationException("Versioning is not supported!"); + } + + @Override + public long queryVersionsSizeFor(String type, String id) throws StrolchPersistenceException { + throw new UnsupportedOperationException("Versioning is not supported!"); + } + + @Override + public void removeVersion(T element) throws StrolchPersistenceException { + throw new UnsupportedOperationException("Versioning is not supported!"); + } + + @Override + public void flush() throws StrolchPersistenceException { + // do nothing + } +} diff --git a/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/ArchivePostgreSqlActivityDao.java b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/ArchivePostgreSqlActivityDao.java new file mode 100644 index 000000000..94454f580 --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/ArchivePostgreSqlActivityDao.java @@ -0,0 +1,20 @@ +package li.strolch.persistence.postgresql; + +import java.sql.Connection; + +import li.strolch.persistence.api.TransactionResult; + +public class ArchivePostgreSqlActivityDao extends PostgreSqlActivityDao { + + public static final String TABLE_NAME = "archive_activities"; + + public ArchivePostgreSqlActivityDao(DataType dataType, Connection connection, TransactionResult txResult, + boolean versioningEnabled) { + super(dataType, connection, txResult, versioningEnabled); + } + + @Override + protected String getTableName() { + return TABLE_NAME; + } +} diff --git a/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/ArchivePostgreSqlOrderDao.java b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/ArchivePostgreSqlOrderDao.java new file mode 100644 index 000000000..2611f313e --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/ArchivePostgreSqlOrderDao.java @@ -0,0 +1,62 @@ +package li.strolch.persistence.postgresql; + +import java.sql.*; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import li.strolch.model.Order; +import li.strolch.persistence.api.StrolchPersistenceException; +import li.strolch.persistence.api.TransactionResult; + +public class ArchivePostgreSqlOrderDao extends PostgreSqlOrderDao { + + public static final String TABLE_NAME = "archive_orders"; + private boolean descending; + + public ArchivePostgreSqlOrderDao(DataType dataType, Connection connection, TransactionResult txResult, + boolean versioningEnabled) { + super(dataType, connection, txResult, versioningEnabled); + } + + @Override + protected String getTableName() { + return TABLE_NAME; + } + + public void setDescending(boolean descending) { + this.descending = descending; + } + + @Override + public List queryAll(long limit, long offset, String... types) { + if (types.length == 0) + return queryAll(limit, offset); + + List list = new ArrayList<>(); + + String ordering = this.descending ? "DESC" : "ASC"; + String sql = "select id, type, asxml from {0} where type = ANY(?) and latest = true order by date " + ordering + + " limit {1,number,#} offset {2,number,#}"; + sql = MessageFormat.format(sql, TABLE_NAME, limit, offset); + + try (PreparedStatement statement = this.connection.prepareStatement(sql)) { + + Array typesArray = statement.getConnection().createArrayOf("varchar", types); + statement.setArray(1, typesArray); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + String id = result.getString("id"); + String type = result.getString("type"); + list.add(parseDbObject(result, id, type)); + } + + return list; + } + + } catch (SQLException e) { + throw new StrolchPersistenceException("Failed to query types due to: " + e.getMessage(), e); + } + } +} diff --git a/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/ArchivePostgreSqlResourceDao.java b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/ArchivePostgreSqlResourceDao.java new file mode 100644 index 000000000..442825b61 --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/ArchivePostgreSqlResourceDao.java @@ -0,0 +1,20 @@ +package li.strolch.persistence.postgresql; + +import java.sql.Connection; + +import li.strolch.persistence.api.TransactionResult; + +public class ArchivePostgreSqlResourceDao extends PostgreSqlResourceDao { + + public static final String TABLE_NAME = "archive_resources"; + + public ArchivePostgreSqlResourceDao(DataType dataType, Connection connection, TransactionResult txResult, + boolean versioningEnabled) { + super(dataType, connection, txResult, versioningEnabled); + } + + @Override + protected String getTableName() { + return TABLE_NAME; + } +} diff --git a/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlDataArchiveHandler.java b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlDataArchiveHandler.java new file mode 100644 index 000000000..901a7309a --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlDataArchiveHandler.java @@ -0,0 +1,90 @@ +package li.strolch.persistence.postgresql; + +import static li.strolch.db.DbConstants.*; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.util.Date; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; + +import li.strolch.agent.api.ComponentContainer; +import li.strolch.agent.api.StrolchComponent; +import li.strolch.db.DbSchemaVersionCheck; +import li.strolch.persistence.api.*; +import li.strolch.runtime.configuration.ComponentConfiguration; + +public class PostgreSqlDataArchiveHandler extends StrolchComponent implements DataArchiveHandler { + + private static final String SCRIPT_PREFIX = "archive"; + + public PostgreSqlDataArchiveHandler(ComponentContainer container, String componentName) { + super(container, componentName); + } + + @Override + public void start() throws Exception { + + PostgreSqlPersistenceHandler persistenceHandler = (PostgreSqlPersistenceHandler) getComponent( + PersistenceHandler.class); + Map dsMap = persistenceHandler.getDataSources(); + + ComponentConfiguration configuration = persistenceHandler.getConfiguration(); + + boolean allowSchemaCreation = configuration.getBoolean(PROP_ALLOW_SCHEMA_CREATION, Boolean.FALSE); + boolean allowSchemaMigration = configuration.getBoolean(PROP_ALLOW_SCHEMA_MIGRATION, Boolean.FALSE); + boolean allowSchemaDrop = configuration.getBoolean(PROP_ALLOW_SCHEMA_DROP, Boolean.FALSE); + + DbSchemaVersionCheck schemaVersionCheck = new DbSchemaVersionCheck(SCRIPT_PREFIX, this.getClass(), + allowSchemaCreation, allowSchemaMigration, allowSchemaDrop); + schemaVersionCheck.checkSchemaVersion(dsMap); + + super.start(); + } + + @Override + public Connection getConnection(StrolchTransaction tx) { + PostgreSqlPersistenceHandler persistenceHandler = (PostgreSqlPersistenceHandler) getComponent( + PersistenceHandler.class); + return persistenceHandler.getConnection(tx.getRealmName()); + } + + @Override + public void run(StrolchTransaction tx, BiConsumer runnable) { + try (Connection connection = getConnection(tx)) { + TransactionResult txResult = new TransactionResult(tx.getRealmName(), System.nanoTime(), new Date()); + runnable.accept(connection, txResult); + connection.commit(); + } catch (Exception e) { + throw new StrolchPersistenceException("Archive DB Connection failed", e); + } + } + + @Override + public T runWithResult(StrolchTransaction tx, BiFunction runnable) { + try (Connection connection = getConnection(tx)) { + TransactionResult txResult = new TransactionResult(tx.getRealmName(), System.nanoTime(), new Date()); + T t = runnable.apply(connection, txResult); + connection.commit(); + return t; + } catch (Exception e) { + throw new StrolchPersistenceException("Archive DB Connection failed", e); + } + } + + @Override + public OrderDao getOrderDao(Connection connection, TransactionResult txResult) { + return new ArchivePostgreSqlOrderDao(DataType.xml, connection, txResult, false); + } + + @Override + public ResourceDao getResourceDao(Connection connection, TransactionResult txResult) { + return new ArchivePostgreSqlResourceDao(DataType.xml, connection, txResult, false); + } + + @Override + public ActivityDao getActivityDao(Connection connection, TransactionResult txResult) { + return new ArchivePostgreSqlActivityDao(DataType.xml, connection, txResult, false); + } +} diff --git a/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.1.0_drop.sql b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.1.0_drop.sql new file mode 100644 index 000000000..30b58ff3a --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.1.0_drop.sql @@ -0,0 +1,2 @@ + +DROP TABLE IF EXISTS archive_orders; diff --git a/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.1.0_initial.sql b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.1.0_initial.sql new file mode 100644 index 000000000..2f6145f36 --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.1.0_initial.sql @@ -0,0 +1,26 @@ + +CREATE TABLE IF NOT EXISTS archive_orders ( + id varchar(255) not null, + version integer not null, + created_by varchar(255) not null, + created_at timestamp with time zone not null, + deleted boolean, + latest boolean not null, + name varchar(255), + type varchar(255), + state order_state, + date timestamp with time zone, + asxml xml not null, + + PRIMARY KEY (id, version) +); + + +INSERT INTO db_version + (version, app, description, created) +values( + '0.1.0', + 'archive', + 'Initial schema version', + CURRENT_TIMESTAMP +); diff --git a/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.2.0_drop.sql b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.2.0_drop.sql new file mode 100644 index 000000000..30b58ff3a --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.2.0_drop.sql @@ -0,0 +1,2 @@ + +DROP TABLE IF EXISTS archive_orders; diff --git a/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.2.0_initial.sql b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.2.0_initial.sql new file mode 100644 index 000000000..94c3c6569 --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.2.0_initial.sql @@ -0,0 +1,36 @@ + +CREATE TABLE IF NOT EXISTS archive_orders ( + id varchar(255) not null, + version integer not null, + created_by varchar(255) not null, + created_at timestamp with time zone not null, + updated_at timestamp with time zone not null, + deleted boolean, + latest boolean not null, + name varchar(255), + type varchar(255), + state order_state, + date timestamp with time zone, + asxml xml not null, + + PRIMARY KEY (id, version) +); + + +INSERT INTO db_version + (version, app, description, created) +values( + '0.1.0', + 'archive', + 'Initial schema version', + CURRENT_TIMESTAMP +); + +INSERT INTO db_version + (version, app, description, created) +values( + '0.2.0', + 'ipsc_archive', + 'Added updated_at column', + CURRENT_TIMESTAMP +); diff --git a/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.2.0_migration.sql b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.2.0_migration.sql new file mode 100644 index 000000000..3baede7e1 --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.2.0_migration.sql @@ -0,0 +1,19 @@ + +-- add version columns +ALTER TABLE archive_orders ADD COLUMN updated_at timestamp with time zone; + +-- set initial values for new columns +UPDATE archive_orders SET updated_at = CURRENT_TIMESTAMP where updated_at IS NULL; + +-- make columns not null +ALTER TABLE archive_orders ALTER COLUMN updated_at SET NOT NULL; + + +INSERT INTO db_version + (version, app, description, created) +values( + '0.2.0', + 'archive', + 'Added updated_at column', + CURRENT_TIMESTAMP +); diff --git a/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.3.0_drop.sql b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.3.0_drop.sql new file mode 100644 index 000000000..3108a6240 --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.3.0_drop.sql @@ -0,0 +1,4 @@ + +DROP TABLE IF EXISTS archive_resources; +DROP TABLE IF EXISTS archive_orders; +DROP TABLE IF EXISTS archive_activities; diff --git a/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.3.0_initial.sql b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.3.0_initial.sql new file mode 100644 index 000000000..e25325978 --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.3.0_initial.sql @@ -0,0 +1,81 @@ + +-- ORDERS +CREATE TABLE IF NOT EXISTS archive_orders ( + id varchar(255) not null, + version integer not null, + created_by varchar(255) not null, + created_at timestamp with time zone not null, + updated_at timestamp with time zone not null, + deleted boolean, + latest boolean not null, + name varchar(255), + type varchar(255), + state order_state, + date timestamp with time zone, + asxml xml, + asjson json, + + PRIMARY KEY (id, version) +); + +-- RESOURCES +CREATE TABLE IF NOT EXISTS archive_resources ( + id varchar(255) not null, + version integer not null, + created_by varchar(255) not null, + created_at timestamp with time zone not null, + updated_at timestamp with time zone not null, + deleted boolean not null, + latest boolean not null, + name varchar(255) not null, + type varchar(255) not null, + asxml xml, + asjson json, + + PRIMARY KEY (id, version) +); + +-- ACTIVITIES +CREATE TABLE IF NOT EXISTS archive_activities ( + id varchar(255) not null, + version integer not null, + created_by varchar(255) not null, + created_at timestamp with time zone not null, + updated_at timestamp with time zone not null, + deleted boolean not null, + latest boolean not null, + name varchar(255) not null, + type varchar(255) not null, + state order_state, + asxml xml, + asjson json, + + PRIMARY KEY (id, version) +); + +INSERT INTO db_version + (version, app, description, created) +values( + '0.1.0', + 'archive', + 'Initial schema version', + CURRENT_TIMESTAMP +); + +INSERT INTO db_version + (version, app, description, created) +values( + '0.2.0', + 'archive', + 'Added updated_at column', + CURRENT_TIMESTAMP +); + +INSERT INTO db_version + (version, app, description, created) +values( + '0.3.0', + 'archive', + 'Added resources and activities', + CURRENT_TIMESTAMP +); diff --git a/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.3.0_migration.sql b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.3.0_migration.sql new file mode 100644 index 000000000..6e8c5e0c0 --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/resources/archive_db_schema_0.3.0_migration.sql @@ -0,0 +1,44 @@ + +-- RESOURCES +CREATE TABLE IF NOT EXISTS archive_resources ( + id varchar(255) not null, + version integer not null, + created_by varchar(255) not null, + created_at timestamp with time zone not null, + updated_at timestamp with time zone not null, + deleted boolean not null, + latest boolean not null, + name varchar(255) not null, + type varchar(255) not null, + asxml xml, + asjson json, + + PRIMARY KEY (id, version) +); + +-- ACTIVITIES +CREATE TABLE IF NOT EXISTS archive_activities ( + id varchar(255) not null, + version integer not null, + created_by varchar(255) not null, + created_at timestamp with time zone not null, + updated_at timestamp with time zone not null, + deleted boolean not null, + latest boolean not null, + name varchar(255) not null, + type varchar(255) not null, + state order_state, + asxml xml, + asjson json, + + PRIMARY KEY (id, version) +); + +INSERT INTO db_version + (version, app, description, created) +values( + '0.3.0', + 'archive', + 'Added resources and activities', + CURRENT_TIMESTAMP +); diff --git a/li.strolch.persistence.postgresql/src/main/resources/archive_db_version.properties b/li.strolch.persistence.postgresql/src/main/resources/archive_db_version.properties new file mode 100644 index 000000000..b2738f3b3 --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/resources/archive_db_version.properties @@ -0,0 +1,2 @@ +# Property file defining what the currently expected version is supposed to be +db_version=0.3.0