
io.ebeaninternal.server.persist.dml.InsertMeta Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ebean Show documentation
Show all versions of ebean Show documentation
composite of common runtime dependencies for all platforms
package io.ebeaninternal.server.persist.dml;
import io.ebean.annotation.Platform;
import io.ebean.bean.EntityBean;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebeaninternal.server.core.PersistRequestBean;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.deploy.InheritInfo;
import io.ebeaninternal.server.persist.dmlbind.Bindable;
import io.ebeaninternal.server.persist.dmlbind.BindableDiscriminator;
import io.ebeaninternal.server.persist.dmlbind.BindableId;
import io.ebeaninternal.server.persist.dmlbind.BindableList;
import java.sql.SQLException;
import static io.ebean.annotation.Platform.MARIADB;
import static io.ebean.annotation.Platform.MYSQL;
/**
* Meta data for insert handler. The meta data is for a particular bean type. It
* is considered immutable and is thread safe.
*/
final class InsertMeta {
private final String sqlNullId;
private final String sqlWithId;
private final String sqlDraftNullId;
private final String sqlDraftWithId;
private final BindableId id;
private final Bindable discriminator;
private final BindableList all;
private final BindableList allExcludeDraftOnly;
private final boolean supportsGetGeneratedKeys;
private final boolean concatinatedKey;
/**
* Used for DB that do not support getGeneratedKeys.
*/
private final boolean supportsSelectLastInsertedId;
private final Bindable shadowFKey;
private final String[] identityDbColumns;
private final Platform platform;
InsertMeta(DatabasePlatform dbPlatform, BeanDescriptor> desc, Bindable shadowFKey, BindableId id, BindableList all) {
this.platform = dbPlatform.getPlatform();
this.discriminator = getDiscriminator(desc);
this.id = id;
this.all = all;
this.allExcludeDraftOnly = all.excludeDraftOnly();
this.shadowFKey = shadowFKey;
String tableName = desc.getBaseTable();
String draftTableName = desc.getDraftTable();
this.sqlWithId = genSql(false, tableName, false);
this.sqlDraftWithId = desc.isDraftable() ? genSql(false, draftTableName, true) : sqlWithId;
// only available for single Id property
if (id.isConcatenated()) {
// concatenated key
this.concatinatedKey = true;
this.identityDbColumns = null;
this.sqlNullId = null;
this.sqlDraftNullId = null;
this.supportsGetGeneratedKeys = false;
this.supportsSelectLastInsertedId = false;
} else {
// insert sql for db identity or sequence insert
this.concatinatedKey = false;
if (id.getIdentityColumn() == null) {
this.identityDbColumns = new String[]{};
this.supportsGetGeneratedKeys = false;
this.supportsSelectLastInsertedId = false;
} else {
this.identityDbColumns = new String[]{id.getIdentityColumn()};
this.supportsGetGeneratedKeys = dbPlatform.getDbIdentity().isSupportsGetGeneratedKeys();
this.supportsSelectLastInsertedId = desc.supportsSelectLastInsertedId();
}
this.sqlNullId = genSql(true, tableName, false);
this.sqlDraftNullId = desc.isDraftable() ? genSql(true, draftTableName, true) : sqlNullId;
}
}
private static Bindable getDiscriminator(BeanDescriptor> desc) {
InheritInfo inheritInfo = desc.getInheritInfo();
return inheritInfo != null ? new BindableDiscriminator(inheritInfo) : null;
}
/**
* Return true if this is a concatenated key.
*/
boolean isConcatenatedKey() {
return concatinatedKey;
}
String[] getIdentityDbColumns() {
return identityDbColumns;
}
/**
* Return true if we should use a SQL query to return the generated key.
* This can not be used with JDBC batch mode.
*/
boolean supportsSelectLastInsertedId() {
return supportsSelectLastInsertedId;
}
/**
* Return true if getGeneratedKeys is supported by the underlying jdbc
* driver and database.
*/
boolean supportsGetGeneratedKeys() {
return supportsGetGeneratedKeys;
}
/**
* Return true if the Id can be derived from other property values.
*/
boolean deriveConcatenatedId(PersistRequestBean> persist) {
return id.deriveConcatenatedId(persist);
}
/**
* Bind the request based on whether the id value(s) are null.
*/
public void bind(DmlHandler request, EntityBean bean, boolean withId, boolean publish) throws SQLException {
if (withId) {
id.dmlBind(request, bean);
}
if (shadowFKey != null) {
shadowFKey.dmlBind(request, bean);
}
if (discriminator != null) {
discriminator.dmlBind(request, bean);
}
if (publish) {
allExcludeDraftOnly.dmlBind(request, bean);
} else {
all.dmlBind(request, bean);
}
}
/**
* get the sql based whether the id value(s) are null.
*/
public String getSql(boolean withId, boolean publish) {
if (withId) {
return publish ? sqlWithId : sqlDraftWithId;
} else {
return publish ? sqlNullId : sqlDraftNullId;
}
}
private String genSql(boolean nullId, String table, boolean draftTable) {
GenerateDmlRequest request = new GenerateDmlRequest();
request.setInsertSetMode();
request.append("insert into ").append(table);
if (nullId && noColumnsForInsert(draftTable)) {
return request.append(defaultValues()).toString();
}
request.append(" (");
if (!nullId) {
id.dmlAppend(request);
}
if (shadowFKey != null) {
shadowFKey.dmlAppend(request);
}
if (discriminator != null) {
discriminator.dmlAppend(request);
}
if (draftTable) {
all.dmlAppend(request);
} else {
allExcludeDraftOnly.dmlAppend(request);
}
request.append(") values (");
request.append(request.getInsertBindBuffer());
request.append(")");
return request.toString();
}
private String defaultValues() {
return platform.base() == MYSQL || platform.base() == MARIADB ? " values (default)" : " default values";
}
/**
* Return true if the insert actually contains no columns.
*/
private boolean noColumnsForInsert(boolean draftTable) {
return shadowFKey == null
&& discriminator == null
&& (draftTable ? all.isEmpty() : allExcludeDraftOnly.isEmpty());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy