You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@empire-db.apache.org by do...@apache.org on 2025/09/26 21:16:19 UTC
(empire-db) branch master updated: EMPIREDB-477 DBGeneratedValue: byFunction or byTrigger
This is an automated email from the ASF dual-hosted git repository.
doebele pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/empire-db.git
The following commit(s) were added to refs/heads/master by this push:
new 097696cf EMPIREDB-477 DBGeneratedValue: byFunction or byTrigger
097696cf is described below
commit 097696cf2afea015c928ea40cfb77700616bda7e
Author: Rainer Döbele <rd...@users.noreply.github.com>
AuthorDate: Fri Sep 26 23:16:15 2025 +0200
EMPIREDB-477
DBGeneratedValue: byFunction or byTrigger
---
.../org/apache/empire/db/DBFuncGeneratedValue.java | 148 ---------------
.../org/apache/empire/db/DBGeneratedValue.java | 198 +++++++++++++++++++++
.../main/java/org/apache/empire/db/DBRowSet.java | 27 ++-
.../main/java/org/apache/empire/db/DBTable.java | 2 +-
.../org/apache/empire/dbms/DBMSHandlerBase.java | 2 +-
5 files changed, 218 insertions(+), 159 deletions(-)
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBFuncGeneratedValue.java b/empire-db/src/main/java/org/apache/empire/db/DBFuncGeneratedValue.java
deleted file mode 100644
index f8e8d971..00000000
--- a/empire-db/src/main/java/org/apache/empire/db/DBFuncGeneratedValue.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.empire.db;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.empire.data.Column;
-import org.apache.empire.data.DataType;
-import org.apache.empire.data.Record;
-import org.apache.empire.exceptions.InvalidArgumentException;
-import org.apache.empire.exceptions.ItemNotFoundException;
-
-/**
- * DBFuncGeneratedValue
- * Auto-generates a record value from other record fields
- * The template must contain the column names wrapped in square brackets
- * like e.g. "normalize([name])" or "[lastName], [firstName]"
- * @author doebele
- */
-public class DBFuncGeneratedValue extends DBGeneratedValue
-{
- private final List<Object> parts;
-
- public DBFuncGeneratedValue(DBRowSet table, String template)
- {
- super(table.getDatabase());
- this.parts = new ArrayList<Object>();
- int idx=0;
- while (idx<template.length())
- {
- int nxt=template.indexOf('[', idx);
- if (nxt<0)
- { // append rest
- parts.add(template.substring(idx));
- break;
- }
- // append
- parts.add(template.substring(idx, nxt++));
- // find end
- int end=template.indexOf(']', nxt);
- if (end<0)
- throw new InvalidArgumentException("template", template);
- // find column
- String name = template.substring(nxt, end);
- DBColumn column = table.getColumn(name);
- if (column==null)
- throw new ItemNotFoundException(name);
- // found
- parts.add(column);
- idx = end+1;
- }
- }
-
- /*
- * (non-Javadoc)
- * @see org.apache.empire.db.DBGeneratedValue#isModified(org.apache.empire.data.Record)
- */
- @Override
- public boolean isModified(Record record)
- {
- for (Object part : parts)
- { // check modified
- if ((part instanceof Column) && record.wasModified((Column)part))
- return true;
- }
- return false;
- }
-
- /*
- * (non-Javadoc)
- * @see org.apache.empire.db.DBGeneratedValue#eval(org.apache.empire.data.Record)
- */
- @Override
- public Object eval(Record record)
- {
- for (Object part : parts)
- { // check null
- if ((part instanceof Column) && record.isNull((Column)part))
- return null;
- }
- // build now
- DBSQLBuilder sql = db.getDbms().createSQLBuilder();
- for (Object part : parts)
- {
- if (part instanceof Column)
- { // append column value
- Column col = (Column)part;
- Object value = record.get(col);
- sql.appendValue(col.getDataType(), value);
- }
- else
- sql.append(part.toString());
- }
- // done
- return db.getValueExpr(sql.toString(), DataType.UNKNOWN);
- }
-
- /*
- * (non-Javadoc)
- * @see org.apache.empire.db.DBExpr#addReferencedColumns(java.util.Set)
- */
- @Override
- public void addReferencedColumns(Set<DBColumn> list)
- {
- for (Object part : parts)
- {
- if (part instanceof DBColumn)
- list.add((DBColumn)part);
- }
- }
-
- /*
- * (non-Javadoc)
- * @see org.apache.empire.db.DBExpr#addSQL(org.apache.empire.db.DBSQLBuilder, long)
- */
- @Override
- public void addSQL(DBSQLBuilder sql, long context)
- {
- for (Object part : parts)
- {
- if (part instanceof Column)
- { // append column value
- DBColumn col = (DBColumn)part;
- col.addSQL(sql, context);
- }
- else
- sql.append(part.toString());
- }
- }
-}
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBGeneratedValue.java b/empire-db/src/main/java/org/apache/empire/db/DBGeneratedValue.java
index 26fd8740..3bc7a21e 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBGeneratedValue.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBGeneratedValue.java
@@ -18,7 +18,19 @@
*/
package org.apache.empire.db;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.empire.commons.ObjectUtils;
+import org.apache.empire.data.Column;
+import org.apache.empire.data.DataType;
import org.apache.empire.data.Record;
+import org.apache.empire.exceptions.InvalidArgumentException;
+import org.apache.empire.exceptions.ItemNotFoundException;
+import org.apache.empire.exceptions.NotSupportedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* DBGeneratedValue
@@ -27,6 +39,192 @@ import org.apache.empire.data.Record;
*/
public abstract class DBGeneratedValue extends DBExpr
{
+ protected static final Logger log = LoggerFactory.getLogger(DBGeneratedValue.class);
+
+ /**
+ * Returns a generated value for a trigger
+ * @param table the table on which the trigger
+ * @param triggerName then name of the trigger
+ * @return the value generator
+ */
+ public static DBGeneratedValue byTrigger(DBTable table, String triggerName)
+ {
+ return new DBTriggerGeneratedValue(table, triggerName);
+ }
+
+ /**
+ * Returns generator for a record value created from other record fields
+ * The function template must contain the column names wrapped in square brackets
+ * like e.g. "normalize([name])" or "[lastName]+', '+[firstName]"
+ * @return the value generator
+ */
+ public static DBGeneratedValue byFunction(DBTable table, String functionTemplate)
+ {
+ return new DBFuncGeneratedValue(table, functionTemplate);
+ }
+
+ /**
+ * DBTriggerGeneratedValue
+ * Value is generated by Trigger
+ * @author doebele
+ */
+ public static class DBTriggerGeneratedValue extends DBGeneratedValue
+ {
+ private final String triggerName;
+
+ public DBTriggerGeneratedValue(DBRowSet table, String triggerName)
+ {
+ super(table.getDatabase());
+ this.triggerName = triggerName;
+ }
+
+ @Override
+ public boolean isModified(Record record)
+ {
+ // Never
+ return false;
+ }
+
+ @Override
+ public Object eval(Record record)
+ {
+ // Nothing to do
+ return ObjectUtils.NO_VALUE;
+ }
+
+ @Override
+ public void addReferencedColumns(Set<DBColumn> list)
+ {
+ log.warn("No reference columns for trigger {}", this.triggerName);
+ }
+
+ @Override
+ public void addSQL(DBSQLBuilder sql, long context)
+ {
+ log.error("Cannot add sql for value generated by trigger {}", this.triggerName);
+ throw new NotSupportedException(this, "addSQL");
+ }
+ }
+
+ /**
+ * DBFuncGeneratedValue
+ * Auto-generates a record value from other record fields
+ * The template must contain the column names wrapped in square brackets
+ * like e.g. "normalize([name])" or "[lastName]+', '+[firstName]"
+ * @author doebele
+ */
+ public static class DBFuncGeneratedValue extends DBGeneratedValue
+ {
+ private final List<Object> parts;
+
+ public DBFuncGeneratedValue(DBTable table, String template)
+ {
+ super(table.getDatabase());
+ this.parts = new ArrayList<Object>();
+ int idx=0;
+ while (idx<template.length())
+ {
+ int nxt=template.indexOf('[', idx);
+ if (nxt<0)
+ { // append rest
+ parts.add(template.substring(idx));
+ break;
+ }
+ // append
+ parts.add(template.substring(idx, nxt++));
+ // find end
+ int end=template.indexOf(']', nxt);
+ if (end<0)
+ throw new InvalidArgumentException("template", template);
+ // find column
+ String name = template.substring(nxt, end);
+ DBColumn column = table.getColumn(name);
+ if (column==null)
+ throw new ItemNotFoundException(name);
+ // found
+ parts.add(column);
+ idx = end+1;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.empire.db.DBGeneratedValue#isModified(org.apache.empire.data.Record)
+ */
+ @Override
+ public boolean isModified(Record record)
+ {
+ for (Object part : parts)
+ { // check modified
+ if ((part instanceof Column) && record.wasModified((Column)part))
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.empire.db.DBGeneratedValue#eval(org.apache.empire.data.Record)
+ */
+ @Override
+ public Object eval(Record record)
+ {
+ for (Object part : parts)
+ { // check null
+ if ((part instanceof Column) && record.isNull((Column)part))
+ return null;
+ }
+ // build now
+ DBSQLBuilder sql = db.getDbms().createSQLBuilder();
+ for (Object part : parts)
+ {
+ if (part instanceof Column)
+ { // append column value
+ Column col = (Column)part;
+ Object value = record.get(col);
+ sql.appendValue(col.getDataType(), value);
+ }
+ else
+ sql.append(part.toString());
+ }
+ // done
+ return db.getValueExpr(sql.toString(), DataType.UNKNOWN);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.empire.db.DBExpr#addReferencedColumns(java.util.Set)
+ */
+ @Override
+ public void addReferencedColumns(Set<DBColumn> list)
+ {
+ for (Object part : parts)
+ {
+ if (part instanceof DBColumn)
+ list.add((DBColumn)part);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.empire.db.DBExpr#addSQL(org.apache.empire.db.DBSQLBuilder, long)
+ */
+ @Override
+ public void addSQL(DBSQLBuilder sql, long context)
+ {
+ for (Object part : parts)
+ {
+ if (part instanceof Column)
+ { // append column value
+ DBColumn col = (DBColumn)part;
+ col.addSQL(sql, context);
+ }
+ else
+ sql.append(part.toString());
+ }
+ }
+ }
+
protected final DBDatabase db;
public DBGeneratedValue(DBDatabase db)
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java b/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
index a42616e4..ce191604 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
@@ -1096,7 +1096,12 @@ public abstract class DBRowSet extends DBExpr implements Entity
continue;
}
// get the auto-generated field value
- fields[i] = value = col.getRecordDefaultValue(record, conn);
+ value = col.getRecordDefaultValue(record, conn);
+ // set updated value
+ fields[i] = (value instanceof DBExpr) ? ObjectUtils.NO_VALUE : value;
+ if (value==ObjectUtils.NO_VALUE)
+ continue;
+ // set empty
empty = ObjectUtils.isEmpty(value);
}
// Add the value to the command
@@ -1159,15 +1164,19 @@ public abstract class DBRowSet extends DBExpr implements Entity
if (timestamp!=null)
cmd.set(col.to(timestamp));
}
- else if (col.isAutoGenerated() && (col.getDefaultValue() instanceof DBGeneratedValue))
- { // Check for AutoInc data type
- DBGeneratedValue genValue = ((DBGeneratedValue)col.getDefaultValue());
+ else if (col.isAutoGenerated() && (col.getDefaultValue() instanceof DBGeneratedValue))
+ { // Update generated value
+ DBGeneratedValue genValue = ((DBGeneratedValue) col.getDefaultValue());
if (genValue.isModified(record))
- { // value has changed
- fields[i] = value = genValue.eval(record);
- // Set the column
- cmd.set(col.to(value));
- setCount++;
+ { // value has changed
+ value = genValue.eval(record);
+ if (value!=ObjectUtils.NO_VALUE)
+ { // Set the column
+ cmd.set(col.to(value));
+ setCount++;
+ }
+ // set updated value
+ fields[i] = (value instanceof DBExpr) ? ObjectUtils.NO_VALUE : value;
}
}
else if (modified)
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBTable.java b/empire-db/src/main/java/org/apache/empire/db/DBTable.java
index ea5cbfc7..3d578583 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBTable.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBTable.java
@@ -900,7 +900,7 @@ public class DBTable extends DBRowSet implements Cloneable
DBColumn column = columns.get(i);
// getDefaultValue
Object value = ((DBTableColumn)column).getRecordDefaultValue(record, conn);
- if (ObjectUtils.isEmpty(value))
+ if (value!=ObjectUtils.NO_VALUE && ObjectUtils.isEmpty(value))
continue;
// Initial value
// Don't set to modified: record.modifyValue(i, value, false);
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandlerBase.java b/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandlerBase.java
index 3751a0ed..7aefab60 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandlerBase.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandlerBase.java
@@ -510,7 +510,7 @@ public abstract class DBMSHandlerBase implements DBMSHandler
return ts;
}
// Other types
- throw new NotSupportedException(this, "getColumnAutoValue() for "+type);
+ throw new NotSupportedException(this, "getColumnAutoValue for "+column.getFullName());
}
/**