From 61b08e1651a49693ac0dd988cf7bea19d1f53277 Mon Sep 17 00:00:00 2001
From: "S.Listl" <S.Listl@SLISTL.aditosoftware.local>
Date: Tue, 10 Mar 2020 10:47:31 +0100
Subject: [PATCH] SqlBuilder insert functions

---
 .../recordcontainers/jdito/onInsert.js        | 34 +++------
 process/Sql_lib/documentation.adoc            | 21 ++++++
 process/Sql_lib/process.js                    | 71 ++++++++++++++++++-
 3 files changed, 102 insertions(+), 24 deletions(-)

diff --git a/entity/Attribute_entity/recordcontainers/jdito/onInsert.js b/entity/Attribute_entity/recordcontainers/jdito/onInsert.js
index e2008693db..45e6ba816f 100644
--- a/entity/Attribute_entity/recordcontainers/jdito/onInsert.js
+++ b/entity/Attribute_entity/recordcontainers/jdito/onInsert.js
@@ -1,27 +1,15 @@
-import("system.neon");
-import("system.db");
 import("system.vars");
+import("Sql_lib");
 
 var rowdata = vars.get("$local.rowdata");
-var columns = [
-    "AB_ATTRIBUTEID",
-    "ATTRIBUTE_ACTIVE",
-    "ATTRIBUTE_NAME",
-    "ATTRIBUTE_PARENT_ID",
-    "ATTRIBUTE_TYPE",
-    "DROPDOWNDEFINITION",
-    "DROPDOWNFILTER",
-    "SORTING"
-];
-var values = [
-    rowdata["UID.value"],
-    rowdata["ATTRIBUTE_ACTIVE.value"] || "",
-    rowdata["ATTRIBUTE_NAME.value"] || "",
-    rowdata["ATTRIBUTE_PARENT_ID.value"] || "",
-    rowdata["ATTRIBUTE_TYPE.value"] || "",
-    rowdata["DROPDOWNDEFINITION.value"] || "",
-    rowdata["DROPDOWNFILTER.value"] || "",
-    rowdata["SORTING.value"] || ""
-];
 
-db.insertData("AB_ATTRIBUTE", columns, null, values);neon.refreshAll();
\ No newline at end of file
+new SqlBuilder().insertFields({
+    "AB_ATTRIBUTEID" : rowdata["UID.value"],
+    "ATTRIBUTE_PARENT_ID" : rowdata["ATTRIBUTE_PARENT_ID.value"],
+    "DROPDOWNDEFINITION" : rowdata["DROPDOWNDEFINITION.value"],
+    "ATTRIBUTE_ACTIVE" : rowdata["ATTRIBUTE_ACTIVE.value"],
+    "ATTRIBUTE_NAME" : rowdata["ATTRIBUTE_NAME.value"],
+    "ATTRIBUTE_TYPE" : rowdata["ATTRIBUTE_TYPE.value"],
+    "DROPDOWNFILTER" : rowdata["DROPDOWNFILTER.value"],
+    "SORTING" : rowdata["SORTING.value"]
+}, "AB_ATTRIBUTE");
\ No newline at end of file
diff --git a/process/Sql_lib/documentation.adoc b/process/Sql_lib/documentation.adoc
index 33dc30f6ed..b654ff1cf3 100644
--- a/process/Sql_lib/documentation.adoc
+++ b/process/Sql_lib/documentation.adoc
@@ -385,6 +385,27 @@ newWhere("SALESORDER.SALESORDERID", "$field.SALESORDERID")
     .updateFields({"ORDERSTATUS" : "1"});
 ----
 
+==== insert-functions
+
+SqlBuilder also provides functions for inserts which don't require a where-condition, they can be called on a `new SqlBuilder()` directly.
+
+The function `insertData()` is a wrapper for `db.insertData()` and has similar parameters:
+[source,js]
+----
+new SqlBuilder()
+    .insertData("AB_OBJECTRELATION", ["AB_OBJECTRELATIONID", "INFO"], null, [util.getNewUUID(), vars.get("$field.INFO")]);
+----
+
+To make the code more readable and more compact, there is another function, `insertFields()`. The syntax is similar to `updateFields()`, you have to pass the columns and values as an object. You can also set the parameter `pAutoUidField`, then the given column will be set to a random UUID:
+[source,js]
+----
+new SqlBuilder().insertFields({
+        "ACTIVITY_ID" : pActivityId,
+        "OBJECT_ROWID" : pRowId,
+        "OBJECT_TYPE" : pObjectType
+    }, "ACTIVITYLINK", "ACTIVITYLINKID");
+----
+
 <<<
 
 == Examples and use cases
diff --git a/process/Sql_lib/process.js b/process/Sql_lib/process.js
index 7e630b7644..ef906bd4af 100644
--- a/process/Sql_lib/process.js
+++ b/process/Sql_lib/process.js
@@ -789,7 +789,7 @@ function SqlBuilder (pAlias)
     this.alias = pAlias;
     
     this._subselectAlias = null;
-
+    
     this._where = {};
     this._initWhere();
 }
@@ -2341,6 +2341,7 @@ SqlBuilder.prototype.updateData = function(pExecuteOnlyIfConditionExists, pTable
  * @param {Object} pFieldValues Object with the columns to update as keys mapped to their values
  * @param {String} [pTableName] The table for updating data. If undefined, the from part of the SqlBuilder will be used (works only if it is a tablename). If no from is set,
  *      the table of the first where-condition is used.
+ * @return {Number} the number of rows affected
  * @example
  * newWhere("SALESORDER.SALESORDERID", "$field.SALESORDERID")
  *  .updateFields({"ORDERSTATUS" : "1"}); //pTableName can be omitted here since it's clearly defined by the given condition
@@ -2362,6 +2363,74 @@ SqlBuilder.prototype.updateFields = function (pFieldValues, pTableName)
     return this.updateData(true, pTableName, columns, null, values);
 }
 
+/**
+ * Inserts data in the database. This function doesn't require any where-condition, it is intended to be called right after 'new SqlBuilder()'. <br/>
+ * 
+ * @param {String} [pTableName] The table for inserting data. If undefined, the from part of the SqlBuilder will be used (works only if it is a tablename). If no from is set,
+ *      the table of the first where-condition is used.
+ * @param {String[]} pColumns The columns where you want to insert into.
+ * @param {SQLTYPES[]} [pColumnTypes=null] normally you can set this to null as the types are calculated if not provided
+ * @param {String[]} pValues The values to be inserted.
+ * @param {Number} [pTimeout=-1] 
+ * @return {Number} the number of rows affected
+ * @throws {Error} if no table is defined
+ */
+SqlBuilder.prototype.insertData = function(pTableName, pColumns, pColumnTypes, pValues, pTimeout)
+{
+    if (!pTableName && !this._tableName)
+        throw SqlBuilder._ERROR_NO_TABLE();
+
+    if (!pColumns)
+        pColumns = null;
+
+    return db.insertData(
+        (pTableName ? pTableName : this._tableName),
+        pColumns,
+        pColumnTypes,
+        pValues,
+        (this.alias ? this.alias : db.getCurrentAlias()),
+        (pTimeout ? pTimeout : -1));
+}
+
+/**
+ * Inserts data in the database. This function calls SqlBuilder.prototype.insertData, but provides a shorter syntax to
+ * improve the readability.
+ * 
+ * @param {Object} pFieldValues Object with the columns to update as keys mapped to their values
+ * @param {String} [pTableName] The table for updating data. If undefined, the from part of the SqlBuilder will be used (works only if it is a tablename). If no from is set,
+ *      the table of the first where-condition is used.
+ * @param {String} [pAutoUidField] UID column that should be filled with a random UUID 
+ * @return {Number} the number of rows affected
+ * @example
+ * new SqlBuilder().insertFields({
+ *         "ACTIVITY_ID" : pActivityId,
+ *         "OBJECT_ROWID" : pRowId,
+ *         "OBJECT_TYPE" : pObjectType
+ *     }, "ACTIVITYLINK", "ACTIVITYLINKID");
+ */
+SqlBuilder.prototype.insertFields = function (pFieldValues, pTableName, pAutoUidField)
+{
+    if (!pFieldValues || typeof(pFieldValues) !== "object")
+        throw SqlBuilder._ERROR_UPDATE_VALUES_INVALID;
+        
+    if (pAutoUidField)
+        pFielsValues[pAutoUidField] = util.getNewUUID();
+    
+    var columns = [];
+    var values = [];
+    for (let field in pFieldValues)
+    {
+        if (pFieldValues[field] !== undefined && pFieldValues[field] !== null)
+        {
+            columns.push(field);
+            values.push(pFieldValues[field].toString());
+        }
+    }
+    if (columns.length === 0)
+        return 0;
+    return this.insertData(pTableName, columns, null, values);
+}
+
 /**
  * Deletes data from the database.<br/>
  * Note: the default for pExecuteOnlyIfConditionExists is true to prevent updating all rows if the SqlBuilder has no condition.
-- 
GitLab