From 3ca0eaec922d19261a5b97c414ea3408ce08d50d Mon Sep 17 00:00:00 2001
From: Johannes Hoermann <j.hoermann@adito.de>
Date: Tue, 22 Oct 2019 11:14:22 +0200
Subject: [PATCH] extend Sql_lib documentation

---
 process/Sql_lib/documentation.adoc | 104 ++++++++++++++++++++++++++---
 1 file changed, 93 insertions(+), 11 deletions(-)

diff --git a/process/Sql_lib/documentation.adoc b/process/Sql_lib/documentation.adoc
index 4645bef4fd7..5c252711d60 100644
--- a/process/Sql_lib/documentation.adoc
+++ b/process/Sql_lib/documentation.adoc
@@ -182,17 +182,72 @@ var cond = newWhereIfSet("TAB1.COL2", null)
 // As you can see. TAB1.COL2 is just ignored completely
 ----
 
-=== join
+=== select
+select(pFields) just sets all fields defined to the select-section of the sql.
+You may pass them as string, SqlBuilder (for subselects) or array (of strings and sqlbuilders)
+
+The following examples are all perfectly valid:
+
+* just a string (note: aliases are possible): "CAMPAIGNCOSTID idAlias, CAMPAIGNSTEP_ID, CAMPAIGNSTEP.NAME, CATEGORY, NET"
+* just an array of strings: ["CAMPAIGNCOSTID", "CAMPAIGNSTEP_ID", "CAMPAIGNSTEP.NAME", "CATEGORY", "NET"]
+* additional keywords like distinct: "distinct CAMPAIGNCOSTID, CAMPAIGNSTEP_ID, CAMPAIGNSTEP.NAME, CATEGORY, NET"
+* array and additional keyword: ["distinct CAMPAIGNCOSTID", "CAMPAIGNSTEP_ID", "CAMPAIGNSTEP.NAME", "CATEGORY", "NET"]
+* subselect: newSelect("ORGANISATION.\"NAME\").from("ORGANISATION").where("ORGANISATION.CONTACT_ID = CONTACT.CONTACTID")
+* array with strings and subselects: ["CAMPAIGNCOSTID", "CAMPAIGNSTEP_ID", "CAMPAIGNSTEP.NAME", "CATEGORY", "NET", newSelect("ORGANISATION.\"NAME\").from("ORGANISATION").where("ORGANISATION.CONTACT_ID = CONTACT.CONTACTID")]
+
+=== from
+from(pTable, pTableAlias) adds a from-part to the sql.
+
+* pTable This can either be a String or a SqlBuilder
+You may use only the tablename or (not recommended) a full from clause already containing joins. (It is better to use .join for this)
+Subselects by using a SqlBuilder are also working
+* pTableAlias just adds an alias-name for the table.
 
+=== join
+A join can be added by using
+
+* .join(pTable, pCondition, pTableAlias, pPrefix, pReplacementForWordJoin)
+* .leftJoin(pTable, pCondition, pTableAlias)
+* .rightJoin(pTable, pCondition, pTableAlias)
+
+The parameters are:
+
+* pTable is just the table name as string.
+(it is possible but not recommended to use a whole join-string for the table e.g. "PERSON on PERSONID = PERSON_ID". Only use this, if you don't have a seperate string for the on-condition.)
+Subselects are also possible by using a SqlBuilder
+(e.g. newSelect("FIRSTNAME").from("PERSON"))
+* pCondition is the on-condition. 
+You can provide it as String (e.g. "PERSONID = PERSON_ID")
+or as SqlBuilder (e.g. newWhere("PERSON.PERSONID", myPersonid))
+* pTableAlias just adds an alias-name for the table.
+* pPrefix here you can specify a prefix for the join. (e.g. "left")
+ .leftJoin / .rightJoin fill this automatically
+* pReplacementForWordJoin is for using something different as the word "join". This is added to support db-specific use cases.
+
+An example:
+[source,js]
+----
+var costData = newSelect("CAMPAIGNCOSTID, CAMPAIGNSTEP_ID, CAMPAIGNSTEP.NAME, CATEGORY, NET")
+                    .from("CAMPAIGNCOST")
+                    .leftJoin("CAMPAIGNSTEP", newWhere("CAMPAIGNSTEP_ID = CAMPAIGNSTEPID"))
+                    .where("CAMPAIGNCOST.CAMPAIGN_ID", campaignId)
+                    .table();
+----
 === group by
+groupBy(pFields) just adds a group by to the sql
+the parameter can be filled the same way as .select(pFields)
 
 === having
+having(pCondition) adds a having condition to the sql.
+pCondition can be a simple string or a SqlBuilder containing a condition. (only the condition from it is used)
 
 === order by
+orderBy(pFields) just adds a order by to the sql
+the parameter can be filled the same way as .select(pFields)
 
-=== Examples and Use Cases
+== Examples and Use Cases
 
-==== already complete condition
+=== already complete condition
 
 If the first parameter is the only one you set, it is treated as a complete condition:
 [source,js]
@@ -223,7 +278,7 @@ var cond = newWhere("PERSON.FIRSTNAME", "Tim")
 // ( PERSON.FIRSTNAME = 'Tim'  or PERSON.FIRSTNAME = 'Fritz'  and PERSON.FIRSTNAME = 'Peter' ) 
 ----
 
-==== simple condition with and & or
+=== simple condition with and & or
 You can just combine and & or as you like:
 
 [source,js]
@@ -238,7 +293,7 @@ var cond = newWhere("PERSON.FIRSTNAME", "Tim")
 
 (Note: the AND before OR: (Tim && Admin) || (Peter && Meier))
 
-==== JDito Variables
+=== JDito Variables
 It is also possible to just pass JDito variables directly:
 [source,js]
 ----
@@ -248,14 +303,14 @@ Note: it is checked for vars.getString(...) != null and vars.getString(...) != u
 If you want to check also for != "" and vars.exists(...) you have to do it by yourself explicitely.
 
 
-==== other condition than "# = ?"
+=== other condition than "# = ?"
 If you need something different as the default "# = ?" condition just pass a string to pCondition.
 Note that the # is replaced by the Table.Column from the first param and ? is the place where the value schould be inserted.
 
-==== codition like "year(#) = ?" with specific FieldType
+=== condition like "year(#) = ?" with specific FieldType
 It is also possible to use more complex sql such as "year(#) = ?" But keep in mind that this may change the SQLTYPE needed and you may have to provede it manually by the 4th param if it cannot be loaded by the table and column name.
 
-==== Subquery
+=== Subquery
 Subqueries are also possible by providing either another Sql condition or a prepared-statement array.
 Some possible combinations:
 
@@ -289,7 +344,7 @@ var cond = newWhere("TABLE.FIELD", aSqlBuilderContainingFullSelect)
 // cond.build() results in ["( TABLE.FIELD =  ( select LASTNAME from PERSON where PERSON.FIRSTNAME = ?  ) ) ", [['Fritz', SQLTYPES.VARCHAR]]]
 ----
 
-==== IN statement with array of values
+=== IN statement with array of values
 pValue can also be an array of values which is automatically transfered into a SQL prepared statement SQL like this:
  ["(?, ?, ?)", [["Fritz", SQLTYPES.VARCHAR], ["Franz", SQLTYPES.VARCHAR], ["Max", SQLTYPES.VARCHAR]]]
 
@@ -301,12 +356,39 @@ var cond = newWhere("PERSON.FIRSTNAME", ["Fritz", "Franz", "Max"], SqlBuilder.IN
 ----
 Note that an empty array is threated like null or undefined: using .where throws an error, using .whereIfSet ignores the whole condition.
 
-==== IN statement with subquery
+=== IN statement with subquery
 You can just use a Subquery together with the pCondition SqlBuilder.IN() or SqlBuilderNOT_.IN()
 
-==== common usage in condition processes with $param variables
+=== common usage in condition processes with $param variables
 In the conditionProcess often conditions are built based on which parameter is given. This can be done very easy by using the *IfSet methods:
 [source,js]
 ----
+// This is a example condition process containing some possible ways to use the SqlBuilder.
+
+// Using newWhereIfSet() to create a new Condition. 
+// The 'IfSet' ignores the condition "CONTACT.ORGANISATION_ID" = "$param.OrgId_param" if "$param.OrgId_param" is null
+var cond = newWhereIfSet("CONTACT.ORGANISATION_ID", "$param.OrgId_param")
+                .andIfSet("PERSON.CONTACT_ID", "$param.ContactId_param"); // same again: if "$param.ContactId_param" is null, this line is ignored
+                
+// --> so if both parameters where null (not filled) the SqlBuilder cond won't contain any condition!
+
+
+// Now we add a parameter containing a json Array
+
+// we have to parse it
+var excludedContacts = JSON.parse(vars.getString("$param.ExcludedContactIds_param"));
+
+// and add it to cond using not in --------------------------------V 
+cond.andIfSet("CONTACT.CONTACTID", excludedContacts, SqlBuilder.NOT_IN());
+
+// if excludedContacts is an empty array (or null), no condition is added as we used "andIfSet()"
+// if you need a different behaviour you may wrap it by an if
+
+// Same for onlyShowContactIds but by using an in-statement
+var onlyShowContactIds = JSON.parse(vars.get("$param.OnlyShowContactIds_param"));
+cond.andIfSet("CONTACT.CONTACTID", onlyShowContactIds, SqlBuilder.IN());
 
+// The conditionProcesss doesn't support prepared statements. So .build() is currently not possible.
+// using .toString() resolves all conditions and builds the finished select as string.
+result.string(cond.toString());
 ----
\ No newline at end of file
-- 
GitLab