mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
|
||||
name: JDK EA
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '39 6 * * 1,3,5'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java_version: [17,18,19,loom,valhalla,metropolis,panama]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Java
|
||||
uses: oracle-actions/setup-java@v1
|
||||
with:
|
||||
website: jdk.java.net
|
||||
release: ${{ matrix.java_version }}
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: maven-cache
|
||||
with:
|
||||
path:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: Build with Maven
|
||||
run: mvn package
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
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 "[]"
|
||||
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
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2012 Authors
|
||||
|
||||
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.
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
EbeanORM
|
||||
|
||||
Copyright 2012 Authors.
|
||||
|
||||
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.
|
||||
+1
-1
@@ -106,7 +106,7 @@
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>1.0</version>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -98,4 +98,14 @@ public class Version<T> {
|
||||
public Map<String, ValuePair> getDiff() {
|
||||
return diff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Version{" +
|
||||
"bean=" + bean +
|
||||
", start=" + start +
|
||||
", end=" + end +
|
||||
", diff=" + diff +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -829,7 +829,7 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
/**
|
||||
* Load the bean when it is a reference.
|
||||
*/
|
||||
protected void loadBean(int loadProperty) {
|
||||
void loadBean(int loadProperty) {
|
||||
lock.lock();
|
||||
try {
|
||||
if (beanLoader == null) {
|
||||
@@ -886,7 +886,7 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* Helper method to check if two objects are equal.
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
protected static boolean notEqual(Object obj1, Object obj2) {
|
||||
static boolean notEqual(Object obj1, Object obj2) {
|
||||
if (obj1 == null) {
|
||||
return (obj2 != null);
|
||||
}
|
||||
|
||||
@@ -606,13 +606,6 @@ public class DatabasePlatform {
|
||||
this.useMigrationStoredProcedures = useMigrationStoredProcedures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normally not needed - overridden in CockroachPlatform.
|
||||
*/
|
||||
public boolean isDdlAutoCommit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DB identity/sequence features for this platform.
|
||||
*
|
||||
|
||||
@@ -18,6 +18,8 @@ public class ClickHousePlatform extends DatabasePlatform {
|
||||
//this.exceptionTranslator =
|
||||
this.nativeUuidType = true;
|
||||
this.dbDefaultValue.setNow("now()");
|
||||
this.dbDefaultValue.setFalse("0");
|
||||
this.dbDefaultValue.setTrue("1");
|
||||
|
||||
this.dbIdentity.setIdType(IdType.IDENTITY);
|
||||
this.dbIdentity.setSupportsGetGeneratedKeys(false);
|
||||
|
||||
@@ -11,14 +11,7 @@ public class CockroachPlatform extends PostgresPlatform {
|
||||
public CockroachPlatform() {
|
||||
super();
|
||||
this.platform = Platform.COCKROACH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Needs a commit after create index such that alter table add foreign key ... succeeds.
|
||||
*/
|
||||
@Override
|
||||
public boolean isDdlAutoCommit() {
|
||||
return false;
|
||||
this.historySupport = null; // not yet implemented in DDL
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ public abstract class BaseDB2Platform extends DatabasePlatform {
|
||||
.addDataIntegrity("23502","23503","23504","23511","23512","23511","42917","23515")
|
||||
.build();
|
||||
|
||||
historySupport = new DB2HistorySupport();
|
||||
booleanDbType = Types.BOOLEAN;
|
||||
dbTypeMap.put(DbType.TINYINT, new DbPlatformType("smallint", false));
|
||||
dbTypeMap.put(DbType.INTEGER, new DbPlatformType("integer", false));
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package io.ebean.config.dbplatform.db2;
|
||||
|
||||
import io.ebean.config.dbplatform.DbStandardHistorySupport;
|
||||
|
||||
/**
|
||||
* DB2 based history support.
|
||||
*/
|
||||
public class DB2HistorySupport extends DbStandardHistorySupport {
|
||||
|
||||
@Override
|
||||
public String getAsOfViewSuffix(String asOfViewSuffix) {
|
||||
return " for system_time as of ?";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionsBetweenSuffix(String asOfViewSuffix) {
|
||||
return " for system_time between ? and ?";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSysPeriodLower(String tableAlias, String sysPeriod) {
|
||||
return tableAlias + "." + sysPeriod + "_start";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSysPeriodUpper(String tableAlias, String sysPeriod) {
|
||||
return tableAlias + "." + sysPeriod + "_end";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
@@ -76,7 +77,7 @@ public class H2HistoryTrigger implements Trigger {
|
||||
public void fire(Connection connection, Object[] oldRow, Object[] newRow) throws SQLException {
|
||||
if (oldRow != null) {
|
||||
// a delete or update event
|
||||
Timestamp now = new Timestamp(System.currentTimeMillis());
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
oldRow[effectEndPosition] = now;
|
||||
if (newRow != null) {
|
||||
// update event. Set the effective start timestamp to now.
|
||||
|
||||
@@ -92,4 +92,8 @@ public class HanaPlatform extends DatabasePlatform {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseMigrationStoredProcedures() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.ebean.plugin;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* General deployment information. This is used in {@link CustomDeployParser}.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.ebean.plugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public interface DeployBeanPropertyMeta {
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package io.ebean.util;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>1.0</version>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
+3
-3
@@ -23,7 +23,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-runner</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>${ebean-ddl-runner.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -130,7 +130,7 @@
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.3.2</version>
|
||||
<version>42.3.3</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>1.0</version>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ package io.ebeaninternal.api;
|
||||
import io.ebean.*;
|
||||
import io.ebean.bean.BeanCollectionLoader;
|
||||
import io.ebean.bean.CallOrigin;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.event.readaudit.ReadAuditLogger;
|
||||
import io.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import io.ebean.meta.MetricVisitor;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebeaninternal.api;
|
||||
|
||||
import io.ebean.meta.QueryPlanRequest;
|
||||
import io.ebeaninternal.server.type.bindcapture.BindCapture;
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import io.ebean.event.changelog.BeanChange;
|
||||
import io.ebean.event.changelog.ChangeSet;
|
||||
import io.ebean.event.changelog.ChangeType;
|
||||
import io.ebean.text.json.JsonContext;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
@@ -15,8 +15,6 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
/**
|
||||
* Wraps the objects involved in executing a SQL / Relational Query.
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,6 @@ import io.avaje.classpath.scanner.ClassPathScannerFactory;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
|
||||
@@ -106,7 +106,9 @@ final class DScriptRunner implements ScriptRunner {
|
||||
try (Connection connection = obtainConnection()) {
|
||||
DdlRunner runner = new DdlRunner(useAutoCommit, scriptName, platformName);
|
||||
runner.runAll(content, connection);
|
||||
connection.commit();
|
||||
if (!connection.getAutoCommit()) {
|
||||
connection.commit();
|
||||
}
|
||||
runner.runNonTransactional(connection);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package io.ebeaninternal.server.core;
|
||||
|
||||
import io.ebean.CacheMode;
|
||||
import io.ebean.ExpressionList;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.bean.EntityBeanIntercept;
|
||||
@@ -40,14 +39,14 @@ final class DefaultBeanLoader {
|
||||
}
|
||||
|
||||
void loadMany(BeanCollection<?> bc, boolean onlyIds) {
|
||||
loadManyInternal(bc.getOwnerBean(), bc.getPropertyName(), null, false, onlyIds);
|
||||
loadManyInternal(bc.getOwnerBean(), bc.getPropertyName(), false, onlyIds);
|
||||
}
|
||||
|
||||
void refreshMany(EntityBean parentBean, String propertyName) {
|
||||
loadManyInternal(parentBean, propertyName, null, true, false);
|
||||
loadManyInternal(parentBean, propertyName, true, false);
|
||||
}
|
||||
|
||||
private void loadManyInternal(EntityBean parentBean, String propertyName, Transaction t, boolean refresh, boolean onlyIds) {
|
||||
private void loadManyInternal(EntityBean parentBean, String propertyName, boolean refresh, boolean onlyIds) {
|
||||
EntityBeanIntercept ebi = parentBean._ebean_getIntercept();
|
||||
PersistenceContext pc = ebi.getPersistenceContext();
|
||||
BeanDescriptor<?> parentDesc = server.descriptor(parentBean.getClass());
|
||||
@@ -106,7 +105,7 @@ final class DefaultBeanLoader {
|
||||
query.setReadOnly(true);
|
||||
}
|
||||
|
||||
server.findOne(query, t);
|
||||
server.findOne(query, null);
|
||||
if (beanCollection != null) {
|
||||
if (beanCollection.checkEmptyLazyLoad()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
@@ -200,7 +199,7 @@ final class DefaultBeanLoader {
|
||||
query.setLazyLoadProperty(ebi.getLazyLoadProperty());
|
||||
if (draft) {
|
||||
query.asDraft();
|
||||
} else {
|
||||
} else if (mode == SpiQuery.Mode.LAZYLOAD_BEAN) {
|
||||
query.setIncludeSoftDeletes();
|
||||
}
|
||||
if (embeddedOwnerIndex > -1) {
|
||||
|
||||
@@ -992,7 +992,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
*/
|
||||
public String renderDbType(DbPlatformType dbType, boolean strict) {
|
||||
if (dbColumnDefn != null) {
|
||||
if(dbColumnDefn.endsWith(";")) {
|
||||
if (dbColumnDefn.endsWith(";")) {
|
||||
return dbColumnDefn + dbType.renderType(dbLength, dbScale, strict);
|
||||
}
|
||||
return dbColumnDefn;
|
||||
@@ -1165,7 +1165,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this <code>isLob()</code> or the type will effectively map to a lob.
|
||||
* Returns true if this <code>isLob()</code> or the type will effectively map to a lob.
|
||||
*/
|
||||
@Override
|
||||
public boolean isDbLob() {
|
||||
@@ -1173,17 +1173,17 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
return true;
|
||||
}
|
||||
switch (dbType) {
|
||||
case DbPlatformType.JSON:
|
||||
case DbPlatformType.JSONB:
|
||||
return dbLength == 0; // must be analog to DbPlatformTypeMapping.lookup
|
||||
case DbPlatformType.JSONBlob:
|
||||
case DbPlatformType.JSONClob:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
case DbPlatformType.JSON:
|
||||
case DbPlatformType.JSONB:
|
||||
return dbLength == 0; // must be analog to DbPlatformTypeMapping.lookup
|
||||
case DbPlatformType.JSONBlob:
|
||||
case DbPlatformType.JSONClob:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean isLobType(int type) {
|
||||
switch (type) {
|
||||
case Types.CLOB:
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
package io.ebeaninternal.server.deploy.parse;
|
||||
|
||||
import io.ebean.annotation.Aggregation;
|
||||
import io.ebean.annotation.Avg;
|
||||
import io.ebean.annotation.DbMigration;
|
||||
import io.ebean.annotation.Index;
|
||||
import io.ebean.annotation.Indices;
|
||||
import io.ebean.annotation.Max;
|
||||
import io.ebean.annotation.Min;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.annotation.Sum;
|
||||
import io.ebean.config.NamingConvention;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.util.AnnotationUtil;
|
||||
@@ -20,7 +15,6 @@ import javax.persistence.JoinColumns;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ final class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext
|
||||
}
|
||||
}
|
||||
|
||||
protected void register(EntityBeanIntercept ebi) {
|
||||
void register(EntityBeanIntercept ebi) {
|
||||
if (currentBuffer.isFull()) {
|
||||
currentBuffer = createBuffer(batchSize);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.ebeaninternal.server.query;
|
||||
import io.ebean.QueryIterator;
|
||||
import io.ebeaninternal.server.core.OrmQueryRequest;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.ebeaninternal.server.query;
|
||||
import io.ebean.QueryIterator;
|
||||
import io.ebeaninternal.server.core.OrmQueryRequest;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
@@ -13,30 +13,22 @@ import java.util.Set;
|
||||
final class SqlTree {
|
||||
|
||||
private final SqlTreeNode rootNode;
|
||||
|
||||
/**
|
||||
* Property if resultSet contains master and detail rows.
|
||||
*/
|
||||
private final STreePropertyAssocMany manyProperty;
|
||||
|
||||
private final String distinctOn;
|
||||
|
||||
private final String selectSql;
|
||||
|
||||
private final String fromSql;
|
||||
|
||||
private final String groupBy;
|
||||
|
||||
/**
|
||||
* Encrypted Properties require additional binding.
|
||||
*/
|
||||
private final STreeProperty[] encryptedProps;
|
||||
|
||||
/**
|
||||
* Where clause for inheritance.
|
||||
*/
|
||||
private final String inheritanceWhereSql;
|
||||
|
||||
private final boolean noJoins;
|
||||
|
||||
/**
|
||||
@@ -44,7 +36,6 @@ final class SqlTree {
|
||||
*/
|
||||
SqlTree(SqlTreeNode rootNode, String distinctOn, String selectSql, String fromSql, String groupBy, String inheritanceWhereSql,
|
||||
STreeProperty[] encryptedProps, STreePropertyAssocMany manyProperty, boolean includeJoins) {
|
||||
|
||||
this.rootNode = rootNode;
|
||||
this.distinctOn = distinctOn;
|
||||
this.selectSql = selectSql;
|
||||
|
||||
@@ -15,22 +15,14 @@ import java.util.TreeSet;
|
||||
final class SqlTreeAlias {
|
||||
|
||||
private final SpiQuery.TemporalMode temporalMode;
|
||||
|
||||
private int counter;
|
||||
|
||||
private int manyWhereCounter;
|
||||
|
||||
private final TreeSet<String> joinProps = new TreeSet<>();
|
||||
|
||||
private HashSet<String> embeddedPropertyJoins;
|
||||
|
||||
private final TreeSet<String> manyWhereJoinProps = new TreeSet<>();
|
||||
|
||||
private final HashMap<String, String> aliasMap = new HashMap<>();
|
||||
|
||||
private final HashMap<String, String> manyWhereAliasMap = new HashMap<>();
|
||||
|
||||
private final String rootTableAlias;
|
||||
private int counter;
|
||||
private int manyWhereCounter;
|
||||
|
||||
SqlTreeAlias(String rootTableAlias, SpiQuery.TemporalMode temporalMode) {
|
||||
this.rootTableAlias = rootTableAlias;
|
||||
|
||||
@@ -224,8 +224,7 @@ public final class SqlTreeBuilder {
|
||||
* Recursively build the query tree depending on what leaves in the tree
|
||||
* should be included.
|
||||
*/
|
||||
private SqlTreeNode buildSelectChain(String prefix, STreePropertyAssoc prop,
|
||||
STreeType desc, List<SqlTreeNode> joinList) {
|
||||
private SqlTreeNode buildSelectChain(String prefix, STreePropertyAssoc prop, STreeType desc, List<SqlTreeNode> joinList) {
|
||||
List<SqlTreeNode> myJoinList = new ArrayList<>();
|
||||
List<STreePropertyAssocOne> extraProps = new ArrayList<>();
|
||||
for (STreePropertyAssocOne one : desc.propsOne()) {
|
||||
@@ -256,7 +255,7 @@ public final class SqlTreeBuilder {
|
||||
}
|
||||
addManyWhereJoins(myJoinList);
|
||||
}
|
||||
extraProps.forEach(props::add); //addExtra
|
||||
extraProps.forEach(props::addExtra);
|
||||
|
||||
if (!rawSql && manyWhereJoins.isFormulaWithJoin(prefix)) {
|
||||
for (String property : manyWhereJoins.getFormulaJoinProperties(prefix)) {
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package io.ebeaninternal.server.query;
|
||||
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.core.type.ScalarType;
|
||||
import io.ebean.util.SplitName;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
import io.ebeaninternal.server.deploy.DbReadContext;
|
||||
import io.ebeaninternal.server.deploy.DbSqlContext;
|
||||
import io.ebeaninternal.server.deploy.TableJoin;
|
||||
|
||||
|
||||
-3
@@ -1,9 +1,6 @@
|
||||
package io.ebeaninternal.server.query;
|
||||
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.core.type.ScalarType;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.deploy.DbReadContext;
|
||||
import io.ebeaninternal.server.deploy.DbSqlContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,6 +33,12 @@ public final class SqlTreeProperties {
|
||||
propsList.addAll(Arrays.asList(props));
|
||||
}
|
||||
|
||||
public void addExtra(STreePropertyAssocOne prop) {
|
||||
if (!propsList.contains(prop)) {
|
||||
add(prop);
|
||||
}
|
||||
}
|
||||
|
||||
public void add(STreeProperty prop) {
|
||||
propsList.add(prop);
|
||||
propNames.add(prop.name());
|
||||
|
||||
-1
@@ -10,7 +10,6 @@ import io.ebeaninternal.api.SpiProfileHandler;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
|
||||
@@ -15,7 +15,6 @@ import io.ebeaninternal.server.persist.BatchedSqlException;
|
||||
import io.ebeaninternal.server.util.Str;
|
||||
import io.ebeanservice.docstore.api.DocStoreTransaction;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.RollbackException;
|
||||
|
||||
@@ -2,7 +2,6 @@ package io.ebeaninternal.server.type;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.ebean.annotation.DbArray;
|
||||
import io.ebean.annotation.DbEnumType;
|
||||
import io.ebean.annotation.DbEnumValue;
|
||||
import io.ebean.annotation.EnumValue;
|
||||
@@ -48,7 +47,6 @@ import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.*;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.ebeaninternal.server.type;
|
||||
|
||||
import io.ebean.core.type.DataBinder;
|
||||
import io.ebean.core.type.DataReader;
|
||||
|
||||
import java.sql.SQLException;
|
||||
@@ -18,6 +19,15 @@ class ScalarTypeClob extends ScalarTypeStringBase {
|
||||
super(true, Types.CLOB);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(DataBinder binder, String value) throws SQLException {
|
||||
if (value == null) {
|
||||
binder.setNull(Types.VARCHAR);
|
||||
} else {
|
||||
binder.setClob(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String read(DataReader reader) throws SQLException {
|
||||
return reader.getStringFromStream();
|
||||
|
||||
@@ -10,8 +10,6 @@ import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.Instant;
|
||||
|
||||
import static io.ebeaninternal.server.type.IsoJsonDateTimeParser.formatIso;
|
||||
|
||||
/**
|
||||
* ScalarType for java.sql.Timestamp.
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebeaninternal.server.type;
|
||||
|
||||
import io.ebean.annotation.DbArray;
|
||||
import io.ebean.core.type.ScalarType;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-runner</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>${ebean-ddl-runner.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -51,7 +51,7 @@
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>1.0</version>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@ public class DdlPlugin implements Plugin {
|
||||
private boolean extraDdl;
|
||||
private boolean createOnly;
|
||||
private boolean jaxbPresent;
|
||||
private boolean ddlAutoCommit;
|
||||
private String dbSchema;
|
||||
private ScriptTransform scriptTransform;
|
||||
private Platform platform;
|
||||
@@ -71,7 +70,6 @@ public class DdlPlugin implements Plugin {
|
||||
final DatabasePlatform databasePlatform = server.databasePlatform();
|
||||
this.platform = databasePlatform.getPlatform();
|
||||
this.platformName = platform.base().name();
|
||||
this.ddlAutoCommit = databasePlatform.isDdlAutoCommit();
|
||||
this.useMigrationStoredProcedures = config.getDatabasePlatform().isUseMigrationStoredProcedures();
|
||||
this.scriptTransform = createScriptTransform(config);
|
||||
this.baseDir = initBaseDir();
|
||||
@@ -161,11 +159,11 @@ public class DdlPlugin implements Plugin {
|
||||
|
||||
DdlRunner runner = createDdlRunner(expectErrors, scriptName);
|
||||
try {
|
||||
if (expectErrors || ddlAutoCommit) {
|
||||
if (expectErrors) {
|
||||
connection.setAutoCommit(true);
|
||||
}
|
||||
runner.runAll(scriptTransform.transform(content), connection);
|
||||
if (expectErrors || ddlAutoCommit) {
|
||||
if (expectErrors) {
|
||||
connection.setAutoCommit(false);
|
||||
}
|
||||
connection.commit();
|
||||
@@ -300,21 +298,13 @@ public class DdlPlugin implements Plugin {
|
||||
}
|
||||
|
||||
protected String generateDropAllDdl() {
|
||||
try {
|
||||
dropAllContent = currentModel().getDropAllDdl();
|
||||
return dropAllContent;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
dropAllContent = currentModel().getDropAllDdl();
|
||||
return dropAllContent;
|
||||
}
|
||||
|
||||
protected String generateCreateAllDdl() {
|
||||
try {
|
||||
createAllContent = currentModel().getCreateDdl();
|
||||
return createAllContent;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
createAllContent = currentModel().getCreateDdl();
|
||||
return createAllContent;
|
||||
}
|
||||
|
||||
protected String getDropFileName() {
|
||||
|
||||
+5
-6
@@ -17,7 +17,6 @@ import io.avaje.classpath.scanner.core.Location;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Database;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.ClassLoadConfig;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.DbConstraintNaming;
|
||||
import io.ebean.config.PlatformConfig;
|
||||
@@ -658,9 +657,9 @@ public class DefaultDbMigration implements DbMigration {
|
||||
// writer needs the current model to provide table/column details for
|
||||
// history ddl generation (triggers, history tables etc)
|
||||
DdlOptions options = new DdlOptions(addForeignKeySkipCheck);
|
||||
DdlWrite write = new DdlWrite(new MConfiguration(), request.current, options);
|
||||
PlatformDdlWriter writer = createDdlWriter(databasePlatform);
|
||||
writer.processMigration(dbMigration, write, request.migrationDir, fullVersion);
|
||||
DdlWrite writer = new DdlWrite(new MConfiguration(), request.current, options);
|
||||
PlatformDdlWriter platformWriter = createDdlWriter(databasePlatform);
|
||||
platformWriter.processMigration(dbMigration, writer, request.migrationDir, fullVersion);
|
||||
}
|
||||
return fullVersion;
|
||||
}
|
||||
@@ -727,7 +726,7 @@ public class DefaultDbMigration implements DbMigration {
|
||||
private void writeExtraPlatformDdl(String fullVersion, CurrentModel currentModel, Migration dbMigration, File writePath, boolean clear) throws IOException {
|
||||
DdlOptions options = new DdlOptions(addForeignKeySkipCheck);
|
||||
for (Pair pair : platforms) {
|
||||
DdlWrite platformBuffer = new DdlWrite(new MConfiguration(), currentModel.read(), options);
|
||||
DdlWrite writer = new DdlWrite(new MConfiguration(), currentModel.read(), options);
|
||||
PlatformDdlWriter platformWriter = createDdlWriter(pair.platform);
|
||||
File subPath = platformWriter.subPath(writePath, pair.prefix);
|
||||
if (clear) {
|
||||
@@ -735,7 +734,7 @@ public class DefaultDbMigration implements DbMigration {
|
||||
existing.delete();
|
||||
}
|
||||
}
|
||||
platformWriter.processMigration(dbMigration, platformBuffer, subPath, fullVersion);
|
||||
platformWriter.processMigration(dbMigration, writer, subPath, fullVersion);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -7,6 +7,8 @@ package io.ebeaninternal.dbmigration;
|
||||
*/
|
||||
public class UnknownResourcePathException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 8533769929372106003L;
|
||||
|
||||
public UnknownResourcePathException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
+18
-19
@@ -18,7 +18,6 @@ import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropIndex;
|
||||
import io.ebeaninternal.dbmigration.migration.DropTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -37,7 +36,7 @@ public class BaseDdlHandler implements DdlHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, ChangeSet changeSet) throws IOException {
|
||||
public void generate(DdlWrite writer, ChangeSet changeSet) {
|
||||
|
||||
List<Object> changeSetChildren = changeSet.getChangeSetChildren();
|
||||
for (Object change : changeSetChildren) {
|
||||
@@ -79,77 +78,77 @@ public class BaseDdlHandler implements DdlHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateProlog(DdlWrite write) throws IOException {
|
||||
tableDdl.generateProlog(write);
|
||||
public void generateProlog(DdlWrite writer) {
|
||||
tableDdl.generateProlog(writer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateEpilog(DdlWrite write) throws IOException {
|
||||
tableDdl.generateEpilog(write);
|
||||
public void generateEpilog(DdlWrite writer) {
|
||||
tableDdl.generateEpilog(writer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, CreateTable createTable) throws IOException {
|
||||
public void generate(DdlWrite writer, CreateTable createTable) {
|
||||
tableDdl.generate(writer, createTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropTable dropTable) throws IOException {
|
||||
public void generate(DdlWrite writer, DropTable dropTable) {
|
||||
tableDdl.generate(writer, dropTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AlterTable alterTable) throws IOException {
|
||||
public void generate(DdlWrite writer, AlterTable alterTable) {
|
||||
tableDdl.generate(writer, alterTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddTableComment addTableComment) throws IOException {
|
||||
public void generate(DdlWrite writer, AddTableComment addTableComment) {
|
||||
tableDdl.generate(writer, addTableComment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddColumn addColumn) throws IOException {
|
||||
public void generate(DdlWrite writer, AddColumn addColumn) {
|
||||
tableDdl.generate(writer, addColumn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropColumn dropColumn) throws IOException {
|
||||
public void generate(DdlWrite writer, DropColumn dropColumn) {
|
||||
tableDdl.generate(writer, dropColumn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException {
|
||||
public void generate(DdlWrite writer, AlterColumn alterColumn) {
|
||||
tableDdl.generate(writer, alterColumn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
public void generate(DdlWrite writer, AddHistoryTable addHistoryTable) {
|
||||
tableDdl.generate(writer, addHistoryTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
|
||||
public void generate(DdlWrite writer, DropHistoryTable dropHistoryTable) {
|
||||
tableDdl.generate(writer, dropHistoryTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, CreateIndex createIndex) throws IOException {
|
||||
public void generate(DdlWrite writer, CreateIndex createIndex) {
|
||||
tableDdl.generate(writer, createIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropIndex dropIndex) throws IOException {
|
||||
public void generate(DdlWrite writer, DropIndex dropIndex) {
|
||||
tableDdl.generate(writer, dropIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddUniqueConstraint constraint) throws IOException {
|
||||
public void generate(DdlWrite writer, AddUniqueConstraint constraint) {
|
||||
tableDdl.generate(writer, constraint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AlterForeignKey alterForeignKey) throws IOException {
|
||||
public void generate(DdlWrite writer, AlterForeignKey alterForeignKey) {
|
||||
tableDdl.generate(writer, alterForeignKey);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-5
@@ -4,8 +4,6 @@ import io.ebeaninternal.dbmigration.migration.AddColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.DropColumn;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Write DDL for AddColumn , DropColumn or AlterColumn.
|
||||
*/
|
||||
@@ -14,15 +12,15 @@ public interface ColumnDdl {
|
||||
/**
|
||||
* Write the add column change.
|
||||
*/
|
||||
void generate(DdlWrite writer, AddColumn addColumn) throws IOException;
|
||||
void generate(DdlWrite writer, AddColumn addColumn);
|
||||
|
||||
/**
|
||||
* Write the drop column change.
|
||||
*/
|
||||
void generate(DdlWrite writer, DropColumn dropColumn) throws IOException;
|
||||
void generate(DdlWrite writer, DropColumn dropColumn);
|
||||
|
||||
/**
|
||||
* Write the alter column changes.
|
||||
*/
|
||||
void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException;
|
||||
void generate(DdlWrite writer, AlterColumn alterColumn);
|
||||
}
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Object that represents an Alter Table statements. Table alters are grouped together by tableName in DDL and can be extended by
|
||||
* a ddl-specific handler (e.g. doing a reorg for DB2 or implement special grouping for Hana). There is one instance per table.
|
||||
*
|
||||
* @author TODO Roland Praml, FOCONIS AG
|
||||
*/
|
||||
public interface DdlAlterTable {
|
||||
|
||||
/**
|
||||
* Writes the alter table statements to <code>target</code>
|
||||
*/
|
||||
void write(Appendable target) throws IOException;
|
||||
|
||||
/**
|
||||
* Adds an alter table command for given column. When you invoke<br>
|
||||
* <code>alterTable(writer, "my_table").add("alter column","my_column).append("type integer")</code> the resulting DDL (in
|
||||
* standard implementation) would be<br>
|
||||
* <code>alter table my_table alter column my_column type integer</code>
|
||||
*
|
||||
* @return a DdlBuffer, which can be used for further appends. Note you MUST NOT call <code>.endOfStatement()</code> on this
|
||||
* buffer.
|
||||
*/
|
||||
DdlBuffer append(String operation, String columnName);
|
||||
|
||||
/**
|
||||
* Adds a raw command. This is mainly used for executing user stored procedures.
|
||||
*/
|
||||
DdlBuffer raw(String string);
|
||||
|
||||
/**
|
||||
* Flag that detects if history DDL (switching on) is handled for this table.
|
||||
*/
|
||||
boolean isHistoryHandled();
|
||||
|
||||
/**
|
||||
* Sets the history handled flag for this table.
|
||||
*/
|
||||
void setHistoryHandled();
|
||||
|
||||
|
||||
}
|
||||
+7
-16
@@ -1,19 +1,10 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration;
|
||||
|
||||
import io.ebeaninternal.dbmigration.model.MConfiguration;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Buffer to append generated DDL to.
|
||||
*/
|
||||
public interface DdlBuffer {
|
||||
|
||||
/**
|
||||
* Return the configuration (default tablespaces etc).
|
||||
*/
|
||||
MConfiguration getConfiguration();
|
||||
|
||||
/**
|
||||
* Return true if the buffer is empty.
|
||||
*/
|
||||
@@ -22,37 +13,37 @@ public interface DdlBuffer {
|
||||
/**
|
||||
* Append a statement allowing for null or empty statements.
|
||||
*/
|
||||
DdlBuffer appendStatement(String content) throws IOException;
|
||||
DdlBuffer appendStatement(String content);
|
||||
|
||||
/**
|
||||
* Append DDL content to the buffer.
|
||||
*/
|
||||
DdlBuffer append(String content) throws IOException;
|
||||
DdlBuffer append(String content);
|
||||
|
||||
/**
|
||||
* Append DDL content to the buffer with space padding.
|
||||
*/
|
||||
DdlBuffer append(String type, int space) throws IOException;
|
||||
DdlBuffer append(String type, int space);
|
||||
|
||||
/**
|
||||
* Append a value that is potentially null or empty and proceed it with a space if so.
|
||||
*/
|
||||
DdlBuffer appendWithSpace(String foreignKeyRestrict) throws IOException;
|
||||
DdlBuffer appendWithSpace(String foreignKeyRestrict);
|
||||
|
||||
/**
|
||||
* Append new line character to the buffer.
|
||||
*/
|
||||
DdlBuffer newLine() throws IOException;
|
||||
DdlBuffer newLine();
|
||||
|
||||
/**
|
||||
* Append the end of statement content.
|
||||
*/
|
||||
DdlBuffer endOfStatement() throws IOException;
|
||||
DdlBuffer endOfStatement();
|
||||
|
||||
/**
|
||||
* End of a change - add some whitespace.
|
||||
*/
|
||||
DdlBuffer end() throws IOException;
|
||||
DdlBuffer end();
|
||||
|
||||
/**
|
||||
* Return the buffer content.
|
||||
|
||||
+16
-18
@@ -15,42 +15,40 @@ import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropIndex;
|
||||
import io.ebeaninternal.dbmigration.migration.DropTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* DDL generation interface.
|
||||
*/
|
||||
public interface DdlHandler {
|
||||
|
||||
void generate(DdlWrite writer, ChangeSet changeSet) throws IOException;
|
||||
void generate(DdlWrite writer, ChangeSet changeSet);
|
||||
|
||||
void generate(DdlWrite writer, CreateTable createTable) throws IOException;
|
||||
void generate(DdlWrite writer, CreateTable createTable);
|
||||
|
||||
void generate(DdlWrite writer, DropTable dropTable) throws IOException;
|
||||
void generate(DdlWrite writer, DropTable dropTable);
|
||||
|
||||
void generate(DdlWrite writer, AlterTable dropTable) throws IOException;
|
||||
void generate(DdlWrite writer, AlterTable dropTable);
|
||||
|
||||
void generate(DdlWrite writer, AddTableComment addTableComment) throws IOException;
|
||||
void generate(DdlWrite writer, AddTableComment addTableComment);
|
||||
|
||||
void generate(DdlWrite writer, AddColumn addColumn) throws IOException;
|
||||
void generate(DdlWrite writer, AddColumn addColumn);
|
||||
|
||||
void generate(DdlWrite writer, DropColumn dropColumn) throws IOException;
|
||||
void generate(DdlWrite writer, DropColumn dropColumn);
|
||||
|
||||
void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException;
|
||||
void generate(DdlWrite writer, AlterColumn alterColumn);
|
||||
|
||||
void generate(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException;
|
||||
void generate(DdlWrite writer, AddHistoryTable addHistoryTable);
|
||||
|
||||
void generate(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException;
|
||||
void generate(DdlWrite writer, DropHistoryTable dropHistoryTable);
|
||||
|
||||
void generate(DdlWrite writer, CreateIndex createIndex) throws IOException;
|
||||
void generate(DdlWrite writer, CreateIndex createIndex);
|
||||
|
||||
void generate(DdlWrite writer, DropIndex dropIndex) throws IOException;
|
||||
void generate(DdlWrite writer, DropIndex dropIndex);
|
||||
|
||||
void generate(DdlWrite writer, AddUniqueConstraint constraint) throws IOException;
|
||||
void generate(DdlWrite writer, AddUniqueConstraint constraint);
|
||||
|
||||
void generate(DdlWrite writer, AlterForeignKey alterForeignKey) throws IOException;
|
||||
void generate(DdlWrite writer, AlterForeignKey alterForeignKey);
|
||||
|
||||
void generateProlog(DdlWrite write) throws IOException;
|
||||
void generateProlog(DdlWrite writer);
|
||||
|
||||
void generateEpilog(DdlWrite write) throws IOException;
|
||||
void generateEpilog(DdlWrite writer);
|
||||
}
|
||||
|
||||
+104
-31
@@ -1,30 +1,46 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.function.Function;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.BaseDdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.model.MConfiguration;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
import io.ebeaninternal.dbmigration.model.ModelContainer;
|
||||
|
||||
/**
|
||||
* Write context holding the buffers for both apply and rollback DDL.
|
||||
* Write context holding the buffers for both apply and rollback DDL. Description of the apply buffers:
|
||||
* <ul>
|
||||
* <li><b>applyDropDependencies:</b> Contains drops for foreign keys, indices, constraint or drop history table</li>
|
||||
* <li><b>apply:</b> Contains @DbMigraion.before, create table, create sequence or disable system versioning statements</li>
|
||||
* <li><b>applyAlterTables:</b> Contains table alters (only that change the table data structure, there may be table alters like
|
||||
* constraints etc. in postAlter)</li>
|
||||
* <li><b>applyPostAlter:</b> Contains check constraints, unique constraints (which CAN be an index), column and table comments,
|
||||
* @DbMigraion.after, drop tables, drop sequences or enable system versioning statement</li>
|
||||
* <li><b>applyForeignKeys: Contains foreign keys and indices.</b>
|
||||
* <li><b>applyHistoryView:</b> The views for trigger based history support</li>
|
||||
* <li><b>applyHistoryTrigger:</b> The triggers for trigger based history support</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class DdlWrite {
|
||||
|
||||
private final ModelContainer currentModel;
|
||||
|
||||
private final DdlBuffer applyDropDependencies;
|
||||
private final DdlBuffer applyDropDependencies = new BaseDdlBuffer();
|
||||
|
||||
private final DdlBuffer apply;
|
||||
private final DdlBuffer apply = new BaseDdlBuffer();
|
||||
|
||||
private final DdlBuffer applyForeignKeys;
|
||||
private final Map<String, DdlAlterTable> applyAlterTables = new TreeMap<>();
|
||||
|
||||
private final DdlBuffer applyHistoryView;
|
||||
private final DdlBuffer applyPostAlter = new BaseDdlBuffer();
|
||||
|
||||
private final DdlBuffer applyHistoryTrigger;
|
||||
private final DdlBuffer applyForeignKeys = new BaseDdlBuffer();
|
||||
|
||||
private final DdlBuffer dropAllForeignKeys;
|
||||
private final DdlBuffer dropAllForeignKeys = new BaseDdlBuffer();
|
||||
|
||||
private final DdlBuffer dropAll;
|
||||
private final DdlBuffer dropAll = new BaseDdlBuffer();
|
||||
|
||||
private final DdlOptions options;
|
||||
|
||||
@@ -40,13 +56,6 @@ public class DdlWrite {
|
||||
*/
|
||||
public DdlWrite(MConfiguration configuration, ModelContainer currentModel, DdlOptions options) {
|
||||
this.currentModel = currentModel;
|
||||
this.applyDropDependencies = new BaseDdlBuffer(configuration);
|
||||
this.apply = new BaseDdlBuffer(configuration);
|
||||
this.applyForeignKeys = new BaseDdlBuffer(configuration);
|
||||
this.applyHistoryView = new BaseDdlBuffer(configuration);
|
||||
this.applyHistoryTrigger = new BaseDdlBuffer(configuration);
|
||||
this.dropAllForeignKeys = new BaseDdlBuffer(configuration);
|
||||
this.dropAll = new BaseDdlBuffer(configuration);
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@@ -73,12 +82,19 @@ public class DdlWrite {
|
||||
*/
|
||||
public boolean isApplyEmpty() {
|
||||
return apply.getBuffer().isEmpty()
|
||||
&& applyAlterTables.isEmpty()
|
||||
&& applyPostAlter.getBuffer().isEmpty()
|
||||
&& applyForeignKeys.getBuffer().isEmpty()
|
||||
&& applyHistoryView.getBuffer().isEmpty()
|
||||
&& applyHistoryTrigger.getBuffer().isEmpty()
|
||||
&& applyDropDependencies.getBuffer().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that POST ALTER is written to.
|
||||
*/
|
||||
public DdlBuffer applyPostAlter() {
|
||||
return applyPostAlter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that APPLY DDL is written to.
|
||||
*/
|
||||
@@ -93,6 +109,20 @@ public class DdlWrite {
|
||||
return applyDropDependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates or returns the DdlAlterTable statement for <code>tablename</code>.
|
||||
*
|
||||
* Note: All alters on a particular table are sorted in natural order in the ddl script. This allows optimizing the alters by
|
||||
* merging them or doing a reorg table after altering is done.
|
||||
*
|
||||
* @param tableName the table name
|
||||
* @param factory the factory to construct a new object
|
||||
* @return
|
||||
*/
|
||||
public DdlAlterTable applyAlterTable(String tableName, Function<String, DdlAlterTable> factory) {
|
||||
return applyAlterTables.computeIfAbsent(tableName, factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that APPLY DDL is written to for foreign keys and their associated indexes.
|
||||
* <p>
|
||||
@@ -103,20 +133,6 @@ public class DdlWrite {
|
||||
return applyForeignKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that apply history-view DDL is written to.
|
||||
*/
|
||||
public DdlBuffer applyHistoryView() {
|
||||
return applyHistoryView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer that apply history-trigger DDL is written to.
|
||||
*/
|
||||
public DdlBuffer applyHistoryTrigger() {
|
||||
return applyHistoryTrigger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer used for the 'drop all DDL' for dropping foreign keys and associated indexes.
|
||||
*/
|
||||
@@ -131,4 +147,61 @@ public class DdlWrite {
|
||||
return dropAll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the apply ddl to the target.
|
||||
*/
|
||||
public void writeApply(Appendable target) throws IOException {
|
||||
if (!applyDropDependencies.isEmpty()) {
|
||||
target.append("-- drop dependencies\n");
|
||||
target.append(applyDropDependencies.getBuffer());
|
||||
}
|
||||
if (!apply.isEmpty()) {
|
||||
target.append("-- apply changes\n");
|
||||
target.append(apply.getBuffer());
|
||||
}
|
||||
if (!applyAlterTables.isEmpty()) {
|
||||
target.append("-- apply alter tables\n");
|
||||
for (DdlAlterTable alterTable : applyAlterTables.values()) {
|
||||
alterTable.write(target);
|
||||
}
|
||||
}
|
||||
if (!applyPostAlter.isEmpty()) {
|
||||
target.append("-- apply post alter\n");
|
||||
target.append(applyPostAlter.getBuffer());
|
||||
}
|
||||
if (!applyForeignKeys.isEmpty()) {
|
||||
target.append("-- foreign keys and indices\n");
|
||||
target.append(applyForeignKeys.getBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the drop all ddl to the target.
|
||||
*/
|
||||
public void writeDropAll(Appendable target) throws IOException {
|
||||
if (!dropAllForeignKeys.isEmpty()) {
|
||||
target.append("-- drop all foreign keys\n");
|
||||
target.append(dropAllForeignKeys.getBuffer());
|
||||
}
|
||||
if (!dropAll.isEmpty()) {
|
||||
target.append("-- drop all\n");
|
||||
target.append(dropAll.getBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all create statements. Mainly used for unit-tests
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try {
|
||||
writeDropAll(sb);
|
||||
writeApply(sb);
|
||||
} catch (IOException e) {
|
||||
// can not happen
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+15
-17
@@ -14,8 +14,6 @@ import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropIndex;
|
||||
import io.ebeaninternal.dbmigration.migration.DropTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Write table DDL.
|
||||
*/
|
||||
@@ -24,75 +22,75 @@ public interface TableDdl {
|
||||
/**
|
||||
* Generate the create table change.
|
||||
*/
|
||||
void generate(DdlWrite writer, CreateTable createTable) throws IOException;
|
||||
void generate(DdlWrite writer, CreateTable createTable);
|
||||
|
||||
/**
|
||||
* Write the drop column change.
|
||||
*/
|
||||
void generate(DdlWrite writer, DropTable dropTable) throws IOException;
|
||||
void generate(DdlWrite writer, DropTable dropTable);
|
||||
|
||||
/**
|
||||
* Write alter table changes.
|
||||
*/
|
||||
void generate(DdlWrite writer, AlterTable dropTable) throws IOException;
|
||||
void generate(DdlWrite writer, AlterTable dropTable);
|
||||
|
||||
/**
|
||||
* Write the add column change.
|
||||
*/
|
||||
void generate(DdlWrite writer, AddColumn addColumn) throws IOException;
|
||||
void generate(DdlWrite writer, AddColumn addColumn);
|
||||
|
||||
/**
|
||||
* Write the alter column changes.
|
||||
*/
|
||||
void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException;
|
||||
void generate(DdlWrite writer, AlterColumn alterColumn);
|
||||
|
||||
/**
|
||||
* Write the drop column change.
|
||||
*/
|
||||
void generate(DdlWrite writer, DropColumn dropColumn) throws IOException;
|
||||
void generate(DdlWrite writer, DropColumn dropColumn);
|
||||
|
||||
/**
|
||||
* Write the AddTableComment change.
|
||||
*/
|
||||
void generate(DdlWrite writer, AddTableComment addTableComment) throws IOException;
|
||||
void generate(DdlWrite writer, AddTableComment addTableComment);
|
||||
|
||||
/**
|
||||
* Write the AddHistoryTable change.
|
||||
*/
|
||||
void generate(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException;
|
||||
void generate(DdlWrite writer, AddHistoryTable addHistoryTable);
|
||||
|
||||
/**
|
||||
* Write the DropHistoryTable change.
|
||||
*/
|
||||
void generate(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException;
|
||||
void generate(DdlWrite writer, DropHistoryTable dropHistoryTable);
|
||||
|
||||
/**
|
||||
* Generate the create index change.
|
||||
*/
|
||||
void generate(DdlWrite writer, CreateIndex createIndex) throws IOException;
|
||||
void generate(DdlWrite writer, CreateIndex createIndex);
|
||||
|
||||
/**
|
||||
* Write the drop index change.
|
||||
*/
|
||||
void generate(DdlWrite writer, DropIndex dropIndex) throws IOException;
|
||||
void generate(DdlWrite writer, DropIndex dropIndex);
|
||||
|
||||
/**
|
||||
* Write add unique constraint.
|
||||
*/
|
||||
void generate(DdlWrite writer, AddUniqueConstraint constraint) throws IOException;
|
||||
void generate(DdlWrite writer, AddUniqueConstraint constraint);
|
||||
|
||||
/**
|
||||
* Writes alter foreign key statements.
|
||||
*/
|
||||
void generate(DdlWrite writer, AlterForeignKey alterForeignKey) throws IOException;
|
||||
void generate(DdlWrite writer, AlterForeignKey alterForeignKey);
|
||||
|
||||
/**
|
||||
* Generate any extra DDL such as stored procedures or TableValueParameters.
|
||||
*/
|
||||
void generateProlog(DdlWrite write) throws IOException;
|
||||
void generateProlog(DdlWrite writer);
|
||||
|
||||
/**
|
||||
* Generate any extra DDL such as regeneration of history triggers.
|
||||
*/
|
||||
void generateEpilog(DdlWrite write) throws IOException;
|
||||
void generateEpilog(DdlWrite writer);
|
||||
}
|
||||
|
||||
+107
-71
@@ -1,14 +1,20 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.config.dbplatform.DbPlatformType;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -18,16 +24,13 @@ public abstract class AbstractHanaDdl extends PlatformDdl {
|
||||
|
||||
public AbstractHanaDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.addColumn = "add (";
|
||||
this.addColumnSuffix = ")";
|
||||
this.alterColumn = "alter (";
|
||||
this.alterColumnSuffix = ")";
|
||||
this.columnDropDefault = " default null";
|
||||
this.columnSetDefault = " default";
|
||||
this.columnSetNotnull = " not null";
|
||||
this.addColumn = "add";
|
||||
this.alterColumn = "alter";
|
||||
this.columnDropDefault = "default null";
|
||||
this.columnSetDefault = "default";
|
||||
this.columnSetNotnull = "not null";
|
||||
this.columnSetNull = " null";
|
||||
this.dropColumn = "drop (";
|
||||
this.dropColumnSuffix = ")";
|
||||
this.dropColumn = "drop";
|
||||
this.dropConstraintIfExists = "drop constraint ";
|
||||
this.dropIndexIfExists = "drop index ";
|
||||
this.dropSequenceIfExists = "drop sequence ";
|
||||
@@ -39,7 +42,7 @@ public abstract class AbstractHanaDdl extends PlatformDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnBaseAttributes(AlterColumn alter) {
|
||||
public void alterColumn(DdlWrite writer, AlterColumn alter) {
|
||||
String tableName = alter.getTableName();
|
||||
String columnName = alter.getColumnName();
|
||||
String currentType = alter.getCurrentType();
|
||||
@@ -52,51 +55,21 @@ public abstract class AbstractHanaDdl extends PlatformDdl {
|
||||
: (alter.getDefaultValue() != null ? alter.getDefaultValue() : alter.getCurrentDefaultValue());
|
||||
String defaultValueClause = (defaultValue == null || defaultValue.isEmpty()) ? "" : " default " + defaultValue;
|
||||
|
||||
try {
|
||||
DdlBuffer buffer = new BaseDdlBuffer(null);
|
||||
if (!isConvertible(currentType, type)) {
|
||||
// add an intermediate conversion if possible
|
||||
if (isNumberType(currentType)) {
|
||||
// numbers can always be converted to decimal
|
||||
buffer.append("alter table ").append(tableName).append(" ").append(alterColumn).append(" ").append(columnName)
|
||||
.append(" decimal ").append(defaultValueClause).append(notnullClause).append(alterColumnSuffix)
|
||||
.endOfStatement();
|
||||
if (!isConvertible(currentType, type)) {
|
||||
// add an intermediate conversion if possible
|
||||
if (isNumberType(currentType)) {
|
||||
// numbers can always be converted to decimal
|
||||
alterTable(writer, tableName).append(alterColumn, columnName).append("decimal").append(notnullClause);
|
||||
|
||||
} else if (isStringType(currentType)) {
|
||||
// strings can always be converted to nclob
|
||||
buffer.append("alter table ").append(tableName).append(" ").append(alterColumn).append(" ").append(columnName)
|
||||
.append(" nclob ").append(defaultValueClause).append(notnullClause).append(alterColumnSuffix)
|
||||
.endOfStatement();
|
||||
}
|
||||
} else if (isStringType(currentType)) {
|
||||
// strings can always be converted to nclob
|
||||
// Note: we do not add default clause here to avoid error[SAP DBTech JDBC: [336]: invalid default value:
|
||||
// default value cannot be created on column of data type NCLOB
|
||||
alterTable(writer, tableName).append(alterColumn, columnName).append("nclob").append(notnullClause);
|
||||
}
|
||||
|
||||
buffer.append("alter table ").append(tableName).append(" ").append(alterColumn).append(" ").append(columnName)
|
||||
.append(" ").append(type).append(defaultValueClause).append(notnullClause).append(alterColumnSuffix);
|
||||
|
||||
return buffer.getBuffer();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnNotnull(String tableName, String columnName, boolean notnull) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlHandler createDdlHandler(DatabaseConfig config) {
|
||||
return new HanaDdlHandler(config, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnType(String tableName, String columnName, String type) {
|
||||
return null;
|
||||
alterTable(writer, tableName).append(alterColumn, columnName).append(type).append(defaultValueClause).append(notnullClause);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -120,20 +93,17 @@ public abstract class AbstractHanaDdl extends PlatformDdl {
|
||||
|
||||
@Override
|
||||
public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
|
||||
DdlBuffer buffer = new BaseDdlBuffer(null);
|
||||
try {
|
||||
buffer.append("delimiter $$").newLine();
|
||||
buffer.append("do").newLine();
|
||||
buffer.append("begin").newLine();
|
||||
buffer.append("declare exit handler for sql_error_code 397 begin end").endOfStatement();
|
||||
buffer.append("exec 'alter table ").append(tableName).append(" ").append(dropUniqueConstraint).append(" ")
|
||||
.append(maxConstraintName(uniqueConstraintName)).append("'").endOfStatement();
|
||||
buffer.append("end").endOfStatement();
|
||||
buffer.append("$$");
|
||||
return buffer.getBuffer();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
DdlBuffer buffer = new BaseDdlBuffer();
|
||||
|
||||
buffer.append("delimiter $$").newLine();
|
||||
buffer.append("do").newLine();
|
||||
buffer.append("begin").newLine();
|
||||
buffer.append("declare exit handler for sql_error_code 397 begin end").endOfStatement();
|
||||
buffer.append("exec 'alter table ").append(tableName).append(" ").append(dropUniqueConstraint).append(" ")
|
||||
.append(maxConstraintName(uniqueConstraintName)).append("'").endOfStatement();
|
||||
buffer.append("end").endOfStatement();
|
||||
buffer.append("$$");
|
||||
return buffer.getBuffer();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -146,9 +116,8 @@ public abstract class AbstractHanaDdl extends PlatformDdl {
|
||||
* foreign keys. That's why we call a user stored procedure here
|
||||
*/
|
||||
@Override
|
||||
public void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException {
|
||||
buffer.append("CALL usp_ebean_drop_column('").append(tableName).append("', '").append(columnName).append("')")
|
||||
.endOfStatement();
|
||||
public void alterTableDropColumn(DdlWrite writer, String tableName, String columnName) {
|
||||
alterTable(writer, tableName).raw("CALL usp_ebean_drop_column('").append(tableName).append("', '").append(columnName).append("')");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,4 +191,71 @@ public abstract class AbstractHanaDdl extends PlatformDdl {
|
||||
return type != null
|
||||
&& (type.startsWith("varchar") || type.startsWith("nvarchar") || "clob".equals(type) || "nclob".equals(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DdlAlterTable alterTable(DdlWrite writer, String tableName) {
|
||||
return writer.applyAlterTable(tableName, HanaAlterTableWrite::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins alter table commands and add open/closing brackets for the alter statements
|
||||
*/
|
||||
private static class HanaAlterTableWrite extends BaseAlterTableWrite {
|
||||
|
||||
public HanaAlterTableWrite(String tableName) {
|
||||
super(tableName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AlterCmd> postProcessCommands(List<AlterCmd> cmds) {
|
||||
List<AlterCmd> newCmds = new ArrayList<>();
|
||||
Map<String, List<AlterCmd>> batches = new LinkedHashMap<>();
|
||||
Set<String> columns = new HashSet<>();
|
||||
for (AlterCmd cmd : cmds) {
|
||||
switch (cmd.getOperation()) {
|
||||
case "add":
|
||||
case "alter":
|
||||
case "drop":
|
||||
if (cmd.getColumn() != null && !columns.add(cmd.getColumn())) {
|
||||
// column already seen
|
||||
flushBatches(newCmds, batches);
|
||||
columns.clear();
|
||||
}
|
||||
batches.computeIfAbsent(cmd.getOperation(), k -> new ArrayList<>()).add(cmd);
|
||||
break;
|
||||
default:
|
||||
flushBatches(newCmds, batches);
|
||||
columns.clear();
|
||||
newCmds.add(cmd);
|
||||
}
|
||||
}
|
||||
flushBatches(newCmds, batches);
|
||||
return newCmds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges add/alter/drop commands into one statement.
|
||||
*/
|
||||
private void flushBatches(List<AlterCmd> newCmds, Map<String, List<AlterCmd>> batches) {
|
||||
for (Entry<String, List<AlterCmd>> entry : batches.entrySet()) {
|
||||
AlterCmd raw = newRawCommand("alter table ").append(tableName()).append(" ")
|
||||
.append(entry.getKey()).append(" (");
|
||||
List<AlterCmd> cmds = entry.getValue();
|
||||
for (int i = 0; i < cmds.size(); i++) {
|
||||
AlterCmd cmd = cmds.get(i);
|
||||
if (i > 0) {
|
||||
raw.append(",\n ");
|
||||
}
|
||||
raw.append(cmd.getColumn());
|
||||
if (!cmd.getAlternation().isEmpty()) {
|
||||
raw.append(" ").append(cmd.getAlternation());
|
||||
}
|
||||
}
|
||||
raw.append(")");
|
||||
newCmds.add(raw);
|
||||
}
|
||||
batches.clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
|
||||
/**
|
||||
* Contains alter statements per table.
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*/
|
||||
public class BaseAlterTableWrite implements DdlAlterTable {
|
||||
|
||||
protected static final String RAW_OPERATION = "$RAW";
|
||||
|
||||
public class AlterCmd {
|
||||
// the command (e.g. "alter", "modify"
|
||||
private final String operation;
|
||||
// the affected column (note: each column can only be altered once on MariaDB)
|
||||
private final String column;
|
||||
|
||||
private final DdlBuffer alternationBuffer = new BaseDdlBuffer() {
|
||||
@Override
|
||||
public DdlBuffer endOfStatement() {
|
||||
throw new UnsupportedOperationException();
|
||||
};
|
||||
};
|
||||
|
||||
protected AlterCmd(String operation, String column) {
|
||||
this.operation = operation;
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
public AlterCmd append(String content) {
|
||||
alternationBuffer.append(content);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public String getColumn() {
|
||||
return column;
|
||||
}
|
||||
|
||||
public String getAlternation() {
|
||||
return alternationBuffer.getBuffer();
|
||||
}
|
||||
|
||||
protected void write(Appendable target) throws IOException {
|
||||
if (operation.equals(RAW_OPERATION)) {
|
||||
// this is a raw command. e.g. an USP call. Must be done in the correct order
|
||||
// of all alter commands
|
||||
target.append(getAlternation());
|
||||
} else {
|
||||
target.append("alter table ").append(tableName).append(' ').append(operation);
|
||||
if (column != null) {
|
||||
target.append(' ').append(column);
|
||||
}
|
||||
if (!getAlternation().isEmpty()) {
|
||||
target.append(' ').append(getAlternation());
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try {
|
||||
write(sb);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private final String tableName;
|
||||
|
||||
private List<AlterCmd> cmds = new ArrayList<>();
|
||||
|
||||
private boolean historyHandled;
|
||||
|
||||
public BaseAlterTableWrite(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public String tableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
protected AlterCmd newRawCommand(String sql) {
|
||||
AlterCmd cmd = new AlterCmd(RAW_OPERATION, null);
|
||||
cmd.alternationBuffer.append(sql);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
public AlterCmd newOperation(String operation, String column) {
|
||||
return new AlterCmd(operation, column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a statement. The statement is prefixed with "alter table TABLENAME" and may be batched, if platform supports this. The
|
||||
* returned StringBuilder can be used, to complete the statement
|
||||
*/
|
||||
@Override
|
||||
public DdlBuffer append(String operation, String column) {
|
||||
AlterCmd cmd = new AlterCmd(operation, column);
|
||||
cmds.add(cmd);
|
||||
return cmd.alternationBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer raw(String sql) {
|
||||
AlterCmd cmd = newRawCommand(sql);
|
||||
cmds.add(cmd);
|
||||
return cmd.alternationBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method can be overwritten to return a new list of commands. The given list must not be modified, but a new command list with
|
||||
* modified commands can be returned (e.g. to handle DB2 reorg or special syntax in Hana)
|
||||
*/
|
||||
protected List<AlterCmd> postProcessCommands(List<AlterCmd> cmds) {
|
||||
return cmds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the DDL to <code>target</code>.
|
||||
*/
|
||||
@Override
|
||||
public void write(Appendable target) throws IOException {
|
||||
for (AlterCmd cmd : postProcessCommands(Collections.unmodifiableList(cmds))) {
|
||||
cmd.write(target);
|
||||
target.append(";\n");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHistoryHandled() {
|
||||
return historyHandled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHistoryHandled() {
|
||||
historyHandled = true;
|
||||
}
|
||||
}
|
||||
+14
-25
@@ -1,45 +1,34 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.model.MConfiguration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* Base implementation of DdlBuffer using an underlying writer.
|
||||
*/
|
||||
public class BaseDdlBuffer implements DdlBuffer {
|
||||
|
||||
protected final StringWriter writer;
|
||||
protected final StringBuilder writer;
|
||||
|
||||
protected final MConfiguration configuration;
|
||||
|
||||
public BaseDdlBuffer(MConfiguration configuration) {
|
||||
this.configuration = configuration;
|
||||
this.writer = new StringWriter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MConfiguration getConfiguration() {
|
||||
return configuration;
|
||||
public BaseDdlBuffer() {
|
||||
this.writer = new StringBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return writer.getBuffer().length() == 0;
|
||||
return writer.length() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer appendWithSpace(String foreignKeyRestrict) throws IOException {
|
||||
if (foreignKeyRestrict != null && !foreignKeyRestrict.isEmpty()) {
|
||||
writer.append(" ").append(foreignKeyRestrict);
|
||||
public DdlBuffer appendWithSpace(String content) {
|
||||
if (content != null && !content.isEmpty()) {
|
||||
writer.append(" ").append(content);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer appendStatement(String content) throws IOException {
|
||||
public DdlBuffer appendStatement(String content) {
|
||||
if (content != null && !content.isEmpty()) {
|
||||
writer.append(content);
|
||||
endOfStatement();
|
||||
@@ -48,19 +37,19 @@ public class BaseDdlBuffer implements DdlBuffer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer append(String content) throws IOException {
|
||||
public DdlBuffer append(String content) {
|
||||
writer.append(content);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer append(String content, int space) throws IOException {
|
||||
public DdlBuffer append(String content, int space) {
|
||||
writer.append(content);
|
||||
appendSpace(space, content);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void appendSpace(int max, String content) throws IOException {
|
||||
protected void appendSpace(int max, String content) {
|
||||
int space = max - content.length();
|
||||
if (space > 0) {
|
||||
for (int i = 0; i < space; i++) {
|
||||
@@ -71,7 +60,7 @@ public class BaseDdlBuffer implements DdlBuffer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer endOfStatement() throws IOException {
|
||||
public DdlBuffer endOfStatement() {
|
||||
writer.append(";\n");
|
||||
return this;
|
||||
}
|
||||
@@ -81,7 +70,7 @@ public class BaseDdlBuffer implements DdlBuffer {
|
||||
* This should be just whitespace or a sql comment.
|
||||
*/
|
||||
@Override
|
||||
public DdlBuffer end() throws IOException {
|
||||
public DdlBuffer end() {
|
||||
if (!isEmpty()) {
|
||||
writer.append("\n");
|
||||
}
|
||||
@@ -89,7 +78,7 @@ public class BaseDdlBuffer implements DdlBuffer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DdlBuffer newLine() throws IOException {
|
||||
public DdlBuffer newLine() {
|
||||
writer.append("\n");
|
||||
return this;
|
||||
}
|
||||
|
||||
+177
-255
@@ -11,7 +11,6 @@ import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.TableDdl;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.util.IndexSet;
|
||||
import io.ebeaninternal.dbmigration.migration.AddColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.AddTableComment;
|
||||
@@ -33,14 +32,9 @@ import io.ebeaninternal.dbmigration.model.MTable;
|
||||
import io.ebeaninternal.dbmigration.model.MTableIdentity;
|
||||
import io.ebeaninternal.server.deploy.IdentityMode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static io.ebean.util.StringHelper.replace;
|
||||
import static io.ebeaninternal.api.PlatformMatch.matchPlatform;
|
||||
@@ -51,12 +45,6 @@ import static io.ebeaninternal.dbmigration.ddlgeneration.platform.SplitColumns.s
|
||||
*/
|
||||
public class BaseTableDdl implements TableDdl {
|
||||
|
||||
enum HistorySupport {
|
||||
NONE,
|
||||
SQL2011,
|
||||
TRIGGER_BASED
|
||||
}
|
||||
|
||||
protected final DbConstraintNaming naming;
|
||||
|
||||
protected final NamingConvention namingConvention;
|
||||
@@ -65,12 +53,6 @@ public class BaseTableDdl implements TableDdl {
|
||||
|
||||
protected final String historyTableSuffix;
|
||||
|
||||
/**
|
||||
* Used to check that indexes on foreign keys should be skipped as a unique index on the columns
|
||||
* already exists.
|
||||
*/
|
||||
protected final IndexSet indexSet = new IndexSet();
|
||||
|
||||
/**
|
||||
* Used when unique constraints specifically for OneToOne can't be created normally (MsSqlServer).
|
||||
*/
|
||||
@@ -78,26 +60,9 @@ public class BaseTableDdl implements TableDdl {
|
||||
|
||||
protected final List<UniqueConstraint> externalCompoundUnique = new ArrayList<>();
|
||||
|
||||
// counters used when constraint names are truncated due to maximum length
|
||||
// and these counters are used to keep the constraint name unique
|
||||
protected int countCheck;
|
||||
protected int countUnique;
|
||||
protected int countForeignKey;
|
||||
protected int countIndex;
|
||||
|
||||
/**
|
||||
* Base tables that have associated history tables that need their triggers/functions regenerated as
|
||||
* columns have been added, removed, included or excluded.
|
||||
*/
|
||||
protected final Map<String, HistoryTableUpdate> regenerateHistoryTriggers = new LinkedHashMap<>();
|
||||
|
||||
private final Set<String> needsReorg = new HashSet<>();
|
||||
|
||||
private int reorgCount;
|
||||
|
||||
private final boolean strictMode;
|
||||
|
||||
private final HistorySupport historySupport;
|
||||
private final boolean alterHistoryTables;
|
||||
|
||||
/**
|
||||
* Helper class that is used to execute the migration ddl before and after the migration action.
|
||||
@@ -148,32 +113,29 @@ public class BaseTableDdl implements TableDdl {
|
||||
after = getScriptsForPlatform(alter.getAfter());
|
||||
}
|
||||
|
||||
void writeBefore(DdlBuffer buffer) throws IOException {
|
||||
void write(DdlWrite writer) {
|
||||
if (!before.isEmpty()) {
|
||||
buffer.end();
|
||||
flushReorgTables(buffer);
|
||||
writer.apply().end();
|
||||
if (withHistory) {
|
||||
buffer.append("-- NOTE: table has @History - special migration may be necessary").newLine();
|
||||
writer.apply().append("-- NOTE: table has @History - special migration may be necessary").newLine();
|
||||
}
|
||||
for (String ddlScript : before) {
|
||||
buffer.appendStatement(translate(ddlScript, tableName, columnName, defaultValue));
|
||||
writer.apply().appendStatement(translate(ddlScript, tableName, columnName, defaultValue));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void writeAfter(DdlBuffer buffer) throws IOException {
|
||||
// effective order in DDL.sql:
|
||||
// 'before' goes to apply-buffer
|
||||
// altered columns will be in the alterTable buffers.
|
||||
// 'after' goes to the post-alter-buffer
|
||||
if (!after.isEmpty()) {
|
||||
if (withHistory) {
|
||||
buffer.append("-- NOTE: table has @History - special migration may be necessary").newLine();
|
||||
}
|
||||
flushReorgTables(buffer);
|
||||
|
||||
writer.applyPostAlter().append("-- NOTE: table has @History - special migration may be necessary").newLine();
|
||||
|
||||
// here we run post migration scripts
|
||||
for (String ddlScript : after) {
|
||||
buffer.appendStatement(translate(ddlScript, tableName, columnName, defaultValue));
|
||||
writer.applyPostAlter().appendStatement(translate(ddlScript, tableName, columnName, defaultValue));
|
||||
}
|
||||
buffer.end();
|
||||
|
||||
writer.applyPostAlter().end();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,9 +183,9 @@ public class BaseTableDdl implements TableDdl {
|
||||
this.strictMode = config.isDdlStrictMode();
|
||||
DbHistorySupport hist = platformDdl.getPlatform().getHistorySupport();
|
||||
if (hist == null) {
|
||||
this.historySupport = HistorySupport.NONE;
|
||||
this.alterHistoryTables = false;
|
||||
} else {
|
||||
this.historySupport = hist.isStandardsBased() ? HistorySupport.SQL2011 : HistorySupport.TRIGGER_BASED;
|
||||
this.alterHistoryTables = platformDdl.historyDdl.alterHistoryTables();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,13 +193,8 @@ public class BaseTableDdl implements TableDdl {
|
||||
* Reset counters and index set for each table processed.
|
||||
*/
|
||||
protected void reset() {
|
||||
indexSet.clear();
|
||||
externalUnique.clear();
|
||||
externalCompoundUnique.clear();
|
||||
countCheck = 0;
|
||||
countUnique = 0;
|
||||
countForeignKey = 0;
|
||||
countIndex = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -245,7 +202,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
* and add them to the appropriate 'apply' and 'rollback' buffers.
|
||||
*/
|
||||
@Override
|
||||
public void generate(DdlWrite writer, CreateTable createTable) throws IOException {
|
||||
public void generate(DdlWrite writer, CreateTable createTable) {
|
||||
reset();
|
||||
|
||||
String tableName = lowerTableName(createTable.getName());
|
||||
@@ -277,7 +234,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
}
|
||||
}
|
||||
if (platformDdl.isInlineForeignKeys()) {
|
||||
writeInlineForeignKeys(writer, createTable);
|
||||
writeInlineForeignKeys(apply, createTable);
|
||||
}
|
||||
apply.newLine().append(")");
|
||||
if (createTable.getTablespace() != null) {
|
||||
@@ -322,7 +279,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
/**
|
||||
* Add table and column comments (separate from the create table statement).
|
||||
*/
|
||||
private void addComments(DdlBuffer apply, CreateTable createTable) throws IOException {
|
||||
private void addComments(DdlBuffer apply, CreateTable createTable) {
|
||||
if (!platformDdl.isInlineComments()) {
|
||||
String tableComment = createTable.getComment();
|
||||
if (hasValue(tableComment)) {
|
||||
@@ -339,7 +296,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
/**
|
||||
* Add the table storage engine clause.
|
||||
*/
|
||||
private void addTableStorageEngine(DdlBuffer apply, CreateTable createTable) throws IOException {
|
||||
private void addTableStorageEngine(DdlBuffer apply, CreateTable createTable) {
|
||||
if (platformDdl.isIncludeStorageEngine()) {
|
||||
platformDdl.tableStorageEngine(apply, createTable.getStorageEngine());
|
||||
}
|
||||
@@ -348,7 +305,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
/**
|
||||
* Add the table comment inline with the create table statement.
|
||||
*/
|
||||
private void addTableCommentInline(DdlBuffer apply, CreateTable createTable) throws IOException {
|
||||
private void addTableCommentInline(DdlBuffer apply, CreateTable createTable) {
|
||||
if (platformDdl.isInlineComments()) {
|
||||
String tableComment = createTable.getComment();
|
||||
if (!StringHelper.isNull(tableComment)) {
|
||||
@@ -357,7 +314,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
}
|
||||
}
|
||||
|
||||
private void writeTableColumns(DdlBuffer apply, List<Column> columns, DdlIdentity identity) throws IOException {
|
||||
private void writeTableColumns(DdlBuffer apply, List<Column> columns, DdlIdentity identity) {
|
||||
platformDdl.writeTableColumns(apply, columns, identity);
|
||||
}
|
||||
|
||||
@@ -365,7 +322,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
* Specific handling of OneToOne unique constraints for MsSqlServer.
|
||||
* For all other DB platforms these unique constraints are done inline as per normal.
|
||||
*/
|
||||
protected void writeUniqueOneToOneConstraints(DdlWrite write, CreateTable createTable) throws IOException {
|
||||
protected void writeUniqueOneToOneConstraints(DdlWrite writer, CreateTable createTable) {
|
||||
String tableName = createTable.getName();
|
||||
for (Column col : externalUnique) {
|
||||
String uqName = col.getUniqueOneToOne();
|
||||
@@ -373,8 +330,9 @@ public class BaseTableDdl implements TableDdl {
|
||||
uqName = col.getUnique();
|
||||
}
|
||||
String[] columnNames = {col.getName()};
|
||||
write.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, Boolean.TRUE.equals(col.isNotnull()) ? null : columnNames));
|
||||
write.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, tableName));
|
||||
String[] nullableColumns = Boolean.TRUE.equals(col.isNotnull()) ? null : columnNames;
|
||||
writer.applyPostAlter().appendStatement(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, nullableColumns));
|
||||
writer.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, tableName));
|
||||
}
|
||||
|
||||
for (UniqueConstraint constraint : externalCompoundUnique) {
|
||||
@@ -382,12 +340,12 @@ public class BaseTableDdl implements TableDdl {
|
||||
String[] columnNames = split(constraint.getColumnNames());
|
||||
String[] nullableColumns = split(constraint.getNullableColumns());
|
||||
|
||||
write.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, nullableColumns));
|
||||
write.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, tableName));
|
||||
writer.applyPostAlter().appendStatement(platformDdl.alterTableAddUniqueConstraint(tableName, uqName, columnNames, nullableColumns));
|
||||
writer.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, tableName));
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeSequence(DdlWrite writer, DdlIdentity identity) throws IOException {
|
||||
protected void writeSequence(DdlWrite writer, DdlIdentity identity) {
|
||||
String seqName = identity.getSequenceName();
|
||||
String createSeq = platformDdl.createSequence(seqName, identity);
|
||||
if (hasValue(createSeq)) {
|
||||
@@ -396,75 +354,75 @@ public class BaseTableDdl implements TableDdl {
|
||||
}
|
||||
}
|
||||
|
||||
protected void createWithHistory(DdlWrite writer, String name) throws IOException {
|
||||
protected void createWithHistory(DdlWrite writer, String name) {
|
||||
MTable table = writer.getTable(name);
|
||||
platformDdl.createWithHistory(writer, table);
|
||||
}
|
||||
|
||||
protected void writeInlineForeignKeys(DdlWrite write, CreateTable createTable) throws IOException {
|
||||
protected void writeInlineForeignKeys(DdlBuffer buffer, CreateTable createTable) {
|
||||
for (Column column : createTable.getColumn()) {
|
||||
String references = column.getReferences();
|
||||
if (hasValue(references)) {
|
||||
writeInlineForeignKey(write, column);
|
||||
writeInlineForeignKey(buffer, column);
|
||||
}
|
||||
}
|
||||
writeInlineCompoundForeignKeys(write, createTable);
|
||||
writeInlineCompoundForeignKeys(buffer, createTable);
|
||||
}
|
||||
|
||||
protected void writeInlineForeignKey(DdlWrite write, Column column) throws IOException {
|
||||
protected void writeInlineForeignKey(DdlBuffer buffer, Column column) {
|
||||
String fkConstraint = platformDdl.tableInlineForeignKey(new WriteForeignKey(null, column));
|
||||
write.apply().append(",").newLine().append(" ").append(fkConstraint);
|
||||
buffer.append(",").newLine().append(" ").append(fkConstraint);
|
||||
}
|
||||
|
||||
protected void writeInlineCompoundForeignKeys(DdlWrite write, CreateTable createTable) throws IOException {
|
||||
protected void writeInlineCompoundForeignKeys(DdlBuffer buffer, CreateTable createTable) {
|
||||
for (ForeignKey key : createTable.getForeignKey()) {
|
||||
String fkConstraint = platformDdl.tableInlineForeignKey(new WriteForeignKey(null, key));
|
||||
write.apply().append(",").newLine().append(" ").append(fkConstraint);
|
||||
buffer.append(",").newLine().append(" ").append(fkConstraint);
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeAddForeignKeys(DdlWrite write, CreateTable createTable) throws IOException {
|
||||
protected void writeAddForeignKeys(DdlWrite writer, CreateTable createTable) {
|
||||
for (Column column : createTable.getColumn()) {
|
||||
String references = column.getReferences();
|
||||
if (hasValue(references)) {
|
||||
writeForeignKey(write, createTable.getName(), column);
|
||||
writeForeignKey(writer, createTable.getName(), column);
|
||||
}
|
||||
}
|
||||
writeAddCompoundForeignKeys(write, createTable);
|
||||
writeAddCompoundForeignKeys(writer, createTable);
|
||||
}
|
||||
|
||||
protected void writeAddCompoundForeignKeys(DdlWrite write, CreateTable createTable) throws IOException {
|
||||
protected void writeAddCompoundForeignKeys(DdlWrite writer, CreateTable createTable) {
|
||||
for (ForeignKey key : createTable.getForeignKey()) {
|
||||
writeForeignKey(write, new WriteForeignKey(createTable.getName(), key));
|
||||
writeForeignKey(writer, new WriteForeignKey(createTable.getName(), key));
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeForeignKey(DdlWrite write, String tableName, Column column) throws IOException {
|
||||
writeForeignKey(write, new WriteForeignKey(tableName, column));
|
||||
protected void writeForeignKey(DdlWrite writer, String tableName, Column column) {
|
||||
writeForeignKey(writer, new WriteForeignKey(tableName, column));
|
||||
}
|
||||
|
||||
protected void writeForeignKey(DdlWrite write, WriteForeignKey request) throws IOException {
|
||||
DdlBuffer fkeyBuffer = write.applyForeignKeys();
|
||||
protected void writeForeignKey(DdlWrite writer, WriteForeignKey request) {
|
||||
DdlBuffer fkeyBuffer = writer.applyForeignKeys();
|
||||
String tableName = lowerTableName(request.table());
|
||||
if (request.indexName() != null) {
|
||||
// no matching unique constraint so add the index
|
||||
fkeyBuffer.appendStatement(platformDdl.createIndex(new WriteCreateIndex(request.indexName(), tableName, request.cols(), false)));
|
||||
}
|
||||
alterTableAddForeignKey(write.getOptions(), fkeyBuffer, request);
|
||||
alterTableAddForeignKey(writer.getOptions(), fkeyBuffer, request);
|
||||
fkeyBuffer.end();
|
||||
|
||||
write.dropAllForeignKeys().appendStatement(platformDdl.alterTableDropForeignKey(tableName, request.fkName()));
|
||||
writer.dropAllForeignKeys().appendStatement(platformDdl.alterTableDropForeignKey(tableName, request.fkName()));
|
||||
if (hasValue(request.indexName())) {
|
||||
write.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(request.indexName(), tableName));
|
||||
writer.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(request.indexName(), tableName));
|
||||
}
|
||||
write.dropAllForeignKeys().end();
|
||||
writer.dropAllForeignKeys().end();
|
||||
}
|
||||
|
||||
protected void alterTableAddForeignKey(DdlOptions options, DdlBuffer buffer, WriteForeignKey request) throws IOException {
|
||||
protected void alterTableAddForeignKey(DdlOptions options, DdlBuffer buffer, WriteForeignKey request) {
|
||||
buffer.appendStatement(platformDdl.alterTableAddForeignKey(options, request));
|
||||
}
|
||||
|
||||
protected void appendColumns(String[] columns, DdlBuffer buffer) throws IOException {
|
||||
protected void appendColumns(String[] columns, DdlBuffer buffer) {
|
||||
buffer.append(" (");
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
if (i > 0) {
|
||||
@@ -478,18 +436,18 @@ public class BaseTableDdl implements TableDdl {
|
||||
/**
|
||||
* Add 'drop table' statement to the buffer.
|
||||
*/
|
||||
protected void dropTable(DdlBuffer buffer, String tableName) throws IOException {
|
||||
protected void dropTable(DdlBuffer buffer, String tableName) {
|
||||
buffer.appendStatement(platformDdl.dropTable(tableName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'drop sequence' statement to the buffer.
|
||||
*/
|
||||
protected void dropSequence(DdlBuffer buffer, String sequenceName) throws IOException {
|
||||
protected void dropSequence(DdlBuffer buffer, String sequenceName) {
|
||||
buffer.appendStatement(platformDdl.dropSequence(sequenceName));
|
||||
}
|
||||
|
||||
protected void writeCompoundUniqueConstraints(DdlBuffer apply, CreateTable createTable) throws IOException {
|
||||
protected void writeCompoundUniqueConstraints(DdlBuffer apply, CreateTable createTable) {
|
||||
boolean inlineUniqueWhenNull = platformDdl.isInlineUniqueWhenNullable();
|
||||
for (UniqueConstraint uniqueConstraint : createTable.getUniqueConstraint()) {
|
||||
if (platformInclude(uniqueConstraint.getPlatforms())) {
|
||||
@@ -512,7 +470,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
/**
|
||||
* Write the unique constraints inline with the create table statement.
|
||||
*/
|
||||
protected void writeUniqueConstraints(DdlBuffer apply, CreateTable createTable) throws IOException {
|
||||
protected void writeUniqueConstraints(DdlBuffer apply, CreateTable createTable) {
|
||||
boolean inlineUniqueWhenNullable = platformDdl.isInlineUniqueWhenNullable();
|
||||
List<Column> columns = new WriteUniqueConstraint(createTable.getColumn()).uniqueKeys();
|
||||
for (Column column : columns) {
|
||||
@@ -529,7 +487,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
/**
|
||||
* Write the unique constraint inline with the create table statement.
|
||||
*/
|
||||
protected void inlineUniqueConstraintSingle(DdlBuffer buffer, Column column) throws IOException {
|
||||
protected void inlineUniqueConstraintSingle(DdlBuffer buffer, Column column) {
|
||||
String uqName = column.getUnique();
|
||||
if (uqName == null) {
|
||||
uqName = column.getUniqueOneToOne();
|
||||
@@ -544,7 +502,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
/**
|
||||
* Write the primary key constraint inline with the create table statement.
|
||||
*/
|
||||
protected void writePrimaryKeyConstraint(DdlBuffer buffer, String pkName, String[] pkColumns) throws IOException {
|
||||
protected void writePrimaryKeyConstraint(DdlBuffer buffer, String pkName, String[] pkColumns) {
|
||||
buffer.append(",").newLine();
|
||||
buffer.append(" constraint ").append(pkName).append(" primary key");
|
||||
appendColumns(pkColumns, buffer);
|
||||
@@ -589,43 +547,43 @@ public class BaseTableDdl implements TableDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, CreateIndex index) throws IOException {
|
||||
public void generate(DdlWrite writer, CreateIndex index) {
|
||||
if (platformInclude(index.getPlatforms())) {
|
||||
flushReorgTables(writer.apply());
|
||||
writer.apply().appendStatement(platformDdl.createIndex(new WriteCreateIndex(index)));
|
||||
writer.applyForeignKeys().appendStatement(platformDdl.createIndex(new WriteCreateIndex(index)));
|
||||
writer.dropAll().appendStatement(platformDdl.dropIndex(index.getIndexName(), index.getTableName(), Boolean.TRUE.equals(index.isConcurrent())));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropIndex dropIndex) throws IOException {
|
||||
public void generate(DdlWrite writer, DropIndex dropIndex) {
|
||||
if (platformInclude(dropIndex.getPlatforms())) {
|
||||
flushReorgTables(writer.apply());
|
||||
writer.apply().appendStatement(platformDdl.dropIndex(dropIndex.getIndexName(), dropIndex.getTableName(), Boolean.TRUE.equals(dropIndex.isConcurrent())));
|
||||
writer.applyDropDependencies()
|
||||
.appendStatement(platformDdl.dropIndex(dropIndex.getIndexName(), dropIndex.getTableName(), Boolean.TRUE.equals(dropIndex.isConcurrent())));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddUniqueConstraint constraint) throws IOException {
|
||||
public void generate(DdlWrite writer, AddUniqueConstraint constraint) {
|
||||
if (platformInclude(constraint.getPlatforms())) {
|
||||
if (DdlHelp.isDropConstraint(constraint.getColumnNames())) {
|
||||
writer.apply().appendStatement(platformDdl.alterTableDropUniqueConstraint(constraint.getTableName(), constraint.getConstraintName()));
|
||||
writer.applyDropDependencies()
|
||||
.appendStatement(platformDdl.alterTableDropUniqueConstraint(constraint.getTableName(), constraint.getConstraintName()));
|
||||
|
||||
} else {
|
||||
flushReorgTables(writer.apply());
|
||||
String[] cols = split(constraint.getColumnNames());
|
||||
String[] nullableColumns = split(constraint.getNullableColumns());
|
||||
writer.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(constraint.getTableName(), constraint.getConstraintName(), cols, nullableColumns));
|
||||
writer.applyPostAlter()
|
||||
.appendStatement(platformDdl.alterTableAddUniqueConstraint(constraint.getTableName(), constraint.getConstraintName(), cols, nullableColumns));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AlterForeignKey alterForeignKey) throws IOException {
|
||||
public void generate(DdlWrite writer, AlterForeignKey alterForeignKey) {
|
||||
if (DdlHelp.isDropForeignKey(alterForeignKey.getColumnNames())) {
|
||||
writer.apply().appendStatement(platformDdl.alterTableDropForeignKey(alterForeignKey.getTableName(), alterForeignKey.getName()));
|
||||
writer.applyDropDependencies().appendStatement(platformDdl.alterTableDropForeignKey(alterForeignKey.getTableName(), alterForeignKey.getName()));
|
||||
} else {
|
||||
writer.apply().appendStatement(platformDdl.alterTableAddForeignKey(writer.getOptions(), new WriteForeignKey(alterForeignKey)));
|
||||
writer.applyForeignKeys().appendStatement(platformDdl.alterTableAddForeignKey(writer.getOptions(), new WriteForeignKey(alterForeignKey)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,7 +591,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
* Add add history table DDL.
|
||||
*/
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
public void generate(DdlWrite writer, AddHistoryTable addHistoryTable) {
|
||||
platformDdl.addHistoryTable(writer, addHistoryTable);
|
||||
}
|
||||
|
||||
@@ -641,37 +599,27 @@ public class BaseTableDdl implements TableDdl {
|
||||
* Add drop history table DDL.
|
||||
*/
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
|
||||
public void generate(DdlWrite writer, DropHistoryTable dropHistoryTable) {
|
||||
platformDdl.dropHistoryTable(writer, dropHistoryTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateProlog(DdlWrite write) throws IOException {
|
||||
platformDdl.generateProlog(write);
|
||||
public void generateProlog(DdlWrite writer) {
|
||||
platformDdl.generateProlog(writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called at the end to generate additional ddl such as regenerate history triggers.
|
||||
*/
|
||||
@Override
|
||||
public void generateEpilog(DdlWrite write) throws IOException {
|
||||
if (!regenerateHistoryTriggers.isEmpty()) {
|
||||
platformDdl.lockTables(write.applyHistoryTrigger(), regenerateHistoryTriggers.keySet());
|
||||
|
||||
for (HistoryTableUpdate update : this.regenerateHistoryTriggers.values()) {
|
||||
platformDdl.regenerateHistoryTriggers(write, update);
|
||||
}
|
||||
|
||||
platformDdl.unlockTables(write.applyHistoryTrigger(), regenerateHistoryTriggers.keySet());
|
||||
}
|
||||
platformDdl.generateEpilog(write);
|
||||
flushReorgTables(write.apply());
|
||||
public void generateEpilog(DdlWrite writer) {
|
||||
platformDdl.generateEpilog(writer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddTableComment addTableComment) throws IOException {
|
||||
public void generate(DdlWrite writer, AddTableComment addTableComment) {
|
||||
if (hasValue(addTableComment.getComment())) {
|
||||
platformDdl.addTableComment(writer.apply(), addTableComment.getName(), addTableComment.getComment());
|
||||
platformDdl.addTableComment(writer.applyPostAlter(), addTableComment.getName(), addTableComment.getComment());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -679,18 +627,20 @@ public class BaseTableDdl implements TableDdl {
|
||||
* Add add column DDL.
|
||||
*/
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddColumn addColumn) throws IOException {
|
||||
public void generate(DdlWrite writer, AddColumn addColumn) {
|
||||
String tableName = addColumn.getTableName();
|
||||
List<Column> columns = addColumn.getColumn();
|
||||
for (Column column : columns) {
|
||||
alterTableAddColumn(writer.apply(), tableName, column, false, isTrue(addColumn.isWithHistory()));
|
||||
alterTableAddColumn(writer, tableName, column, false, isTrue(addColumn.isWithHistory()));
|
||||
}
|
||||
if (isTrue(addColumn.isWithHistory()) && historySupport == HistorySupport.TRIGGER_BASED) {
|
||||
if (isTrue(addColumn.isWithHistory())) {
|
||||
platformDdl.regenerateHistoryTriggers(writer, tableName);
|
||||
// make same changes to the history table
|
||||
String historyTable = historyTable(tableName);
|
||||
for (Column column : columns) {
|
||||
regenerateHistoryTriggers(tableName, HistoryTableUpdate.Change.ADD, column.getName());
|
||||
alterTableAddColumn(writer.apply(), historyTable, column, true, true);
|
||||
if (alterHistoryTables) {
|
||||
String historyTable = historyTable(tableName);
|
||||
for (Column column : columns) {
|
||||
alterTableAddColumn(writer, historyTable, column, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Column column : columns) {
|
||||
@@ -698,27 +648,26 @@ public class BaseTableDdl implements TableDdl {
|
||||
writeForeignKey(writer, tableName, column);
|
||||
}
|
||||
}
|
||||
writer.apply().end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add drop table DDL.
|
||||
*/
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropTable dropTable) throws IOException {
|
||||
dropTable(writer.apply(), dropTable.getName());
|
||||
public void generate(DdlWrite writer, DropTable dropTable) {
|
||||
dropTable(writer.applyPostAlter(), dropTable.getName());
|
||||
if (hasValue(dropTable.getSequenceCol())
|
||||
&& platformDdl.getPlatform().getDbIdentity().isSupportsSequence()) {
|
||||
String sequenceName = dropTable.getSequenceName();
|
||||
if (!hasValue(sequenceName)) {
|
||||
sequenceName = namingConvention.getSequenceName(dropTable.getName(), dropTable.getSequenceCol());
|
||||
}
|
||||
dropSequence(writer.apply(), sequenceName);
|
||||
dropSequence(writer.applyPostAlter(), sequenceName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AlterTable alterTable) throws IOException {
|
||||
public void generate(DdlWrite writer, AlterTable alterTable) {
|
||||
if (hasValue(alterTable.getTablespace()) || hasValue(alterTable.getIndexTablespace()) || hasValue(alterTable.getLobTablespace())) {
|
||||
writer.apply().appendStatement(platformDdl.alterTableTablespace(alterTable.getName(),
|
||||
DdlHelp.toTablespace(alterTable.getTablespace()),
|
||||
@@ -727,8 +676,7 @@ public class BaseTableDdl implements TableDdl {
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeTablespaceChange(DdlBuffer buffer, String tablename, String tableSpace, String indexSpace,
|
||||
String lobSpace) throws IOException {
|
||||
protected void writeTablespaceChange(DdlBuffer buffer, String tablename, String tableSpace, String indexSpace, String lobSpace) {
|
||||
buffer.appendStatement("-- TableSpace changed: Table: " + tablename + ", tableSpace " + tableSpace + ", indexSpace "
|
||||
+ indexSpace + ", lobSpace " + lobSpace);
|
||||
if (strictMode) {
|
||||
@@ -741,30 +689,32 @@ public class BaseTableDdl implements TableDdl {
|
||||
* Add drop column DDL.
|
||||
*/
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropColumn dropColumn) throws IOException {
|
||||
public void generate(DdlWrite writer, DropColumn dropColumn) {
|
||||
String tableName = dropColumn.getTableName();
|
||||
alterTableDropColumn(writer.apply(), tableName, dropColumn.getColumnName());
|
||||
alterTableDropColumn(writer, tableName, dropColumn.getColumnName());
|
||||
|
||||
if (isTrue(dropColumn.isWithHistory()) && historySupport == HistorySupport.TRIGGER_BASED) {
|
||||
if (isTrue(dropColumn.isWithHistory())) {
|
||||
platformDdl.regenerateHistoryTriggers(writer, tableName);
|
||||
// also drop from the history table
|
||||
regenerateHistoryTriggers(tableName, HistoryTableUpdate.Change.DROP, dropColumn.getColumnName());
|
||||
alterTableDropColumn(writer.apply(), historyTable(tableName), dropColumn.getColumnName());
|
||||
if (alterHistoryTables) {
|
||||
alterTableDropColumn(writer, historyTable(tableName), dropColumn.getColumnName());
|
||||
}
|
||||
}
|
||||
writer.apply().end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all the appropriate changes based on the column changes.
|
||||
*/
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException {
|
||||
public void generate(DdlWrite writer, AlterColumn alterColumn) {
|
||||
DdlMigrationHelp ddlHelp = new DdlMigrationHelp(alterColumn);
|
||||
ddlHelp.writeBefore(writer.apply());
|
||||
ddlHelp.write(writer);
|
||||
|
||||
if (isTrue(alterColumn.isHistoryExclude())) {
|
||||
regenerateHistoryTriggers(alterColumn.getTableName(), HistoryTableUpdate.Change.EXCLUDE, alterColumn.getColumnName());
|
||||
} else if (isFalse(alterColumn.isHistoryExclude())) {
|
||||
regenerateHistoryTriggers(alterColumn.getTableName(), HistoryTableUpdate.Change.INCLUDE, alterColumn.getColumnName());
|
||||
if (alterColumn.isHistoryExclude() != null) {
|
||||
// CHECKME should we drop a small comment, if historyExclude changes, as not all DB systems will support this
|
||||
// writer.apply().append("-- historyExclude of ").append(alterColumn.getTableName()).append(".").append(alterColumn.getColumnName())
|
||||
// .append(" altered to ").append(String.valueOf(alterColumn.isHistoryExclude())).end();
|
||||
platformDdl.regenerateHistoryTriggers(writer, alterColumn.getTableName());
|
||||
}
|
||||
|
||||
if (hasValue(alterColumn.getDropForeignKey())) {
|
||||
@@ -796,31 +746,21 @@ public class BaseTableDdl implements TableDdl {
|
||||
// drop constraint before altering type etc
|
||||
dropCheckConstraint(writer, alterColumn, alterColumn.getCheckConstraintName());
|
||||
}
|
||||
boolean alterBaseAttributes = false;
|
||||
if (hasValue(alterColumn.getType())) {
|
||||
alterColumnType(writer, alterColumn);
|
||||
alterBaseAttributes = true;
|
||||
}
|
||||
if (hasValue(alterColumn.getDefaultValue())) {
|
||||
alterColumnDefaultValue(writer, alterColumn);
|
||||
alterBaseAttributes = true;
|
||||
}
|
||||
if (alterColumn.isNotnull() != null) {
|
||||
alterColumnNotnull(writer, alterColumn);
|
||||
alterBaseAttributes = true;
|
||||
}
|
||||
if (alterBaseAttributes) {
|
||||
alterColumnBaseAttributes(writer, alterColumn);
|
||||
|
||||
if (hasValue(alterColumn.getType())
|
||||
|| hasValue(alterColumn.getDefaultValue())
|
||||
|| alterColumn.isNotnull() != null) {
|
||||
alterColumn(writer, alterColumn);
|
||||
}
|
||||
|
||||
if (alterCheckConstraint) {
|
||||
// add constraint last (after potential type change)
|
||||
addCheckConstraint(writer, alterColumn);
|
||||
}
|
||||
ddlHelp.writeAfter(writer.apply());
|
||||
}
|
||||
|
||||
private void alterColumnComment(DdlWrite writer, AlterColumn alterColumn) throws IOException {
|
||||
platformDdl.addColumnComment(writer.apply(), alterColumn.getTableName(), alterColumn.getColumnName(), alterColumn.getComment());
|
||||
private void alterColumnComment(DdlWrite writer, AlterColumn alterColumn) {
|
||||
platformDdl.addColumnComment(writer.applyPostAlter(), alterColumn.getTableName(), alterColumn.getColumnName(), alterColumn.getComment());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -831,124 +771,106 @@ public class BaseTableDdl implements TableDdl {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the base table that we need to regenerate the history triggers on.
|
||||
* alter all the base attributes (type/default/notnull) of the column together.
|
||||
* Some platforms (like mysql/sqlserver/hana) must do that in one statement,
|
||||
* other platforms may use several statements for altering one of the base
|
||||
* attributes.
|
||||
*/
|
||||
protected void regenerateHistoryTriggers(String baseTableName, HistoryTableUpdate.Change change, String column) {
|
||||
HistoryTableUpdate update = regenerateHistoryTriggers.computeIfAbsent(baseTableName, HistoryTableUpdate::new);
|
||||
update.add(change, column);
|
||||
}
|
||||
protected void alterColumn(DdlWrite writer, AlterColumn alter) {
|
||||
platformDdl.alterColumn(writer, alter);
|
||||
|
||||
/**
|
||||
* This is mysql specific - alter all the base attributes of the column together.
|
||||
* Will be called, if there is a type, dbdefault or notnull change.
|
||||
*/
|
||||
protected void alterColumnBaseAttributes(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
String ddl = platformDdl.alterColumnBaseAttributes(alter);
|
||||
if (hasValue(ddl)) {
|
||||
writer.apply().appendStatement(ddl);
|
||||
|
||||
if (isTrue(alter.isWithHistory()) && alter.getType() != null && historySupport == HistorySupport.TRIGGER_BASED) {
|
||||
// mysql and sql server column type change allowing nulls in the history table column
|
||||
regenerateHistoryTriggers(alter.getTableName(), HistoryTableUpdate.Change.ALTER, alter.getColumnName());
|
||||
AlterColumn alterHistoryColumn = new AlterColumn();
|
||||
alterHistoryColumn.setTableName(historyTable(alter.getTableName()));
|
||||
alterHistoryColumn.setColumnName(alter.getColumnName());
|
||||
alterHistoryColumn.setType(alter.getType());
|
||||
String histColumnDdl = platformDdl.alterColumnBaseAttributes(alterHistoryColumn);
|
||||
|
||||
// write the apply to history table
|
||||
writer.apply().appendStatement(histColumnDdl);
|
||||
if (isTrue(alter.isWithHistory())) {
|
||||
// we will apply only type changes or notNull -> null transition
|
||||
boolean isNull = Boolean.FALSE.equals(alter.isNotnull());
|
||||
boolean applyToHistory = alter.getType() != null || isNull;
|
||||
boolean syncExact = platformDdl.getPlatform().isPlatform(Platform.DB2);
|
||||
// DB2 needs exact sync for notnull/null
|
||||
if (syncExact && alter.isNotnull() != null) {
|
||||
applyToHistory = true;
|
||||
}
|
||||
if (applyToHistory) {
|
||||
platformDdl.regenerateHistoryTriggers(writer, alter.getTableName());
|
||||
if (alterHistoryTables) {
|
||||
AlterColumn alterHistoryColumn = new AlterColumn();
|
||||
alterHistoryColumn.setTableName(historyTable(alter.getTableName()));
|
||||
alterHistoryColumn.setColumnName(alter.getColumnName());
|
||||
// ignore default value (not needed on history tables)
|
||||
alterHistoryColumn.setCurrentType(alter.getCurrentType());
|
||||
alterHistoryColumn.setType(alter.getType());
|
||||
if (syncExact) {
|
||||
alterHistoryColumn.setCurrentNotnull(alter.isCurrentNotnull());
|
||||
alterHistoryColumn.setNotnull(alter.isNotnull());
|
||||
} else if (isNull) {
|
||||
// do transition from notNull to null
|
||||
alterHistoryColumn.setCurrentNotnull(Boolean.TRUE);
|
||||
alterHistoryColumn.setNotnull(Boolean.FALSE);
|
||||
} else {
|
||||
// assume that the column contains null values from the past (required for platforms like mysql/sqlserver/hana)
|
||||
alterHistoryColumn.setCurrentNotnull(Boolean.FALSE);
|
||||
}
|
||||
platformDdl.alterColumn(writer, alterHistoryColumn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void alterColumnDefaultValue(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
writer.apply().appendStatement(platformDdl.alterColumnDefaultValue(alter.getTableName(), alter.getColumnName(), alter.getDefaultValue()));
|
||||
protected void dropCheckConstraint(DdlWrite writer, AlterColumn alter, String constraintName) {
|
||||
writer.applyDropDependencies()
|
||||
.appendStatement(platformDdl.alterTableDropConstraint(alter.getTableName(), constraintName));
|
||||
}
|
||||
|
||||
protected void dropCheckConstraint(DdlWrite writer, AlterColumn alter, String constraintName) throws IOException {
|
||||
writer.apply().appendStatement(platformDdl.alterTableDropConstraint(alter.getTableName(), constraintName));
|
||||
protected void addCheckConstraint(DdlWrite writer, AlterColumn alter) {
|
||||
writer.applyPostAlter()
|
||||
.appendStatement(platformDdl.alterTableAddCheckConstraint(alter.getTableName(), alter.getCheckConstraintName(), alter.getCheckConstraint()));
|
||||
}
|
||||
|
||||
protected void addCheckConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
writer.apply().appendStatement(platformDdl.alterTableAddCheckConstraint(alter.getTableName(), alter.getCheckConstraintName(), alter.getCheckConstraint()));
|
||||
protected void alterColumnAddForeignKey(DdlWrite writer, AlterColumn alterColumn) {
|
||||
alterTableAddForeignKey(writer.getOptions(), writer.applyForeignKeys(), new WriteForeignKey(alterColumn));
|
||||
}
|
||||
|
||||
protected void alterColumnNotnull(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
writer.apply().appendStatement(platformDdl.alterColumnNotnull(alter.getTableName(), alter.getColumnName(), alter.isNotnull()));
|
||||
needsReorg.add(alter.getTableName());
|
||||
protected void alterColumnDropForeignKey(DdlWrite writer, AlterColumn alter) {
|
||||
writer.applyDropDependencies()
|
||||
.appendStatement(platformDdl.alterTableDropForeignKey(alter.getTableName(), alter.getDropForeignKey()));
|
||||
}
|
||||
|
||||
protected void alterColumnType(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
String ddl = platformDdl.alterColumnType(alter.getTableName(), alter.getColumnName(), alter.getType());
|
||||
if (hasValue(ddl)) {
|
||||
needsReorg.add(alter.getTableName());
|
||||
writer.apply().appendStatement(ddl);
|
||||
if (isTrue(alter.isWithHistory()) && historySupport == HistorySupport.TRIGGER_BASED) {
|
||||
regenerateHistoryTriggers(alter.getTableName(), HistoryTableUpdate.Change.ALTER, alter.getColumnName());
|
||||
// apply same type change to matching column in the history table
|
||||
ddl = platformDdl.alterColumnType(historyTable(alter.getTableName()), alter.getColumnName(), alter.getType());
|
||||
writer.apply().appendStatement(ddl);
|
||||
}
|
||||
}
|
||||
protected void alterColumnDropUniqueConstraint(DdlWrite writer, AlterColumn alter) {
|
||||
writer.applyDropDependencies()
|
||||
.appendStatement(platformDdl.alterTableDropUniqueConstraint(alter.getTableName(), alter.getDropUnique()));
|
||||
}
|
||||
|
||||
protected void alterColumnAddForeignKey(DdlWrite writer, AlterColumn alterColumn) throws IOException {
|
||||
alterTableAddForeignKey(writer.getOptions(), writer.apply(), new WriteForeignKey(alterColumn));
|
||||
}
|
||||
|
||||
protected void alterColumnDropForeignKey(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
writer.apply().appendStatement(platformDdl.alterTableDropForeignKey(alter.getTableName(), alter.getDropForeignKey()));
|
||||
}
|
||||
|
||||
protected void alterColumnDropUniqueConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
writer.apply().appendStatement(platformDdl.alterTableDropUniqueConstraint(alter.getTableName(), alter.getDropUnique()));
|
||||
}
|
||||
|
||||
protected void alterColumnAddUniqueOneToOneConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
protected void alterColumnAddUniqueOneToOneConstraint(DdlWrite writer, AlterColumn alter) {
|
||||
addUniqueConstraint(writer, alter, alter.getUniqueOneToOne());
|
||||
}
|
||||
|
||||
protected void alterColumnAddUniqueConstraint(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
protected void alterColumnAddUniqueConstraint(DdlWrite writer, AlterColumn alter) {
|
||||
addUniqueConstraint(writer, alter, alter.getUnique());
|
||||
}
|
||||
|
||||
protected void addUniqueConstraint(DdlWrite writer, AlterColumn alter, String uqName) throws IOException {
|
||||
protected void addUniqueConstraint(DdlWrite writer, AlterColumn alter, String uqName) {
|
||||
String[] cols = {alter.getColumnName()};
|
||||
boolean notNull = alter.isNotnull() != null ? alter.isNotnull() : Boolean.TRUE.equals(alter.isNotnull());
|
||||
writer.apply().appendStatement(platformDdl.alterTableAddUniqueConstraint(alter.getTableName(), uqName, cols, notNull ? null : cols));
|
||||
writer.applyPostAlter()
|
||||
.appendStatement(platformDdl.alterTableAddUniqueConstraint(alter.getTableName(), uqName, cols, notNull ? null : cols));
|
||||
|
||||
writer.dropAllForeignKeys().appendStatement(platformDdl.dropIndex(uqName, alter.getTableName()));
|
||||
}
|
||||
|
||||
|
||||
protected void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException {
|
||||
platformDdl.alterTableDropColumn(buffer, tableName, columnName);
|
||||
needsReorg.add(tableName);
|
||||
protected void alterTableDropColumn(DdlWrite writer, String tableName, String columnName) {
|
||||
platformDdl.alterTableDropColumn(writer, tableName, columnName);
|
||||
}
|
||||
|
||||
protected void alterTableAddColumn(DdlBuffer buffer, String tableName, Column column, boolean onHistoryTable, boolean withHistory) throws IOException {
|
||||
protected void alterTableAddColumn(DdlWrite writer, String tableName, Column column, boolean onHistoryTable, boolean withHistory) {
|
||||
DdlMigrationHelp help = new DdlMigrationHelp(tableName, column, withHistory);
|
||||
if (!onHistoryTable) {
|
||||
help.writeBefore(buffer);
|
||||
help.write(writer);
|
||||
}
|
||||
|
||||
platformDdl.alterTableAddColumn(buffer, tableName, column, onHistoryTable, help.getDefaultValue());
|
||||
platformDdl.alterTableAddColumn(writer, tableName, column, onHistoryTable, help.getDefaultValue());
|
||||
final String comment = column.getComment();
|
||||
if (comment != null && !comment.isEmpty()) {
|
||||
platformDdl.addColumnComment(buffer, tableName, column.getName(), comment);
|
||||
platformDdl.addColumnComment(writer.applyPostAlter(), tableName, column.getName(), comment);
|
||||
}
|
||||
|
||||
if (!onHistoryTable) {
|
||||
help.writeAfter(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
protected void flushReorgTables(DdlBuffer buffer) throws IOException {
|
||||
for (String table : needsReorg) {
|
||||
buffer.appendStatement(platformDdl.reorgTable(table, ++reorgCount));
|
||||
}
|
||||
needsReorg.clear();
|
||||
}
|
||||
|
||||
protected boolean isFalse(Boolean value) {
|
||||
|
||||
+1
@@ -15,6 +15,7 @@ class ClickHouseDbArray {
|
||||
mapping.put("integer[]", "Array(UInt32)");
|
||||
mapping.put("bigint[]", "Array(UInt64)");
|
||||
mapping.put("float[]", "Array(Float32)");
|
||||
mapping.put("decimal[]", "Array(Decimal)");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-8
@@ -6,8 +6,6 @@ import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ClickHouseDdl extends PlatformDdl {
|
||||
|
||||
private static final String LOG_TABLE = "ENGINE = Log()";
|
||||
@@ -16,6 +14,7 @@ public class ClickHouseDdl extends PlatformDdl {
|
||||
super(platform);
|
||||
this.includeStorageEngine = true;
|
||||
this.identitySuffix = "";
|
||||
this.columnNotNull = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -32,7 +31,7 @@ public class ClickHouseDdl extends PlatformDdl {
|
||||
* Add an table storage engine to the create table statement.
|
||||
*/
|
||||
@Override
|
||||
public void tableStorageEngine(DdlBuffer apply, String storageEngine) throws IOException {
|
||||
public void tableStorageEngine(DdlBuffer apply, String storageEngine) {
|
||||
if (storageEngine == null) {
|
||||
// default to Log() table but really should all be explicit (need arguments for MergeTree etc)
|
||||
storageEngine = LOG_TABLE;
|
||||
@@ -70,11 +69,6 @@ public class ClickHouseDdl extends PlatformDdl {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeColumnNotNull(DdlBuffer buffer) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) {
|
||||
// do nothing
|
||||
|
||||
+6
@@ -36,6 +36,12 @@ public class CockroachDdl extends PlatformDdl {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
|
||||
// workaround for: https://github.com/cockroachdb/cockroach/issues/42840
|
||||
return "drop index " + maxConstraintName(uniqueConstraintName) + " cascade";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInlineComments() {
|
||||
return false;
|
||||
|
||||
+134
-56
@@ -1,10 +1,14 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import io.ebean.annotation.ConstraintMode;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.ebean.util.StringHelper;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.Column;
|
||||
|
||||
/**
|
||||
* DB2 platform specific DDL.
|
||||
@@ -44,6 +48,7 @@ public class DB2Ddl extends PlatformDdl {
|
||||
this.columnSetNull = "drop not null";
|
||||
this.columnSetType = "set data type ";
|
||||
this.inlineUniqueWhenNullable = false;
|
||||
this.historyDdl = new Db2HistoryDdl();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,8 +76,9 @@ public class DB2Ddl extends PlatformDdl {
|
||||
if (uqName == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
sb.append("create unique index ").append(maxConstraintName(uqName));
|
||||
sb.append(" on ").append(lowerTableName(tableName)).append('(');
|
||||
sb = new StringBuilder("create unique index ");
|
||||
sb.append(maxConstraintName(uqName)).append(" on ").append(tableName).append('(');
|
||||
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
@@ -83,17 +89,82 @@ public class DB2Ddl extends PlatformDdl {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
// @Override
|
||||
// public void addTablespace(DdlBuffer apply, String tablespaceName, String indexTablespace, String lobTablespace)
|
||||
// throws IOException {
|
||||
// apply.append(" in ").append(tablespaceName).append(" index in ").append(indexTablespace).append(" long in ").append(lobTablespace);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void alterTableAddColumn(DdlWrite writer, String tableName, Column column, boolean onHistoryTable, String defaultValue) {
|
||||
|
||||
String convertedType = convert(column.getType());
|
||||
DdlBuffer buffer = alterTable(writer, tableName).append(addColumn, column.getName());
|
||||
buffer.append(convertedType);
|
||||
|
||||
// Add default value also to history table if it is not excluded
|
||||
if (defaultValue != null) {
|
||||
buffer.append(" default ");
|
||||
buffer.append(defaultValue);
|
||||
}
|
||||
|
||||
if (isTrue(column.isNotnull())) {
|
||||
buffer.appendWithSpace(columnNotNull);
|
||||
}
|
||||
// DB2 History table must match exact!
|
||||
if (!onHistoryTable) {
|
||||
// check constraints cannot be added in one statement for h2
|
||||
if (!StringHelper.isNull(column.getCheckConstraint())) {
|
||||
String ddl = alterTableAddCheckConstraint(tableName, column.getCheckConstraintName(), column.getCheckConstraint());
|
||||
writer.applyPostAlter().appendStatement(ddl);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public String alterTableDropForeignKey(String tableName, String fkName) {
|
||||
return alterTableDropConstraint(tableName, fkName);
|
||||
};
|
||||
|
||||
@Override
|
||||
public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
|
||||
return alterTableDropConstraint(tableName, uniqueConstraintName) + "\n"
|
||||
+ dropIndex(uniqueConstraintName, tableName);
|
||||
return alterTableDropConstraint(tableName, uniqueConstraintName)
|
||||
+ "\n" + dropIndex(uniqueConstraintName, tableName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendForeignKeyOnUpdate(StringBuilder buffer, ConstraintMode mode) {
|
||||
// do nothing, no on update clause for db2
|
||||
public String alterTableDropConstraint(String tableName, String constraintName) {
|
||||
StringBuilder sb = new StringBuilder(300);
|
||||
sb.append("delimiter $$\n")
|
||||
.append("begin\n")
|
||||
.append("if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = '")
|
||||
.append(maxConstraintName(constraintName).toUpperCase())
|
||||
.append("' and tabname = '").append(lowerTableName(tableName).toUpperCase()).append("') then\n")
|
||||
|
||||
.append(" prepare stmt from 'alter table ").append(lowerTableName(tableName))
|
||||
.append(" drop constraint ").append(maxConstraintName(constraintName)).append("';\n")
|
||||
|
||||
.append(" execute stmt;\n")
|
||||
.append("end if;\n")
|
||||
.append("end$$");
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dropIndex(String indexName, String tableName, boolean concurrent) {
|
||||
StringBuilder sb = new StringBuilder(300);
|
||||
sb.append("delimiter $$\n")
|
||||
.append("begin\n")
|
||||
.append("if exists (select indname from syscat.indexes where indschema = current_schema and indname = '")
|
||||
.append(maxConstraintName(indexName).toUpperCase()).append("') then\n")
|
||||
.append(" prepare stmt from 'drop index ").append(maxConstraintName(indexName)).append("';\n")
|
||||
.append(" execute stmt;\n")
|
||||
.append("end if;\n")
|
||||
.append("end$$");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dropSequence(String sequenceName) {
|
||||
@@ -101,61 +172,68 @@ public class DB2Ddl extends PlatformDdl {
|
||||
sb.append("delimiter $$\n");
|
||||
sb.append("begin\n");
|
||||
sb.append("if exists (select seqschema from syscat.sequences where seqschema = current_schema and seqname = '")
|
||||
.append(maxConstraintName(sequenceName).toUpperCase()).append("') then\n");
|
||||
.append(maxConstraintName(sequenceName).toUpperCase()).append("') then\n");
|
||||
sb.append(" prepare stmt from 'drop sequence ").append(maxConstraintName(sequenceName)).append("';\n");
|
||||
sb.append(" execute stmt;\n");
|
||||
sb.append("end if;\n");
|
||||
sb.append("end$$");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableDropForeignKey(String tableName, String fkName) {
|
||||
return alterTableDropConstraint(tableName, fkName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableDropConstraint(String tableName, String constraintName) {
|
||||
StringBuilder sb = new StringBuilder(300);
|
||||
sb.append("delimiter $$\n");
|
||||
sb.append("begin\n");
|
||||
sb.append("if exists (select constname from syscat.tabconst where tabschema = current_schema and constname = '");
|
||||
sb.append(maxConstraintName(constraintName).toUpperCase());
|
||||
sb.append("' and tabname = '").append(lowerTableName(tableName).toUpperCase()).append("') then\n");
|
||||
|
||||
sb.append(" prepare stmt from 'alter table ").append(lowerTableName(tableName));
|
||||
sb.append(" drop constraint ").append(maxConstraintName(constraintName)).append("';\n");
|
||||
|
||||
sb.append(" execute stmt;\n");
|
||||
sb.append("end if;\n");
|
||||
sb.append("end$$");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dropIndex(String indexName, String tableName, boolean concurrent) {
|
||||
StringBuilder sb = new StringBuilder(300);
|
||||
sb.append("delimiter $$\n");
|
||||
sb.append("begin\n");
|
||||
sb.append("if exists (select indname from syscat.indexes where indschema = current_schema and indname = '");
|
||||
sb.append(maxConstraintName(indexName).toUpperCase()).append("') then\n");
|
||||
@Override
|
||||
protected DdlAlterTable alterTable(DdlWrite writer, String tableName) {
|
||||
return writer.applyAlterTable(tableName, Db2AlterTableWrite::new);
|
||||
};
|
||||
static class Db2AlterTableWrite extends BaseAlterTableWrite {
|
||||
|
||||
sb.append(" prepare stmt from 'drop index ").append(maxConstraintName(indexName)).append("';\n");
|
||||
sb.append(" execute stmt;\n");
|
||||
sb.append("end if;\n");
|
||||
sb.append("end$$");
|
||||
return sb.toString();
|
||||
}
|
||||
public Db2AlterTableWrite(String tableName) {
|
||||
super(tableName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String reorgTable(String table, int counter) {
|
||||
return "call sysproc.admin_cmd('reorg table " + lowerTableName(table) + "') /* reorg #" + counter + " */";
|
||||
@Override
|
||||
protected List<AlterCmd> postProcessCommands(List<AlterCmd> cmds) {
|
||||
List<AlterCmd> ret = new ArrayList<>(cmds.size() + 1);
|
||||
boolean requiresReorg = false;
|
||||
for (AlterCmd cmd : cmds) {
|
||||
ret.add(cmd);
|
||||
if (!requiresReorg && checkReorg(cmd)) {
|
||||
requiresReorg = true;
|
||||
}
|
||||
}
|
||||
if (requiresReorg) {
|
||||
ret.add(newRawCommand("call sysproc.admin_cmd('reorg table " + tableName() + "')"));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* determine, if we need a reorg.
|
||||
*
|
||||
* See: https://www.ibm.com/docs/en/db2/11.5?topic=statements-alter-table The following is the full list of REORG-recommended
|
||||
* ALTER statements that cause a version change and place the table into a REORG-pending state:
|
||||
* <ul>
|
||||
* <li>DROP COLUMN
|
||||
* <li>ALTER COLUMN SET NOT NULL
|
||||
* <li>ALTER COLUMN DROP NOT NULL
|
||||
* <li>ALTER COLUMN SET DATA TYPE, except in the following situations:<br>
|
||||
* Increasing the length of a VARCHAR or VARGRAPHIC column<br>
|
||||
* Decreasing the length of a VARCHAR or VARGRAPHIC column without truncating trailing blanks from existing data, when no indexes
|
||||
* exist on the column
|
||||
* </ul>
|
||||
*
|
||||
*/
|
||||
private boolean checkReorg(AlterCmd cmd) {
|
||||
switch (cmd.getOperation()) {
|
||||
case "drop column":
|
||||
return true;
|
||||
case "alter column":
|
||||
String alter = cmd.getAlternation();
|
||||
return alter.equals("set not null")
|
||||
|| alter.equals("drop not default")
|
||||
|| alter.startsWith("set data type"); // note: altering varchar length only is not detected here
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTablespace(DdlBuffer apply, String tablespaceName, String indexTablespace, String lobTablespace)
|
||||
throws IOException {
|
||||
apply.append(" in ").append(tablespaceName).append(" index in ").append(indexTablespace).append(" long in ").append(lobTablespace);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.model.MColumn;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
/**
|
||||
* DB2 History support.
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*/
|
||||
public class Db2HistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
private String systemPeriodStart;
|
||||
private String systemPeriodEnd;
|
||||
private String transactionId;
|
||||
private PlatformDdl platformDdl;
|
||||
private String historySuffix;
|
||||
|
||||
@Override
|
||||
public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
this.systemPeriodStart = config.getAsOfSysPeriod() + "_start";
|
||||
this.systemPeriodEnd = config.getAsOfSysPeriod() + "_end";
|
||||
this.transactionId = config.getAsOfSysPeriod() + "_txn"; // required for DB2
|
||||
this.platformDdl = platformDdl;
|
||||
this.historySuffix = config.getHistoryTableSuffix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) {
|
||||
String tableName = table.getName();
|
||||
String historyTableName = tableName + historySuffix;
|
||||
|
||||
DdlBuffer apply = writer.applyPostAlter();
|
||||
apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(historyTableName).append(" (").newLine();
|
||||
|
||||
// create history table
|
||||
Collection<MColumn> cols = table.allColumns();
|
||||
for (MColumn column : cols) {
|
||||
if (!column.isDraftOnly()) {
|
||||
writeColumnDefinition(apply, column.getName(), column.getType(), column.isNotnull() || column.isPrimaryKey());
|
||||
apply.append(",").newLine();
|
||||
}
|
||||
}
|
||||
writeColumnDefinition(apply, systemPeriodStart, "timestamp(12)", true);
|
||||
apply.append(",").newLine();
|
||||
writeColumnDefinition(apply, systemPeriodEnd, "timestamp(12)", true);
|
||||
apply.append(",").newLine();
|
||||
writeColumnDefinition(apply, transactionId, "timestamp(12)", false);
|
||||
apply.newLine().append(")").endOfStatement();
|
||||
|
||||
// enable system versioning
|
||||
addSysPeriodColumns(writer, tableName);
|
||||
enableSystemVersioning(apply, tableName);
|
||||
platformDdl.alterTable(writer, tableName).setHistoryHandled();
|
||||
|
||||
// drop all: We do not drop columns here, as the whole table will be dropped
|
||||
disableSystemVersioning(writer.dropAll(), tableName);
|
||||
writer.dropAll().append("drop table ").append(historyTableName).endOfStatement();
|
||||
}
|
||||
|
||||
void addSysPeriodColumns(DdlWrite writer, String baseTable) {
|
||||
platformDdl.alterTableAddColumn(writer, baseTable, systemPeriodStart, "timestamp(12) not null generated always as row begin", null);
|
||||
platformDdl.alterTableAddColumn(writer, baseTable, systemPeriodEnd, "timestamp(12) not null generated always as row end", null);
|
||||
platformDdl.alterTableAddColumn(writer, baseTable, transactionId, "timestamp(12) generated always as transaction start id", null);
|
||||
platformDdl.alterTable(writer, baseTable).append("add period system_time", null)
|
||||
.append("(").append(systemPeriodStart).append(",").append(systemPeriodEnd).append(")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) {
|
||||
dropHistoryTable(writer, dropHistoryTable.getBaseTable(), dropHistoryTable.getBaseTable() + historySuffix);
|
||||
}
|
||||
|
||||
protected void dropHistoryTable(DdlWrite writer, String baseTable, String historyTable) {
|
||||
disableSystemVersioning(writer.apply(), baseTable);
|
||||
writer.apply().append("alter table ").append(baseTable).append(" drop period system_time").endOfStatement();
|
||||
|
||||
// drop the period & period columns
|
||||
platformDdl.alterTableDropColumn(writer, baseTable, systemPeriodStart);
|
||||
platformDdl.alterTableDropColumn(writer, baseTable, systemPeriodEnd);
|
||||
platformDdl.alterTableDropColumn(writer, baseTable, transactionId);
|
||||
|
||||
// drop the history table
|
||||
writer.applyPostAlter().append("drop table ").append(historyTable).endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) {
|
||||
MTable table = writer.getTable(addHistoryTable.getBaseTable());
|
||||
if (table == null) {
|
||||
throw new IllegalStateException("MTable " + addHistoryTable.getBaseTable() + " not found in writer? (required for history DDL)");
|
||||
}
|
||||
createWithHistory(writer, table);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alterHistoryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTriggers(DdlWrite writer, String tableName) {
|
||||
DdlAlterTable alter = platformDdl.alterTable(writer, tableName);
|
||||
MTable table = writer.getTable(tableName);
|
||||
if (table.isWithHistory() && !alter.isHistoryHandled()) {
|
||||
disableSystemVersioning(writer.apply(), tableName);
|
||||
enableSystemVersioning(writer.applyPostAlter(), tableName);
|
||||
alter.setHistoryHandled();
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeColumnDefinition(DdlBuffer buffer, String columnName, String type, boolean isNotNull) {
|
||||
|
||||
String platformType = platformDdl.convert(type);
|
||||
buffer.append(" ").append(platformDdl.lowerColumnName(columnName));
|
||||
buffer.append(" ").append(platformType);
|
||||
if (isNotNull) {
|
||||
buffer.append(" not null");
|
||||
}
|
||||
}
|
||||
|
||||
public void disableSystemVersioning(DdlBuffer apply, String tableName) {
|
||||
apply.append("alter table ").append(tableName).append(" drop versioning").endOfStatement();
|
||||
}
|
||||
|
||||
public void enableSystemVersioning(DdlBuffer apply, String tableName) {
|
||||
apply.append("alter table ").append(tableName).append(" add versioning use history table ").append(tableName).append(historySuffix).endOfStatement();
|
||||
}
|
||||
|
||||
}
|
||||
+79
-96
@@ -2,6 +2,7 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.DbConstraintNaming;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
@@ -9,8 +10,6 @@ import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.model.MColumn;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -49,51 +48,20 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTriggers(DdlWrite writer, HistoryTableUpdate update) throws IOException {
|
||||
|
||||
MTable table = writer.getTable(update.getBaseTable());
|
||||
if (table == null) {
|
||||
throw new IllegalStateException("MTable " + update.getBaseTable() + " not found in writer? (required for history DDL)");
|
||||
}
|
||||
updateTriggers(writer, table, update);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the existing triggers/stored procedures/views for history table support given the included columns.
|
||||
*/
|
||||
protected abstract void updateHistoryTriggers(DbTriggerUpdate triggerUpdate) throws IOException;
|
||||
|
||||
/**
|
||||
* Process the HistoryTableUpdate which can result in changes to the apply, rollback
|
||||
* and drop scripts.
|
||||
*/
|
||||
protected void updateTriggers(DdlWrite writer, MTable table, HistoryTableUpdate update) throws IOException {
|
||||
|
||||
writer.applyHistoryTrigger().append("-- changes: ").append(update.description()).newLine();
|
||||
|
||||
updateHistoryTriggers(createDbTriggerUpdate(writer, table));
|
||||
}
|
||||
|
||||
protected DbTriggerUpdate createDbTriggerUpdate(DdlWrite writer, MTable table) {
|
||||
|
||||
List<String> columns = columnNamesForApply(table);
|
||||
String baseTableName = table.getName();
|
||||
String historyTableName = historyTableName(baseTableName);
|
||||
return new DbTriggerUpdate(baseTableName, historyTableName, writer, columns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) {
|
||||
|
||||
String baseTable = dropHistoryTable.getBaseTable();
|
||||
|
||||
// drop in appropriate order
|
||||
dropTriggers(writer.applyDropDependencies(), baseTable);
|
||||
dropHistoryTableEtc(writer.applyDropDependencies(), baseTable);
|
||||
dropWithHistoryView(writer.applyDropDependencies(), baseTable);
|
||||
dropHistoryTable(writer.applyDropDependencies(), baseTable);
|
||||
|
||||
dropSysPeriodColumns(writer, baseTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) {
|
||||
|
||||
String baseTable = addHistoryTable.getBaseTable();
|
||||
MTable table = writer.getTable(baseTable);
|
||||
@@ -105,27 +73,55 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
public void createWithHistory(DdlWrite writer, MTable table) {
|
||||
|
||||
String baseTable = table.getName();
|
||||
String whenCreatedColumn = table.getWhenCreatedColumn();
|
||||
|
||||
addSysPeriodColumns(writer, baseTable, table.getWhenCreatedColumn());
|
||||
createHistoryTable(writer.applyPostAlter(), table);
|
||||
|
||||
createWithHistoryView(writer.applyPostAlter(), table.getName());
|
||||
createTriggers(writer.applyPostAlter(), baseTable, columnNamesForApply(table));
|
||||
writer.applyPostAlter().end();
|
||||
|
||||
// drop all scripts
|
||||
dropTriggers(writer.dropAll(), baseTable);
|
||||
dropHistoryTableEtc(writer.dropAll(), baseTable);
|
||||
dropWithHistoryView(writer.dropAll(), baseTable);
|
||||
dropHistoryTable(writer.dropAll(), baseTable);
|
||||
// no need to dropSysPeriodColumns as whole table will be deleted soon
|
||||
|
||||
addHistoryTable(writer, table, whenCreatedColumn);
|
||||
createStoredFunction(writer, table);
|
||||
createTriggers(writer, table);
|
||||
}
|
||||
|
||||
protected abstract void createTriggers(DdlWrite writer, MTable table) throws IOException;
|
||||
@Override
|
||||
public void updateTriggers(DdlWrite writer, String tableName) {
|
||||
MTable table = writer.getTable(tableName);
|
||||
if (table != null && table.isWithHistory()) {
|
||||
DdlAlterTable alter = platformDdl.alterTable(writer, tableName);
|
||||
if (!alter.isHistoryHandled()) {
|
||||
// this code effectively disables history support before the table alter and enables it again
|
||||
// immediately after the table alter. As all alters per table are altogether now, this can done here
|
||||
dropTriggers(writer.apply(), tableName);
|
||||
dropWithHistoryView(writer.apply(), tableName);
|
||||
// here are the alter commands
|
||||
createWithHistoryView(writer.applyPostAlter(), tableName);
|
||||
createTriggers(writer.applyPostAlter(), tableName, columnNamesForApply(table));
|
||||
|
||||
protected abstract void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException;
|
||||
|
||||
protected void createStoredFunction(DdlWrite writer, MTable table) throws IOException {
|
||||
// do nothing
|
||||
alter.setHistoryHandled();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will add a history trigger to the buffer. The config
|
||||
*
|
||||
* @param buffer
|
||||
* @param table
|
||||
*/
|
||||
protected abstract void createTriggers(DdlBuffer buffer, String baseTable, List<String> columnNames);
|
||||
|
||||
protected abstract void dropTriggers(DdlBuffer buffer, String baseTable);
|
||||
|
||||
|
||||
protected String normalise(String tableName) {
|
||||
return constraintNaming.normaliseTable(tableName);
|
||||
}
|
||||
@@ -150,35 +146,32 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
return normalise(baseTableName) + "_history_del";
|
||||
}
|
||||
|
||||
protected void addHistoryTable(DdlWrite writer, MTable table, String whenCreatedColumn) throws IOException {
|
||||
protected void addHistoryTable(DdlWrite writer, MTable table, String whenCreatedColumn) {
|
||||
|
||||
String baseTableName = table.getName();
|
||||
|
||||
DdlBuffer apply = writer.applyHistoryView();
|
||||
|
||||
addSysPeriodColumns(apply, baseTableName, whenCreatedColumn);
|
||||
createHistoryTable(apply, table);
|
||||
createWithHistoryView(apply, baseTableName);
|
||||
addSysPeriodColumns(writer, baseTableName, whenCreatedColumn);
|
||||
createHistoryTable(writer.applyPostAlter(), table);
|
||||
createWithHistoryView(writer.applyPostAlter(), baseTableName);
|
||||
}
|
||||
|
||||
protected void addSysPeriodColumns(DdlBuffer apply, String baseTableName, String whenCreatedColumn) throws IOException {
|
||||
|
||||
apply.append("alter table ").append(baseTableName).append(" add column ")
|
||||
.append(sysPeriodStart).append(" ").append(sysPeriodType).append(" default ").append(now).endOfStatement();
|
||||
apply.append("alter table ").append(baseTableName).append(" add column ")
|
||||
.append(sysPeriodEnd).append(" ").append(sysPeriodType).endOfStatement();
|
||||
protected void addSysPeriodColumns(DdlWrite writer, String baseTableName, String whenCreatedColumn) {
|
||||
|
||||
platformDdl.alterTableAddColumn(writer, baseTableName, sysPeriodStart, sysPeriodType, now);
|
||||
platformDdl.alterTableAddColumn(writer, baseTableName, sysPeriodEnd, sysPeriodType, null);
|
||||
if (whenCreatedColumn != null) {
|
||||
apply.append("update ").append(baseTableName).append(" set ").append(sysPeriodStart).append(" = ").append(whenCreatedColumn).endOfStatement();
|
||||
writer.applyPostAlter()
|
||||
.append("update ").append(baseTableName).append(" set ").append(sysPeriodStart).append(" = ").append(whenCreatedColumn).endOfStatement();
|
||||
}
|
||||
}
|
||||
|
||||
protected void createHistoryTable(DdlBuffer apply, MTable table) throws IOException {
|
||||
protected void createHistoryTable(DdlBuffer apply, MTable table) {
|
||||
createHistoryTableAs(apply, table);
|
||||
createHistoryTableWithPeriod(apply);
|
||||
}
|
||||
|
||||
protected void createHistoryTableAs(DdlBuffer apply, MTable table) throws IOException {
|
||||
protected void createHistoryTableAs(DdlBuffer apply, MTable table) {
|
||||
apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(table.getName()).append(historySuffix).append("(").newLine();
|
||||
for (MColumn column : table.allColumns()) {
|
||||
if (!column.isDraftOnly()) {
|
||||
@@ -188,7 +181,7 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
}
|
||||
}
|
||||
|
||||
protected void createHistoryTableWithPeriod(DdlBuffer apply) throws IOException {
|
||||
protected void createHistoryTableWithPeriod(DdlBuffer apply) {
|
||||
writeColumnDefinition(apply, sysPeriodStart, sysPeriodType);
|
||||
apply.append(",").newLine();
|
||||
writeColumnDefinition(apply, sysPeriodEnd, sysPeriodType);
|
||||
@@ -198,7 +191,7 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
/**
|
||||
* Write the column definition to the create table statement.
|
||||
*/
|
||||
protected void writeColumnDefinition(DdlBuffer buffer, String columnName, String type) throws IOException {
|
||||
protected void writeColumnDefinition(DdlBuffer buffer, String columnName, String type) {
|
||||
|
||||
String platformType = platformDdl.convert(type);
|
||||
buffer.append(" ");
|
||||
@@ -206,57 +199,43 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
buffer.append(platformType);
|
||||
}
|
||||
|
||||
protected void createWithHistoryView(DdlBuffer apply, String baseTableName) throws IOException {
|
||||
protected void createWithHistoryView(DdlBuffer apply, String baseTableName) {
|
||||
|
||||
apply
|
||||
.append("create view ").append(baseTableName).append(viewSuffix)
|
||||
.append(" as select * from ").append(baseTableName)
|
||||
.append(" union all select * from ").append(baseTableName).append(historySuffix)
|
||||
.endOfStatement().end();
|
||||
.endOfStatement();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For postgres/h2/mysql we need to drop and recreate the view. Well, we could add columns to the end of the view
|
||||
* but otherwise we need to drop and create it.
|
||||
*/
|
||||
protected void recreateHistoryView(DbTriggerUpdate update) throws IOException {
|
||||
|
||||
DdlBuffer buffer = update.dropDependencyBuffer();
|
||||
// we need to drop the view early/first before any changes to the tables etc
|
||||
buffer.append("drop view if exists ").append(update.getBaseTable()).append(viewSuffix).endOfStatement();
|
||||
|
||||
// recreate the view after all ddl modifications - the view requires ALL columns, also the historyExclude ones.
|
||||
createWithHistoryView(update.historyViewBuffer(), update.getBaseTable());
|
||||
}
|
||||
|
||||
protected void appendSysPeriodColumns(DdlBuffer apply, String prefix) throws IOException {
|
||||
protected void appendSysPeriodColumns(DdlBuffer apply, String prefix) {
|
||||
appendColumnName(apply, prefix, sysPeriodStart);
|
||||
appendColumnName(apply, prefix, sysPeriodEnd);
|
||||
}
|
||||
|
||||
protected void dropHistoryTableEtc(DdlBuffer buffer, String baseTableName) throws IOException {
|
||||
|
||||
buffer.append("drop view ").append(baseTableName).append(viewSuffix).endOfStatement();
|
||||
dropSysPeriodColumns(buffer, baseTableName);
|
||||
buffer.append("drop table ").append(baseTableName).append(historySuffix).endOfStatement().end();
|
||||
protected void dropWithHistoryView(DdlBuffer apply, String baseTableName) {
|
||||
apply.append("drop view ").append(baseTableName).append(viewSuffix).endOfStatement();
|
||||
}
|
||||
|
||||
protected void dropSysPeriodColumns(DdlBuffer buffer, String baseTableName) throws IOException {
|
||||
platformDdl.alterTableDropColumn(buffer, baseTableName, sysPeriodStart);
|
||||
platformDdl.alterTableDropColumn(buffer, baseTableName, sysPeriodEnd);
|
||||
protected void dropHistoryTable(DdlBuffer apply, String baseTableName) {
|
||||
apply.append("drop table ").append(baseTableName).append(historySuffix).endOfStatement().end();
|
||||
}
|
||||
|
||||
protected void appendInsertIntoHistory(DdlBuffer buffer, String historyTable, List<String> columns) throws IOException {
|
||||
protected void dropSysPeriodColumns(DdlWrite writer, String baseTableName) {
|
||||
platformDdl.alterTableDropColumn(writer, baseTableName, sysPeriodStart);
|
||||
platformDdl.alterTableDropColumn(writer, baseTableName, sysPeriodEnd);
|
||||
}
|
||||
|
||||
buffer.append(" insert into ").append(historyTable).append(" (").append(sysPeriodStart).append(",").append(sysPeriodEnd).append(",");
|
||||
protected void appendInsertIntoHistory(DdlBuffer buffer, String baseTable, List<String> columns) {
|
||||
|
||||
buffer.append(" insert into ").append(baseTable).append(historySuffix).append(" (").append(sysPeriodStart).append(",").append(sysPeriodEnd).append(",");
|
||||
appendColumnNames(buffer, columns, "");
|
||||
buffer.append(") values (OLD.").append(sysPeriodStart).append(", ").append(sysPeriodEndValue).append(",");
|
||||
appendColumnNames(buffer, columns, "OLD.");
|
||||
buffer.append(");").newLine();
|
||||
}
|
||||
|
||||
void appendColumnNames(DdlBuffer buffer, List<String> columns, String columnPrefix) throws IOException {
|
||||
void appendColumnNames(DdlBuffer buffer, List<String> columns, String columnPrefix) {
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
if (i > 0) {
|
||||
buffer.append(", ");
|
||||
@@ -269,7 +248,7 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
/**
|
||||
* Append a single column to the buffer if it is not null.
|
||||
*/
|
||||
void appendColumnName(DdlBuffer buffer, String prefix, String columnName) throws IOException {
|
||||
void appendColumnName(DdlBuffer buffer, String prefix, String columnName) {
|
||||
if (columnName != null) {
|
||||
buffer.append(prefix).append(columnName);
|
||||
}
|
||||
@@ -287,4 +266,8 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
|
||||
return table.allHistoryColumns(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alterHistoryTables() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* DB trigger update when a change occurs on a table with history.
|
||||
*/
|
||||
public class DbTriggerUpdate {
|
||||
|
||||
private final String baseTableName;
|
||||
|
||||
private final String historyTableName;
|
||||
|
||||
private final DdlWrite writer;
|
||||
|
||||
private final List<String> columns;
|
||||
|
||||
public DbTriggerUpdate(String baseTableName, String historyTableName, DdlWrite writer, List<String> columns) {
|
||||
this.baseTableName = baseTableName;
|
||||
this.historyTableName = historyTableName;
|
||||
this.writer = writer;
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the appropriate buffer for the current mode.
|
||||
*/
|
||||
public DdlBuffer historyViewBuffer() {
|
||||
return writer.applyHistoryView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the appropriate buffer for the current mode.
|
||||
*/
|
||||
public DdlBuffer historyTriggerBuffer() {
|
||||
return writer.applyHistoryTrigger();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the appropriate drop dependency buffer for the current mode.
|
||||
*/
|
||||
public DdlBuffer dropDependencyBuffer() {
|
||||
return writer.applyDropDependencies();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the base table name.
|
||||
*/
|
||||
public String getBaseTable() {
|
||||
return baseTableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the history table name.
|
||||
*/
|
||||
public String getHistoryTable() {
|
||||
return historyTableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the included columns.
|
||||
*/
|
||||
public List<String> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
}
|
||||
+6
-18
@@ -1,10 +1,8 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
import java.util.List;
|
||||
|
||||
import java.io.IOException;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
|
||||
/**
|
||||
* H2 history support using DB triggers to maintain a history table.
|
||||
@@ -20,26 +18,16 @@ public class H2HistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException {
|
||||
protected void dropTriggers(DdlBuffer buffer, String baseTable) {
|
||||
buffer.append("drop trigger ").append(updateTriggerName(baseTable)).endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createTriggers(DdlWrite writer, MTable table) throws IOException {
|
||||
String baseTableName = table.getName();
|
||||
DdlBuffer apply = writer.applyHistoryTrigger();
|
||||
addCreateTrigger(apply, updateTriggerName(baseTableName), baseTableName);
|
||||
protected void createTriggers(DdlBuffer buffer, String baseTable, List<String> columnNames) {
|
||||
addCreateTrigger(buffer, updateTriggerName(baseTable), baseTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateHistoryTriggers(DbTriggerUpdate update) throws IOException {
|
||||
recreateHistoryView(update);
|
||||
DdlBuffer buffer = update.historyTriggerBuffer();
|
||||
dropTriggers(buffer, update.getBaseTable());
|
||||
addCreateTrigger(buffer, updateTriggerName(update.getBaseTable()), update.getBaseTable());
|
||||
}
|
||||
|
||||
private void addCreateTrigger(DdlBuffer apply, String triggerName, String baseTable) throws IOException {
|
||||
private void addCreateTrigger(DdlBuffer apply, String triggerName, String baseTable) {
|
||||
// Note that this does not take into account the historyTable name (excepts _history suffix) and
|
||||
// does not take into account excluded columns (all columns included in history)
|
||||
apply
|
||||
|
||||
+10
-16
@@ -3,8 +3,6 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class HanaColumnStoreDdl extends AbstractHanaDdl {
|
||||
|
||||
public HanaColumnStoreDdl(DatabasePlatform platform) {
|
||||
@@ -31,20 +29,16 @@ public class HanaColumnStoreDdl extends AbstractHanaDdl {
|
||||
|
||||
@Override
|
||||
public String dropIndex(String indexName, String tableName, boolean concurrent) {
|
||||
DdlBuffer buffer = new BaseDdlBuffer(null);
|
||||
try {
|
||||
buffer.append("delimiter $$").newLine();
|
||||
buffer.append("do").newLine();
|
||||
buffer.append("begin").newLine();
|
||||
buffer.append("declare exit handler for sql_error_code 261 begin end").endOfStatement();
|
||||
buffer.append("exec '").append(dropIndexIfExists).append(maxConstraintName(indexName)).append("'")
|
||||
.endOfStatement();
|
||||
buffer.append("end").endOfStatement();
|
||||
buffer.append("$$");
|
||||
return buffer.getBuffer();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
DdlBuffer buffer = new BaseDdlBuffer();
|
||||
buffer.append("delimiter $$").newLine();
|
||||
buffer.append("do").newLine();
|
||||
buffer.append("begin").newLine();
|
||||
buffer.append("declare exit handler for sql_error_code 261 begin end").endOfStatement();
|
||||
buffer.append("exec '").append(dropIndexIfExists).append(maxConstraintName(indexName)).append("'")
|
||||
.endOfStatement();
|
||||
buffer.append("end").endOfStatement();
|
||||
buffer.append("$$");
|
||||
return buffer.getBuffer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.BaseDdlHandler;
|
||||
|
||||
public class HanaDdlHandler extends BaseDdlHandler {
|
||||
|
||||
public HanaDdlHandler(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
super(config, platformDdl, new HanaTableDdl(config, platformDdl));
|
||||
}
|
||||
}
|
||||
+26
-43
@@ -1,6 +1,7 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
@@ -8,11 +9,7 @@ import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.model.MColumn;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class HanaHistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
@@ -20,8 +17,6 @@ public class HanaHistoryDdl implements PlatformHistoryDdl {
|
||||
private String systemPeriodEnd;
|
||||
private PlatformDdl platformDdl;
|
||||
private String historySuffix;
|
||||
private final AtomicInteger counter = new AtomicInteger(0);
|
||||
private Map<String, String> createdHistoryTables = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
@@ -32,13 +27,10 @@ public class HanaHistoryDdl implements PlatformHistoryDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
public void createWithHistory(DdlWrite writer, MTable table) {
|
||||
String tableName = table.getName();
|
||||
String historyTableName = tableName + historySuffix;
|
||||
DdlBuffer apply = writer.applyHistoryView();
|
||||
if (apply.isEmpty()) {
|
||||
createdHistoryTables.clear();
|
||||
}
|
||||
DdlBuffer apply = writer.applyPostAlter();
|
||||
|
||||
apply.append(platformDdl.getCreateTableCommandPrefix()).append(" ").append(historyTableName).append(" (").newLine();
|
||||
|
||||
@@ -65,20 +57,19 @@ public class HanaHistoryDdl implements PlatformHistoryDdl {
|
||||
apply.append("alter table ").append(tableName).append(" add period for system_time(").append(systemPeriodStart)
|
||||
.append(",").append(systemPeriodEnd).append(")").endOfStatement();
|
||||
|
||||
enableSystemVersioning(apply, tableName, historyTableName, true, false);
|
||||
|
||||
createdHistoryTables.put(tableName, historyTableName);
|
||||
enableSystemVersioning(apply, tableName, true);
|
||||
platformDdl.alterTable(writer, tableName).setHistoryHandled();
|
||||
|
||||
dropHistoryTable(writer.dropAll(), tableName, historyTableName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) {
|
||||
dropHistoryTable(writer.applyDropDependencies(), dropHistoryTable.getBaseTable(),
|
||||
dropHistoryTable.getBaseTable() + historySuffix);
|
||||
}
|
||||
|
||||
protected void dropHistoryTable(DdlBuffer apply, String baseTable, String historyTable) throws IOException {
|
||||
protected void dropHistoryTable(DdlBuffer apply, String baseTable, String historyTable) {
|
||||
// disable system versioning
|
||||
disableSystemVersioning(apply, baseTable);
|
||||
|
||||
@@ -93,7 +84,7 @@ public class HanaHistoryDdl implements PlatformHistoryDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) {
|
||||
MTable table = writer.getTable(addHistoryTable.getBaseTable());
|
||||
if (table == null) {
|
||||
throw new IllegalStateException("MTable " + addHistoryTable.getBaseTable() + " not found in writer? (required for history DDL)");
|
||||
@@ -102,12 +93,23 @@ public class HanaHistoryDdl implements PlatformHistoryDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTriggers(DdlWrite write, HistoryTableUpdate baseTable) {
|
||||
// nothing to do
|
||||
public boolean alterHistoryTables() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTriggers(DdlWrite writer, String tableName) {
|
||||
DdlAlterTable alter = platformDdl.alterTable(writer, tableName);
|
||||
MTable table = writer.getTable(tableName);
|
||||
if (table.isWithHistory() && !alter.isHistoryHandled()) {
|
||||
disableSystemVersioning(writer.apply(), tableName);
|
||||
enableSystemVersioning(writer.applyPostAlter(), tableName, false);
|
||||
alter.setHistoryHandled();
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeColumnDefinition(DdlBuffer buffer, String columnName, String type, String defaultValue,
|
||||
boolean isNotNull, String generated) throws IOException {
|
||||
boolean isNotNull, String generated) {
|
||||
|
||||
String platformType = platformDdl.convert(type);
|
||||
buffer.append(" ").append(platformDdl.lowerColumnName(columnName));
|
||||
@@ -123,35 +125,16 @@ public class HanaHistoryDdl implements PlatformHistoryDdl {
|
||||
}
|
||||
}
|
||||
|
||||
public void disableSystemVersioning(DdlBuffer apply, String tableName) throws IOException {
|
||||
disableSystemVersioning(apply, tableName, false);
|
||||
public void disableSystemVersioning(DdlBuffer apply, String tableName) {
|
||||
apply.append("alter table ").append(tableName).append(" drop system versioning").endOfStatement();
|
||||
}
|
||||
|
||||
public void disableSystemVersioning(DdlBuffer apply, String tableName, boolean uniqueStatement) throws IOException {
|
||||
apply.append("alter table ").append(tableName).append(" drop system versioning");
|
||||
if (uniqueStatement) {
|
||||
// needed for the DB migration test to prevent the statement from being filtered
|
||||
// out as a duplicate
|
||||
apply.append(" /* ").append(String.valueOf(counter.getAndIncrement())).append(" */");
|
||||
}
|
||||
apply.endOfStatement();
|
||||
}
|
||||
|
||||
public void enableSystemVersioning(DdlBuffer apply, String tableName, String historyTableName, boolean validated,
|
||||
boolean uniqueStatement) throws IOException {
|
||||
apply.append("alter table ").append(tableName).append(" add system versioning history table ").append(historyTableName);
|
||||
public void enableSystemVersioning(DdlBuffer apply, String tableName, boolean validated) {
|
||||
apply.append("alter table ").append(tableName).append(" add system versioning history table ").append(tableName).append(historySuffix);
|
||||
if (!validated) {
|
||||
apply.append(" not validated");
|
||||
}
|
||||
if (uniqueStatement) {
|
||||
// needed for the DB migration test to prevent the statement from being filtered
|
||||
// out as a duplicate
|
||||
apply.append(" /* ").append(String.valueOf(counter.getAndIncrement())).append(" */");
|
||||
}
|
||||
apply.endOfStatement();
|
||||
}
|
||||
|
||||
public boolean isSystemVersioningEnabled(String tableName) {
|
||||
return !createdHistoryTables.containsKey(tableName);
|
||||
}
|
||||
}
|
||||
|
||||
-131
@@ -1,131 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.PropertiesWrapper;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AddColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.Column;
|
||||
import io.ebeaninternal.dbmigration.migration.DropColumn;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class HanaTableDdl extends BaseTableDdl {
|
||||
|
||||
private final HanaHistoryDdl historyDdl;
|
||||
private final boolean generateUniqueDdl;
|
||||
|
||||
public HanaTableDdl(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
super(config, platformDdl);
|
||||
this.historyDdl = (HanaHistoryDdl) platformDdl.historyDdl;
|
||||
if (config.getProperties() != null) {
|
||||
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "hana", config.getProperties(), config.getClassLoadConfig());
|
||||
this.generateUniqueDdl = wrapper.getBoolean("generateUniqueDdl", false);
|
||||
} else {
|
||||
this.generateUniqueDdl = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void alterColumnDefaultValue(DdlWrite writer, AlterColumn alter) throws IOException {
|
||||
// done in alterColumnBaseAttributes
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AddColumn addColumn) throws IOException {
|
||||
String tableName = addColumn.getTableName();
|
||||
MTable table = writer.getTable(tableName);
|
||||
if (table == null) {
|
||||
super.generate(writer, addColumn);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean manageSystemVersioning = isTrue(table.isWithHistory()) && historyDdl.isSystemVersioningEnabled(tableName);
|
||||
|
||||
if (manageSystemVersioning) {
|
||||
historyDdl.disableSystemVersioning(writer.apply(), table.getName(), this.generateUniqueDdl);
|
||||
}
|
||||
|
||||
super.generate(writer, addColumn);
|
||||
|
||||
if (manageSystemVersioning) {
|
||||
// make same changes to the history table
|
||||
String historyTable = historyTable(tableName);
|
||||
List<Column> columns = addColumn.getColumn();
|
||||
for (Column column : columns) {
|
||||
alterTableAddColumn(writer.apply(), historyTable, column, true, true);
|
||||
}
|
||||
|
||||
historyDdl.enableSystemVersioning(writer.apply(), table.getName(), historyTable, false, this.generateUniqueDdl);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, AlterColumn alterColumn) throws IOException {
|
||||
String tableName = alterColumn.getTableName();
|
||||
MTable table = writer.getTable(tableName);
|
||||
if (table == null) {
|
||||
super.generate(writer, alterColumn);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean manageSystemVersioning = isTrue(table.isWithHistory()) && historyDdl.isSystemVersioningEnabled(tableName);
|
||||
|
||||
if (manageSystemVersioning) {
|
||||
historyDdl.disableSystemVersioning(writer.apply(), tableName, this.generateUniqueDdl);
|
||||
}
|
||||
|
||||
super.generate(writer, alterColumn);
|
||||
|
||||
if (manageSystemVersioning) {
|
||||
// make same changes to the history table
|
||||
String historyTable = historyTable(tableName);
|
||||
if (hasValue(alterColumn.getType()) || hasValue(alterColumn.getDefaultValue()) || alterColumn.isNotnull() != null) {
|
||||
AlterColumn alterHistoryColumn = new AlterColumn();
|
||||
alterHistoryColumn.setTableName(historyTable);
|
||||
alterHistoryColumn.setColumnName(alterColumn.getColumnName());
|
||||
alterHistoryColumn.setType(alterColumn.getType());
|
||||
alterHistoryColumn.setDefaultValue(alterColumn.getDefaultValue());
|
||||
alterHistoryColumn.setNotnull(alterColumn.isNotnull());
|
||||
alterHistoryColumn.setCurrentType(alterColumn.getCurrentType());
|
||||
alterHistoryColumn.setCurrentDefaultValue(alterColumn.getCurrentDefaultValue());
|
||||
alterHistoryColumn.setCurrentNotnull(alterColumn.isCurrentNotnull());
|
||||
String histColumnDdl = platformDdl.alterColumnBaseAttributes(alterHistoryColumn);
|
||||
|
||||
// write the apply to history table
|
||||
writer.apply().append(histColumnDdl).endOfStatement();
|
||||
}
|
||||
|
||||
historyDdl.enableSystemVersioning(writer.apply(), tableName, historyTable, false, this.generateUniqueDdl);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(DdlWrite writer, DropColumn dropColumn) throws IOException {
|
||||
String tableName = dropColumn.getTableName();
|
||||
MTable table = writer.getTable(tableName);
|
||||
if (table == null) {
|
||||
super.generate(writer, dropColumn);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean manageSystemVersioning = isTrue(table.isWithHistory()) && historyDdl.isSystemVersioningEnabled(tableName);
|
||||
|
||||
if (manageSystemVersioning) {
|
||||
historyDdl.disableSystemVersioning(writer.apply(), tableName, this.generateUniqueDdl);
|
||||
}
|
||||
|
||||
super.generate(writer, dropColumn);
|
||||
|
||||
if (manageSystemVersioning) {
|
||||
// also drop from the history table
|
||||
String historyTable = historyTable(tableName);
|
||||
alterTableDropColumn(writer.apply(), historyTable, dropColumn.getColumnName());
|
||||
|
||||
historyDdl.enableSystemVersioning(writer.apply(), tableName, historyTable, false, this.generateUniqueDdl);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-79
@@ -1,79 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Bean holding comments relating to a history table that needs to have it's
|
||||
* associated triggers/function updated due to columns added/dropped/included
|
||||
* or excluded.
|
||||
*/
|
||||
public class HistoryTableUpdate {
|
||||
|
||||
/**
|
||||
* Column change type.
|
||||
*/
|
||||
public enum Change {
|
||||
ADD,
|
||||
DROP,
|
||||
INCLUDE,
|
||||
EXCLUDE,
|
||||
ALTER
|
||||
}
|
||||
|
||||
private static class Column {
|
||||
|
||||
final Change change;
|
||||
|
||||
final String column;
|
||||
|
||||
public Column(Change change, String column) {
|
||||
this.change = change;
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return description();
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return change.name().toLowerCase() + " " + column;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final String baseTable;
|
||||
|
||||
private final List<Column> columnChanges = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Construct with a given base table name.
|
||||
*/
|
||||
public HistoryTableUpdate(String baseTable) {
|
||||
this.baseTable = baseTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a description of the changes that cause the history trigger/function
|
||||
* to be regenerated (added, included, excluded and dropped columns).
|
||||
*/
|
||||
public String description() {
|
||||
return columnChanges.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a comment for column added, dropped, included or excluded.
|
||||
*/
|
||||
public void add(Change change, String column) {
|
||||
columnChanges.add(new Column(change, column));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the base table name.
|
||||
*/
|
||||
public String getBaseTable() {
|
||||
return baseTable;
|
||||
}
|
||||
|
||||
}
|
||||
+19
-13
@@ -1,53 +1,59 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* History DDL for MariaDB.
|
||||
*/
|
||||
public class MariaDbHistoryDdl implements PlatformHistoryDdl {
|
||||
|
||||
private PlatformDdl platformDdl;
|
||||
|
||||
@Override
|
||||
public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
|
||||
// do nothing
|
||||
this.platformDdl = platformDdl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
public void createWithHistory(DdlWrite writer, MTable table) {
|
||||
String baseTable = table.getName();
|
||||
enableSystemVersioning(writer, baseTable);
|
||||
}
|
||||
|
||||
private void enableSystemVersioning(DdlWrite writer, String baseTable) throws IOException {
|
||||
DdlBuffer apply = writer.applyHistoryView();
|
||||
apply.append("alter table ").append(baseTable).append(" add system versioning").endOfStatement();
|
||||
private void enableSystemVersioning(DdlWrite writer, String baseTable) {
|
||||
platformDdl.alterTable(writer, baseTable).append("add system versioning", null);
|
||||
|
||||
DdlBuffer drop = writer.dropAll();
|
||||
drop.append("alter table ").append(baseTable).append(" drop system versioning").endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) {
|
||||
String baseTable = dropHistoryTable.getBaseTable();
|
||||
DdlBuffer apply = writer.applyHistoryView();
|
||||
apply.append("alter table ").append(baseTable).append(" drop system versioning").endOfStatement();
|
||||
platformDdl.alterTable(writer, baseTable).append("drop system versioning", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) {
|
||||
String baseTable = addHistoryTable.getBaseTable();
|
||||
enableSystemVersioning(writer, baseTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTriggers(DdlWrite writer, HistoryTableUpdate baseTable) {
|
||||
// do nothing
|
||||
public void updateTriggers(DdlWrite writer, String tableName) {
|
||||
MTable table = writer.getTable(tableName);
|
||||
// For MariaDB we need to enable system_versioning_alter_history only once
|
||||
// per DDL script. This info is stored in the virtual "__$HISTORY_FLAG__" table
|
||||
DdlAlterTable history = platformDdl.alterTable(writer, "__$HISTORY_FLAG__");
|
||||
if (table != null && table.isWithHistory() && !history.isHistoryHandled()) {
|
||||
writer.apply().appendStatement("SET @@system_versioning_alter_history = 1");
|
||||
history.setHistoryHandled();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+30
-67
@@ -3,12 +3,10 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.util.StringHelper;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.Column;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* MySql specific DDL.
|
||||
*/
|
||||
@@ -22,7 +20,7 @@ public class MySqlDdl extends PlatformDdl {
|
||||
|
||||
public MySqlDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.alterColumn = "modify";
|
||||
this.alterColumn = "alter";
|
||||
this.dropUniqueConstraint = "drop index";
|
||||
this.historyDdl = new MySqlHistoryDdl();
|
||||
this.inlineComments = true;
|
||||
@@ -38,11 +36,11 @@ public class MySqlDdl extends PlatformDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void alterTableDropColumn(final DdlBuffer buffer, final String tableName, final String columnName) throws IOException {
|
||||
public void alterTableDropColumn(DdlWrite writer, String tableName, String columnName) {
|
||||
if (this.useMigrationStoredProcedures) {
|
||||
buffer.append("CALL usp_ebean_drop_column('").append(tableName).append("', '").append(columnName).append("')").endOfStatement();
|
||||
alterTable(writer, tableName).raw("CALL usp_ebean_drop_column('").append(tableName).append("', '").append(columnName).append("')");
|
||||
} else {
|
||||
super.alterTableDropColumn(buffer, tableName, columnName);
|
||||
super.alterTableDropColumn(writer, tableName, columnName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,42 +90,35 @@ public class MySqlDdl extends PlatformDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnType(String tableName, String columnName, String type) {
|
||||
// can't alter itself - done in alterColumnBaseAttributes()
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnNotnull(String tableName, String columnName, boolean notnull) {
|
||||
// can't alter itself - done in alterColumnBaseAttributes()
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
|
||||
String suffix = DdlHelp.isDropDefault(defaultValue) ? columnDropDefault : columnSetDefault + " " + convertDefaultValue(defaultValue);
|
||||
return "alter table " + tableName + " alter " + columnName + " " + suffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnBaseAttributes(AlterColumn alter) {
|
||||
if (alter.getType() == null && alter.isNotnull() == null) {
|
||||
// No type change or notNull change
|
||||
// defaultValue change already handled in alterColumnDefaultValue
|
||||
return null;
|
||||
}
|
||||
public void alterColumn(DdlWrite writer, AlterColumn alter) {
|
||||
String tableName = alter.getTableName();
|
||||
String columnName = alter.getColumnName();
|
||||
String type = alter.getType() != null ? alter.getType() : alter.getCurrentType();
|
||||
type = convert(type);
|
||||
boolean notnull = (alter.isNotnull() != null) ? alter.isNotnull() : Boolean.TRUE.equals(alter.isCurrentNotnull());
|
||||
String notnullClause = notnull ? " not null" : "";
|
||||
|
||||
return "alter table " + tableName + " modify " + columnName + " " + type + notnullClause;
|
||||
if (alter.getType() == null && alter.isNotnull() == null) {
|
||||
// No type change or notNull change -> handle default value change
|
||||
if (hasValue(alter.getDefaultValue())) {
|
||||
alterColumnDefault(writer, alter);
|
||||
}
|
||||
} else {
|
||||
// we must regenerate whole statement -> read altered and current value
|
||||
String type = alter.getType() != null ? alter.getType() : alter.getCurrentType();
|
||||
type = convert(type);
|
||||
boolean notnull = (alter.isNotnull() != null) ? alter.isNotnull() : Boolean.TRUE.equals(alter.isCurrentNotnull());
|
||||
String defaultValue = alter.getDefaultValue() != null ? alter.getDefaultValue() : alter.getCurrentDefaultValue();
|
||||
|
||||
DdlBuffer buffer = alterTable(writer, tableName).append("modify", columnName);
|
||||
buffer.append(type);
|
||||
if (notnull) {
|
||||
buffer.append(" not null");
|
||||
}
|
||||
if (hasValue(defaultValue) && !DdlHelp.isDropDefault(defaultValue)) {
|
||||
buffer.append(" default ").append(convertDefaultValue(defaultValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeColumnDefinition(DdlBuffer buffer, Column column, DdlIdentity identity) throws IOException {
|
||||
protected void writeColumnDefinition(DdlBuffer buffer, Column column, DdlIdentity identity) {
|
||||
super.writeColumnDefinition(buffer, column, identity);
|
||||
String comment = column.getComment();
|
||||
if (!StringHelper.isNull(comment)) {
|
||||
@@ -140,7 +131,7 @@ public class MySqlDdl extends PlatformDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inlineTableComment(DdlBuffer apply, String tableComment) throws IOException {
|
||||
public void inlineTableComment(DdlBuffer apply, String tableComment) {
|
||||
if (tableComment.length() > 1000) {
|
||||
tableComment = tableComment.substring(0, 1000);
|
||||
}
|
||||
@@ -151,7 +142,7 @@ public class MySqlDdl extends PlatformDdl {
|
||||
* Add table comment as a separate statement (from the create table statement).
|
||||
*/
|
||||
@Override
|
||||
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) throws IOException {
|
||||
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) {
|
||||
if (DdlHelp.isDropComment(tableComment)) {
|
||||
tableComment = "";
|
||||
}
|
||||
@@ -163,32 +154,4 @@ public class MySqlDdl extends PlatformDdl {
|
||||
// alter comment currently not supported as it requires to repeat whole column definition
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Locks all tables for triggers that have to be updated.
|
||||
*/
|
||||
@Override
|
||||
public void lockTables(DdlBuffer buffer, Collection<String> tables) throws IOException {
|
||||
if (!tables.isEmpty()) {
|
||||
buffer.append("lock tables ");
|
||||
int i = 0;
|
||||
for (String table : tables) {
|
||||
if (i > 0) {
|
||||
buffer.append(", ");
|
||||
}
|
||||
buffer.append(table).append(" write");
|
||||
i++;
|
||||
}
|
||||
buffer.endOfStatement();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks all tables for triggers that have to be updated.
|
||||
*/
|
||||
@Override
|
||||
public void unlockTables(DdlBuffer buffer, Collection<String> tables) throws IOException {
|
||||
buffer.append("unlock tables").endOfStatement();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+14
-29
@@ -1,10 +1,8 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
import java.util.List;
|
||||
|
||||
import java.io.IOException;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
|
||||
/**
|
||||
* MySql history support using DB triggers to maintain a history table.
|
||||
@@ -15,54 +13,41 @@ public class MySqlHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException {
|
||||
protected void dropTriggers(DdlBuffer buffer, String baseTable) {
|
||||
buffer.append("drop trigger ").append(updateTriggerName(baseTable)).endOfStatement();
|
||||
buffer.append("drop trigger ").append(deleteTriggerName(baseTable)).endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createTriggers(DdlWrite writer, MTable table) throws IOException {
|
||||
|
||||
DbTriggerUpdate update = createDbTriggerUpdate(writer, table);
|
||||
|
||||
addBeforeUpdate(updateTriggerName(update.getBaseTable()), update);
|
||||
addBeforeDelete(deleteTriggerName(update.getBaseTable()), update);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateHistoryTriggers(DbTriggerUpdate update) throws IOException {
|
||||
protected void createTriggers(DdlBuffer buffer, String baseTable, List<String> columnNames) {
|
||||
|
||||
recreateHistoryView(update);
|
||||
buffer.append("lock tables ").append(baseTable).append(" write").endOfStatement();
|
||||
addBeforeUpdate(buffer, updateTriggerName(baseTable), baseTable, columnNames);
|
||||
addBeforeDelete(buffer, deleteTriggerName(baseTable), baseTable, columnNames);
|
||||
buffer.appendStatement("unlock tables");
|
||||
|
||||
DdlBuffer buffer = update.historyTriggerBuffer();
|
||||
String baseTable = update.getBaseTable();
|
||||
|
||||
dropTriggers(buffer, baseTable);
|
||||
addBeforeUpdate(updateTriggerName(baseTable), update);
|
||||
addBeforeDelete(deleteTriggerName(baseTable), update);
|
||||
}
|
||||
|
||||
private void addBeforeUpdate(String triggerName, DbTriggerUpdate update) throws IOException {
|
||||
private void addBeforeUpdate(DdlBuffer apply, String triggerName, String tableName, List<String> columnNames) {
|
||||
|
||||
DdlBuffer apply = update.historyTriggerBuffer();
|
||||
apply
|
||||
.append("delimiter $$").newLine()
|
||||
.append("create trigger ").append(triggerName).append(" before update on ").append(update.getBaseTable())
|
||||
.append("create trigger ").append(triggerName).append(" before update on ").append(tableName)
|
||||
.append(" for each row begin").newLine();
|
||||
appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
|
||||
appendInsertIntoHistory(apply, tableName, columnNames);
|
||||
apply
|
||||
.append(" set NEW.").append(sysPeriod).append("_start = now(6)").endOfStatement()
|
||||
.append("end$$").newLine();
|
||||
}
|
||||
|
||||
private void addBeforeDelete(String triggerName, DbTriggerUpdate update) throws IOException {
|
||||
private void addBeforeDelete(DdlBuffer apply, String triggerName, String tableName, List<String> columnNames) {
|
||||
|
||||
DdlBuffer apply = update.historyTriggerBuffer();
|
||||
apply
|
||||
.append("delimiter $$").newLine()
|
||||
.append("create trigger ").append(triggerName).append(" before delete on ").append(update.getBaseTable())
|
||||
.append("create trigger ").append(triggerName).append(" before delete on ").append(tableName)
|
||||
.append(" for each row begin").newLine();
|
||||
appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
|
||||
appendInsertIntoHistory(apply, tableName, columnNames);
|
||||
apply.append("end$$").newLine();
|
||||
}
|
||||
|
||||
|
||||
+2
-8
@@ -6,8 +6,6 @@ import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Default history implementation that does nothing. Needs to be replaced
|
||||
* with an appropriate implementation for the given database platform.
|
||||
@@ -20,7 +18,7 @@ public class NoHistorySupportDdl implements PlatformHistoryDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
public void createWithHistory(DdlWrite writer, MTable table) {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
@@ -30,12 +28,8 @@ public class NoHistorySupportDdl implements PlatformHistoryDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTriggers(DdlWrite write, HistoryTableUpdate update) {
|
||||
// does nothing
|
||||
}
|
||||
}
|
||||
|
||||
+16
-33
@@ -1,10 +1,9 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
|
||||
/**
|
||||
* NuoDB history support using DB triggers to maintain a history table.
|
||||
@@ -17,59 +16,43 @@ public class NuoDbHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException {
|
||||
protected void dropTriggers(DdlBuffer buffer, String baseTable) {
|
||||
|
||||
buffer.append("drop trigger ").append(updateTriggerName(baseTable)).endOfStatement();
|
||||
buffer.append("drop trigger ").append(deleteTriggerName(baseTable)).endOfStatement();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createTriggers(DdlWrite writer, MTable table) throws IOException {
|
||||
protected void createTriggers(DdlBuffer buffer, String baseTable, List<String> columnNames) {
|
||||
|
||||
DbTriggerUpdate update = createDbTriggerUpdate(writer, table);
|
||||
|
||||
addBeforeUpdate(updateTriggerName(update.getBaseTable()), update);
|
||||
addBeforeDelete(deleteTriggerName(update.getBaseTable()), update);
|
||||
addBeforeUpdate(buffer, updateTriggerName(baseTable), baseTable, columnNames);
|
||||
addBeforeDelete(buffer, deleteTriggerName(baseTable), baseTable, columnNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateHistoryTriggers(DbTriggerUpdate update) throws IOException {
|
||||
private void addBeforeUpdate(DdlBuffer apply, String triggerName, String tableName, List<String> columnNames) {
|
||||
|
||||
recreateHistoryView(update);
|
||||
addTriggerStart(triggerName, tableName, apply, " before update for each row as ");
|
||||
|
||||
DdlBuffer buffer = update.historyTriggerBuffer();
|
||||
String baseTable = update.getBaseTable();
|
||||
|
||||
dropTriggers(buffer, baseTable);
|
||||
addBeforeUpdate(updateTriggerName(baseTable), update);
|
||||
addBeforeDelete(deleteTriggerName(baseTable), update);
|
||||
}
|
||||
|
||||
private void addBeforeUpdate(String triggerName, DbTriggerUpdate update) throws IOException {
|
||||
|
||||
DdlBuffer apply = update.historyTriggerBuffer();
|
||||
addTriggerStart(triggerName, update, apply, " before update for each row as ");
|
||||
apply.append(" NEW.sys_period_start = greatest(current_timestamp, date_add(OLD.sys_period_start, interval 1 microsecond))").endOfStatement();
|
||||
appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
|
||||
appendInsertIntoHistory(apply, tableName, columnNames);
|
||||
addEndTrigger(apply);
|
||||
}
|
||||
|
||||
private void addBeforeDelete(String triggerName, DbTriggerUpdate update) throws IOException {
|
||||
private void addBeforeDelete(DdlBuffer apply, String triggerName, String tableName, List<String> columnNames) {
|
||||
|
||||
DdlBuffer apply = update.historyTriggerBuffer();
|
||||
addTriggerStart(triggerName, update, apply, " before delete for each row as");
|
||||
appendInsertIntoHistory(apply, update.getHistoryTable(), update.getColumns());
|
||||
addTriggerStart(triggerName, tableName, apply, " before delete for each row as");
|
||||
appendInsertIntoHistory(apply, tableName, columnNames);
|
||||
addEndTrigger(apply);
|
||||
}
|
||||
|
||||
private void addTriggerStart(String triggerName, DbTriggerUpdate update, DdlBuffer apply, String s) throws IOException {
|
||||
private void addTriggerStart(String triggerName, String baseTable, DdlBuffer apply, String s) {
|
||||
apply
|
||||
.append("delimiter $$").newLine()
|
||||
.append("create or replace trigger ").append(triggerName).append(" for ").append(update.getBaseTable())
|
||||
.append("create or replace trigger ").append(triggerName).append(" for ").append(baseTable)
|
||||
.append(s).newLine();
|
||||
}
|
||||
|
||||
private void addEndTrigger(DdlBuffer apply) throws IOException {
|
||||
private void addEndTrigger(DdlBuffer apply) {
|
||||
apply.append("end_trigger")
|
||||
.endOfStatement()
|
||||
.append("$$").newLine()
|
||||
|
||||
+34
@@ -20,6 +20,8 @@ public class OracleDdl extends PlatformDdl {
|
||||
this.columnSetNotnull = "not null";
|
||||
this.columnSetNull = "null";
|
||||
this.columnSetDefault = "default";
|
||||
this.columnDropDefault = "default null"; // dropping default is not supported. See:
|
||||
// https://stackoverflow.com/questions/8481532/how-do-i-remove-the-default-value-from-a-column-in-oracle
|
||||
this.identitySuffix = " generated by default as identity";
|
||||
}
|
||||
|
||||
@@ -33,6 +35,21 @@ public class OracleDdl extends PlatformDdl {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dropSequence(String sequenceName) {
|
||||
return ignoreError(-2289, super.dropSequence(sequenceName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableDropConstraint(String tableName, String constraintName) {
|
||||
return ignoreError(-2443, super.alterTableDropConstraint(tableName, constraintName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
|
||||
return ignoreError(-2443, super.alterTableDropUniqueConstraint(tableName, uniqueConstraintName));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendForeignKeyOnUpdate(StringBuilder buffer, ConstraintMode mode) {
|
||||
// do nothing, no on update clause for oracle
|
||||
@@ -57,4 +74,21 @@ public class OracleDdl extends PlatformDdl {
|
||||
return asIdentityStandardOptions(columnDefn, identity);
|
||||
}
|
||||
|
||||
/**
|
||||
* generates anonymous pl/sql block that catches expected error so that we can
|
||||
* effectively do a 'drop if exists'
|
||||
*/
|
||||
private String ignoreError(int errorNr, String statement) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("delimiter $$\n")
|
||||
.append("declare\n")
|
||||
.append(" expected_error exception;\n")
|
||||
.append(" pragma exception_init(expected_error, ").append(errorNr).append(");\n")
|
||||
.append("begin\n")
|
||||
.append(" execute immediate '").append(statement).append("';\n")
|
||||
.append("exception\n")
|
||||
.append(" when expected_error then null;\n")
|
||||
.append("end;\n$$");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
+92
-89
@@ -9,11 +9,7 @@ import io.ebean.config.dbplatform.DbDefaultValue;
|
||||
import io.ebean.config.dbplatform.DbIdentity;
|
||||
import io.ebean.config.dbplatform.IdType;
|
||||
import io.ebean.util.StringHelper;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.BaseDdlHandler;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.*;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.util.PlatformTypeConverter;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.platform.util.VowelRemover;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
@@ -22,8 +18,6 @@ import io.ebeaninternal.dbmigration.migration.Column;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
@@ -82,16 +76,12 @@ public class PlatformDdl {
|
||||
|
||||
protected String alterColumn = "alter column";
|
||||
|
||||
protected String alterColumnSuffix = "";
|
||||
|
||||
protected String dropUniqueConstraint = "drop constraint";
|
||||
|
||||
protected String addConstraint = "add constraint";
|
||||
|
||||
protected String addColumn = "add column";
|
||||
|
||||
protected String addColumnSuffix = "";
|
||||
|
||||
protected String columnSetType = "";
|
||||
|
||||
protected String columnSetDefault = "set default";
|
||||
@@ -102,14 +92,14 @@ public class PlatformDdl {
|
||||
|
||||
protected String columnSetNull = "set null";
|
||||
|
||||
protected String columnNotNull = "not null";
|
||||
|
||||
protected String updateNullWithDefault = "update ${table} set ${column} = ${default} where ${column} is null";
|
||||
|
||||
protected String createTable = "create table";
|
||||
|
||||
protected String dropColumn = "drop column";
|
||||
|
||||
protected String dropColumnSuffix = "";
|
||||
|
||||
protected String addForeignKeySkipCheck = "";
|
||||
|
||||
protected String uniqueIndex = "unique";
|
||||
@@ -236,7 +226,7 @@ public class PlatformDdl {
|
||||
/**
|
||||
* Write all the table columns converting to platform types as necessary.
|
||||
*/
|
||||
public void writeTableColumns(DdlBuffer apply, List<Column> columns, DdlIdentity identity) throws IOException {
|
||||
public void writeTableColumns(DdlBuffer apply, List<Column> columns, DdlIdentity identity) {
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
if (i > 0) {
|
||||
apply.append(",");
|
||||
@@ -260,7 +250,7 @@ public class PlatformDdl {
|
||||
/**
|
||||
* Write the column definition to the create table statement.
|
||||
*/
|
||||
protected void writeColumnDefinition(DdlBuffer buffer, Column column, DdlIdentity identity) throws IOException {
|
||||
protected void writeColumnDefinition(DdlBuffer buffer, Column column, DdlIdentity identity) {
|
||||
|
||||
String columnDefn = convert(column.getType());
|
||||
if (identity.useIdentity() && isTrue(column.isPrimaryKey())) {
|
||||
@@ -277,20 +267,13 @@ public class PlatformDdl {
|
||||
}
|
||||
}
|
||||
if (isTrue(column.isNotnull()) || isTrue(column.isPrimaryKey())) {
|
||||
writeColumnNotNull(buffer);
|
||||
buffer.appendWithSpace(columnNotNull);
|
||||
}
|
||||
|
||||
// add check constraints later as we really want to give them a nice name
|
||||
// so that the database can potentially provide a nice SQL error
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow for platform overriding (e.g. ClickHouse).
|
||||
*/
|
||||
protected void writeColumnNotNull(DdlBuffer buffer) throws IOException {
|
||||
buffer.append(" not null");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the check constraint.
|
||||
*/
|
||||
@@ -319,9 +302,7 @@ public class PlatformDdl {
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
type = extract(type);
|
||||
|
||||
if (type.contains("[]")) {
|
||||
return convertArrayType(type);
|
||||
}
|
||||
@@ -333,16 +314,18 @@ public class PlatformDdl {
|
||||
// e.g. @Column(columnDefinition = "db2;blob(64M);sqlserver,h2;varchar(227);varchar(127)")
|
||||
private String extract(String type) {
|
||||
String[] tmp = type.split(";");
|
||||
assert tmp.length % 2 == 1;
|
||||
for (int i = 0; i < tmp.length - 2; i+=2) {
|
||||
if (tmp.length % 2 == 0) {
|
||||
throw new IllegalArgumentException("You need an odd number of arguments. See Issue #2559 for details");
|
||||
}
|
||||
for (int i = 0; i < tmp.length - 2; i += 2) {
|
||||
String[] platforms = tmp[i].split(",");
|
||||
for (String plat : platforms) {
|
||||
if (platform.isPlatform(Platform.valueOf(plat.toUpperCase(Locale.ENGLISH)))) {
|
||||
return tmp[i+1];
|
||||
return tmp[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return tmp[tmp.length-1]; // else
|
||||
return tmp[tmp.length - 1]; // else
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -359,29 +342,29 @@ public class PlatformDdl {
|
||||
/**
|
||||
* Add history support to this table using the platform specific mechanism.
|
||||
*/
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
public void createWithHistory(DdlWrite writer, MTable table) {
|
||||
historyDdl.createWithHistory(writer, table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop history support for a given table.
|
||||
*/
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) {
|
||||
historyDdl.dropHistoryTable(writer, dropHistoryTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add history support to an existing table.
|
||||
*/
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) {
|
||||
historyDdl.addHistoryTable(writer, addHistoryTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerate the history triggers (or function) due to a column being added/dropped/excluded or included.
|
||||
*/
|
||||
public void regenerateHistoryTriggers(DdlWrite write, HistoryTableUpdate update) throws IOException {
|
||||
historyDdl.updateTriggers(write, update);
|
||||
public void regenerateHistoryTriggers(DdlWrite writer, String tableName) {
|
||||
historyDdl.updateTriggers(writer, tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -550,13 +533,11 @@ public class PlatformDdl {
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public void alterTableAddColumn(DdlBuffer buffer, String tableName, Column column, boolean onHistoryTable, String defaultValue) throws IOException {
|
||||
public void alterTableAddColumn(DdlWrite writer, String tableName, Column column, boolean onHistoryTable, String defaultValue) {
|
||||
|
||||
String convertedType = convert(column.getType());
|
||||
|
||||
buffer.append("alter table ").append(tableName)
|
||||
.append(" ").append(addColumn).append(" ").append(column.getName())
|
||||
.append(" ").append(convertedType);
|
||||
DdlBuffer buffer = alterTable(writer, tableName).append(addColumn, column.getName());
|
||||
buffer.append(convertedType);
|
||||
|
||||
// Add default value also to history table if it is not excluded
|
||||
if (defaultValue != null) {
|
||||
@@ -568,28 +549,35 @@ public class PlatformDdl {
|
||||
|
||||
if (!onHistoryTable) {
|
||||
if (isTrue(column.isNotnull())) {
|
||||
writeColumnNotNull(buffer);
|
||||
buffer.appendWithSpace(columnNotNull);
|
||||
}
|
||||
buffer.append(addColumnSuffix);
|
||||
buffer.endOfStatement();
|
||||
|
||||
// check constraints cannot be added in one statement for h2
|
||||
if (!StringHelper.isNull(column.getCheckConstraint())) {
|
||||
String ddl = alterTableAddCheckConstraint(tableName, column.getCheckConstraintName(), column.getCheckConstraint());
|
||||
if (hasValue(ddl)) {
|
||||
buffer.append(ddl).endOfStatement();
|
||||
}
|
||||
writer.applyPostAlter().appendStatement(ddl);
|
||||
}
|
||||
} else {
|
||||
buffer.append(addColumnSuffix);
|
||||
buffer.endOfStatement();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException {
|
||||
buffer.append("alter table ").append(tableName).append(" ").append(dropColumn).append(" ").append(columnName)
|
||||
.append(dropColumnSuffix).endOfStatement();
|
||||
/**
|
||||
* This method is used from DbTriggerBasedHistoryDdl to add the sysPeriodColumns.
|
||||
*/
|
||||
public void alterTableAddColumn(DdlWrite writer, String tableName, String columnName, String columnType, String defaultValue) {
|
||||
|
||||
String convertedType = convert(columnType);
|
||||
DdlBuffer buffer = alterTable(writer, tableName).append(addColumn, columnName);
|
||||
buffer.append(convertedType);
|
||||
|
||||
if (defaultValue != null) {
|
||||
buffer.append(" default ");
|
||||
buffer.append(defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
public void alterTableDropColumn(DdlWrite writer, String tableName, String columnName) {
|
||||
alterTable(writer, tableName).append(dropColumn, columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -604,22 +592,27 @@ public class PlatformDdl {
|
||||
/**
|
||||
* Alter a column type.
|
||||
* <p>
|
||||
* Note that that MySql and SQL Server instead use alterColumnBaseAttributes()
|
||||
* Note that that MySql, SQL Server, and HANA instead use alterColumn()
|
||||
* </p>
|
||||
*/
|
||||
public String alterColumnType(String tableName, String columnName, String type) {
|
||||
return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + columnSetType + convert(type) + alterColumnSuffix;
|
||||
protected void alterColumnType(DdlWrite writer, AlterColumn alter) {
|
||||
alterTable(writer, alter.getTableName()).append(alterColumn, alter.getColumnName())
|
||||
.append(columnSetType).append(convert(alter.getType()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter a column adding or removing the not null constraint.
|
||||
* <p>
|
||||
* Note that that MySql, SQL Server, and HANA instead use alterColumnBaseAttributes()
|
||||
* Note that that MySql, SQL Server, and HANA instead use alterColumn()
|
||||
* </p>
|
||||
*/
|
||||
public String alterColumnNotnull(String tableName, String columnName, boolean notnull) {
|
||||
String suffix = notnull ? columnSetNotnull : columnSetNull;
|
||||
return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + suffix + alterColumnSuffix;
|
||||
protected void alterColumnNotnull(DdlWrite writer, AlterColumn alter) {
|
||||
DdlBuffer buffer = alterTable(writer, alter.getTableName()).append(alterColumn, alter.getColumnName());
|
||||
if (Boolean.TRUE.equals(alter.isNotnull())) {
|
||||
buffer.append(columnSetNotnull);
|
||||
} else {
|
||||
buffer.append(columnSetNull);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -631,22 +624,46 @@ public class PlatformDdl {
|
||||
|
||||
/**
|
||||
* Alter column setting the default value.
|
||||
* <p>
|
||||
* Note that that MySql, SQL Server, and HANA instead use alterColumn()
|
||||
* </p>
|
||||
*/
|
||||
public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
|
||||
String suffix = DdlHelp.isDropDefault(defaultValue) ? columnDropDefault : columnSetDefault + " " + convertDefaultValue(defaultValue);
|
||||
return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + suffix + alterColumnSuffix;
|
||||
protected void alterColumnDefault(DdlWrite writer, AlterColumn alter) {
|
||||
DdlBuffer buffer = alterTable(writer, alter.getTableName()).append(alterColumn, alter.getColumnName());
|
||||
if (DdlHelp.isDropDefault(alter.getDefaultValue())) {
|
||||
buffer.append(columnDropDefault);
|
||||
} else {
|
||||
buffer.append(columnSetDefault).appendWithSpace(convertDefaultValue(alter.getDefaultValue()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter column setting both the type and not null constraint.
|
||||
* Alter column setting (type, default value and not null constraint).
|
||||
* <p>
|
||||
* Used by MySql, SQL Server, and HANA as these require both column attributes to be set together.
|
||||
* Used by MySql, SQL Server, and HANA as these require all column attributes to
|
||||
* be set together.
|
||||
* </p>
|
||||
*/
|
||||
public String alterColumnBaseAttributes(AlterColumn alter) {
|
||||
// by default do nothing, only used by mysql, sql server, and HANA as they can only
|
||||
// modify the column with the full column definition
|
||||
return null;
|
||||
public void alterColumn(DdlWrite writer, AlterColumn alter) {
|
||||
|
||||
if (hasValue(alter.getType())) {
|
||||
alterColumnType(writer, alter);
|
||||
}
|
||||
|
||||
if (hasValue(alter.getDefaultValue())) {
|
||||
alterColumnDefault(writer, alter);
|
||||
}
|
||||
|
||||
if (alter.isNotnull() != null) {
|
||||
alterColumnNotnull(writer, alter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates or replace a new DdlAlterTable for given tableName.
|
||||
*/
|
||||
protected DdlAlterTable alterTable(DdlWrite writer, String tableName) {
|
||||
return writer.applyAlterTable(tableName, BaseAlterTableWrite::new);
|
||||
}
|
||||
|
||||
protected void appendColumns(String[] columns, StringBuilder buffer) {
|
||||
@@ -705,21 +722,21 @@ public class PlatformDdl {
|
||||
/**
|
||||
* Add an inline table comment to the create table statement.
|
||||
*/
|
||||
public void inlineTableComment(DdlBuffer apply, String tableComment) throws IOException {
|
||||
public void inlineTableComment(DdlBuffer apply, String tableComment) {
|
||||
// do nothing by default (MySql only)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an table storage engine to the create table statement.
|
||||
*/
|
||||
public void tableStorageEngine(DdlBuffer apply, String storageEngine) throws IOException {
|
||||
public void tableStorageEngine(DdlBuffer apply, String storageEngine) {
|
||||
// do nothing by default
|
||||
}
|
||||
|
||||
/**
|
||||
* Add table comment as a separate statement (from the create table statement).
|
||||
*/
|
||||
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) throws IOException {
|
||||
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) {
|
||||
if (DdlHelp.isDropComment(tableComment)) {
|
||||
tableComment = "";
|
||||
}
|
||||
@@ -729,7 +746,7 @@ public class PlatformDdl {
|
||||
/**
|
||||
* Add column comment as a separate statement.
|
||||
*/
|
||||
public void addColumnComment(DdlBuffer apply, String table, String column, String comment) throws IOException {
|
||||
public void addColumnComment(DdlBuffer apply, String table, String column, String comment) {
|
||||
if (DdlHelp.isDropComment(comment)) {
|
||||
comment = "";
|
||||
}
|
||||
@@ -739,14 +756,14 @@ public class PlatformDdl {
|
||||
/**
|
||||
* Use this to generate a prolog for each script (stored procedures)
|
||||
*/
|
||||
public void generateProlog(DdlWrite write) throws IOException {
|
||||
public void generateProlog(DdlWrite writer) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to generate an epilog. Will be added at the end of script
|
||||
*/
|
||||
public void generateEpilog(DdlWrite write) throws IOException {
|
||||
public void generateEpilog(DdlWrite writer) {
|
||||
|
||||
}
|
||||
|
||||
@@ -769,20 +786,6 @@ public class PlatformDdl {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mysql-specific: Locks all tables for triggers that have to be updated.
|
||||
*/
|
||||
public void lockTables(DdlBuffer buffer, Collection<String> tables) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Mysql-specific: Unlocks all tables for triggers that have to be updated.
|
||||
*/
|
||||
public void unlockTables(DdlBuffer buffer, Collection<String> tables) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the database-specific "create table" command prefix. For HANA this is
|
||||
* either "create column table" or "create row table", for all other databases
|
||||
@@ -798,7 +801,7 @@ public class PlatformDdl {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addTablePartition(DdlBuffer apply, String partitionMode, String partitionColumn) throws IOException {
|
||||
public void addTablePartition(DdlBuffer apply, String partitionMode, String partitionColumn) {
|
||||
// only supported by postgres initially
|
||||
}
|
||||
|
||||
@@ -806,7 +809,7 @@ public class PlatformDdl {
|
||||
* Adds tablespace declaration. Now only supported for db2.
|
||||
* @throws IOException
|
||||
*/
|
||||
public void addTablespace(DdlBuffer apply, String tablespaceName, String indexTablespace, String lobTablespace) throws IOException{
|
||||
public void addTablespace(DdlBuffer apply, String tablespaceName, String indexTablespace, String lobTablespace) {
|
||||
// now only supported for db2
|
||||
}
|
||||
|
||||
|
||||
+16
-6
@@ -6,8 +6,6 @@ import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Defines the implementation for adding history support to a table.
|
||||
*/
|
||||
@@ -21,20 +19,32 @@ public interface PlatformHistoryDdl {
|
||||
/**
|
||||
* Creates a new table and add history support to the table using platform specific mechanism.
|
||||
*/
|
||||
void createWithHistory(DdlWrite writer, MTable table) throws IOException;
|
||||
void createWithHistory(DdlWrite writer, MTable table);
|
||||
|
||||
/**
|
||||
* Drop history support for the given table.
|
||||
*/
|
||||
void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException;
|
||||
void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable);
|
||||
|
||||
/**
|
||||
* Add history support to the given table.
|
||||
*/
|
||||
void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException;
|
||||
void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable);
|
||||
|
||||
/**
|
||||
* Returns true, if alters on the live tables should be applied also to the history tables. This is required for DbTriggerBased
|
||||
* histories or on platforms like Hana, which are not SQL2011 history compatible (at least from DDL perspective)
|
||||
*/
|
||||
default boolean alterHistoryTables() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerate the history triggers/stored function due to column added/dropped/included or excluded.
|
||||
*
|
||||
* Note: This function may be called multiple times for the same table.
|
||||
*/
|
||||
void updateTriggers(DdlWrite write, HistoryTableUpdate baseTable) throws IOException;
|
||||
default void updateTriggers(DdlWrite writer, String tableName) {
|
||||
// nop
|
||||
}
|
||||
}
|
||||
|
||||
+8
-5
@@ -2,8 +2,8 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
|
||||
import java.io.IOException;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
|
||||
/**
|
||||
* Postgres specific DDL.
|
||||
@@ -40,7 +40,7 @@ public class PostgresDdl extends PlatformDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTablePartition(DdlBuffer apply, String partitionMode, String partitionColumn) throws IOException {
|
||||
public void addTablePartition(DdlBuffer apply, String partitionMode, String partitionColumn) {
|
||||
apply.append(" partition by range (").append(partitionColumn).append(")");
|
||||
}
|
||||
|
||||
@@ -58,7 +58,10 @@ public class PostgresDdl extends PlatformDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnType(String tableName, String columnName, String type) {
|
||||
return super.alterColumnType(tableName, columnName, type) + " using " + columnName + "::" + convert(type);
|
||||
protected void alterColumnType(DdlWrite writer, AlterColumn alter) {
|
||||
String type = convert(alter.getType());
|
||||
alterTable(writer, alter.getTableName()).append(alterColumn, alter.getColumnName())
|
||||
.append(columnSetType).append(type)
|
||||
.append(" using ").append(alter.getColumnName()).append("::").append(type);
|
||||
}
|
||||
}
|
||||
|
||||
+14
-36
@@ -4,7 +4,6 @@ import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -21,7 +20,7 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
* Use Postgres create table like to create the history table.
|
||||
*/
|
||||
@Override
|
||||
protected void createHistoryTable(DdlBuffer apply, MTable table) throws IOException {
|
||||
protected void createHistoryTable(DdlBuffer apply, MTable table) {
|
||||
apply.append("create table ").append(table.getName()).append(historySuffix)
|
||||
.append("(like ").append(table.getName()).append(")").endOfStatement();
|
||||
}
|
||||
@@ -30,50 +29,45 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
* Use Postgres range type rather than start and end timestamps.
|
||||
*/
|
||||
@Override
|
||||
protected void addSysPeriodColumns(DdlBuffer apply, String baseTableName, String whenCreatedColumn) throws IOException {
|
||||
apply
|
||||
.append("alter table ").append(baseTableName)
|
||||
.append(" add column ").append(sysPeriod).append(" tstzrange not null default tstzrange(").append(now).append(", null)")
|
||||
.endOfStatement();
|
||||
|
||||
protected void addSysPeriodColumns(DdlWrite writer, String baseTableName, String whenCreatedColumn) {
|
||||
platformDdl.alterTableAddColumn(writer, baseTableName, sysPeriod, "tstzrange not null", "tstzrange(" + now + ", null)");
|
||||
if (whenCreatedColumn != null) {
|
||||
apply.append("update ").append(baseTableName).append(" set ")
|
||||
writer.applyPostAlter()
|
||||
.append("update ").append(baseTableName).append(" set ")
|
||||
.append(sysPeriod).append(" = tstzrange(").append(whenCreatedColumn).append(", null)").endOfStatement();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendSysPeriodColumns(DdlBuffer apply, String prefix) throws IOException {
|
||||
protected void appendSysPeriodColumns(DdlBuffer apply, String prefix) {
|
||||
appendColumnName(apply, prefix, sysPeriod);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dropSysPeriodColumns(DdlBuffer buffer, String baseTableName) throws IOException {
|
||||
buffer.append("alter table ").append(baseTableName).append(" drop column ").append(sysPeriod).endOfStatement();
|
||||
protected void dropSysPeriodColumns(DdlWrite writer, String baseTableName) {
|
||||
platformDdl.alterTableDropColumn(writer, baseTableName, sysPeriod);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createTriggers(DdlWrite writer, MTable table) throws IOException {
|
||||
String baseTableName = table.getName();
|
||||
protected void createTriggers(DdlBuffer buffer, String baseTableName, List<String> columnNames) {
|
||||
String procedureName = procedureName(baseTableName);
|
||||
String triggerName = triggerName(baseTableName);
|
||||
|
||||
DdlBuffer apply = writer.applyHistoryTrigger();
|
||||
apply
|
||||
createOrReplaceFunction(buffer, procedureName, historyTableName(baseTableName), columnNames);
|
||||
buffer
|
||||
.append("create trigger ").append(triggerName).newLine()
|
||||
.append(" before update or delete on ").append(baseTableName).newLine()
|
||||
.append(" for each row execute procedure ").append(procedureName).append("();").newLine().newLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dropTriggers(DdlBuffer buffer, String baseTable) throws IOException {
|
||||
protected void dropTriggers(DdlBuffer buffer, String baseTable) {
|
||||
// rollback trigger then function
|
||||
buffer.append("drop trigger if exists ").append(triggerName(baseTable)).append(" on ").append(baseTable).append(" cascade").endOfStatement();
|
||||
buffer.append("drop function if exists ").append(procedureName(baseTable)).append("()").endOfStatement();
|
||||
buffer.end();
|
||||
}
|
||||
|
||||
protected void createOrReplaceFunction(DdlBuffer apply, String procedureName, String historyTable, List<String> includedColumns) throws IOException {
|
||||
protected void createOrReplaceFunction(DdlBuffer apply, String procedureName, String historyTable, List<String> includedColumns) {
|
||||
apply
|
||||
.append("create or replace function ").append(procedureName).append("() returns trigger as $$").newLine();
|
||||
|
||||
@@ -105,23 +99,7 @@ public class PostgresHistoryDdl extends DbTriggerBasedHistoryDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createStoredFunction(DdlWrite writer, MTable table) throws IOException {
|
||||
String procedureName = procedureName(table.getName());
|
||||
String historyTable = historyTableName(table.getName());
|
||||
|
||||
List<String> columnNames = columnNamesForApply(table);
|
||||
createOrReplaceFunction(writer.applyHistoryTrigger(), procedureName, historyTable, columnNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateHistoryTriggers(DbTriggerUpdate update) throws IOException {
|
||||
String procedureName = procedureName(update.getBaseTable());
|
||||
recreateHistoryView(update);
|
||||
createOrReplaceFunction(update.historyTriggerBuffer(), procedureName, update.getHistoryTable(), update.getColumns());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendInsertIntoHistory(DdlBuffer buffer, String historyTable, List<String> columns) throws IOException {
|
||||
protected void appendInsertIntoHistory(DdlBuffer buffer, String historyTable, List<String> columns) {
|
||||
buffer.append(" insert into ").append(historyTable).append(" (").append(sysPeriod).append(",");
|
||||
appendColumnNames(buffer, columns, "");
|
||||
buffer.append(") values (tstzrange(lowerTs,upperTs), ");
|
||||
|
||||
+61
-3
@@ -1,11 +1,19 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
|
||||
/**
|
||||
* DB2 platform specific DDL.
|
||||
* SQLite platform specific DDL.
|
||||
*
|
||||
* Note: SQLite has very limited alter capabilities. Altering a column is not
|
||||
* supported and may need a recreation of the whole table
|
||||
*/
|
||||
public class SQLiteDdl extends PlatformDdl {
|
||||
|
||||
@@ -27,7 +35,57 @@ public class SQLiteDdl extends PlatformDdl {
|
||||
|
||||
@Override
|
||||
public String alterTableAddForeignKey(DdlOptions options, WriteForeignKey request) {
|
||||
// not supported
|
||||
return null;
|
||||
return "-- not supported: " + super.alterTableAddForeignKey(options, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableDropForeignKey(String tableName, String fkName) {
|
||||
return "-- not supported: " + super.alterTableDropForeignKey(tableName, fkName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableAddCheckConstraint(String tableName, String checkConstraintName, String checkConstraint) {
|
||||
return "-- not supported: " + super.alterTableAddCheckConstraint(tableName, checkConstraintName, checkConstraint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableDropConstraint(String tableName, String constraintName) {
|
||||
return "-- not supported: " + super.alterTableDropConstraint(tableName, constraintName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableAddUniqueConstraint(String tableName, String uqName, String[] columns, String[] nullableColumns) {
|
||||
return "-- not supported: " + super.alterTableAddUniqueConstraint(tableName, uqName, columns, nullableColumns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
|
||||
return "-- not supported: " + super.alterTableDropUniqueConstraint(tableName, uniqueConstraintName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DdlAlterTable alterTable(DdlWrite writer, String tableName) {
|
||||
return writer.applyAlterTable(tableName, SQLiteAlterTableWrite::new);
|
||||
}
|
||||
|
||||
static class SQLiteAlterTableWrite extends BaseAlterTableWrite {
|
||||
public SQLiteAlterTableWrite(String tableName) {
|
||||
super(tableName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AlterCmd> postProcessCommands(List<AlterCmd> cmds) {
|
||||
List<AlterCmd> ret = new ArrayList<AlterCmd>();
|
||||
for (AlterCmd cmd : cmds) {
|
||||
switch (cmd.getOperation()) {
|
||||
case "alter column":
|
||||
ret.add(newRawCommand("-- not supported: " + cmd));
|
||||
break;
|
||||
default:
|
||||
ret.add(cmd);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+83
-70
@@ -6,13 +6,17 @@ import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* MS SQL Server platform specific DDL.
|
||||
*/
|
||||
public class SqlServerDdl extends PlatformDdl {
|
||||
|
||||
private static final String CONSTRAINT = "C";
|
||||
private static final String UNIQUE_CONSTRAINT = "UQ";
|
||||
private static final String USER_TABLE = "U";
|
||||
private static final String FOREIGN_KEY = "F";
|
||||
private static final String SEQUENCE_OBJECT = "SO";
|
||||
|
||||
public SqlServerDdl(DatabasePlatform platform) {
|
||||
super(platform);
|
||||
this.identitySuffix = " identity(1,1)";
|
||||
@@ -33,12 +37,7 @@ public class SqlServerDdl extends PlatformDdl {
|
||||
|
||||
@Override
|
||||
public String dropTable(String tableName) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("IF OBJECT_ID('");
|
||||
buffer.append(tableName);
|
||||
buffer.append("', 'U') IS NOT NULL drop table ");
|
||||
buffer.append(tableName);
|
||||
return buffer.toString();
|
||||
return ifObjectExists(tableName, USER_TABLE) + "drop table " + tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,12 +47,12 @@ public class SqlServerDdl extends PlatformDdl {
|
||||
if (pos != -1) {
|
||||
objectId = tableName.substring(0, pos + 1) + fkName;
|
||||
}
|
||||
return "IF OBJECT_ID('" + objectId + "', 'F') IS NOT NULL " + super.alterTableDropForeignKey(tableName, fkName);
|
||||
return ifObjectExists(objectId, FOREIGN_KEY) + super.alterTableDropForeignKey(tableName, fkName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dropSequence(String sequenceName) {
|
||||
return "IF OBJECT_ID('" + sequenceName + "', 'SO') IS NOT NULL drop sequence " + sequenceName;
|
||||
return ifObjectExists(sequenceName, SEQUENCE_OBJECT) + "drop sequence " + sequenceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,12 +72,12 @@ public class SqlServerDdl extends PlatformDdl {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
// issues#233
|
||||
StringBuilder sb = new StringBuilder("create unique nonclustered index ");
|
||||
sb.append(uqName).append(" on ").append(tableName).append('(');
|
||||
|
||||
StringBuilder sb = new StringBuilder(256);
|
||||
sb.append("create unique nonclustered index ").append(uqName).append(" on ").append(tableName).append('(');
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(columns[i]);
|
||||
}
|
||||
@@ -93,11 +92,9 @@ public class SqlServerDdl extends PlatformDdl {
|
||||
|
||||
@Override
|
||||
public String alterTableDropConstraint(String tableName, String constraintName) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("IF (OBJECT_ID('").append(constraintName).append("', 'C') IS NOT NULL) ");
|
||||
sb.append(super.alterTableDropConstraint(tableName, constraintName));
|
||||
return sb.toString();
|
||||
return ifObjectExists(maxConstraintName(constraintName), CONSTRAINT) + super.alterTableDropConstraint(tableName, constraintName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a unique constraint from the table (Sometimes this is an index).
|
||||
*/
|
||||
@@ -105,10 +102,12 @@ public class SqlServerDdl extends PlatformDdl {
|
||||
public String alterTableDropUniqueConstraint(String tableName, String uniqueConstraintName) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(dropIndex(uniqueConstraintName, tableName)).append(";\n");
|
||||
sb.append("IF (OBJECT_ID('").append(maxConstraintName(uniqueConstraintName)).append("', 'UQ') IS NOT NULL) ");
|
||||
sb.append(super.alterTableDropUniqueConstraint(tableName, uniqueConstraintName));
|
||||
|
||||
sb.append(ifObjectExists(maxConstraintName(uniqueConstraintName), UNIQUE_CONSTRAINT))
|
||||
.append(super.alterTableDropUniqueConstraint(tableName, uniqueConstraintName));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and return the create sequence DDL.
|
||||
*/
|
||||
@@ -135,57 +134,60 @@ public class SqlServerDdl extends PlatformDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnDefaultValue(String tableName, String columnName, String defaultValue) {
|
||||
protected void alterColumnDefault(DdlWrite writer, AlterColumn alter) {
|
||||
// Unfortunately, the SqlServer creates default values with a random name.
|
||||
// You can specify a name in DDL, but this does not work in conjunction with
|
||||
// temporal tables in certain cases. So we have to delete the constraint with
|
||||
// a rather complex statement.
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (DdlHelp.isDropDefault(defaultValue)) {
|
||||
sb.append("EXEC usp_ebean_drop_default_constraint ").append(tableName).append(", ").append(columnName);
|
||||
} else {
|
||||
sb.append("alter table ").append(tableName);
|
||||
sb.append(" add default ").append(convertDefaultValue(defaultValue)).append(" for ").append(columnName);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnBaseAttributes(AlterColumn alter) {
|
||||
if (alter.getType() == null && alter.isNotnull() == null) {
|
||||
// No type change or notNull change
|
||||
// defaultValue change already handled in alterColumnDefaultValue
|
||||
return null;
|
||||
}
|
||||
String tableName = alter.getTableName();
|
||||
String columnName = alter.getColumnName();
|
||||
String type = alter.getType() != null ? alter.getType() : alter.getCurrentType();
|
||||
type = convert(type);
|
||||
boolean notnull = (alter.isNotnull() != null) ? alter.isNotnull() : Boolean.TRUE.equals(alter.isCurrentNotnull());
|
||||
String notnullClause = notnull ? " not null" : "";
|
||||
|
||||
return "alter table " + tableName + " " + alterColumn + " " + columnName + " " + type + notnullClause;
|
||||
String defaultValue = alter.getDefaultValue();
|
||||
if (DdlHelp.isDropDefault(defaultValue)) {
|
||||
execUspDropDefaultConstraint(writer, tableName, columnName);
|
||||
} else {
|
||||
execUspDropDefaultConstraint(writer, tableName, columnName);
|
||||
setDefaultValue(writer, tableName, columnName, defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnType(String tableName, String columnName, String type) {
|
||||
public void alterColumn(DdlWrite writer, AlterColumn alter) {
|
||||
String tableName = alter.getTableName();
|
||||
String columnName = alter.getColumnName();
|
||||
if (alter.getType() == null && alter.isNotnull() == null) {
|
||||
// No type change or notNull change
|
||||
if (hasValue(alter.getDefaultValue())) {
|
||||
alterColumnDefault(writer, alter);
|
||||
}
|
||||
} else {
|
||||
// we must regenerate whole statement -> read altered and current value
|
||||
String type = alter.getType() != null ? alter.getType() : alter.getCurrentType();
|
||||
type = convert(type);
|
||||
boolean notnull = (alter.isNotnull() != null) ? alter.isNotnull() : Boolean.TRUE.equals(alter.isCurrentNotnull());
|
||||
String defaultValue = alter.getDefaultValue() != null ? alter.getDefaultValue() : alter.getCurrentDefaultValue();
|
||||
if (hasValue(defaultValue)) {
|
||||
// default value present -> drop default constraint before altering
|
||||
execUspDropDefaultConstraint(writer, tableName, columnName);
|
||||
}
|
||||
|
||||
// can't alter itself - done in alterColumnBaseAttributes()
|
||||
return null;
|
||||
}
|
||||
DdlBuffer buffer = alterTable(writer, tableName).append(alterColumn, columnName);
|
||||
buffer.append(type);
|
||||
if (notnull) {
|
||||
buffer.append(" not null");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String alterColumnNotnull(String tableName, String columnName, boolean notnull) {
|
||||
|
||||
// can't alter itself - done in alterColumnBaseAttributes()
|
||||
return null;
|
||||
// re add - default constraint
|
||||
if (hasValue(defaultValue) && !DdlHelp.isDropDefault(defaultValue)) {
|
||||
setDefaultValue(writer, tableName, columnName, defaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add table comment as a separate statement (from the create table statement).
|
||||
*/
|
||||
@Override
|
||||
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) throws IOException {
|
||||
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) {
|
||||
|
||||
// do nothing for MS SQL Server (cause it requires stored procedures etc)
|
||||
}
|
||||
@@ -194,7 +196,7 @@ public class SqlServerDdl extends PlatformDdl {
|
||||
* Add column comment as a separate statement.
|
||||
*/
|
||||
@Override
|
||||
public void addColumnComment(DdlBuffer apply, String table, String column, String comment) throws IOException {
|
||||
public void addColumnComment(DdlBuffer apply, String table, String column, String comment) {
|
||||
|
||||
// do nothing for MS SQL Server (cause it requires stored procedures etc)
|
||||
}
|
||||
@@ -204,47 +206,58 @@ public class SqlServerDdl extends PlatformDdl {
|
||||
* (constraints, default values, indices and foreign keys). That's why we call a user stored procedure here
|
||||
*/
|
||||
@Override
|
||||
public void alterTableDropColumn(DdlBuffer buffer, String tableName, String columnName) throws IOException {
|
||||
|
||||
buffer.append("EXEC usp_ebean_drop_column ").append(tableName).append(", ").append(columnName).endOfStatement();
|
||||
public void alterTableDropColumn(DdlWrite writer, String tableName, String columnName) {
|
||||
alterTable(writer, tableName).raw("EXEC usp_ebean_drop_column ").append(tableName).append(", ").append(columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* This writes the multi value datatypes needed for MultiValueBind.
|
||||
*/
|
||||
@Override
|
||||
public void generateProlog(DdlWrite write) throws IOException {
|
||||
super.generateProlog(write);
|
||||
public void generateProlog(DdlWrite writer) {
|
||||
super.generateProlog(writer);
|
||||
|
||||
generateTVPDefinitions(write, "bigint");
|
||||
generateTVPDefinitions(write, "float");
|
||||
generateTVPDefinitions(write, "bit");
|
||||
generateTVPDefinitions(write, "date");
|
||||
generateTVPDefinitions(write, "time");
|
||||
generateTVPDefinitions(writer, "bigint");
|
||||
generateTVPDefinitions(writer, "float");
|
||||
generateTVPDefinitions(writer, "bit");
|
||||
generateTVPDefinitions(writer, "date");
|
||||
generateTVPDefinitions(writer, "time");
|
||||
//generateTVPDefinitions(write, "datetime2");
|
||||
generateTVPDefinitions(write, "uniqueidentifier");
|
||||
generateTVPDefinitions(write, "nvarchar(max)");
|
||||
generateTVPDefinitions(writer, "uniqueidentifier");
|
||||
generateTVPDefinitions(writer, "nvarchar(max)");
|
||||
|
||||
}
|
||||
|
||||
private void generateTVPDefinitions(DdlWrite write, String definition) throws IOException {
|
||||
private void generateTVPDefinitions(DdlWrite writer, String definition) {
|
||||
int pos = definition.indexOf('(');
|
||||
String name = pos == -1 ? definition : definition.substring(0, pos);
|
||||
|
||||
dropTVP(write.dropAll(), name);
|
||||
dropTVP(writer.dropAll(), name);
|
||||
//TVPs are included in "I__create_procs.sql"
|
||||
//createTVP(write.apply(), name, definition);
|
||||
}
|
||||
|
||||
private void dropTVP(DdlBuffer ddl, String name) throws IOException {
|
||||
private void dropTVP(DdlBuffer ddl, String name) {
|
||||
ddl.append("if exists (select name from sys.types where name = 'ebean_").append(name)
|
||||
.append("_tvp') drop type ebean_").append(name).append("_tvp").endOfStatement();
|
||||
}
|
||||
|
||||
private void createTVP(DdlBuffer ddl, String name, String definition) throws IOException {
|
||||
@SuppressWarnings("unused")
|
||||
private void createTVP(DdlBuffer ddl, String name, String definition) {
|
||||
ddl.append("if not exists (select name from sys.types where name = 'ebean_").append(name)
|
||||
.append("_tvp') create type ebean_").append(name).append("_tvp as table (c1 ").append(definition).append(")")
|
||||
.endOfStatement();
|
||||
}
|
||||
|
||||
public static String ifObjectExists(String object, String objectType) {
|
||||
return "IF OBJECT_ID('" + object + "', '" + objectType + "') IS NOT NULL ";
|
||||
}
|
||||
|
||||
private void execUspDropDefaultConstraint(DdlWrite writer, String tableName, String columnName) {
|
||||
alterTable(writer, tableName).raw("EXEC usp_ebean_drop_default_constraint " + tableName + ", " + columnName);
|
||||
}
|
||||
|
||||
private void setDefaultValue(DdlWrite writer, String tableName, String columnName, String defaultValue) {
|
||||
alterTable(writer, tableName).append("add default " + convertDefaultValue(defaultValue) + " for", columnName);
|
||||
}
|
||||
}
|
||||
|
||||
+35
-26
@@ -1,14 +1,14 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlAlterTable;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Vilmos Nagy
|
||||
*/
|
||||
@@ -26,7 +26,7 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWithHistory(DdlWrite writer, MTable table) throws IOException {
|
||||
public void createWithHistory(DdlWrite writer, MTable table) {
|
||||
String baseTable = table.getName();
|
||||
enableSystemVersioning(writer, baseTable);
|
||||
}
|
||||
@@ -43,8 +43,8 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl {
|
||||
return historyTable;
|
||||
}
|
||||
|
||||
private void enableSystemVersioning(DdlWrite writer, String baseTable) throws IOException {
|
||||
DdlBuffer apply = writer.applyHistoryView();
|
||||
private void enableSystemVersioning(DdlWrite writer, String baseTable) {
|
||||
DdlBuffer apply = writer.applyPostAlter();
|
||||
apply.append("alter table ").append(baseTable).newLine()
|
||||
.append(" add ").append(systemPeriodStart).append(" datetime2 GENERATED ALWAYS AS ROW START NOT NULL DEFAULT SYSUTCDATETIME(),").newLine()
|
||||
.append(" ").append(systemPeriodEnd).append(" datetime2 GENERATED ALWAYS AS ROW END NOT NULL DEFAULT '9999-12-31T23:59:59.9999999',").newLine()
|
||||
@@ -59,40 +59,49 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) throws IOException {
|
||||
public void dropHistoryTable(DdlWrite writer, DropHistoryTable dropHistoryTable) {
|
||||
String baseTable = dropHistoryTable.getBaseTable();
|
||||
DdlBuffer apply = writer.applyHistoryView();
|
||||
apply.append("-- dropping history support for ").append(baseTable).endOfStatement();
|
||||
// drop default constraints
|
||||
AlterColumn alter = new AlterColumn();
|
||||
alter.setTableName(baseTable);
|
||||
alter.setDefaultValue(DdlHelp.DROP_DEFAULT);
|
||||
alter.setColumnName(systemPeriodStart);
|
||||
platformDdl.alterColumn(writer, alter);
|
||||
alter.setColumnName(systemPeriodEnd);
|
||||
platformDdl.alterColumn(writer, alter);
|
||||
|
||||
apply.append(platformDdl.alterColumnDefaultValue(baseTable, systemPeriodStart, DdlHelp.DROP_DEFAULT)).endOfStatement();
|
||||
apply.append(platformDdl.alterColumnDefaultValue(baseTable, systemPeriodEnd, DdlHelp.DROP_DEFAULT)).endOfStatement();
|
||||
// switch of versioning & period
|
||||
// switch of versioning & period - must be done before altering
|
||||
DdlBuffer apply = writer.apply();
|
||||
apply.append("-- dropping history support for ").append(baseTable).endOfStatement();
|
||||
apply.append("alter table ").append(baseTable).append(" set (system_versioning = off)").endOfStatement();
|
||||
apply.append("alter table ").append(baseTable).append(" drop period for system_time").endOfStatement();
|
||||
// now drop tables & columns
|
||||
apply.append("alter table ").append(baseTable).append(" drop column ").append(systemPeriodStart).endOfStatement();
|
||||
apply.append("alter table ").append(baseTable).append(" drop column ").append(systemPeriodEnd).endOfStatement();
|
||||
apply.append("IF OBJECT_ID('").append(baseTable).append("_history', 'U') IS NOT NULL drop table ").append(baseTable).append("_history").endOfStatement();
|
||||
apply.end();
|
||||
// now drop tables & columns, they will go to alter table/post alter buffers
|
||||
platformDdl.alterTableDropColumn(writer, baseTable, systemPeriodStart);
|
||||
platformDdl.alterTableDropColumn(writer, baseTable, systemPeriodEnd);
|
||||
writer.applyPostAlter().appendStatement(platformDdl.dropTable(baseTable + "_history"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) throws IOException {
|
||||
public void addHistoryTable(DdlWrite writer, AddHistoryTable addHistoryTable) {
|
||||
String baseTable = addHistoryTable.getBaseTable();
|
||||
enableSystemVersioning(writer, baseTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTriggers(DdlWrite writer, HistoryTableUpdate baseTable) throws IOException {
|
||||
// SQL Server 2016 does not need triggers
|
||||
DdlBuffer apply = writer.applyHistoryView();
|
||||
String baseTableName = baseTable.getBaseTable();
|
||||
apply.append("-- alter table ").append(baseTableName).append(" set (system_versioning = off (history_table=")
|
||||
.append(getHistoryTable(baseTableName)).append("))").endOfStatement();
|
||||
apply.append("-- history migration goes here").newLine();
|
||||
apply.append("-- alter table ").append(baseTableName).append(" set (system_versioning = on (history_table=")
|
||||
.append(getHistoryTable(baseTableName)).append("))").endOfStatement();
|
||||
|
||||
public void updateTriggers(DdlWrite writer, String tableName) {
|
||||
DdlAlterTable alter = platformDdl.alterTable(writer, tableName);
|
||||
writer.getTable(tableName);
|
||||
if (!alter.isHistoryHandled()) {
|
||||
// SQL Server 2016 does not need triggers
|
||||
DdlBuffer apply = writer.apply();
|
||||
apply.append("-- alter table ").append(tableName).append(" set (system_versioning = off (history_table=")
|
||||
.append(getHistoryTable(tableName)).append("))").endOfStatement();
|
||||
apply.append("-- history migration goes here").newLine();
|
||||
apply.append("-- alter table ").append(tableName).append(" set (system_versioning = on (history_table=")
|
||||
.append(getHistoryTable(tableName)).append("))").endOfStatement();
|
||||
}
|
||||
alter.setHistoryHandled();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-3
@@ -3,12 +3,10 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.model.MTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class YugabyteHistoryDdl extends PostgresHistoryDdl {
|
||||
|
||||
@Override
|
||||
protected void createHistoryTable(DdlBuffer apply, MTable table) throws IOException {
|
||||
protected void createHistoryTable(DdlBuffer apply, MTable table) {
|
||||
createHistoryTableAs(apply, table);
|
||||
writeColumnDefinition(apply, sysPeriod, "tstzrange");
|
||||
apply.newLine().append(")").endOfStatement();
|
||||
|
||||
+21
-15
@@ -36,7 +36,7 @@ public class CurrentModel {
|
||||
|
||||
private ModelContainer model;
|
||||
private ChangeSet changeSet;
|
||||
private DdlWrite write;
|
||||
private DdlWrite writer;
|
||||
|
||||
/**
|
||||
* Construct with a given EbeanServer instance for DDL create all generation, not migration.
|
||||
@@ -117,7 +117,7 @@ public class CurrentModel {
|
||||
/**
|
||||
* Return the 'Create' DDL.
|
||||
*/
|
||||
public String getCreateDdl() throws IOException {
|
||||
public String getCreateDdl() {
|
||||
|
||||
createDdl();
|
||||
|
||||
@@ -128,10 +128,13 @@ public class CurrentModel {
|
||||
if (jaxbPresent) {
|
||||
addExtraDdl(ddl, ExtraDdlXmlReader.readBuiltin(), "-- init script ");
|
||||
}
|
||||
ddl.append(write.apply().getBuffer());
|
||||
ddl.append(write.applyForeignKeys().getBuffer());
|
||||
ddl.append(write.applyHistoryView().getBuffer());
|
||||
ddl.append(write.applyHistoryTrigger().getBuffer());
|
||||
|
||||
try {
|
||||
writer.writeApply(ddl);
|
||||
} catch (IOException e) { // should not happen on StringBuilder
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return ddl.toString();
|
||||
}
|
||||
|
||||
@@ -150,7 +153,7 @@ public class CurrentModel {
|
||||
/**
|
||||
* Return the 'Drop' DDL.
|
||||
*/
|
||||
public String getDropAllDdl() throws IOException {
|
||||
public String getDropAllDdl() {
|
||||
|
||||
createDdl();
|
||||
|
||||
@@ -158,22 +161,25 @@ public class CurrentModel {
|
||||
if (ddlHeader != null && !ddlHeader.isEmpty()) {
|
||||
ddl.append(ddlHeader).append('\n');
|
||||
}
|
||||
ddl.append(write.dropAllForeignKeys().getBuffer());
|
||||
ddl.append(write.dropAll().getBuffer());
|
||||
try {
|
||||
writer.writeDropAll(ddl);
|
||||
} catch (IOException e) { // should not happen on StringBuilder
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return ddl.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create all the DDL based on the changeSet.
|
||||
*/
|
||||
private void createDdl() throws IOException {
|
||||
if (write == null) {
|
||||
private void createDdl() {
|
||||
if (writer == null) {
|
||||
ChangeSet createChangeSet = getChangeSet();
|
||||
write = new DdlWrite(new MConfiguration(), model, ddlOptions);
|
||||
writer = new DdlWrite(new MConfiguration(), model, ddlOptions);
|
||||
DdlHandler handler = handler();
|
||||
handler.generateProlog(write);
|
||||
handler.generate(write, createChangeSet);
|
||||
handler.generateEpilog(write);
|
||||
handler.generateProlog(writer);
|
||||
handler.generate(writer, createChangeSet);
|
||||
handler.generateEpilog(writer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -89,8 +89,9 @@ public class MTableIdentity {
|
||||
return IdentityType.EXTERNAL;
|
||||
case GENERATOR:
|
||||
return IdentityType.GENERATOR;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int toInt(BigInteger firstVal, BigInteger secVal) {
|
||||
|
||||
+12
-26
@@ -3,7 +3,6 @@ package io.ebeaninternal.dbmigration.model;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.util.IOUtils;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.PlatformDdlBuilder;
|
||||
@@ -39,23 +38,24 @@ public class PlatformDdlWriter {
|
||||
/**
|
||||
* Write the migration as platform specific ddl.
|
||||
*/
|
||||
public void processMigration(Migration dbMigration, DdlWrite write, File writePath, String fullVersion) throws IOException {
|
||||
public void processMigration(Migration dbMigration, DdlWrite writer, File writePath, String fullVersion)
|
||||
throws IOException {
|
||||
DdlHandler handler = handler();
|
||||
handler.generateProlog(write);
|
||||
handler.generateProlog(writer);
|
||||
if (lockTimeoutSeconds > 0) {
|
||||
String lockSql = platformDdl.setLockTimeout(lockTimeoutSeconds);
|
||||
if (lockSql != null) {
|
||||
write.apply().append(lockSql).endOfStatement().newLine();
|
||||
writer.apply().append(lockSql).endOfStatement().newLine();
|
||||
}
|
||||
}
|
||||
List<ChangeSet> changeSets = dbMigration.getChangeSet();
|
||||
for (ChangeSet changeSet : changeSets) {
|
||||
if (isApply(changeSet)) {
|
||||
handler.generate(write, changeSet);
|
||||
handler.generate(writer, changeSet);
|
||||
}
|
||||
}
|
||||
handler.generateEpilog(write);
|
||||
writePlatformDdl(write, writePath, fullVersion);
|
||||
handler.generateEpilog(writer);
|
||||
writePlatformDdl(writer, writePath, fullVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,10 +68,10 @@ public class PlatformDdlWriter {
|
||||
/**
|
||||
* Write the ddl files.
|
||||
*/
|
||||
protected void writePlatformDdl(DdlWrite write, File resourcePath, String fullVersion) throws IOException {
|
||||
if (!write.isApplyEmpty()) {
|
||||
protected void writePlatformDdl(DdlWrite writer, File resourcePath, String fullVersion) throws IOException {
|
||||
if (!writer.isApplyEmpty()) {
|
||||
try (Writer applyWriter = createWriter(resourcePath, fullVersion, ".sql")) {
|
||||
writeApplyDdl(applyWriter, write);
|
||||
writeApplyDdl(applyWriter, writer);
|
||||
applyWriter.flush();
|
||||
}
|
||||
}
|
||||
@@ -85,26 +85,12 @@ public class PlatformDdlWriter {
|
||||
/**
|
||||
* Write the 'Apply' DDL buffers to the writer.
|
||||
*/
|
||||
protected void writeApplyDdl(Writer writer, DdlWrite write) throws IOException {
|
||||
protected void writeApplyDdl(Writer writer, DdlWrite ddl) throws IOException {
|
||||
String header = databaseConfig.getDdlHeader();
|
||||
if (header != null && !header.isEmpty()) {
|
||||
writer.append(header).append('\n');
|
||||
}
|
||||
// merge the apply buffers in the appropriate order
|
||||
prependDropDependencies(writer, write.applyDropDependencies());
|
||||
writer.append("-- apply changes\n");
|
||||
writer.append(write.apply().getBuffer());
|
||||
writer.append(write.applyForeignKeys().getBuffer());
|
||||
writer.append(write.applyHistoryView().getBuffer());
|
||||
writer.append(write.applyHistoryTrigger().getBuffer());
|
||||
}
|
||||
|
||||
private void prependDropDependencies(Writer writer, DdlBuffer buffer) throws IOException {
|
||||
if (!buffer.isEmpty()) {
|
||||
writer.append("-- drop dependencies\n");
|
||||
writer.append(buffer.getBuffer());
|
||||
writer.append("\n");
|
||||
}
|
||||
ddl.writeApply(writer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+105
-101
@@ -19,7 +19,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
public class BaseDdlHandlerTest extends BaseTestCase {
|
||||
|
||||
private static boolean useV1Syntax = Boolean.getBoolean("ebean.h2.useV1Syntax");
|
||||
|
||||
|
||||
private final DatabaseConfig serverConfig = new DatabaseConfig();
|
||||
|
||||
private DdlHandler handler(DatabasePlatform platform) {
|
||||
@@ -45,192 +45,196 @@ public class BaseDdlHandlerTest extends BaseTestCase {
|
||||
@Test
|
||||
public void addColumn_nullable_noConstraint() throws Exception {
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
h2Handler().generate(write, Helper.getAddColumn());
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column added_to_foo varchar(20);\n\n");
|
||||
DdlWrite writer = new DdlWrite();
|
||||
h2Handler().generate(writer, Helper.getAddColumn());
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column added_to_foo varchar(20);\n");
|
||||
|
||||
write = new DdlWrite();
|
||||
sqlserverHandler().generate(write, Helper.getAddColumn());
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add added_to_foo nvarchar(20);\n\n");
|
||||
writer = new DdlWrite();
|
||||
sqlserverHandler().generate(writer, Helper.getAddColumn());
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add added_to_foo nvarchar(20);\n");
|
||||
|
||||
write = new DdlWrite();
|
||||
hanaHandler().generate(write, Helper.getAddColumn());
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add ( added_to_foo nvarchar(20));\n\n");
|
||||
writer = new DdlWrite();
|
||||
hanaHandler().generate(writer, Helper.getAddColumn());
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add (added_to_foo nvarchar(20));\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addColumn_withCheckConstraint() throws Exception {
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
h2Handler().generate(write, Helper.getAlterTableAddColumnWithCheckConstraint());
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column status integer;\n"
|
||||
+ "alter table foo add constraint ck_ordering_status check ( status in (0,1));\n\n");
|
||||
DdlWrite writer = new DdlWrite();
|
||||
h2Handler().generate(writer, Helper.getAlterTableAddColumnWithCheckConstraint());
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column status integer;\n"
|
||||
+ "-- apply post alter\nalter table foo add constraint ck_ordering_status check ( status in (0,1));\n");
|
||||
|
||||
write = new DdlWrite();
|
||||
hanaHandler().generate(write, Helper.getAlterTableAddColumnWithCheckConstraint());
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add ( status integer);\n"
|
||||
+ "alter table foo add constraint ck_ordering_status check ( status in (0,1));\n\n");
|
||||
writer = new DdlWrite();
|
||||
hanaHandler().generate(writer, Helper.getAlterTableAddColumnWithCheckConstraint());
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add (status integer);\n"
|
||||
+ "-- apply post alter\nalter table foo add constraint ck_ordering_status check ( status in (0,1));\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the functionality of the Ebean {@literal @}DbArray extension during DDL
|
||||
* generation.
|
||||
* Test the functionality of the Ebean {@literal @}DbArray extension during DDL generation.
|
||||
*/
|
||||
@Test
|
||||
public void addColumn_dbarray() throws Exception {
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
|
||||
DdlHandler postgresHandler = postgresHandler();
|
||||
postgresHandler.generate(write, Helper.getAlterTableAddDbArrayColumn());
|
||||
postgresHandler.generate(writer, Helper.getAlterTableAddDbArrayColumn());
|
||||
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_added_to_foo varchar[];\n\n");
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_added_to_foo varchar[];\n");
|
||||
|
||||
write = new DdlWrite();
|
||||
writer = new DdlWrite();
|
||||
|
||||
DdlHandler sqlserverHandler = sqlserverHandler();
|
||||
sqlserverHandler.generate(write, Helper.getAlterTableAddDbArrayColumn());
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add dbarray_added_to_foo varchar(1000);\n\n");
|
||||
sqlserverHandler.generate(writer, Helper.getAlterTableAddDbArrayColumn());
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add dbarray_added_to_foo varchar(1000);\n");
|
||||
|
||||
write = new DdlWrite();
|
||||
writer = new DdlWrite();
|
||||
|
||||
DdlHandler hanaHandler = hanaHandler();
|
||||
hanaHandler.generate(write, Helper.getAlterTableAddDbArrayColumn());
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add ( dbarray_added_to_foo nvarchar(255) array);\n\n");
|
||||
hanaHandler.generate(writer, Helper.getAlterTableAddDbArrayColumn());
|
||||
assertThat(writer.toString())
|
||||
.isEqualTo("-- apply alter tables\nalter table foo add (dbarray_added_to_foo nvarchar(255) array);\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addColumn_dbarray_withLength() throws Exception {
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
|
||||
postgresHandler().generate(write, Helper.getAlterTableAddDbArrayColumnWithLength());
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_ninety varchar[];\n\n");
|
||||
postgresHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnWithLength());
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_ninety varchar[];\n");
|
||||
|
||||
write = new DdlWrite();
|
||||
h2Handler().generate(write, Helper.getAlterTableAddDbArrayColumnWithLength());
|
||||
writer = new DdlWrite();
|
||||
h2Handler().generate(writer, Helper.getAlterTableAddDbArrayColumnWithLength());
|
||||
if (useV1Syntax) {
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_ninety array;\n\n");
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_ninety array;\n");
|
||||
} else {
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_ninety varchar array;\n\n");
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_ninety varchar array;\n");
|
||||
}
|
||||
|
||||
write = new DdlWrite();
|
||||
sqlserverHandler().generate(write, Helper.getAlterTableAddDbArrayColumnWithLength());
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add dbarray_ninety varchar(90);\n\n");
|
||||
writer = new DdlWrite();
|
||||
sqlserverHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnWithLength());
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add dbarray_ninety varchar(90);\n");
|
||||
|
||||
write = new DdlWrite();
|
||||
hanaHandler().generate(write, Helper.getAlterTableAddDbArrayColumnWithLength());
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add ( dbarray_ninety nvarchar(255) array(90));\n\n");
|
||||
writer = new DdlWrite();
|
||||
hanaHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnWithLength());
|
||||
assertThat(writer.toString())
|
||||
.isEqualTo("-- apply alter tables\nalter table foo add (dbarray_ninety nvarchar(255) array(90));\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addColumn_dbarray_integer_withLength() throws Exception {
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
postgresHandler().generate(write, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_integer integer[];\n\n");
|
||||
DdlWrite writer = new DdlWrite();
|
||||
postgresHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_integer integer[];\n");
|
||||
|
||||
write = new DdlWrite();
|
||||
h2Handler().generate(write, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
|
||||
writer = new DdlWrite();
|
||||
h2Handler().generate(writer, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
|
||||
if (useV1Syntax) {
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_integer array;\n\n");
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_integer array;\n");
|
||||
} else {
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add column dbarray_integer integer array;\n\n");
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_integer integer array;\n");
|
||||
}
|
||||
|
||||
write = new DdlWrite();
|
||||
sqlserverHandler().generate(write, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add dbarray_integer varchar(90);\n\n");
|
||||
writer = new DdlWrite();
|
||||
sqlserverHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add dbarray_integer varchar(90);\n");
|
||||
|
||||
write = new DdlWrite();
|
||||
sqlserverHandler().generate(write, Helper.getAlterTableAddDbArrayColumnInteger());
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add dbarray_integer varchar(1000);\n\n");
|
||||
writer = new DdlWrite();
|
||||
sqlserverHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnInteger());
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add dbarray_integer varchar(1000);\n");
|
||||
|
||||
write = new DdlWrite();
|
||||
hanaHandler().generate(write, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add ( dbarray_integer integer array(90));\n\n");
|
||||
writer = new DdlWrite();
|
||||
hanaHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add (dbarray_integer integer array(90));\n");
|
||||
|
||||
write = new DdlWrite();
|
||||
hanaHandler().generate(write, Helper.getAlterTableAddDbArrayColumnInteger());
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo add ( dbarray_integer integer array);\n\n");
|
||||
writer = new DdlWrite();
|
||||
hanaHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnInteger());
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add (dbarray_integer integer array);\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addColumn_withForeignKey() throws Exception {
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
|
||||
DdlHandler handler = h2Handler();
|
||||
handler.generate(write, Helper.getAlterTableAddColumn());
|
||||
handler.generate(writer, Helper.getAlterTableAddColumn());
|
||||
|
||||
String buffer = write.apply().getBuffer();
|
||||
assertThat(buffer).contains("alter table foo add column some_id integer;");
|
||||
String buffer = writer.toString();
|
||||
assertThat(buffer).contains("-- apply alter tables\nalter table foo add column some_id integer;");
|
||||
|
||||
String fkBuffer = write.applyForeignKeys().getBuffer();
|
||||
String fkBuffer = writer.applyForeignKeys().getBuffer();
|
||||
assertThat(fkBuffer).contains(
|
||||
"alter table foo add constraint fk_foo_some_id foreign key (some_id) references bar (id) on delete restrict on update restrict;");
|
||||
"alter table foo add constraint fk_foo_some_id foreign key (some_id) references bar (id) on delete restrict on update restrict;");
|
||||
assertThat(fkBuffer).contains("create index idx_foo_some_id on foo (some_id);");
|
||||
assertThat(write.dropAll().getBuffer()).isEqualTo("");
|
||||
assertThat(writer.dropAll().getBuffer()).isEqualTo("");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dropColumn() throws Exception {
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
DdlHandler handler = h2Handler();
|
||||
|
||||
handler.generate(write, Helper.getDropColumn());
|
||||
handler.generate(writer, Helper.getDropColumn());
|
||||
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table foo drop column col2;\n\n");
|
||||
assertThat(write.dropAll().getBuffer()).isEqualTo("");
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo drop column col2;\n");
|
||||
assertThat(writer.dropAll().getBuffer()).isEqualTo("");
|
||||
|
||||
write = new DdlWrite();
|
||||
writer = new DdlWrite();
|
||||
DdlHandler hanaHandler = hanaHandler();
|
||||
|
||||
hanaHandler.generate(write, Helper.getDropColumn());
|
||||
hanaHandler.generate(writer, Helper.getDropColumn());
|
||||
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("CALL usp_ebean_drop_column('foo', 'col2');\n\n");
|
||||
assertThat(write.dropAll().getBuffer()).isEqualTo("");
|
||||
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nCALL usp_ebean_drop_column('foo', 'col2');\n");
|
||||
assertThat(writer.dropAll().getBuffer()).isEqualTo("");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createTable() throws Exception {
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
DdlHandler handler = h2Handler();
|
||||
|
||||
handler.generate(write, Helper.getCreateTable());
|
||||
handler.generate(writer, Helper.getCreateTable());
|
||||
|
||||
String createTableDDL = Helper.asText(this, "/assert/create-table.txt");
|
||||
String createTableDDL = Helper.asText(this, "/assert/drop-create-table.txt");
|
||||
|
||||
assertThat(write.apply().getBuffer()).isEqualTo(createTableDDL);
|
||||
assertThat(write.dropAll().getBuffer().trim()).isEqualTo("drop table if exists foo;");
|
||||
assertThat(writer.toString()).isEqualTo(createTableDDL);
|
||||
assertThat(writer.dropAll().getBuffer().trim()).isEqualTo("drop table if exists foo;");
|
||||
|
||||
write = new DdlWrite();
|
||||
writer = new DdlWrite();
|
||||
DdlHandler hanaHandler = hanaHandler();
|
||||
|
||||
hanaHandler.generate(write, Helper.getCreateTable());
|
||||
hanaHandler.generate(writer, Helper.getCreateTable());
|
||||
|
||||
String createColumnTableDDL = Helper.asText(this, "/assert/create-column-table.txt");
|
||||
String createColumnTableDDL = Helper.asText(this, "/assert/drop-create-column-table.txt");
|
||||
|
||||
assertThat(write.apply().getBuffer()).isEqualTo(createColumnTableDDL);
|
||||
assertThat(write.dropAll().getBuffer().trim()).isEqualTo("drop table foo cascade;");
|
||||
assertThat(writer.toString()).isEqualTo(createColumnTableDDL);
|
||||
assertThat(writer.dropAll().getBuffer().trim()).isEqualTo("drop table foo cascade;");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void generateChangeSet() throws Exception {
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
DdlHandler handler = h2Handler();
|
||||
|
||||
handler.generate(write, Helper.getChangeSet());
|
||||
handler.generate(writer, Helper.getChangeSet());
|
||||
|
||||
String apply = Helper.asText(this, "/assert/BaseDdlHandlerTest/baseApply.sql");
|
||||
String rollbackLast = Helper.asText(this, "/assert/BaseDdlHandlerTest/baseDropAll.sql");
|
||||
|
||||
assertThat(write.apply().getBuffer()).isEqualTo(apply);
|
||||
assertThat(write.dropAll().getBuffer()).isEqualTo(rollbackLast);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
writer.writeApply(sb);
|
||||
assertThat(sb.toString()).isEqualTo(apply);
|
||||
sb = new StringBuilder();
|
||||
writer.writeDropAll(sb);
|
||||
assertThat(sb.toString()).isEqualTo(rollbackLast);
|
||||
}
|
||||
|
||||
@Disabled
|
||||
@@ -241,16 +245,16 @@ public class BaseDdlHandlerTest extends BaseTestCase {
|
||||
|
||||
ChangeSet createChangeSet = new CurrentModel(defaultServer).getChangeSet();
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
|
||||
DdlHandler handler = h2Handler();
|
||||
handler.generate(write, createChangeSet);
|
||||
handler.generate(writer, createChangeSet);
|
||||
|
||||
String apply = Helper.asText(this, "/assert/changeset-apply.txt");
|
||||
String rollbackLast = Helper.asText(this, "/assert/changeset-dropAll.txt");
|
||||
|
||||
assertThat(write.apply().getBuffer()).isEqualTo(apply);
|
||||
assertThat(write.dropAll().getBuffer()).isEqualTo(rollbackLast);
|
||||
assertThat(writer.toString()).isEqualTo(apply);
|
||||
assertThat(writer.dropAll().getBuffer()).isEqualTo(rollbackLast);
|
||||
}
|
||||
|
||||
@Disabled
|
||||
@@ -260,20 +264,20 @@ public class BaseDdlHandlerTest extends BaseTestCase {
|
||||
|
||||
ChangeSet createChangeSet = new CurrentModel(defaultServer).getChangeSet();
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
|
||||
DdlHandler handler = postgresHandler();
|
||||
handler.generate(write, createChangeSet);
|
||||
handler.generate(writer, createChangeSet);
|
||||
|
||||
String apply = Helper.asText(this, "/assert/changeset-pg-apply.sql");
|
||||
String applyLast = Helper.asText(this, "/assert/changeset-pg-applyLast.sql");
|
||||
String rollbackFirst = Helper.asText(this, "/assert/changeset-pg-rollbackFirst.sql");
|
||||
String rollbackLast = Helper.asText(this, "/assert/changeset-pg-rollbackLast.sql");
|
||||
|
||||
assertThat(write.apply().getBuffer()).isEqualTo(apply);
|
||||
assertThat(write.applyForeignKeys().getBuffer()).isEqualTo(applyLast);
|
||||
assertThat(write.dropAllForeignKeys().getBuffer()).isEqualTo(rollbackFirst);
|
||||
assertThat(write.dropAll().getBuffer()).isEqualTo(rollbackLast);
|
||||
assertThat(writer.toString()).isEqualTo(apply);
|
||||
assertThat(writer.applyForeignKeys().getBuffer()).isEqualTo(applyLast);
|
||||
assertThat(writer.dropAllForeignKeys().getBuffer()).isEqualTo(rollbackFirst);
|
||||
assertThat(writer.dropAll().getBuffer()).isEqualTo(rollbackLast);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+36
-37
@@ -15,7 +15,6 @@ import io.ebeaninternal.dbmigration.migration.Column;
|
||||
import io.ebeaninternal.dbmigration.migration.CreateTable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -28,121 +27,121 @@ public class BaseTableDdlTest {
|
||||
private final PlatformDdl h2ddl = PlatformDdlBuilder.create(new H2Platform());
|
||||
|
||||
@Test
|
||||
public void testAlterColumn() throws IOException {
|
||||
public void testAlterColumn() {
|
||||
BaseTableDdl ddlGen = new BaseTableDdl(serverConfig, h2ddl);
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
|
||||
AlterColumn alterColumn = new AlterColumn();
|
||||
alterColumn.setTableName("mytab");
|
||||
alterColumn.setCheckConstraint("check (acol in ('A','B'))");
|
||||
alterColumn.setCheckConstraintName("ck_mytab_acol");
|
||||
|
||||
ddlGen.generate(write, alterColumn);
|
||||
ddlGen.generate(writer, alterColumn);
|
||||
|
||||
String ddl = write.apply().getBuffer();
|
||||
String ddl = writer.toString();
|
||||
assertThat(ddl).contains("alter table mytab drop constraint if exists ck_mytab_acol");
|
||||
assertThat(ddl).contains("alter table mytab add constraint ck_mytab_acol check (acol in ('A','B'))");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddColumn_withTypeConversion() throws IOException {
|
||||
public void testAddColumn_withTypeConversion() {
|
||||
|
||||
BaseTableDdl ddlGen = new BaseTableDdl(serverConfig, PlatformDdlBuilder.create(new OraclePlatform()));
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
|
||||
Column column = new Column();
|
||||
column.setName("col_name");
|
||||
column.setType("varchar(20)");
|
||||
|
||||
ddlGen.alterTableAddColumn(write.apply(), "mytable", column, false, false);
|
||||
ddlGen.alterTableAddColumn(writer, "mytable", column, false, false);
|
||||
|
||||
String ddl = write.apply().getBuffer();
|
||||
String ddl = writer.toString();
|
||||
assertThat(ddl).contains("alter table mytable add col_name varchar2(20)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddColumn_withTypeConversion_clickHouseVarchar() throws IOException {
|
||||
public void testAddColumn_withTypeConversion_clickHouseVarchar() {
|
||||
|
||||
ClickHouseTableDdl ddlGen = new ClickHouseTableDdl(serverConfig, PlatformDdlBuilder.create(new ClickHousePlatform()));
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
|
||||
Column column = new Column();
|
||||
column.setName("col_name");
|
||||
column.setType("varchar(20)");
|
||||
|
||||
ddlGen.alterTableAddColumn(write.apply(), "mytable", column, false, false);
|
||||
ddlGen.alterTableAddColumn(writer, "mytable", column, false, false);
|
||||
|
||||
String ddl = write.apply().getBuffer();
|
||||
String ddl = writer.toString();
|
||||
assertThat(ddl).contains("alter table mytable add column col_name String");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlterColumnComment() throws IOException {
|
||||
public void testAlterColumnComment() {
|
||||
|
||||
BaseTableDdl ddlGen = new BaseTableDdl(serverConfig, h2ddl);
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
|
||||
AlterColumn alterColumn = new AlterColumn();
|
||||
alterColumn.setTableName("mytab");
|
||||
alterColumn.setColumnName("acol");
|
||||
alterColumn.setComment("my comment");
|
||||
|
||||
ddlGen.generate(write, alterColumn);
|
||||
ddlGen.generate(writer, alterColumn);
|
||||
|
||||
String ddl = write.apply().getBuffer();
|
||||
String ddl = writer.applyPostAlter().getBuffer();
|
||||
assertThat(ddl).contains("comment on column mytab.acol is 'my comment'");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void alterTableAddColumnWithComment() throws IOException {
|
||||
public void alterTableAddColumnWithComment() {
|
||||
BaseTableDdl ddl = new BaseTableDdl(serverConfig, h2ddl);
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
Column column = new Column();
|
||||
column.setName("my_column");
|
||||
column.setComment("some comment");
|
||||
column.setType("int");
|
||||
|
||||
ddl.alterTableAddColumn(write.apply(), "my_table", column, false, false);
|
||||
assertEquals(
|
||||
"alter table my_table add column my_column int;\n" +
|
||||
"comment on column my_table.my_column is 'some comment';\n", write.apply().getBuffer());
|
||||
ddl.alterTableAddColumn(writer, "my_table", column, false, false);
|
||||
assertEquals("-- apply alter tables\nalter table my_table add column my_column int;\n"
|
||||
+ "-- apply post alter\ncomment on column my_table.my_column is 'some comment';\n",
|
||||
writer.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddTableComment() throws IOException {
|
||||
public void testAddTableComment() {
|
||||
|
||||
BaseTableDdl ddlGen = new BaseTableDdl(serverConfig, h2ddl);
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
|
||||
AddTableComment addTableComment = new AddTableComment();
|
||||
addTableComment.setName("mytab");
|
||||
addTableComment.setComment("my comment");
|
||||
|
||||
ddlGen.generate(write, addTableComment);
|
||||
ddlGen.generate(writer, addTableComment);
|
||||
|
||||
String ddl = write.apply().getBuffer();
|
||||
String ddl = writer.applyPostAlter().getBuffer();
|
||||
assertThat(ddl).contains("comment on table mytab is 'my comment'");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddTableComment_mysql() throws IOException {
|
||||
public void testAddTableComment_mysql() {
|
||||
|
||||
BaseTableDdl ddlGen = new BaseTableDdl(serverConfig, PlatformDdlBuilder.create(new MySqlPlatform()));
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
|
||||
AddTableComment addTableComment = new AddTableComment();
|
||||
addTableComment.setName("mytab");
|
||||
addTableComment.setComment("my comment");
|
||||
|
||||
ddlGen.generate(write, addTableComment);
|
||||
ddlGen.generate(writer, addTableComment);
|
||||
|
||||
String ddl = write.apply().getBuffer();
|
||||
String ddl = writer.applyPostAlter().getBuffer();
|
||||
assertThat(ddl).contains("alter table mytab comment = 'my comment'");
|
||||
}
|
||||
|
||||
@@ -151,14 +150,14 @@ public class BaseTableDdlTest {
|
||||
|
||||
BaseTableDdl ddlGen = new BaseTableDdl(serverConfig, h2ddl);
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
|
||||
ddlGen.generate(write, createTable());
|
||||
String apply = write.apply().getBuffer();
|
||||
String applyLast = write.applyForeignKeys().getBuffer();
|
||||
ddlGen.generate(writer, createTable());
|
||||
String apply = writer.apply().getBuffer();
|
||||
String applyLast = writer.applyForeignKeys().getBuffer();
|
||||
|
||||
String rollbackFirst = write.dropAllForeignKeys().getBuffer();
|
||||
String rollbackLast = write.dropAll().getBuffer();
|
||||
String rollbackFirst = writer.dropAllForeignKeys().getBuffer();
|
||||
String rollbackLast = writer.dropAll().getBuffer();
|
||||
|
||||
assertThat(apply).isEqualTo(Helper.asText(this, "/assert/BaseTableDdlTest/createTable-apply.txt"));
|
||||
assertThat(applyLast).isEqualTo(Helper.asText(this, "/assert/BaseTableDdlTest/createTable-applyLast.txt"));
|
||||
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.DB;
|
||||
import io.ebean.config.dbplatform.h2.H2Platform;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.ddlgeneration.PlatformDdlBuilder;
|
||||
import io.ebeaninternal.dbmigration.model.CurrentModel;
|
||||
import io.ebeaninternal.dbmigration.model.MConfiguration;
|
||||
import io.ebeaninternal.dbmigration.model.ModelContainer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
public class H2HistoryDdlTest {
|
||||
|
||||
@Test
|
||||
public void testRegenerateHistoryTriggers() throws Exception {
|
||||
|
||||
SpiEbeanServer ebeanServer = (SpiEbeanServer) DB.getDefault();
|
||||
|
||||
HistoryTableUpdate update = new HistoryTableUpdate("c_user");
|
||||
update.add(HistoryTableUpdate.Change.ADD, "one");
|
||||
update.add(HistoryTableUpdate.Change.DROP, "two");
|
||||
|
||||
|
||||
CurrentModel currentModel = new CurrentModel(ebeanServer);
|
||||
ModelContainer modelContainer = currentModel.read();
|
||||
DdlWrite write = new DdlWrite(new MConfiguration(), modelContainer, new DdlOptions());
|
||||
|
||||
H2Platform h2Platform = new H2Platform();
|
||||
PlatformDdl h2Ddl = PlatformDdlBuilder.create(h2Platform);
|
||||
h2Ddl.configure(ebeanServer.config());
|
||||
h2Ddl.regenerateHistoryTriggers(write, update);
|
||||
|
||||
assertThat(write.applyHistoryView().isEmpty()).isFalse();
|
||||
assertThat(write.applyHistoryTrigger().isEmpty()).isFalse();
|
||||
assertThat(write.applyHistoryView().getBuffer())
|
||||
.contains("create view")
|
||||
.doesNotContain("create trigger");
|
||||
assertThat(write.applyHistoryTrigger().getBuffer())
|
||||
.contains("add one")
|
||||
.contains("create trigger")
|
||||
.doesNotContain("create view");
|
||||
assertThat(write.dropAll().isEmpty()).isTrue();
|
||||
|
||||
}
|
||||
}
|
||||
+10
-10
@@ -5,24 +5,22 @@ import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebeaninternal.dbmigration.migration.Column;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class HanaDdlTest {
|
||||
|
||||
@Test
|
||||
public void alterTableDropColumn() throws IOException {
|
||||
public void alterTableDropColumn() {
|
||||
HanaColumnStoreDdl ddl = new HanaColumnStoreDdl(new HanaPlatform());
|
||||
DdlWrite write = new DdlWrite();
|
||||
ddl.alterTableDropColumn(write.apply(), "my_table", "my_column");
|
||||
assertEquals("CALL usp_ebean_drop_column('my_table', 'my_column');\n", write.apply().getBuffer());
|
||||
DdlWrite writer = new DdlWrite();
|
||||
ddl.alterTableDropColumn(writer, "my_table", "my_column");
|
||||
assertEquals("-- apply alter tables\nCALL usp_ebean_drop_column('my_table', 'my_column');\n", writer.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void alterTableAddColumn() throws IOException {
|
||||
public void alterTableAddColumn() {
|
||||
HanaColumnStoreDdl ddl = new HanaColumnStoreDdl(new HanaPlatform());
|
||||
DdlWrite write = new DdlWrite();
|
||||
DdlWrite writer = new DdlWrite();
|
||||
Column column = new Column();
|
||||
column.setName("my_column");
|
||||
column.setComment("comment");
|
||||
@@ -35,7 +33,9 @@ public class HanaDdlTest {
|
||||
column.setCheckConstraintName("check_constraint");
|
||||
column.setHistoryExclude(Boolean.TRUE);
|
||||
column.setIdentity(Boolean.TRUE);
|
||||
ddl.alterTableAddColumn(write.apply(), "my_table", column, false, "1");
|
||||
assertEquals("alter table my_table add ( my_column int default 1 not null);\nalter table my_table add constraint check_constraint CHECK(my_column > 0);\n", write.apply().getBuffer());
|
||||
ddl.alterTableAddColumn(writer, "my_table", column, false, "1");
|
||||
assertEquals(
|
||||
"-- apply alter tables\nalter table my_table add (my_column int default 1 not null);\n-- apply post alter\nalter table my_table add constraint check_constraint CHECK(my_column > 0);\n",
|
||||
writer.toString());
|
||||
}
|
||||
}
|
||||
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
public class HistoryTableUpdateTest {
|
||||
|
||||
@Test
|
||||
public void testDescription() throws Exception {
|
||||
|
||||
HistoryTableUpdate upd = new HistoryTableUpdate("mytab");
|
||||
upd.add(HistoryTableUpdate.Change.ADD, "two");
|
||||
upd.add(HistoryTableUpdate.Change.DROP, "four");
|
||||
|
||||
assertThat(upd.description()).isEqualTo("[add two, drop four]");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescription_withIncludeExclude() throws Exception {
|
||||
|
||||
HistoryTableUpdate upd = new HistoryTableUpdate("mytab");
|
||||
upd.add(HistoryTableUpdate.Change.ADD, "two");
|
||||
upd.add(HistoryTableUpdate.Change.INCLUDE, "five");
|
||||
upd.add(HistoryTableUpdate.Change.EXCLUDE, "six");
|
||||
upd.add(HistoryTableUpdate.Change.DROP, "four");
|
||||
|
||||
assertThat(upd.description()).isEqualTo("[add two, include five, exclude six, drop four]");
|
||||
}
|
||||
|
||||
}
|
||||
+430
-168
@@ -3,6 +3,7 @@ package io.ebeaninternal.dbmigration.ddlgeneration.platform;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.dbplatform.IdType;
|
||||
import io.ebean.config.dbplatform.db2.DB2LuwPlatform;
|
||||
import io.ebean.config.dbplatform.h2.H2Platform;
|
||||
import io.ebean.config.dbplatform.hana.HanaPlatform;
|
||||
import io.ebean.config.dbplatform.mysql.MySqlPlatform;
|
||||
@@ -14,14 +15,11 @@ import io.ebeaninternal.dbmigration.ddlgeneration.PlatformDdlBuilder;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterColumn;
|
||||
import io.ebeaninternal.dbmigration.migration.AlterForeignKey;
|
||||
import io.ebeaninternal.dbmigration.migration.Column;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.assertj.core.api.SoftAssertions;
|
||||
|
||||
public class PlatformDdl_AlterColumnTest {
|
||||
|
||||
@@ -33,229 +31,424 @@ public class PlatformDdl_AlterColumnTest {
|
||||
private final PlatformDdl oraDdl = PlatformDdlBuilder.create(new OraclePlatform());
|
||||
private final PlatformDdl sqlServerDdl = PlatformDdlBuilder.create(new SqlServer17Platform());
|
||||
private final PlatformDdl hanaDdl = PlatformDdlBuilder.create(new HanaPlatform());
|
||||
private final PlatformDdl db2Ddl = PlatformDdlBuilder.create(new DB2LuwPlatform());
|
||||
|
||||
private final SoftAssertions softly = new SoftAssertions();
|
||||
|
||||
{
|
||||
DatabaseConfig serverConfig = DB.getDefault().pluginApi().config();
|
||||
sqlServerDdl.configure(serverConfig);
|
||||
}
|
||||
|
||||
AlterColumn alterNotNull() {
|
||||
AlterColumn alterColumn = new AlterColumn();
|
||||
alterColumn.setTableName("mytab");
|
||||
alterColumn.setColumnName("acol");
|
||||
alterColumn.setCurrentType("varchar(5)");
|
||||
alterColumn.setNotnull(Boolean.TRUE);
|
||||
|
||||
return alterColumn;
|
||||
@AfterEach
|
||||
void assertAll() {
|
||||
softly.assertAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertArrayType_default() {
|
||||
assertThat(mysqlDdl.convertArrayType("varchar[](90)")).isEqualTo("varchar(90)");
|
||||
assertThat(mysqlDdl.convertArrayType("integer[](60)")).isEqualTo("varchar(60)");
|
||||
assertThat(mysqlDdl.convertArrayType("varchar[]")).isEqualTo("varchar(1000)");
|
||||
assertThat(mysqlDdl.convertArrayType("integer[]")).isEqualTo("varchar(1000)");
|
||||
softly.assertThat(mysqlDdl.convertArrayType("varchar[](90)")).isEqualTo("varchar(90)");
|
||||
softly.assertThat(mysqlDdl.convertArrayType("integer[](60)")).isEqualTo("varchar(60)");
|
||||
softly.assertThat(mysqlDdl.convertArrayType("varchar[]")).isEqualTo("varchar(1000)");
|
||||
softly.assertThat(mysqlDdl.convertArrayType("integer[]")).isEqualTo("varchar(1000)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertArrayType_h2() {
|
||||
if (useV1Syntax) {
|
||||
assertThat(h2Ddl.convertArrayType("varchar[](90)")).isEqualTo("array");
|
||||
assertThat(h2Ddl.convertArrayType("integer[](60)")).isEqualTo("array");
|
||||
assertThat(h2Ddl.convertArrayType("varchar[]")).isEqualTo("array");
|
||||
assertThat(h2Ddl.convertArrayType("integer[]")).isEqualTo("array");
|
||||
softly.assertThat(h2Ddl.convertArrayType("varchar[](90)")).isEqualTo("array");
|
||||
softly.assertThat(h2Ddl.convertArrayType("integer[](60)")).isEqualTo("array");
|
||||
softly.assertThat(h2Ddl.convertArrayType("varchar[]")).isEqualTo("array");
|
||||
softly.assertThat(h2Ddl.convertArrayType("integer[]")).isEqualTo("array");
|
||||
} else {
|
||||
assertThat(h2Ddl.convertArrayType("varchar[](90)")).isEqualTo("varchar array");
|
||||
assertThat(h2Ddl.convertArrayType("integer[](60)")).isEqualTo("integer array");
|
||||
assertThat(h2Ddl.convertArrayType("varchar[]")).isEqualTo("varchar array");
|
||||
assertThat(h2Ddl.convertArrayType("integer[]")).isEqualTo("integer array");
|
||||
softly.assertThat(h2Ddl.convertArrayType("varchar[](90)")).isEqualTo("varchar array");
|
||||
softly.assertThat(h2Ddl.convertArrayType("integer[](60)")).isEqualTo("integer array");
|
||||
softly.assertThat(h2Ddl.convertArrayType("varchar[]")).isEqualTo("varchar array");
|
||||
softly.assertThat(h2Ddl.convertArrayType("integer[]")).isEqualTo("integer array");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertArrayType_postgres() {
|
||||
assertThat(pgDdl.convertArrayType("varchar[](90)")).isEqualTo("varchar[]");
|
||||
assertThat(pgDdl.convertArrayType("integer[](60)")).isEqualTo("integer[]");
|
||||
assertThat(pgDdl.convertArrayType("varchar[]")).isEqualTo("varchar[]");
|
||||
assertThat(pgDdl.convertArrayType("integer[]")).isEqualTo("integer[]");
|
||||
softly.assertThat(pgDdl.convertArrayType("varchar[](90)")).isEqualTo("varchar[]");
|
||||
softly.assertThat(pgDdl.convertArrayType("integer[](60)")).isEqualTo("integer[]");
|
||||
softly.assertThat(pgDdl.convertArrayType("varchar[]")).isEqualTo("varchar[]");
|
||||
softly.assertThat(pgDdl.convertArrayType("integer[]")).isEqualTo("integer[]");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertArrayType_hana() {
|
||||
assertThat(hanaDdl.convertArrayType("varchar[](90)")).isEqualTo("nvarchar(255) array(90)");
|
||||
assertThat(hanaDdl.convertArrayType("integer[](60)")).isEqualTo("integer array(60)");
|
||||
assertThat(hanaDdl.convertArrayType("varchar[]")).isEqualTo("nvarchar(255) array");
|
||||
assertThat(hanaDdl.convertArrayType("integer[]")).isEqualTo("integer array");
|
||||
softly.assertThat(hanaDdl.convertArrayType("varchar[](90)")).isEqualTo("nvarchar(255) array(90)");
|
||||
softly.assertThat(hanaDdl.convertArrayType("integer[](60)")).isEqualTo("integer array(60)");
|
||||
softly.assertThat(hanaDdl.convertArrayType("varchar[]")).isEqualTo("nvarchar(255) array");
|
||||
softly.assertThat(hanaDdl.convertArrayType("integer[]")).isEqualTo("integer array");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlterColumnBaseAttributes() {
|
||||
|
||||
AlterColumn alterColumn = alterNotNull();
|
||||
assertNull(h2Ddl.alterColumnBaseAttributes(alterColumn));
|
||||
assertNull(pgDdl.alterColumnBaseAttributes(alterColumn));
|
||||
assertNull(oraDdl.alterColumnBaseAttributes(alterColumn));
|
||||
AlterColumn alter = new AlterColumn();
|
||||
alter.setTableName("mytab");
|
||||
alter.setColumnName("acol");
|
||||
alter.setCurrentType("varchar(5)");
|
||||
alter.setCurrentDefaultValue("'ho'");
|
||||
alter.setCurrentNotnull(Boolean.FALSE);
|
||||
|
||||
String sql = mysqlDdl.alterColumnBaseAttributes(alterColumn);
|
||||
assertEquals("alter table mytab modify acol varchar(5) not null", sql);
|
||||
// alter all attributes
|
||||
alter.setNotnull(Boolean.TRUE); // -> alter to not null
|
||||
alter.setDefaultValue("'hi'"); // and set default
|
||||
alter.setType("varchar(50)"); // and alter type
|
||||
|
||||
sql = sqlServerDdl.alterColumnBaseAttributes(alterColumn);
|
||||
assertEquals("alter table mytab alter column acol nvarchar(5) not null", sql);
|
||||
String sql = alterColumn(h2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol varchar(50);\n"
|
||||
+ "alter table mytab alter column acol set default 'hi';\n"
|
||||
+ "alter table mytab alter column acol set not null;\n");
|
||||
|
||||
sql = hanaDdl.alterColumnBaseAttributes(alterColumn);
|
||||
assertEquals("alter table mytab alter ( acol nvarchar(5) not null)", sql);
|
||||
sql = alterColumn(pgDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol type varchar(50) using acol::varchar(50);\n"
|
||||
+ "alter table mytab alter column acol set default 'hi';\n"
|
||||
+ "alter table mytab alter column acol set not null;\n");
|
||||
|
||||
alterColumn.setNotnull(Boolean.FALSE);
|
||||
sql = mysqlDdl.alterColumnBaseAttributes(alterColumn);
|
||||
assertEquals("alter table mytab modify acol varchar(5)", sql);
|
||||
sql = alterColumn(oraDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab modify acol varchar2(50);\n"
|
||||
+ "alter table mytab modify acol default 'hi';\n"
|
||||
+ "alter table mytab modify acol not null;\n");
|
||||
|
||||
sql = hanaDdl.alterColumnBaseAttributes(alterColumn);
|
||||
assertEquals("alter table mytab alter ( acol nvarchar(5))", sql);
|
||||
sql = alterColumn(mysqlDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab modify acol varchar(50) not null default 'hi';\n");
|
||||
|
||||
alterColumn.setNotnull(null);
|
||||
alterColumn.setType("varchar(100)");
|
||||
sql = alterColumn(sqlServerDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "EXEC usp_ebean_drop_default_constraint mytab, acol;\n"
|
||||
+ "alter table mytab alter column acol nvarchar(50) not null;\n"
|
||||
+ "alter table mytab add default 'hi' for acol;\n");
|
||||
|
||||
sql = mysqlDdl.alterColumnBaseAttributes(alterColumn);
|
||||
assertEquals("alter table mytab modify acol varchar(100)", sql);
|
||||
sql = alterColumn(hanaDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter (acol nvarchar(50) default 'hi' not null);\n");
|
||||
|
||||
sql = hanaDdl.alterColumnBaseAttributes(alterColumn);
|
||||
assertEquals("alter table mytab alter ( acol nvarchar(100))", sql);
|
||||
sql = alterColumn(db2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol set data type varchar(50);\n"
|
||||
+ "alter table mytab alter column acol set default 'hi';\n"
|
||||
+ "alter table mytab alter column acol set not null;\n"
|
||||
+ "call sysproc.admin_cmd('reorg table mytab');\n");
|
||||
|
||||
alterColumn.setCurrentNotnull(Boolean.TRUE);
|
||||
sql = mysqlDdl.alterColumnBaseAttributes(alterColumn);
|
||||
assertEquals("alter table mytab modify acol varchar(100) not null", sql);
|
||||
//
|
||||
alter.setCurrentNotnull(Boolean.TRUE);
|
||||
alter.setNotnull(Boolean.FALSE);
|
||||
alter.setDefaultValue("DROP DEFAULT");
|
||||
alter.setType(null); // do not alter type
|
||||
|
||||
sql = alterColumn(h2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol drop default;\n"
|
||||
+ "alter table mytab alter column acol set null;\n");
|
||||
|
||||
sql = alterColumn(pgDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol drop default;\n"
|
||||
+ "alter table mytab alter column acol drop not null;\n");
|
||||
|
||||
sql = alterColumn(oraDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab modify acol default null;\n"
|
||||
+ "alter table mytab modify acol null;\n");
|
||||
|
||||
sql = alterColumn(mysqlDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab modify acol varchar(5);\n");
|
||||
|
||||
sql = alterColumn(sqlServerDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "EXEC usp_ebean_drop_default_constraint mytab, acol;\n"
|
||||
+ "alter table mytab alter column acol nvarchar(5);\n");
|
||||
|
||||
sql = alterColumn(hanaDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter (acol nvarchar(5) default null);\n");
|
||||
|
||||
sql = alterColumn(db2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol drop default;\n"
|
||||
+ "alter table mytab alter column acol drop not null;\n");
|
||||
|
||||
sql = hanaDdl.alterColumnBaseAttributes(alterColumn);
|
||||
assertEquals("alter table mytab alter ( acol nvarchar(100) not null)", sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlterColumnType() {
|
||||
|
||||
String sql = h2Ddl.alterColumnType("mytab", "acol", "varchar(20)");
|
||||
assertEquals("alter table mytab alter column acol varchar(20)", sql);
|
||||
AlterColumn alter = new AlterColumn();
|
||||
alter.setTableName("mytab");
|
||||
alter.setColumnName("acol");
|
||||
alter.setCurrentType("integer");
|
||||
alter.setType("varchar(20)");
|
||||
|
||||
sql = pgDdl.alterColumnType("mytab", "acol", "varchar(20)");
|
||||
assertEquals("alter table mytab alter column acol type varchar(20) using acol::varchar(20)", sql);
|
||||
sql = pgDdl.alterColumnType("mytab", "acol", "bigint");
|
||||
assertEquals("alter table mytab alter column acol type bigint using acol::bigint", sql);
|
||||
String sql = alterColumn(h2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol varchar(20);\n");
|
||||
|
||||
sql = oraDdl.alterColumnType("mytab", "acol", "varchar(20)");
|
||||
assertEquals("alter table mytab modify acol varchar2(20)", sql);
|
||||
sql = alterColumn(pgDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol type varchar(20) using acol::varchar(20);\n");
|
||||
|
||||
sql = mysqlDdl.alterColumnType("mytab", "acol", "varchar(20)");
|
||||
assertNull(sql);
|
||||
sql = alterColumn(oraDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab modify acol varchar2(20);\n");
|
||||
|
||||
sql = sqlServerDdl.alterColumnType("mytab", "acol", "varchar(20)");
|
||||
assertNull(sql);
|
||||
sql = alterColumn(mysqlDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab modify acol varchar(20);\n");
|
||||
|
||||
sql = alterColumn(sqlServerDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol nvarchar(20);\n");
|
||||
|
||||
sql = alterColumn(hanaDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter (acol nvarchar(20));\n");
|
||||
|
||||
sql = alterColumn(db2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol set data type varchar(20);\n"
|
||||
// Note, this reorg may be not necessary when only length attribute is alterd
|
||||
// but this is currently not implemented.
|
||||
+ "call sysproc.admin_cmd('reorg table mytab');\n");
|
||||
|
||||
alter.setType("bigint");
|
||||
sql = alterColumn(pgDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol type bigint using acol::bigint;\n");
|
||||
|
||||
alter.setCurrentType("bigint");
|
||||
alter.setType("integer");
|
||||
sql = alterColumn(hanaDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter (acol decimal);\n"
|
||||
+ "alter table mytab alter (acol integer);\n");
|
||||
|
||||
alter.setCurrentType("varchar(20)");
|
||||
alter.setType("varchar(10)");
|
||||
sql = alterColumn(hanaDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter (acol nclob);\n"
|
||||
+ "alter table mytab alter (acol nvarchar(10));\n");
|
||||
|
||||
sql = hanaDdl.alterColumnType("mytab", "acol", "varchar(20)");
|
||||
assertNull(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlterColumnNotnull() {
|
||||
AlterColumn alter = new AlterColumn();
|
||||
alter.setTableName("mytab");
|
||||
alter.setColumnName("acol");
|
||||
alter.setCurrentType("varchar(20)");
|
||||
alter.setCurrentNotnull(Boolean.FALSE);
|
||||
alter.setNotnull(Boolean.TRUE);
|
||||
|
||||
String sql = h2Ddl.alterColumnNotnull("mytab", "acol", true);
|
||||
assertEquals("alter table mytab alter column acol set not null", sql);
|
||||
String sql = alterColumn(h2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol set not null;\n");
|
||||
|
||||
sql = pgDdl.alterColumnNotnull("mytab", "acol", true);
|
||||
assertEquals("alter table mytab alter column acol set not null", sql);
|
||||
sql = alterColumn(pgDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol set not null;\n");
|
||||
|
||||
sql = oraDdl.alterColumnNotnull("mytab", "acol", true);
|
||||
assertEquals("alter table mytab modify acol not null", sql);
|
||||
sql = alterColumn(oraDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab modify acol not null;\n");
|
||||
|
||||
sql = mysqlDdl.alterColumnNotnull("mytab", "acol", true);
|
||||
assertNull(sql);
|
||||
sql = alterColumn(mysqlDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab modify acol varchar(20) not null;\n");
|
||||
|
||||
sql = sqlServerDdl.alterColumnNotnull("mytab", "acol", true);
|
||||
assertNull(sql);
|
||||
sql = alterColumn(sqlServerDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol nvarchar(20) not null;\n");
|
||||
|
||||
sql = alterColumn(hanaDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter (acol nvarchar(20) not null);\n");
|
||||
|
||||
sql = alterColumn(db2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol set not null;\n"
|
||||
+ "call sysproc.admin_cmd('reorg table mytab');\n");
|
||||
|
||||
sql = hanaDdl.alterColumnNotnull("mytab", "acol", true);
|
||||
assertNull(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlterColumnNull() {
|
||||
|
||||
String sql = h2Ddl.alterColumnNotnull("mytab", "acol", false);
|
||||
assertEquals("alter table mytab alter column acol set null", sql);
|
||||
AlterColumn alter = new AlterColumn();
|
||||
alter.setTableName("mytab");
|
||||
alter.setColumnName("acol");
|
||||
alter.setCurrentType("varchar(20)");
|
||||
alter.setCurrentDefaultValue("'hi'");
|
||||
alter.setCurrentNotnull(Boolean.TRUE);
|
||||
|
||||
sql = pgDdl.alterColumnNotnull("mytab", "acol", false);
|
||||
assertEquals("alter table mytab alter column acol drop not null", sql);
|
||||
alter.setNotnull(Boolean.FALSE);
|
||||
String sql = alterColumn(h2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol set null;\n");
|
||||
|
||||
sql = oraDdl.alterColumnNotnull("mytab", "acol", false);
|
||||
assertEquals("alter table mytab modify acol null", sql);
|
||||
sql = alterColumn(pgDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol drop not null;\n");
|
||||
|
||||
sql = mysqlDdl.alterColumnNotnull("mytab", "acol", false);
|
||||
assertNull(sql);
|
||||
sql = alterColumn(oraDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab modify acol null;\n");
|
||||
|
||||
sql = sqlServerDdl.alterColumnNotnull("mytab", "acol", false);
|
||||
assertNull(sql);
|
||||
sql = alterColumn(mysqlDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab modify acol varchar(20) default 'hi';\n");
|
||||
|
||||
sql = hanaDdl.alterColumnNotnull("mytab", "acol", false);
|
||||
assertNull(sql);
|
||||
sql = alterColumn(sqlServerDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "EXEC usp_ebean_drop_default_constraint mytab, acol;\n"
|
||||
+ "alter table mytab alter column acol nvarchar(20);\n"
|
||||
+ "alter table mytab add default 'hi' for acol;\n");
|
||||
|
||||
sql = alterColumn(hanaDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter (acol nvarchar(20) default 'hi');\n");
|
||||
|
||||
sql = alterColumn(db2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol drop not null;\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlterColumnDefaultValue() {
|
||||
public void testAlterColumnAddDefaultValue() {
|
||||
AlterColumn alter = new AlterColumn();
|
||||
alter.setTableName("mytab");
|
||||
alter.setColumnName("acol");
|
||||
alter.setCurrentType("varchar(20)");
|
||||
alter.setCurrentNotnull(Boolean.TRUE);
|
||||
alter.setDefaultValue("'hi'");
|
||||
|
||||
String sql = h2Ddl.alterColumnDefaultValue("mytab", "acol", "'hi'");
|
||||
assertEquals("alter table mytab alter column acol set default 'hi'", sql);
|
||||
String sql = alterColumn(h2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol set default 'hi';\n");
|
||||
|
||||
sql = pgDdl.alterColumnDefaultValue("mytab", "acol", "'hi'");
|
||||
assertEquals("alter table mytab alter column acol set default 'hi'", sql);
|
||||
sql = alterColumn(pgDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol set default 'hi';\n");
|
||||
|
||||
sql = oraDdl.alterColumnDefaultValue("mytab", "acol", "'hi'");
|
||||
assertEquals("alter table mytab modify acol default 'hi'", sql);
|
||||
sql = alterColumn(oraDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab modify acol default 'hi';\n");
|
||||
|
||||
sql = mysqlDdl.alterColumnDefaultValue("mytab", "acol", "'hi'");
|
||||
assertEquals("alter table mytab alter acol set default 'hi'", sql);
|
||||
sql = alterColumn(mysqlDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter acol set default 'hi';\n");
|
||||
|
||||
sql = sqlServerDdl.alterColumnDefaultValue("mytab", "acol", "'hi'");
|
||||
assertEquals("alter table mytab add default 'hi' for acol", sql);
|
||||
sql = alterColumn(sqlServerDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "EXEC usp_ebean_drop_default_constraint mytab, acol;\n"
|
||||
+ "alter table mytab add default 'hi' for acol;\n");
|
||||
|
||||
boolean exceptionCaught = false;
|
||||
try {
|
||||
hanaDdl.alterColumnDefaultValue("mytab", "acol", "'hi'");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
exceptionCaught = true;
|
||||
}
|
||||
assertTrue(exceptionCaught);
|
||||
sql = alterColumn(hanaDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter (acol nvarchar(20) default 'hi' not null);\n");
|
||||
|
||||
sql = alterColumn(db2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol set default 'hi';\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlterColumnChangeDefaultValue() {
|
||||
AlterColumn alter = new AlterColumn();
|
||||
alter.setTableName("mytab");
|
||||
alter.setColumnName("acol");
|
||||
alter.setCurrentType("varchar(20)");
|
||||
alter.setCurrentNotnull(Boolean.TRUE);
|
||||
alter.setDefaultValue("'ho'");
|
||||
alter.setDefaultValue("'hi'");
|
||||
|
||||
String sql = alterColumn(h2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol set default 'hi';\n");
|
||||
|
||||
sql = alterColumn(pgDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol set default 'hi';\n");
|
||||
|
||||
sql = alterColumn(oraDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab modify acol default 'hi';\n");
|
||||
|
||||
sql = alterColumn(mysqlDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter acol set default 'hi';\n");
|
||||
|
||||
sql = alterColumn(sqlServerDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "EXEC usp_ebean_drop_default_constraint mytab, acol;\n"
|
||||
+ "alter table mytab add default 'hi' for acol;\n");
|
||||
|
||||
sql = alterColumn(hanaDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter (acol nvarchar(20) default 'hi' not null);\n");
|
||||
|
||||
sql = alterColumn(db2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol set default 'hi';\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlterColumnDropDefault() {
|
||||
|
||||
String sql = h2Ddl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
|
||||
assertEquals("alter table mytab alter column acol drop default", sql);
|
||||
AlterColumn alter = new AlterColumn();
|
||||
alter.setTableName("mytab");
|
||||
alter.setColumnName("acol");
|
||||
alter.setCurrentType("varchar(20)");
|
||||
alter.setCurrentNotnull(Boolean.TRUE);
|
||||
alter.setCurrentDefaultValue("'hi'");
|
||||
alter.setDefaultValue("DROP DEFAULT");
|
||||
|
||||
sql = pgDdl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
|
||||
assertEquals("alter table mytab alter column acol drop default", sql);
|
||||
String sql = alterColumn(h2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol drop default;\n");
|
||||
|
||||
sql = oraDdl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
|
||||
assertEquals("alter table mytab modify acol drop default", sql);
|
||||
sql = alterColumn(pgDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol drop default;\n");
|
||||
|
||||
sql = mysqlDdl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
|
||||
assertEquals("alter table mytab alter acol drop default", sql);
|
||||
sql = alterColumn(oraDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab modify acol default null;\n");
|
||||
|
||||
sql = sqlServerDdl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
|
||||
assertEquals("EXEC usp_ebean_drop_default_constraint mytab, acol", sql);
|
||||
sql = alterColumn(mysqlDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter acol drop default;\n");
|
||||
|
||||
sql = alterColumn(sqlServerDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "EXEC usp_ebean_drop_default_constraint mytab, acol;\n");
|
||||
|
||||
sql = alterColumn(hanaDdl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter (acol nvarchar(20) default null not null);\n");
|
||||
|
||||
sql = alterColumn(db2Ddl, alter);
|
||||
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table mytab alter column acol drop default;\n");
|
||||
|
||||
boolean exceptionCaught = false;
|
||||
try {
|
||||
hanaDdl.alterColumnDefaultValue("mytab", "acol", "DROP DEFAULT");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
exceptionCaught = true;
|
||||
}
|
||||
assertTrue(exceptionCaught);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oracle_alterTableAddColumn() throws IOException {
|
||||
DdlWrite write = new DdlWrite();
|
||||
oraDdl.alterTableAddColumn(write.apply(), "my_table", simpleColumn(), false, "1");
|
||||
assertThat(write.apply().getBuffer()).isEqualTo("alter table my_table add my_column int default 1 not null;\n");
|
||||
public void oracle_alterTableAddColumn() {
|
||||
DdlWrite writer = new DdlWrite();
|
||||
oraDdl.alterTableAddColumn(writer, "my_table", simpleColumn(), false, "1");
|
||||
softly.assertThat(writer.toString())
|
||||
.isEqualTo("-- apply alter tables\n"
|
||||
+ "alter table my_table add my_column int default 1 not null;\n");
|
||||
}
|
||||
|
||||
private Column simpleColumn() {
|
||||
@@ -269,79 +462,148 @@ public class PlatformDdl_AlterColumnTest {
|
||||
|
||||
@Test
|
||||
public void useIdentityType_h2() {
|
||||
assertEquals(h2Ddl.useIdentityType(null), IdType.IDENTITY);
|
||||
assertEquals(h2Ddl.useIdentityType(IdType.SEQUENCE), IdType.SEQUENCE);
|
||||
assertEquals(h2Ddl.useIdentityType(IdType.IDENTITY), IdType.IDENTITY);
|
||||
assertEquals(h2Ddl.useIdentityType(IdType.GENERATOR), IdType.GENERATOR);
|
||||
assertEquals(h2Ddl.useIdentityType(IdType.EXTERNAL), IdType.EXTERNAL);
|
||||
softly.assertThat(h2Ddl.useIdentityType(null)).isEqualTo(IdType.IDENTITY);
|
||||
softly.assertThat(h2Ddl.useIdentityType(IdType.SEQUENCE)).isEqualTo(IdType.SEQUENCE);
|
||||
softly.assertThat(h2Ddl.useIdentityType(IdType.IDENTITY)).isEqualTo(IdType.IDENTITY);
|
||||
softly.assertThat(h2Ddl.useIdentityType(IdType.GENERATOR)).isEqualTo(IdType.GENERATOR);
|
||||
softly.assertThat(h2Ddl.useIdentityType(IdType.EXTERNAL)).isEqualTo(IdType.EXTERNAL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useIdentityType_postgres() {
|
||||
assertEquals(pgDdl.useIdentityType(IdType.GENERATOR), IdType.GENERATOR);
|
||||
assertEquals(pgDdl.useIdentityType(IdType.EXTERNAL), IdType.EXTERNAL);
|
||||
softly.assertThat(pgDdl.useIdentityType(IdType.GENERATOR)).isEqualTo(IdType.GENERATOR);
|
||||
softly.assertThat(pgDdl.useIdentityType(IdType.EXTERNAL)).isEqualTo(IdType.EXTERNAL);
|
||||
|
||||
assertEquals(pgDdl.useIdentityType(null), IdType.IDENTITY);
|
||||
assertEquals(pgDdl.useIdentityType(IdType.SEQUENCE), IdType.SEQUENCE);
|
||||
assertEquals(pgDdl.useIdentityType(IdType.IDENTITY), IdType.IDENTITY);
|
||||
softly.assertThat(pgDdl.useIdentityType(null)).isEqualTo(IdType.IDENTITY);
|
||||
softly.assertThat(pgDdl.useIdentityType(IdType.SEQUENCE)).isEqualTo(IdType.SEQUENCE);
|
||||
softly.assertThat(pgDdl.useIdentityType(IdType.IDENTITY)).isEqualTo(IdType.IDENTITY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useIdentityType_mysql() {
|
||||
|
||||
assertEquals(mysqlDdl.useIdentityType(null), IdType.IDENTITY);
|
||||
assertEquals(mysqlDdl.useIdentityType(IdType.SEQUENCE), IdType.IDENTITY);
|
||||
assertEquals(mysqlDdl.useIdentityType(IdType.IDENTITY), IdType.IDENTITY);
|
||||
assertEquals(mysqlDdl.useIdentityType(IdType.GENERATOR), IdType.GENERATOR);
|
||||
assertEquals(mysqlDdl.useIdentityType(IdType.EXTERNAL), IdType.EXTERNAL);
|
||||
softly.assertThat(mysqlDdl.useIdentityType(null)).isEqualTo(IdType.IDENTITY);
|
||||
softly.assertThat(mysqlDdl.useIdentityType(IdType.SEQUENCE)).isEqualTo(IdType.IDENTITY);
|
||||
softly.assertThat(mysqlDdl.useIdentityType(IdType.IDENTITY)).isEqualTo(IdType.IDENTITY);
|
||||
softly.assertThat(mysqlDdl.useIdentityType(IdType.GENERATOR)).isEqualTo(IdType.GENERATOR);
|
||||
softly.assertThat(mysqlDdl.useIdentityType(IdType.EXTERNAL)).isEqualTo(IdType.EXTERNAL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useIdentityType_oracle() {
|
||||
|
||||
assertEquals(oraDdl.useIdentityType(null), IdType.IDENTITY);
|
||||
assertEquals(oraDdl.useIdentityType(IdType.SEQUENCE), IdType.SEQUENCE);
|
||||
assertEquals(oraDdl.useIdentityType(IdType.IDENTITY), IdType.IDENTITY);
|
||||
assertEquals(oraDdl.useIdentityType(IdType.GENERATOR), IdType.GENERATOR);
|
||||
assertEquals(oraDdl.useIdentityType(IdType.EXTERNAL), IdType.EXTERNAL);
|
||||
softly.assertThat(oraDdl.useIdentityType(null)).isEqualTo(IdType.IDENTITY);
|
||||
softly.assertThat(oraDdl.useIdentityType(IdType.SEQUENCE)).isEqualTo(IdType.SEQUENCE);
|
||||
softly.assertThat(oraDdl.useIdentityType(IdType.IDENTITY)).isEqualTo(IdType.IDENTITY);
|
||||
softly.assertThat(oraDdl.useIdentityType(IdType.GENERATOR)).isEqualTo(IdType.GENERATOR);
|
||||
softly.assertThat(oraDdl.useIdentityType(IdType.EXTERNAL)).isEqualTo(IdType.EXTERNAL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useIdentityType_hana() {
|
||||
|
||||
assertEquals(hanaDdl.useIdentityType(null), IdType.IDENTITY);
|
||||
assertEquals(hanaDdl.useIdentityType(IdType.SEQUENCE), IdType.IDENTITY);
|
||||
assertEquals(hanaDdl.useIdentityType(IdType.IDENTITY), IdType.IDENTITY);
|
||||
assertEquals(hanaDdl.useIdentityType(IdType.GENERATOR), IdType.GENERATOR);
|
||||
assertEquals(hanaDdl.useIdentityType(IdType.EXTERNAL), IdType.EXTERNAL);
|
||||
softly.assertThat(hanaDdl.useIdentityType(null)).isEqualTo(IdType.IDENTITY);
|
||||
softly.assertThat(hanaDdl.useIdentityType(IdType.SEQUENCE)).isEqualTo(IdType.IDENTITY);
|
||||
softly.assertThat(hanaDdl.useIdentityType(IdType.IDENTITY)).isEqualTo(IdType.IDENTITY);
|
||||
softly.assertThat(hanaDdl.useIdentityType(IdType.GENERATOR)).isEqualTo(IdType.GENERATOR);
|
||||
softly.assertThat(hanaDdl.useIdentityType(IdType.EXTERNAL)).isEqualTo(IdType.EXTERNAL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appendForeignKeySuffix_when_defaults() {
|
||||
assertThat(alterFkey(null, null)).isEqualTo(" on delete restrict on update restrict");
|
||||
softly.assertThat(alterFkey(h2Ddl, null, null)).isEqualTo(" on delete restrict on update restrict");
|
||||
softly.assertThat(alterFkey(pgDdl, null, null)).isEqualTo(" on delete restrict on update restrict");
|
||||
softly.assertThat(alterFkey(mysqlDdl, null, null)).isEqualTo(" on delete restrict on update restrict");
|
||||
softly.assertThat(alterFkey(oraDdl, null, null)).isEqualTo("");
|
||||
softly.assertThat(alterFkey(sqlServerDdl, null, null)).isEqualTo("");
|
||||
softly.assertThat(alterFkey(hanaDdl, null, null)).isEqualTo(" on delete restrict on update restrict");
|
||||
softly.assertThat(alterFkey(db2Ddl, null, null)).isEqualTo(" on delete restrict on update restrict");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appendForeignKeySuffix_when_RestrictSetNull() {
|
||||
assertThat(alterFkey("RESTRICT", "SET_NULL")).isEqualTo(" on delete restrict on update set null");
|
||||
softly.assertThat(alterFkey(h2Ddl, "RESTRICT", "SET_NULL"))
|
||||
.isEqualTo(" on delete restrict on update set null");
|
||||
|
||||
softly.assertThat(alterFkey(pgDdl, "RESTRICT", "SET_NULL"))
|
||||
.isEqualTo(" on delete restrict on update set null");
|
||||
|
||||
softly.assertThat(alterFkey(mysqlDdl, "RESTRICT", "SET_NULL"))
|
||||
.isEqualTo(" on delete restrict on update set null");
|
||||
|
||||
softly.assertThat(alterFkey(oraDdl, "RESTRICT", "SET_NULL"))
|
||||
.isEqualTo("");
|
||||
|
||||
softly.assertThat(alterFkey(sqlServerDdl, "RESTRICT", "SET_NULL"))
|
||||
.isEqualTo(" on update set null");
|
||||
|
||||
softly.assertThat(alterFkey(hanaDdl, "RESTRICT", "SET_NULL"))
|
||||
.isEqualTo(" on delete restrict on update set null");
|
||||
|
||||
softly.assertThat(alterFkey(db2Ddl, "RESTRICT", "SET_NULL"))
|
||||
.isEqualTo(" on delete restrict on update set null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appendForeignKeySuffix_when_SetNullRestrict() {
|
||||
assertThat(alterFkey("SET_NULL", "RESTRICT")).isEqualTo(" on delete set null on update restrict");
|
||||
softly.assertThat(alterFkey(h2Ddl, "SET_NULL", "RESTRICT"))
|
||||
.isEqualTo(" on delete set null on update restrict");
|
||||
|
||||
softly.assertThat(alterFkey(pgDdl, "SET_NULL", "RESTRICT"))
|
||||
.isEqualTo(" on delete set null on update restrict");
|
||||
|
||||
softly.assertThat(alterFkey(mysqlDdl, "SET_NULL", "RESTRICT"))
|
||||
.isEqualTo(" on delete set null on update restrict");
|
||||
|
||||
softly.assertThat(alterFkey(oraDdl, "SET_NULL", "RESTRICT"))
|
||||
.isEqualTo(" on delete set null");
|
||||
|
||||
softly.assertThat(alterFkey(sqlServerDdl, "SET_NULL", "RESTRICT"))
|
||||
.isEqualTo(" on delete set null");
|
||||
|
||||
softly.assertThat(alterFkey(hanaDdl, "SET_NULL", "RESTRICT"))
|
||||
.isEqualTo(" on delete set null on update restrict");
|
||||
|
||||
softly.assertThat(alterFkey(db2Ddl, "SET_NULL", "RESTRICT"))
|
||||
.isEqualTo(" on delete set null on update restrict");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appendForeignKeySuffix_when_SetDefaultCascade() {
|
||||
assertThat(alterFkey("SET_DEFAULT", "CASCADE")).isEqualTo(" on delete set default on update cascade");
|
||||
softly.assertThat(alterFkey(h2Ddl, "SET_DEFAULT", "CASCADE"))
|
||||
.isEqualTo(" on delete set default on update cascade");
|
||||
|
||||
softly.assertThat(alterFkey(pgDdl, "SET_DEFAULT", "CASCADE"))
|
||||
.isEqualTo(" on delete set default on update cascade");
|
||||
|
||||
softly.assertThat(alterFkey(mysqlDdl, "SET_DEFAULT", "CASCADE"))
|
||||
.isEqualTo(" on delete set default on update cascade");
|
||||
|
||||
softly.assertThat(alterFkey(oraDdl, "SET_DEFAULT", "CASCADE"))
|
||||
.isEqualTo("");
|
||||
|
||||
softly.assertThat(alterFkey(sqlServerDdl, "SET_DEFAULT", "CASCADE"))
|
||||
.isEqualTo(" on delete set default on update cascade");
|
||||
|
||||
softly.assertThat(alterFkey(hanaDdl, "SET_DEFAULT", "CASCADE"))
|
||||
.isEqualTo(" on delete set default on update cascade");
|
||||
|
||||
softly.assertThat(alterFkey(db2Ddl, "SET_DEFAULT", "CASCADE"))
|
||||
.isEqualTo(" on delete set default on update cascade");
|
||||
}
|
||||
|
||||
private String alterFkey(String onDelete, String onUpdate) {
|
||||
private String alterColumn(PlatformDdl ddl, AlterColumn alterColumn) {
|
||||
DdlWrite write = new DdlWrite();
|
||||
ddl.alterColumn(write, alterColumn);
|
||||
return write.toString();
|
||||
}
|
||||
|
||||
private String alterFkey(PlatformDdl ddl, String onDelete, String onUpdate) {
|
||||
AlterForeignKey afk = new AlterForeignKey();
|
||||
afk.setOnDelete(onDelete);
|
||||
afk.setOnUpdate(onUpdate);
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
h2Ddl.appendForeignKeySuffix(new WriteForeignKey(afk), buffer);
|
||||
ddl.appendForeignKeySuffix(new WriteForeignKey(afk), buffer);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
|
||||
+11
-2
@@ -29,11 +29,20 @@ public class PlatformDdl_dropUniqueConstraintTest {
|
||||
sql = pgDdl.alterTableDropUniqueConstraint("mytab", "uq_name");
|
||||
assertEquals("alter table mytab drop constraint uq_name", sql);
|
||||
sql = oraDdl.alterTableDropUniqueConstraint("mytab", "uq_name");
|
||||
assertEquals("alter table mytab drop constraint uq_name", sql);
|
||||
assertEquals("delimiter $$\n"
|
||||
+ "declare\n"
|
||||
+ " expected_error exception;\n"
|
||||
+ " pragma exception_init(expected_error, -2443);\n"
|
||||
+ "begin\n"
|
||||
+ " execute immediate 'alter table mytab drop constraint uq_name';\n"
|
||||
+ "exception\n"
|
||||
+ " when expected_error then null;\n"
|
||||
+ "end;\n"
|
||||
+ "$$", sql);
|
||||
sql = sqlServerDdl.alterTableDropUniqueConstraint("mytab", "uq_name");
|
||||
assertEquals(
|
||||
"IF EXISTS (SELECT name FROM sys.indexes WHERE object_id = OBJECT_ID('mytab','U') AND name = 'uq_name') drop index uq_name ON mytab;\n"
|
||||
+ "IF (OBJECT_ID('uq_name', 'UQ') IS NOT NULL) alter table mytab drop constraint uq_name",
|
||||
+ "IF OBJECT_ID('uq_name', 'UQ') IS NOT NULL alter table mytab drop constraint uq_name",
|
||||
sql);
|
||||
|
||||
sql = mysqlDdl.alterTableDropUniqueConstraint("mytab", "uq_name");
|
||||
|
||||
@@ -5,14 +5,11 @@ import io.ebean.Database;
|
||||
import io.ebean.annotation.PersistBatch;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public abstract class BaseTestCase {
|
||||
|
||||
protected static Logger logger = LoggerFactory.getLogger(BaseTestCase.class);
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.localtest;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.dbmigration.DbMigration;
|
||||
import io.ebeaninternal.api.DbOffline;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
-- apply changes
|
||||
create table foo (
|
||||
col1 varchar(4) generated by default as identity not null,
|
||||
col2 varchar(30) not null,
|
||||
@@ -6,7 +7,6 @@ create table foo (
|
||||
);
|
||||
comment on table foo is 'comment';
|
||||
|
||||
-- apply alter tables
|
||||
alter table foo add column added_to_foo varchar(20);
|
||||
|
||||
alter table foo drop column col2;
|
||||
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
-- drop all
|
||||
drop table if exists foo;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ create table ckey_parent (
|
||||
constraint pk_ckey_parent primary key (one_key,two_key)
|
||||
);
|
||||
|
||||
-- foreign keys and indices
|
||||
create index ix_ckey_detail_parent on ckey_detail (one_key,two_key);
|
||||
alter table ckey_detail add constraint fk_ckey_detail_parent foreign key (one_key,two_key) references ckey_parent (one_key,two_key) on delete restrict on update restrict;
|
||||
|
||||
|
||||
+1
@@ -13,6 +13,7 @@ create table phones (
|
||||
constraint pk_phones primary key (id)
|
||||
);
|
||||
|
||||
-- foreign keys and indices
|
||||
create index ix_phones_person_id on phones (person_id);
|
||||
alter table phones add constraint fk_phones_person_id foreign key (person_id) references persons (id) on delete restrict on update restrict;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user