]> Kevux Git Server - koopa/commitdiff
Progress: continue development on database abstraction
authorKevin Day <thekevinday@gmail.com>
Mon, 7 Jan 2019 03:12:09 +0000 (21:12 -0600)
committerKevin Day <thekevinday@gmail.com>
Mon, 7 Jan 2019 04:06:04 +0000 (22:06 -0600)
Implement query placeholder.
Begin removing alternatives to query placeholder.

78 files changed:
common/database/classes/database_alter_aggregate.php
common/database/classes/database_alter_coalation.php
common/database/classes/database_alter_conversion.php
common/database/classes/database_alter_database.php
common/database/classes/database_alter_domain.php
common/database/classes/database_alter_event_trigger.php
common/database/classes/database_alter_extension.php
common/database/classes/database_alter_foreign_data_wrapper.php
common/database/classes/database_alter_foreign_table.php
common/database/classes/database_alter_function.php
common/database/classes/database_alter_group.php
common/database/classes/database_alter_index.php
common/database/classes/database_alter_language.php
common/database/classes/database_alter_large_object.php
common/database/classes/database_alter_materialized_view.php
common/database/classes/database_alter_operator.php
common/database/classes/database_alter_operator_class.php
common/database/classes/database_query.php
common/database/classes/database_query_parameter.php [deleted file]
common/database/classes/database_query_placeholder_bool.php [new file with mode: 0644]
common/database/classes/database_query_placeholder_float.php [new file with mode: 0644]
common/database/classes/database_query_placeholder_int.php [new file with mode: 0644]
common/database/classes/database_query_placeholder_null.php [new file with mode: 0644]
common/database/classes/database_query_placeholder_string.php [new file with mode: 0644]
common/database/enumerations/database_operand.php [new file with mode: 0644]
common/database/enumerations/database_set_operator.php [new file with mode: 0644]
common/database/interfaces/database_query_parameter.php [deleted file]
common/database/interfaces/database_query_placeholder.php [new file with mode: 0644]
common/database/traits/database_action.php
common/database/traits/database_add_user.php
common/database/traits/database_argument_type.php
common/database/traits/database_cascade.php
common/database/traits/database_cluster_on.php [new file with mode: 0644]
common/database/traits/database_column_reset.php
common/database/traits/database_column_set.php
common/database/traits/database_column_set_statistics.php
common/database/traits/database_column_set_storage.php
common/database/traits/database_constraint.php
common/database/traits/database_depends_on_extension.php
common/database/traits/database_enable_trigger.php
common/database/traits/database_for_role.php
common/database/traits/database_function_action.php
common/database/traits/database_grant.php
common/database/traits/database_grant_option_for.php
common/database/traits/database_group_by.php
common/database/traits/database_handler.php
common/database/traits/database_in_schema.php
common/database/traits/database_inherit.php
common/database/traits/database_name.php
common/database/traits/database_no_wait.php
common/database/traits/database_oid.php
common/database/traits/database_on.php
common/database/traits/database_operand_left.php [new file with mode: 0644]
common/database/traits/database_operand_right.php [new file with mode: 0644]
common/database/traits/database_options.php
common/database/traits/database_order_by.php
common/database/traits/database_owned_by.php
common/database/traits/database_owner_to.php
common/database/traits/database_placeholder.php [new file with mode: 0644]
common/database/traits/database_privilege.php
common/database/traits/database_procedural.php
common/database/traits/database_rename_column.php
common/database/traits/database_rename_to.php
common/database/traits/database_reset.php
common/database/traits/database_reset_storage_parameter.php
common/database/traits/database_restrict.php
common/database/traits/database_role_specification.php
common/database/traits/database_set.php
common/database/traits/database_set_operator.php [new file with mode: 0644]
common/database/traits/database_set_schema.php
common/database/traits/database_set_storage_parameter.php
common/database/traits/database_set_tablespace.php
common/database/traits/database_set_with_oids.php
common/database/traits/database_set_without_cluster.php
common/database/traits/database_to_role.php
common/database/traits/database_using.php [new file with mode: 0644]
common/database/traits/database_validator.php
common/database/traits/database_with_grant_option.php

index 51dbb8c05f856605015907cf2e28339b65cd7af3..75ac036fc36d066356d397b037cbd1eee10fe806 100644 (file)
@@ -272,8 +272,7 @@ class c_database_alter_aggregate extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    // the aggregate name is required.
-    if (!is_string($this->name)) {
+    if (is_null($this->name)) {
       return new c_base_return_false();
     }
 
@@ -313,9 +312,9 @@ class c_database_alter_aggregate extends c_database_query {
       }
       unset($order_by_signature);
 
-      if (is_string($aggregate_signatures)) {
+      if (isset($aggregate_signatures)) {
         $aggregate_signatures = ' (' . $aggregate_signatures;
-        if (is_string($order_by_signatures)) {
+        if (isset($order_by_signatures)) {
           $aggregate_signatures = ' ' . c_database_string::ORDER_BY . ' ' . $order_by_signatures . '';
         }
         $aggregate_signatures .= ')';
@@ -324,13 +323,13 @@ class c_database_alter_aggregate extends c_database_query {
     }
 
     $value = $this->p_do_build_name() . ' ';
-    if (is_string($this->rename_to)) {
+    if (isset($this->rename_to)) {
       $value .= $aggregate_signatures . ' ' . $this->p_do_build_rename_to();
     }
-    else if (is_string($this->owner_to)) {
+    else if (isset($this->owner_to)) {
       $value .= $aggregate_signatures . ' ' . $this->p_do_build_owner_to();
     }
-    else if (is_string($this->set_schema)) {
+    else if (isset($this->set_schema)) {
       $value .= $aggregate_signatures . ' ' . $this->p_do_build_set_schema();
     }
     else {
index 27604cae60d035b8f3e30c3c0820d9c5056cc9e1..b47acea79b6ffb47a27560c97ee67a32fb5a6192 100644 (file)
@@ -128,8 +128,7 @@ class c_database_alter_coalation extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    // the collation name is required.
-    if (!is_string($this->name)) {
+    if (is_null($this->name)) {
       return new c_base_return_false();
     }
 
@@ -139,13 +138,13 @@ class c_database_alter_coalation extends c_database_query {
         $value .= c_database_string::REFRESH_VERSION;
       }
     }
-    else if (is_string($this->rename_to)) {
+    else if (isset($this->rename_to)) {
       $value .= $this->p_do_build_rename_to();
     }
-    else if (is_string($this->owner_to)) {
+    else if (isset($this->owner_to)) {
       $value .= $this->p_do_build_owner_to();
     }
-    else if (is_string($this->set_schema)) {
+    else if (isset($this->set_schema)) {
       $value .= $this->p_do_build_set_schema();
     }
     else {
index f8fbfb1616b869a274439c9fb1c42d72478fa7e5..f4616d4cd77ee5dcc32e4645b9cd39187517a525 100644 (file)
@@ -78,8 +78,7 @@ class c_database_alter_conversion extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    // the collation name is required.
-    if (!is_string($this->name)) {
+    if (is_null($this->name)) {
       return new c_base_return_false();
     }
 
@@ -87,10 +86,10 @@ class c_database_alter_conversion extends c_database_query {
     if (is_string($this->rename_to)) {
       $value .= $this->p_do_build_rename_to();
     }
-    else if (is_string($this->owner_to)) {
+    else if (isset($this->owner_to)) {
       $value .= $this->p_do_build_owner_to();
     }
-    else if (is_string($this->set_schema)) {
+    else if (isset($this->set_schema)) {
       $value .= $this->p_do_build_set_schema();
     }
     else {
index a19f4a0a7f8f63968ede894ae9ec3d74a14901d2..76944393375d6fae7cebbe1244b792a18631ce7e 100644 (file)
@@ -143,7 +143,7 @@ class c_database_alter_database extends c_database_query {
    */
   public function do_build() {
     // the database name is required.
-    if (!is_string($this->name)) {
+    if (is_null($this->name)) {
       return new c_base_return_false();
     }
 
@@ -154,13 +154,13 @@ class c_database_alter_database extends c_database_query {
         $value .= $this->option->get_value_exact();
       }
     }
-    else if (is_string($this->rename_to)) {
+    else if (isset($this->rename_to)) {
       $value .= $this->p_do_build_rename_to();
     }
-    else if (is_string($this->owner_to)) {
+    else if (isset($this->owner_to)) {
       $value .= $this->p_do_build_owner_to();
     }
-    else if (is_string($this->set_tablespace)) {
+    else if (isset($this->set_tablespace)) {
       $value .= $this->p_do_build_set_tablespace();
     }
     else if (is_array($this->set)) {
index da1cf4a8664d779a53b65c8438593d146e997b27..adefbd3192e64a521a7c34d4b4706d3217f54bb5 100644 (file)
@@ -286,7 +286,7 @@ class c_database_alter_coalation extends c_database_query {
           break;
 
         case e_database_action::OWNER_TO:
-          if (!is_string($this->owner_to)) {
+          if (!isset($this->owner_to)) {
             unset($value);
             return new c_base_return_false();
           }
@@ -295,7 +295,7 @@ class c_database_alter_coalation extends c_database_query {
           break;
 
         case e_database_action::RENAME_CONSTRAINT:
-          if (!is_string($this->constraint['name']) || !is_string($this->constraint['name_new'])) {
+          if (!isset($this->constraint['name']) || !isset($this->constraint['name_new'])) {
             unset($value);
             return new c_base_return_false();
           }
@@ -304,7 +304,7 @@ class c_database_alter_coalation extends c_database_query {
           break;
 
         case e_database_action::RENAME_TO:
-          if (!is_string($this->rename_to)) {
+          if (!isset($this->rename_to)) {
             unset($value);
             return new c_base_return_false();
           }
@@ -320,7 +320,7 @@ class c_database_alter_coalation extends c_database_query {
           break;
 
         case e_database_action::SET_DEFAULT:
-          if (!is_string($this->expression)) {
+          if (!isset($this->expression)) {
             unset($value);
             return new c_base_return_false();
           }
@@ -329,7 +329,7 @@ class c_database_alter_coalation extends c_database_query {
           break;
 
         case e_database_action::SET_SCHEMA:
-          if (!is_string($this->set_schema)) {
+          if (!isset($this->set_schema)) {
             unset($value);
             return new c_base_return_false();
           }
index 8588d4169d4512f4904a19c148a09eaac427bea5..c609c531161f63a157c54d4ad7cc781ab79e5b27 100644 (file)
@@ -104,7 +104,7 @@ class c_database_alter_coalation extends c_database_query {
         }
         break;
       case e_database_action::OWNER_TO:
-        if (is_string($this->owner_to)) {
+        if (isset($this->owner_to)) {
           $value .= $this->p_do_build_owner_to();
         }
         else {
@@ -113,7 +113,7 @@ class c_database_alter_coalation extends c_database_query {
         }
         break;
       case e_database_action::RENAME_TO:
-        if (is_string($this->rename_to)) {
+        if (isset($this->rename_to)) {
           $value .= $this->p_do_build_rename_to();
         }
         else {
index cdbb304cec587c511e1572532f5de7af1a873671..b926be89274b448ce3420cdaf2e63f805dfdc7f6 100644 (file)
@@ -87,7 +87,7 @@ class c_database_alter_extension extends c_database_query {
     switch($this->action) {
       case e_database_action::UPDATE:
         $value .= c_database_string::UPDATE;
-        if (is_string($this->action_parameter)) {
+        if (isset($this->action_parameter)) {
           $value .= ' ' . c_database_string::TO . ' ' . $this->action_parameter;
         }
         else {
@@ -96,7 +96,7 @@ class c_database_alter_extension extends c_database_query {
         }
         break;
       case e_database_action::SET_SCHEMA:
-        if (is_string($this->set_schema)) {
+        if (isset($this->set_schema)) {
           $value = $this->p_do_build_set_schema();
         }
         else {
index 8376662949b37b5de5b6e019f345a0d0ba0ad2f1..58b7f0e6d1d0cc94ad536acc1256a10b4ece3c2f 100644 (file)
@@ -90,13 +90,13 @@ class c_database_alter_foreign_data_wrapper extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    if (!is_string($this->name)) {
+    if (is_null($this->name)) {
       return new c_base_return_false();
     }
 
     $action = NULL;
     if ($this->action === e_database_action::OWNER_TO) {
-      if (is_string($this->owner_to)) {
+      if (isset($this->owner_to)) {
         $action = $this->p_do_build_owner_to();
       }
       else {
@@ -105,7 +105,7 @@ class c_database_alter_foreign_data_wrapper extends c_database_query {
       }
     }
     else if ($this->action === e_database_action::RENAME_TO) {
-      if (is_string($this->rename_to)) {
+      if (isset($this->rename_to)) {
         $action = $this->p_do_build_rename_to();
       }
       else {
index 113beb57e143f27d11ca8a01b7df2312987da4c1..f4578e904d96a2dd1ed64d93a9a0df95599092fe 100644 (file)
@@ -302,7 +302,7 @@ class c_database_alter_foreign_table extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    if (!is_string($this->name)) {
+    if (is_null($this->name)) {
       return new c_base_return_false();
     }
 
@@ -319,7 +319,7 @@ class c_database_alter_foreign_table extends c_database_query {
 
       $value .= ' ' . $this->p_do_build_rename_column();
     }
-    else if (is_string($this->rename_to)) {
+    else if (isset($this->rename_to)) {
       $value .= is_null($value) ? '' : ' ';
       $value .= $this->p_do_build_rename_to();
     }
index f0bade5065c3bbddcccf3a1a08a2f8a8b0307504..f3bee19bdd8e401fcba7d16c9d11ae19e6a1a3cb 100644 (file)
@@ -93,7 +93,7 @@ class c_database_alter_function extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    if (!is_string($this->name)) {
+    if (is_null($this->name)) {
       return new c_base_return_false();
     }
 
@@ -110,16 +110,16 @@ class c_database_alter_function extends c_database_query {
         $value .= ' ' . $this->p_do_build_restrict();
       }
     }
-    else if (is_string($this->rename_to)) {
+    else if (isset($this->rename_to)) {
       $value .= $this->p_do_build_rename_to();
     }
-    else if (is_string($this->owner_to)) {
+    else if (isset($this->owner_to)) {
       $value .= $this->p_do_build_owner_to();
     }
-    else if (is_string($this->set_schema)) {
+    else if (isset($this->set_schema)) {
       $value .= $this->p_do_build_set_schema();
     }
-    else if (is_string($this->depends_on_extension)) {
+    else if (isset($this->depends_on_extension)) {
       $value .= $this->p_do_build_depends_on_extension();
     }
     else {
index cea116acdc376fa8dcadb0d7cb3557d4c791aa6a..a3adb003351b9c63988cbbef03154b543b0da238 100644 (file)
@@ -78,11 +78,11 @@ class c_database_alter_group extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    if (is_array($this->add_user) && (is_int($this->role_specification) || is_string($this->role_specification))) {
+    if (is_array($this->add_user) && isset($this->role_specification)) {
       $value = $this->p_do_build_role_specification();
       $value .= ' ' . $this->p_do_build_add_user();
     }
-    else if (!is_string($this->name) && !is_string($this->rename_to)) {
+    else if (isset($this->name) && is_null($this->rename_to)) {
       $value = $this->p_do_build_name();
       $value .= ' ' . $this->p_do_build_rename_to();
     }
index 15158048aba9bba32fc8f68d958b33063c18dba0..a35930e3629e9910404d8e3c5538c2adee316f55 100644 (file)
@@ -99,7 +99,7 @@ class c_database_alter_index extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    if (!is_string($this->name)) {
+    if (is_null($this->name)) {
       return new c_base_return_false();
     }
 
@@ -109,13 +109,13 @@ class c_database_alter_index extends c_database_query {
     }
 
     $value = $this->p_do_build_name();
-    if (is_string($this->rename_to)) {
+    if (isset($this->rename_to)) {
       $value .= ' ' . $this->p_do_build_rename_to();
     }
-    else if (is_string($this->set_tablespace)) {
+    else if (isset($this->set_tablespace)) {
       $value .= ' ' . $this->p_do_build_set_tablespace();
     }
-    else if (is_string($this->depends_on_extension)) {
+    else if (isset($this->depends_on_extension)) {
       $if_exists = NULL;
       $value .= ' ' . $this->p_do_build_depends_on_extension();
     }
@@ -125,7 +125,7 @@ class c_database_alter_index extends c_database_query {
     else if (is_array($this->reset_storage_parameter)) {
       $value .= ' ' . $this->p_do_build_reset_storage_parameter();
     }
-    else if (is_string($this->set_tablespace)) {
+    else if (isset($this->set_tablespace)) {
       $if_exists = NULL;
       $value = c_database_string::ALL_IN_TABLESPACE . ' ' . $value;
 
@@ -142,7 +142,7 @@ class c_database_alter_index extends c_database_query {
 
     $this->value = static::p_QUERY_COMMAND;
 
-    if (is_string($if_exists)) {
+    if (isset($if_exists)) {
       $this->value .= $if_exists;
     }
     unset($if_exists);
index 047981bf383f3b8e9be65d45d34f4ca11b46b9e7..addd716dfe0636966ce384f8841a537f1a4eeb27 100644 (file)
@@ -79,12 +79,12 @@ class c_database_alter_language extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    if (!is_string($this->name)) {
+    if (is_null($this->name)) {
       return new c_base_return_false();
     }
 
     $value = $this->p_do_build_name();
-    if (is_string($this->rename_to)) {
+    if (isset($this->rename_to)) {
       $value .= ' ' . $this->p_do_build_rename_to();
     }
     else if (is_array($this->owner_to)) {
index ca4171c9e6e3c96ead694a671dbcf8bbeca574ee..65a8a28e6bfbafee44e82c7fb609d01c35bb041e 100644 (file)
@@ -70,7 +70,7 @@ class c_database_alter_large_object extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    if (!is_string($this->oid) || !is_array($this->owner_to)) {
+    if (is_null($this->oid) || !is_array($this->owner_to)) {
       return new c_base_return_false();
     }
 
index 7faa5753e176eebe5585b53c5b48af4a7d614751..e613ed102ffcb167e82ddb914790dbb4260de183 100644 (file)
@@ -139,7 +139,7 @@ class c_database_alter_materialized_view extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    if (!is_string($this->name)) {
+    if (is_null($this->name)) {
       return new c_base_return_false();
     }
 
@@ -149,20 +149,20 @@ class c_database_alter_materialized_view extends c_database_query {
     }
 
     $value = $this->p_do_build_name();
-    if (is_string($this->depends_on_extension)) {
+    if (isset($this->depends_on_extension)) {
       $value .= ' ' . $this->p_do_build_depends_on_extension();
       $if_exists = NULL;
     }
     else if (is_array($this->rename_column)) {
       $value .= ' ' . $this->p_do_build_rename_column();
     }
-    else if (is_string($this->rename_to)) {
+    else if (isset($this->rename_to)) {
       $value .= ' ' . $this->p_do_build_rename_to();
     }
-    else if (is_string($this->set_schema)) {
+    else if (isset($this->set_schema)) {
       $value .= ' ' . $this->p_do_build_set_schema();
     }
-    else if (is_string($this->set_tablespace)) {
+    else if (isset($this->set_tablespace)) {
       $if_exists = NULL;
       $value = c_database_string::ALL_IN_TABLESPACE . ' ' . $value;
 
@@ -188,19 +188,19 @@ class c_database_alter_materialized_view extends c_database_query {
     else if (is_array($this->column_set_storage)) {
       $value .= ' ' . $this->p_do_build_column_set_storage();
     }
-    else if (is_string($this->cluster_on)) {
+    else if (isset($this->cluster_on)) {
       $value .= ' ' . $this->p_do_build_cluster_on();
     }
-    else if (is_string($this->set_without_cluster)) {
+    else if (isset($this->set_without_cluster)) {
       $value .= ' ' . $this->p_do_build_set_without_cluster();
     }
-    else if (is_string($this->set_storage_parameter)) {
+    else if (isset($this->set_storage_parameter)) {
       $value .= ' ' . $this->p_do_build_set_storage_parameter();
     }
-    else if (is_string($this->reset_storage_parameter)) {
+    else if (isset($this->reset_storage_parameter)) {
       $value .= ' ' . $this->p_do_build_reset_storage_parameter();
     }
-    else if (is_string($this->owner_to)) {
+    else if (isset($this->owner_to)) {
       $value .= ' ' . $this->p_do_build_owner_to();
     }
     else {
@@ -211,7 +211,7 @@ class c_database_alter_materialized_view extends c_database_query {
 
     $this->value = static::p_QUERY_COMMAND;
 
-    if (is_string($if_exists)) {
+    if (isset($if_exists)) {
       $this->value .= ' ' . $if_exists;
     }
     unset($if_exists);
index 54885a78e40eb319f679ce49d2db285b60047332..04245b01023f2b75efab0b1eebc859b911f4a0a3 100644 (file)
@@ -10,14 +10,28 @@ require_once('common/base/classes/base_return.php');
 
 require_once('common/database/classes/database_query.php');
 
+require_once('common/database/traits/database_name.php');
+require_once('common/database/traits/database_operand_left.php');
+require_once('common/database/traits/database_operand_right.php');
+require_once('common/database/traits/database_owner_to.php');
+require_once('common/database/traits/database_set_operator.php');
+require_once('common/database/traits/database_set_schema.php');
+
 
 /**
- * The class for building and returning a Postgresql ALTER COALATION query string.
+ * The class for building and returning a Postgresql ALTER OPERATOR query string.
  *
- * @see: https://www.postgresql.org/docs/current/static/sql-alteraggregate.html
+ * @see: https://www.postgresql.org/docs/current/static/sql-alteroperator.html
  */
-class c_database_alter_coalation extends c_database_query {
-  protected const p_QUERY_COMMAND = 'alter coalation';
+class c_database_alter_operator extends c_database_query {
+  use t_database_name;
+  use t_database_operand_left;
+  use t_database_operand_right;
+  use t_database_owner_to;
+  use t_database_set_operator;
+  use t_database_set_schema;
+
+  protected const p_QUERY_COMMAND = 'alter operator';
 
 
   /**
@@ -25,12 +39,26 @@ class c_database_alter_coalation extends c_database_query {
    */
   public function __construct() {
     parent::__construct();
+
+    $this->name          = NULL;
+    $this->operand_left  = NULL;
+    $this->operand_right = NULL;
+    $this->owner_to      = NULL;
+    $this->set_operator  = NULL;
+    $this->set_schema    = NULL;
   }
 
   /**
    * Class destructor.
    */
   public function __destruct() {
+    unset($this->name);
+    unset($this->operand_left);
+    unset($this->operand_right);
+    unset($this->owner_to);
+    unset($this->set_operator);
+    unset($this->set_schema);
+
     parent::__destruct();
   }
 
@@ -59,9 +87,28 @@ class c_database_alter_coalation extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    $this->value = NULL;
+    if (is_null($this->name) || is_null($this->operand_left) || is_null($this->operand_right)) {
+      return new c_base_return_false();
+    }
+
+    $value = $this->p_do_build_name() . ' (' . $this->p_do_build_operand_left() . ', ' . $this->p_do_build_operand_right() . ')';
+    if (isset($this->owner_to)) {
+      $value .= ' ' . $this->p_do_build_owner_to();
+    }
+    else if (isset($this->set_schema)) {
+      $value .= ' ' . $this->p_do_build_set_schema();
+    }
+    else if (is_array($this->set_operator)) {
+      $value .= ' ' . $this->p_do_build_set_operator();
+    }
+    else {
+      unset($value);
+      return new c_base_return_false();
+    }
 
-    // @todo
+    $this->value = static::p_QUERY_COMMAND;
+    $this->value .= ' ' . $value;
+    unset($value);
 
     return new c_base_return_true();
   }
index 54885a78e40eb319f679ce49d2db285b60047332..d3cd98a252e0c8f04d7a27782b72ca698502a5f9 100644 (file)
@@ -10,14 +10,24 @@ require_once('common/base/classes/base_return.php');
 
 require_once('common/database/classes/database_query.php');
 
+require_once('common/database/traits/database_name.php');
+require_once('common/database/traits/database_owner_to.php');
+require_once('common/database/traits/database_set_schema.php');
+require_once('common/database/traits/database_using.php');
+
 
 /**
- * The class for building and returning a Postgresql ALTER COALATION query string.
+ * The class for building and returning a Postgresql ALTER OPERATOR CLASS query string.
  *
- * @see: https://www.postgresql.org/docs/current/static/sql-alteraggregate.html
+ * @see: https://www.postgresql.org/docs/current/static/sql-alteroperatorclass.html
  */
-class c_database_alter_coalation extends c_database_query {
-  protected const p_QUERY_COMMAND = 'alter coalation';
+class c_database_alter_operator_class extends c_database_query {
+  use t_database_name;
+  use t_database_owner_to;
+  use t_database_set_schema;
+  use t_database_using;
+
+  protected const p_QUERY_COMMAND = 'alter operator class';
 
 
   /**
@@ -59,9 +69,25 @@ class c_database_alter_coalation extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    $this->value = NULL;
+    if (is_null($this->name) || !isset($this->using)) {
+      return new c_base_return_false();
+    }
+
+    $value = $this->p_do_build_name() . ' ' . $this->p_do_build_using();
+    if (isset($this->set_schema)) {
+      $value .= ' ' . $this->p_do_build_set_schema();
+    }
+    else if (isset($this->owner_to)) {
+      $value .= ' ' . $this->p_do_build_owner_to();
+    }
+    else {
+      unset($value);
+      return new c_base_return_false();
+    }
 
-    // @todo
+    $this->value = static::p_QUERY_COMMAND;
+    $this->value .= ' ' . $value;
+    unset($value);
 
     return new c_base_return_true();
   }
index 82cae3708dc5a97efc6528fba159a706665e312e..a9e538b44fd714ce579df97b5432568f2e49294e 100644 (file)
@@ -8,8 +8,14 @@
  * The following query parameter placeholders are reserved for use for auto-generation reasons:
  *   - :qp_# such that # is any valid whole number >= 0.
  *
- * @todo: a base class is needed for handling all query parameters because SQL functions may be used anywhere!
- *        This will make argument handling more complex than using simple integers, strings, etc..
+ * The query placeholders are intended to be auto-managed as much as possible.
+ * Whenever a string value is used, the implementing classes are expected to convert this to a query placeholder.
+ * Classes should handle string literals via PHP constants.
+ * The current design uses numeric array indexes that functions similar to a write-only manner.
+ * As a result, if any of the query placeholders are removed, then all values need to be re-assigned.
+ *
+ * @todo: Review the classes defined here to see if they are still needed.
+ *        (query arguments are likely to be removed as query placeholders are intended to be used.)
  *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
@@ -19,7 +25,11 @@ require_once('common/base/classes/base_error.php');
 require_once('common/base/classes/base_return.php');
 
 require_once('common/database/interfaces/database_query.php');
-require_once('common/database/interfaces/database_query_parameter.php');
+require_once('common/database/interfaces/database_query_placeholder_bool.php');
+require_once('common/database/interfaces/database_query_placeholder_float.php');
+require_once('common/database/interfaces/database_query_placeholder_int.php');
+require_once('common/database/interfaces/database_query_placeholder_null.php');
+require_once('common/database/interfaces/database_query_placeholder_string.php');
 
 /**
  * The base class for building and returning a Postgresql query string.
@@ -33,7 +43,8 @@ require_once('common/database/interfaces/database_query_parameter.php');
 abstract class c_database_query extends c_base_return_string implements i_database_query {
   public const PARAMETER_NONE = 0;
 
-  protected const p_QUERY_COMMAND = '';
+  protected const p_QUERY_COMMAND     = '';
+  protected const p_QUERY_PLACEHOLDER = ':qp_';
 
   protected $placeholders;
 
@@ -77,6 +88,20 @@ abstract class c_database_query extends c_base_return_string implements i_databa
   }
 
   /**
+   * Provide to string object override.
+   *
+   * Unlike normal c_base_retun_value classes, this will return the placeholder name instead of value.
+   *
+   * @return string
+   *   The string representation of the placeholder name contained in this object.
+   *
+   * @see: http://php.net/manual/en/language.oop5.magic.php@object.tostring
+   */
+  public function __toString() {
+    return strval($this->get_name());
+  }
+
+  /**
    * Assign the value.
    *
    * This changes the behavior of the extended class from accepting only strings to accepting only c_database_query.
@@ -102,18 +127,32 @@ abstract class c_database_query extends c_base_return_string implements i_databa
    *
    * This does not sanitize the placeholder.
    *
-   * @param string $placeholder
-   *   The placeholder string, without the leading ':'.
-   * @param $value
-   *   The placeholder value the placeholder represents.
-   *   @todo: add placeholder types and validation?
+   * @param string $value
+   *   The value that the placeholder represents.
+   * @param int|null $placeholder
+   *   (optional) The placeholder array key id.
+   *   When NULL, the placeholder is appended.
    *
-   * @return c_base_return_status
-   *   TRUE if added, FALSE otherwise.
+   * @return i_database_query_placeholder|c_base_return_false
+   *   A query placeholder representing is returned on success.
    *   FALSE with the error bit set is returned on error.
    */
-  public function add_placeholder($placeholder, $value) {
-    if (!is_string($placeholder)) {
+  public function add_placeholder($value, $placeholder = NULL) {
+    if (!is_string($value)) {
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'value', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+      return c_base_return_error::s_false($error);
+    }
+
+    if (is_int($placeholder)) {
+      $total = count($this->placeholders);
+      if ($placeholder < 0 || $placeholder > $total) {
+        unset($total);
+        $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'placeholder', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+        return c_base_return_error::s_false($error);
+      }
+      unset($total);
+    }
+    else if (!is_null($placeholder)) {
       $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'placeholder', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
       return c_base_return_error::s_false($error);
     }
@@ -122,67 +161,113 @@ abstract class c_database_query extends c_base_return_string implements i_databa
       $this->placeholders = [];
     }
 
-    $this->placeholders[$placeholder] = $value;
-    return new c_base_return_true();
+    if (is_float($placeholder)) {
+      $placeholder_value = new c_database_query_placeholder_float();
+    }
+    else if (is_int($placeholder)) {
+      $placeholder_value = new c_database_query_placeholder_int();
+    }
+    else if (is_bool($placeholder)) {
+      $placeholder_value = new c_database_query_placeholder_bool();
+    }
+    else if (is_null($placeholder)) {
+      $placeholder_value = new c_database_query_placeholder_null();
+    }
+    else {
+      $placeholder_value = new c_database_query_placeholder_string();
+    }
+
+    $result = $placeholder_value->set_prefix(static::p_QUERY_PLACEHOLDER);
+    if ($result->has_error()) {
+      return c_base_return_error::s_false($result->get_error());
+    }
+
+    if (!$placeholder_value->set_value($value)) {
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'value', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+      return c_base_return_error::s_false($error);
+    }
+
+    if (is_null($placeholder)) {
+      $placeholder = count($this->placeholders) + 1;
+    }
+
+    $result = $placeholder_value->set_id($placeholder);
+    if ($result->has_error()) {
+      return c_base_return_error::s_false($result->get_error());
+    }
+    unset($result);
+
+    $this->placeholders[$placeholder] = $placeholder_value;
+
+    return $placeholder_value;
   }
 
   /**
-   * Get a query parameter placeholder value.
+   * Get a query parameter placeholder value(s).
+   *
+   * To get an array of placeholders fit for PDO usage, instead use get_placeholders().
    *
-   * @param string $placeholder
-   *   Name of the placeholder to return the value of, without the leading ':'.
+   * @param int|null $index
+   *   (optional) Index of the placeholder.
+   *   Set to NULL to get all placeholders.
    *
-   * @return c_base_return_value|c_base_return_status
-   *   The value assigned to the placeholder.
+   * @return i_database_query_placeholder|c_base_return_array|c_base_return_status
+   *   The placeholder assigned at the index.
+   *   When $index is NULL, an array of placeholders are returned.
    *   FALSE without the error bit set is returned if placeholder does not exist.
    *   FALSE with the error bit set is returned on error.
+   *   An empty array with the error bit set is returned on error when $index is NULL.
+   *
+   * @see: get_placeholders()
    */
-  public function get_placeholder($placeholder) {
-    if (!is_string($placeholder)) {
-      $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'placeholder', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+  public function get_placeholder($index = NULL) {
+    if (is_null($index)) {
+      if (is_array($this->placeholders)) {
+        return c_base_return_array::s_new($this->placeholders);
+      }
+
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'placeholders', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+      return c_base_return_error::s_vale([], 'c_base_return_array', $error);
+    }
+    else if (!is_int($index)) {
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'index', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
       return c_base_return_error::s_false($error);
     }
 
-    if (is_array($this->placeholders) && array_key_exists($placeholder, $this->placeholders)) {
-      return c_base_return_value::s_new($this->placeholders[$placeholder]);
+    if (is_array($this->placeholders) && array_key_exists($index, $this->placeholders)) {
+      return $this->placeholders[$index];
     }
 
     return new c_base_return_false();
   }
 
   /**
-   * Get all query parameter placeholders assigned.
+   * Gets all placeholders in a array structure design for PDO input parameter arguments.
+   *
+   * This is intended to be used as a parameter for the dbo->prepare() or dbo->execute() methods.
+   * To simply get all of the placeholders in the original structure, instead call get_placeholder() with no arguments.
    *
    * @return c_base_return_array
-   *   An array of all assigned placeholders.
-   *   An empty array with the error bit set is returned on error.
+   *   An array for use as input_parameters.
+   *   An array with the error bit set is returned on error.
+   *
+   * @see: get_placeholder()
    */
   public function get_placeholders() {
     if (is_array($this->placeholders)) {
-      return c_base_return_array::s_new($this->placeholders);
-    }
+      $input_parameters = [];
 
-    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'query', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
-    return c_base_return_error::s_vale([], 'c_base_return_array', $error);
-  }
+      foreach ($this->placeholders as $placeholder) {
+        if ($placeholder instanceof i_database_query_placeholder) {
+          $input_parameters[$placeholder->get_name()->get_value_exact()] = $placeholder->get_value_exact();
+        }
+      }
 
-  /**
-   * Remove a query parameter placeholder and its value.
-   *
-   * @param string $placeholder
-   *   Name of the placeholder to remove, without the leading ':'.
-   *
-   * @return c_base_return_status
-   *   TRUE if placeholder exists and is removed, FALSE otherwise.
-   *   FALSE with the error bit set is returned on error.
-   */
-  public function remove_placeholder($placeholder) {
-    if (is_array($this->placeholders) && array_key_exists($placeholder, $this->placeholders)) {
-      unset($this->placeholders[$placeholder]);
-      return new c_base_return_true();
+      return c_base_return_array::s_new($input_parameters);
     }
 
-    return new c_base_return_false();
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'placeholders', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    return c_base_return_error::s_vale([], 'c_base_return_array', $error);
   }
 
   /**
@@ -237,6 +322,8 @@ abstract class c_database_query extends c_base_return_string implements i_databa
  *
  * SQL queries may be passed to other SQL queries, marking them as sub-queries.
  * This will most commonly be added to other expressions.
+ *
+ * @fixme: rewrite/replace/remove this.
  */
 class c_database_argument_query extends c_base_return_string implements i_database_query_parameter {
   protected $query;
diff --git a/common/database/classes/database_query_parameter.php b/common/database/classes/database_query_parameter.php
deleted file mode 100644 (file)
index 98b4a70..0000000
+++ /dev/null
@@ -1,609 +0,0 @@
-<?php
-/**
- * @file
- * Provides classes for specific Postgesql Queries Parameter support.
- *
- * @errata:
- *   There is a lot of indecision on how this is to be design/used.
- *   Query parameters are being provided as a possible solution and may be removed in the future.
- *   I need to sit down and review the design before coming to a decision.
- *   Until then, this is being provided as a possibility.
- *   That said, I am strongly considering having the SQL generation functions do the actual generation of the query parameters.
- *   All would leave to implement would be embeded queries, which would be handled by some aspect of this implementation.
- *   The query parameters (or something like that) is needed for sub-query support.
- *
- * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
- */
-namespace n_koopa;
-
-require_once('common/base/classes/base_error.php');
-require_once('common/base/classes/base_return.php');
-
-require_once('common/database/interfaces/database_query_parameter.php');
-
-require_once('common/database/classes/database_query.php');
-
-/**
- * A query parameter representing a string.
- *
- * @see: c_base_return_string
- */
-class c_database_query_parameter extends c_base_return_string implements i_database_query_parameter {
-
-  /**
-   * @see: t_base_return_value::p_s_new()
-   */
-  public static function s_new($value) {
-    return self::p_s_new($value, __CLASS__);
-  }
-
-  /**
-   * @see: t_base_return_value::p_s_value()
-   */
-  public static function s_value($return) {
-    return self::p_s_value($return, __CLASS__);
-  }
-
-  /**
-   * @see: t_base_return_value_exact::p_s_value_exact()
-   */
-  public static function s_value_exact($return) {
-    return self::p_s_value_exact($return, __CLASS__, '');
-  }
-}
-
-/**
- * A query parameter representing a boolean.
- *
- * @see: c_base_return_bool
- */
-class c_database_query_parameter_bool extends c_base_return_bool implements i_database_query_parameter {
-
-  /**
-   * @see: t_base_return_value::p_s_new()
-   */
-  public static function s_new($value) {
-    return self::p_s_new($value, __CLASS__);
-  }
-
-  /**
-   * @see: t_base_return_value::p_s_value()
-   */
-  public static function s_value($return) {
-    return self::p_s_value($return, __CLASS__);
-  }
-
-  /**
-   * @see: t_base_return_value_exact::p_s_value_exact()
-   */
-  public static function s_value_exact($return) {
-    return self::p_s_value_exact($return, __CLASS__, FALSE);
-  }
-}
-
-/**
- * A query parameter representing a integer.
- *
- * @see: c_base_return_int
- */
-class c_database_query_parameter_int extends c_base_return_int implements i_database_query_parameter {
-
-  /**
-   * @see: t_base_return_value::p_s_new()
-   */
-  public static function s_new($value) {
-    return self::p_s_new($value, __CLASS__);
-  }
-
-  /**
-   * @see: t_base_return_value::p_s_value()
-   */
-  public static function s_value($return) {
-    return self::p_s_value($return, __CLASS__);
-  }
-
-  /**
-   * @see: t_base_return_value_exact::p_s_value_exact()
-   */
-  public static function s_value_exact($return) {
-    return self::p_s_value_exact($return, __CLASS__, 0);
-  }
-}
-
-/**
- * A query parameter representing a float.
- *
- * @see: c_base_return_float
- */
-class c_database_query_parameter_float extends c_base_return_float implements i_database_query_parameter {
-
-  /**
-   * @see: t_base_return_value::p_s_new()
-   */
-  public static function s_new($value) {
-    return self::p_s_new($value, __CLASS__);
-  }
-
-  /**
-   * @see: t_base_return_value::p_s_value()
-   */
-  public static function s_value($return) {
-    return self::p_s_value($return, __CLASS__);
-  }
-
-  /**
-   * @see: t_base_return_value_exact::p_s_value_exact()
-   */
-  public static function s_value_exact($return) {
-    return self::p_s_value_exact($return, __CLASS__, 0.0);
-  }
-}
-
-/**
- * A query parameter representing a json array, stored in this object as an array.
- *
- * @see: c_base_return_array
- */
-class c_database_query_parameter_json extends c_base_return_array implements i_database_query_parameter {
-
-  /**
-   * @see: t_base_return_value::p_s_new()
-   */
-  public static function s_new($value) {
-    return self::p_s_new($value, __CLASS__);
-  }
-
-  /**
-   * @see: t_base_return_value::p_s_value()
-   */
-  public static function s_value($return) {
-    return self::p_s_value($return, __CLASS__);
-  }
-
-  /**
-   * @see: t_base_return_value_exact::p_s_value_exact()
-   */
-  public static function s_value_exact($return) {
-    return self::p_s_value_exact($return, __CLASS__, []);
-  }
-
-  /**
-   * Assign the value.
-   *
-   * @param array $value
-   *   Any value so long as it is an array.
-   *   NULL is not allowed.
-   *
-   * @return bool
-   *   TRUE on success, FALSE otherwise.
-   *   FALSE is returned if any value in the array is not of type i_base_query_parameter.
-   */
-  public function set_value($value) {
-    if (!is_array($value)) {
-      return FALSE;
-    }
-
-    // guarantee that only i_base_query_parameter are assigend in the array.
-    foreach ($value as $v) {
-      if (!($v instanceof i_base_query_parameter)) {
-        unset($v);
-        return FALSE;
-      }
-    }
-    unset($v);
-
-    $this->value = $value;
-    return TRUE;
-  }
-
-  /**
-   * Assign the value at a specific index in the array.
-   *
-   * @param i_base_query_parameter $value
-   *   Any i_base_query_parameter implementation to be assigned at the specified position in the array.
-   * @param int|string $key
-   *   A key to assign a specific value to.
-   *
-   * @return bool
-   *   TRUE on success, FALSE otherwise.
-   *   FALSE is returned if value is not of type i_base_query_parameter.
-   */
-  public function set_value_at($value, $key) {
-    if (!($value instanceof i_base_query_parameter)) {
-      return FALSE;
-    }
-
-    return parent::set_value_at($value, $key);
-  }
-
-  /**
-   * Append the value at the end of the array.
-   *
-   * @param i_base_query_parameter $value
-   *   Any i_base_query_parameter to be appended in the array.
-   *
-   * @return bool
-   *   TRUE on success, FALSE otherwise.
-   *   FALSE is returned if value is not of type i_base_query_parameter.
-   */
-  public function set_value_append($value) {
-    if (!($value instanceof i_base_query_parameter)) {
-      return FALSE;
-    }
-
-    return parent::set_value_append($value);
-  }
-
-  /**
-   * Assigns the array from a serialized array string.
-   *
-   * @param string $serialized
-   *   A serialized string to convert to an array.
-   *
-   * @return bool
-   *   TRUE on success, FALSE otherwise.
-   *   if converted string does not produce an array, FALSE is returned and value is set to an empty array.
-   *   FALSE is returned if any value in the array is not of type i_base_query_parameter.
-   *
-   * @see: unserialize()
-   */
-  public function set_value_serialized($serialized) {
-    if (!is_string($serialized)) {
-      return FALSE;
-    }
-
-    $unserialized = unserialize($serialized);
-    if (is_array($unserialized)) {
-      // guarantee that only i_base_query_parameter are assigend in the array.
-      foreach ($unserialized as $v) {
-        if (!($v instanceof i_base_query_parameter)) {
-          unset($v);
-          return FALSE;
-        }
-      }
-      unset($v);
-
-      $this->value = $unserialized;
-      unset($unserialized);
-
-      return TRUE;
-    }
-    unset($unserialized);
-
-    $this->value = [];
-    return FALSE;
-  }
-
-  /**
-   * Assigns the array from a json-serialized array string.
-   *
-   * @param string $jsonized
-   *   A jsonized string to convert to an array.
-   * @param bool $associative
-   *   (optional) When TRUE array is return as an associative array.
-   * @param int $options
-   *   (optional) bitmask of json constants.
-   * @param int $depth
-   *   (optional) Maximum array depth.
-   *
-   * @return bool
-   *   TRUE on success, FALSE otherwise.
-   *   if converted string does not produce an array, FALSE is returned and value is set to an empty array.
-   *   FALSE is returned if any value in the array is not of type i_base_query_parameter.
-   *
-   * @see: json_decode()
-   */
-  public function set_value_jsonized($jsonized, $associative = TRUE, $options = 0, $depth = 512) {
-    if (!is_string($jsonized)) {
-      return FALSE;
-    }
-
-    if (!is_bool($associative)) {
-      $associative = TRUE;
-    }
-
-    if (!is_int($options)) {
-      $options = 0;
-    }
-
-    if (!is_int($depth) || $depth < 1) {
-      $depth = 512;
-    }
-
-    $decoded = json_decode($jsonized, $associative, $options, $depth);
-    if (is_array($decoded)) {
-      // guarantee that only i_base_query_parameter are assigend in the array.
-      foreach ($unserialized as $v) {
-        if (!($v instanceof i_base_query_parameter)) {
-          unset($v);
-          return FALSE;
-        }
-      }
-      unset($v);
-
-      $this->value = $decoded;
-      unset($decoded);
-
-      return TRUE;
-    }
-    unset($decoded);
-
-    $this->value = [];
-    return FALSE;
-  }
-}
-
-/**
- * A query parameter representing an array of query parameters, stored in this object as an array.
- *
- * All array values must be an implementation of type i_database_query_parameter.
- *
- * @see: c_base_return_array
- */
-class c_database_query_parameter_set extends c_base_return_array implements i_database_query_parameter {
-
-  /**
-   * @see: t_base_return_value::p_s_new()
-   */
-  public static function s_new($value) {
-    return self::p_s_new($value, __CLASS__);
-  }
-
-  /**
-   * @see: t_base_return_value::p_s_value()
-   */
-  public static function s_value($return) {
-    return self::p_s_value($return, __CLASS__);
-  }
-
-  /**
-   * @see: t_base_return_value_exact::p_s_value_exact()
-   */
-  public static function s_value_exact($return) {
-    return self::p_s_value_exact($return, __CLASS__, []);
-  }
-
-  /**
-   * Assign the value.
-   *
-   * @param array $value
-   *   Any value so long as it is an array.
-   *   NULL is not allowed.
-   *
-   * @return bool
-   *   TRUE on success, FALSE otherwise.
-   *   FALSE is returned if any value in the array is not of type i_base_query_parameter.
-   */
-  public function set_value($value) {
-    if (!is_array($value)) {
-      return FALSE;
-    }
-
-    // guarantee that only i_base_query_parameter are assigend in the array.
-    foreach ($value as $v) {
-      if (!($v instanceof i_base_query_parameter)) {
-        unset($v);
-        return FALSE;
-      }
-    }
-    unset($v);
-
-    $this->value = $value;
-    return TRUE;
-  }
-
-  /**
-   * Assign the value at a specific index in the array.
-   *
-   * @param i_base_query_parameter $value
-   *   Any i_base_query_parameter implementation to be assigned at the specified position in the array.
-   * @param int|string $key
-   *   A key to assign a specific value to.
-   *
-   * @return bool
-   *   TRUE on success, FALSE otherwise.
-   *   FALSE is returned if value is not of type i_base_query_parameter.
-   */
-  public function set_value_at($value, $key) {
-    if (!($value instanceof i_base_query_parameter)) {
-      return FALSE;
-    }
-
-    return parent::set_value_at($value, $key);
-  }
-
-  /**
-   * Append the value at the end of the array.
-   *
-   * @param i_base_query_parameter $value
-   *   Any i_base_query_parameter to be appended in the array.
-   *
-   * @return bool
-   *   TRUE on success, FALSE otherwise.
-   *   FALSE is returned if value is not of type i_base_query_parameter.
-   */
-  public function set_value_append($value) {
-    if (!($value instanceof i_base_query_parameter)) {
-      return FALSE;
-    }
-
-    return parent::set_value_append($value);
-  }
-
-  /**
-   * Assigns the array from a serialized array string.
-   *
-   * @param string $serialized
-   *  A serialized string to convert to an array.
-   *
-   * @return bool
-   *   TRUE on success, FALSE otherwise.
-   *   if converted string does not produce an array, FALSE is returned and value is set to an empty array.
-   *   FALSE is returned if any value in the array is not of type i_base_query_parameter.
-   *
-   * @see: unserialize()
-   */
-  public function set_value_serialized($serialized) {
-    if (!is_string($serialized)) {
-      return FALSE;
-    }
-
-    $unserialized = unserialize($serialized);
-    if (is_array($unserialized)) {
-      // guarantee that only i_base_query_parameter are assigend in the array.
-      foreach ($unserialized as $v) {
-        if (!($v instanceof i_base_query_parameter)) {
-          unset($v);
-          return FALSE;
-        }
-      }
-      unset($v);
-
-      $this->value = $unserialized;
-      unset($unserialized);
-
-      return TRUE;
-    }
-    unset($unserialized);
-
-    $this->value = [];
-    return FALSE;
-  }
-
-  /**
-   * Returns the data as a json-serialized array string.
-   *
-   * @param string $jsonized
-   *  A jsonized string to convert to an array.
-   * @param bool $associative
-   *   (optional) When TRUE array is return as an associative array.
-   * @param int $options
-   *   (optional) bitmask of json constants.
-   * @param int $depth
-   *   (optional) Maximum array depth.
-   *
-   * @return bool
-   *   TRUE on success, FALSE otherwise.
-   *   if converted string does not produce an array, FALSE is returned and value is set to an empty array.
-   *   FALSE is returned if any value in the array is not of type i_base_query_parameter.
-   *
-   * @see: json_decode()
-   */
-  public function set_value_jsonized($jsonized, $associative = TRUE, $options = 0, $depth = 512) {
-    if (!is_string($jsonized)) {
-      return FALSE;
-    }
-
-    if (!is_bool($associative)) {
-      $associative = TRUE;
-    }
-
-    if (!is_int($options)) {
-      $options = 0;
-    }
-
-    if (!is_int($depth) || $depth < 1) {
-      $depth = 512;
-    }
-
-    $decoded = json_decode($jsonized, $associative, $options, $depth);
-    if (is_array($decoded)) {
-      // guarantee that only i_base_query_parameter are assigend in the array.
-      foreach ($unserialized as $v) {
-        if (!($v instanceof i_base_query_parameter)) {
-          unset($v);
-          return FALSE;
-        }
-      }
-      unset($v);
-
-      $this->value = $decoded;
-      unset($decoded);
-
-      return TRUE;
-    }
-    unset($decoded);
-
-    $this->value = [];
-    return FALSE;
-  }
-}
-
-/**
- * A query parameter representing an embedded query.
- *
- * @see: c_base_return_object
- * @see: i_database_query
- */
-class c_database_query_parameter_query extends c_base_return_object implements i_database_query_parameter {
-
-  /**
-   * @see: t_base_return_value::p_s_new()
-   */
-  public static function s_new($value) {
-    return self::p_s_new($value, __CLASS__);
-  }
-
-  /**
-   * @see: t_base_return_value::p_s_value()
-   */
-  public static function s_value($return) {
-    return self::p_s_value($return, __CLASS__);
-  }
-
-  /**
-   * @see: t_base_return_value_exact::p_s_value_exact()
-   */
-  public static function s_value_exact($return) {
-    return self::p_s_value_exact($return, __CLASS__, '');
-  }
-
-  /**
-   * Assign the value.
-   *
-   * @param object $value
-   *   Any value so long as it is an object.
-   *   This object is cloned.
-   *   NULL is not allowed.
-   *
-   * @return bool
-   *   TRUE on success, FALSE otherwise.
-   *
-   * @see: clone()
-   */
-  public function set_value($value) {
-    $this->value = clone($value);
-    return parent::set_value($value);
-  }
-
-  /**
-   * Return the value.
-   *
-   * @return object|null $value
-   *   The value object stored within this class.
-   *   NULL may be returned if there is no defined valid resource.
-   */
-  public function get_value() {
-    if ($this->value instanceof i_database_query) {
-      return $this->value;
-    }
-
-    $this->value = NULL;
-    return NULL;
-  }
-
-  /**
-   * Return the value of the expected type.
-   *
-   * @return array $value
-   *   The value array stored within this class.
-   */
-  public function get_value_exact() {
-    if ($this->value instanceof i_database_query) {
-      return $this->value;
-    }
-
-    $class = __CLASS__;
-    return new $class();
-  }
-}
diff --git a/common/database/classes/database_query_placeholder_bool.php b/common/database/classes/database_query_placeholder_bool.php
new file mode 100644 (file)
index 0000000..d03d7fa
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+/**
+ * @file
+ * Provides a class for specific Postgesql query placeholder generation.
+ */
+namespace n_koopa;
+
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+
+require_once('common/database/interfaces/database_query_placeholder.php');
+
+require_once('common/database/traits/database_query_placeholder.php');
+
+
+/**
+ * The class for managing an bool query placeholder.
+ */
+class c_database_query_placeholder_bool extends c_base_return_bool implements i_database_query_placeholder {
+  use t_database_placeholder {
+    t_database_placeholder::has_value insteadof t_base_return_value;
+  }
+
+
+  /**
+   * Class constructor.
+   */
+  public function __construct() {
+    parent::__construct();
+
+    $this->assigned = FALSE;
+    $this->id       = NULL;
+    $this->prefix   = NULL;
+  }
+
+  /**
+   * Class destructor.
+   */
+  public function __destruct() {
+    unset($this->assigned);
+    unset($this->id);
+    unset($this->pefix);
+
+    parent::__destruct();
+  }
+
+  /**
+   * @see: t_base_return_value::p_s_new()
+   */
+  public static function s_new($value) {
+    return self::p_s_new($value, __CLASS__);
+  }
+
+  /**
+   * @see: t_base_return_value::p_s_value()
+   */
+  public static function s_value($return) {
+    return self::p_s_value($return, __CLASS__);
+  }
+
+  /**
+   * @see: t_base_return_value_exact::p_s_value_exact()
+   */
+  public static function s_value_exact($return) {
+    return self::p_s_value_exact($return, __CLASS__, '');
+  }
+
+  /**
+   * Custom override of set_value for assigning a bool value.
+   *
+   * @see: t_base_return_value::set_value()
+   */
+  public function set_data($value) {
+    if (!is_bool($value)) {
+      return FALSE;
+    }
+
+    $this->value = $value;
+    $this->assigned = TRUE;
+    return TRUE;
+  }
+}
diff --git a/common/database/classes/database_query_placeholder_float.php b/common/database/classes/database_query_placeholder_float.php
new file mode 100644 (file)
index 0000000..c911296
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+/**
+ * @file
+ * Provides a class for specific Postgesql query placeholder generation.
+ */
+namespace n_koopa;
+
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+
+require_once('common/database/interfaces/database_query_placeholder.php');
+
+require_once('common/database/traits/database_query_placeholder.php');
+
+
+/**
+ * The class for managing an float query placeholder.
+ */
+class c_database_query_placeholder_float extends c_base_return_float implements i_database_query_placeholder {
+  use t_database_placeholder {
+    t_database_placeholder::has_value insteadof t_base_return_value;
+  }
+
+
+  /**
+   * Class constructor.
+   */
+  public function __construct() {
+    parent::__construct();
+
+    $this->assigned = FALSE;
+    $this->id       = NULL;
+    $this->prefix   = NULL;
+  }
+
+  /**
+   * Class destructor.
+   */
+  public function __destruct() {
+    unset($this->assigned);
+    unset($this->id);
+    unset($this->pefix);
+
+    parent::__destruct();
+  }
+
+  /**
+   * @see: t_base_return_value::p_s_new()
+   */
+  public static function s_new($value) {
+    return self::p_s_new($value, __CLASS__);
+  }
+
+  /**
+   * @see: t_base_return_value::p_s_value()
+   */
+  public static function s_value($return) {
+    return self::p_s_value($return, __CLASS__);
+  }
+
+  /**
+   * @see: t_base_return_value_exact::p_s_value_exact()
+   */
+  public static function s_value_exact($return) {
+    return self::p_s_value_exact($return, __CLASS__, '');
+  }
+
+  /**
+   * Custom override of set_value for assigning a float value.
+   *
+   * @see: t_base_return_value::set_value()
+   */
+  public function set_value($value) {
+    if (!is_float($value)) {
+      return FALSE;
+    }
+
+    $this->value = $value;
+    $this->assigned = TRUE;
+    return TRUE;
+  }
+}
diff --git a/common/database/classes/database_query_placeholder_int.php b/common/database/classes/database_query_placeholder_int.php
new file mode 100644 (file)
index 0000000..a54242d
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+/**
+ * @file
+ * Provides a class for specific Postgesql query placeholder generation.
+ */
+namespace n_koopa;
+
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+
+require_once('common/database/interfaces/database_query_placeholder.php');
+
+require_once('common/database/traits/database_query_placeholder.php');
+
+
+/**
+ * The class for managing an int query placeholder.
+ */
+class c_database_query_placeholder_int extends c_base_return_int implements i_database_query_placeholder {
+  use t_database_placeholder {
+    t_database_placeholder::has_value insteadof t_base_return_value;
+  }
+
+
+  /**
+   * Class constructor.
+   */
+  public function __construct() {
+    parent::__construct();
+
+    $this->assigned = FALSE;
+    $this->id       = NULL;
+    $this->prefix   = NULL;
+  }
+
+  /**
+   * Class destructor.
+   */
+  public function __destruct() {
+    unset($this->assigned);
+    unset($this->id);
+    unset($this->pefix);
+
+    parent::__destruct();
+  }
+
+  /**
+   * @see: t_base_return_value::p_s_new()
+   */
+  public static function s_new($value) {
+    return self::p_s_new($value, __CLASS__);
+  }
+
+  /**
+   * @see: t_base_return_value::p_s_value()
+   */
+  public static function s_value($return) {
+    return self::p_s_value($return, __CLASS__);
+  }
+
+  /**
+   * @see: t_base_return_value_exact::p_s_value_exact()
+   */
+  public static function s_value_exact($return) {
+    return self::p_s_value_exact($return, __CLASS__, '');
+  }
+
+  /**
+   * Custom override of set_value for assigning an int value.
+   *
+   * @see: t_base_return_value::set_value()
+   */
+  public function set_data($value) {
+    if (!is_int($value)) {
+      return FALSE;
+    }
+
+    $this->value = $value;
+    $this->assigned = TRUE;
+    return TRUE;
+  }
+}
diff --git a/common/database/classes/database_query_placeholder_null.php b/common/database/classes/database_query_placeholder_null.php
new file mode 100644 (file)
index 0000000..e6e979e
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+/**
+ * @file
+ * Provides a class for specific Postgesql query placeholder generation.
+ */
+namespace n_koopa;
+
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+
+require_once('common/database/interfaces/database_query_placeholder.php');
+
+require_once('common/database/traits/database_query_placeholder.php');
+
+
+/**
+ * The class for managing an null query placeholder.
+ */
+class c_database_query_placeholder_null extends c_base_return_null implements i_database_query_placeholder {
+  use t_database_placeholder {
+    t_database_placeholder::has_value insteadof t_base_return_value;
+  }
+
+
+  /**
+   * Class constructor.
+   */
+  public function __construct() {
+    parent::__construct();
+
+    $this->assigned = FALSE;
+    $this->id       = NULL;
+    $this->prefix   = NULL;
+  }
+
+  /**
+   * Class destructor.
+   */
+  public function __destruct() {
+    unset($this->assigned);
+    unset($this->id);
+    unset($this->pefix);
+
+    parent::__destruct();
+  }
+
+  /**
+   * @see: t_base_return_value::p_s_new()
+   */
+  public static function s_new($value) {
+    return self::p_s_new($value, __CLASS__);
+  }
+
+  /**
+   * @see: t_base_return_value::p_s_value()
+   */
+  public static function s_value($return) {
+    return self::p_s_value($return, __CLASS__);
+  }
+
+  /**
+   * @see: t_base_return_value_exact::p_s_value_exact()
+   */
+  public static function s_value_exact($return) {
+    return self::p_s_value_exact($return, __CLASS__, '');
+  }
+
+  /**
+   * Custom override of set_value for assigning a null value.
+   *
+   * @see: t_base_return_value::set_value()
+   */
+  public function set_data($value) {
+    if (!is_null($value)) {
+      return FALSE;
+    }
+
+    $this->value = NULL;
+    $this->assigned = TRUE;
+    return TRUE;
+  }
+}
diff --git a/common/database/classes/database_query_placeholder_string.php b/common/database/classes/database_query_placeholder_string.php
new file mode 100644 (file)
index 0000000..d1a5013
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+/**
+ * @file
+ * Provides a class for specific Postgesql query placeholder generation.
+ */
+namespace n_koopa;
+
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+
+require_once('common/database/interfaces/database_query_placeholder.php');
+
+require_once('common/database/traits/database_query_placeholder.php');
+
+
+/**
+ * The class for managing an string query placeholder.
+ */
+class c_database_query_placeholder_string extends c_base_return_string implements i_database_query_placeholder {
+  use t_database_placeholder {
+    t_database_placeholder::has_value insteadof t_base_return_value;
+  }
+
+
+  /**
+   * Class constructor.
+   */
+  public function __construct() {
+    parent::__construct();
+
+    $this->assigned = FALSE;
+    $this->id       = NULL;
+    $this->prefix   = NULL;
+  }
+
+  /**
+   * Class destructor.
+   */
+  public function __destruct() {
+    unset($this->assigned);
+    unset($this->id);
+    unset($this->pefix);
+
+    parent::__destruct();
+  }
+
+  /**
+   * @see: t_base_return_value::p_s_new()
+   */
+  public static function s_new($value) {
+    return self::p_s_new($value, __CLASS__);
+  }
+
+  /**
+   * @see: t_base_return_value::p_s_value()
+   */
+  public static function s_value($return) {
+    return self::p_s_value($return, __CLASS__);
+  }
+
+  /**
+   * @see: t_base_return_value_exact::p_s_value_exact()
+   */
+  public static function s_value_exact($return) {
+    return self::p_s_value_exact($return, __CLASS__, '');
+  }
+
+  /**
+   * Custom override of set_value for assigning a string value.
+   *
+   * @see: t_base_return_value::set_value()
+   */
+  public function set_data($value) {
+    if (!is_string($value)) {
+      return FALSE;
+    }
+
+    $this->data = $value;
+    $this->assigned = TRUE;
+    return TRUE;
+  }
+}
diff --git a/common/database/enumerations/database_operand.php b/common/database/enumerations/database_operand.php
new file mode 100644 (file)
index 0000000..ca7a73d
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+/**
+ * @file
+ * Provides enumeration classes for managing codes used for generating specific Postgesql Queries.
+ *
+ * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
+ */
+namespace n_koopa;
+
+/**
+ * Codes associated with operator type and related queries.
+ */
+class e_database_operand {
+  public const NONE = 0;
+}
diff --git a/common/database/enumerations/database_set_operator.php b/common/database/enumerations/database_set_operator.php
new file mode 100644 (file)
index 0000000..344fea1
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+/**
+ * @file
+ * Provides enumeration classes for managing codes used for generating specific Postgesql Queries.
+ *
+ * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
+ */
+namespace n_koopa;
+
+/**
+ * Codes associated with (operator) SET and related queries.
+ */
+class e_database_set_operator {
+  public const NONE     = 0;
+  public const JOIN     = 1;
+  public const RESTRICT = 2;
+}
diff --git a/common/database/interfaces/database_query_parameter.php b/common/database/interfaces/database_query_parameter.php
deleted file mode 100644 (file)
index 02591d2..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-/**
- * @file
- * Provides interfaces for specific Postgesql Queries parameters.
- *
- * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
- */
-namespace n_koopa;
-
-/**
- * An interface for passing query parameters to a query for use by PDO or similar.
- *
- * This is defined as a way to achieve multiple inheritance for the purposes of class type detection.
- */
-interface i_database_query_parameter {
-
-  /**
-   * @see: c_base_return::s_new().
-   */
-  public static function s_new($value);
-
-  /**
-   * @see: t_base_return_value::s_value()
-   */
-  public static function s_value($return);
-
-  /**
-   * @see: t_base_return_value_exact::s_value_exact()
-   */
-  public static function s_value_exact($return);
-
-  /**
-   * @see: c_base_return::has_value()
-   */
-  public function set_value($value);
-
-  /**
-   * @see: c_base_return::get_value()
-   */
-  public function get_value();
-
-  /**
-   * @see: c_base_return::get_value_exact()
-   */
-  public function get_value_exact();
-
-  /**
-   * @see: c_base_return::has_value()
-   */
-  public function has_value();
-}
diff --git a/common/database/interfaces/database_query_placeholder.php b/common/database/interfaces/database_query_placeholder.php
new file mode 100644 (file)
index 0000000..51e0b45
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+/**
+ * @file
+ * Provides interfaces for specific Postgesql query parameter placeholders.
+ *
+ * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
+ */
+namespace n_koopa;
+
+/**
+ * An interface for passing query parameter placeholders to a query for use by PDO or similar.
+ *
+ * The implementing class is expected and assumed to be of type c_base_return_value.
+ * The get_value(), set_value(), and has_value() method should represent this.
+ */
+interface i_database_query_placeholder {
+
+  /**
+   * Reset all query values in this class.
+   *
+   * @return c_base_return_status
+   *   TRUE on success, FALSE otherwise.
+   *   FALSE with the error bit set is returned on error.
+   */
+  public function do_reset();
+
+  /**
+   * Return the value.
+   *
+   * @return $value
+   *   Always returns value represented by this class.
+   */
+  public function get_value();
+
+  /**
+   * Gets the id used for generating the placeholder name.
+   *
+   * @return c_base_return_id|c_base_return_null
+   *   A value is returned on success.
+   *   NULL is returned if not assigned.
+   *   NULL with the error bit set is returned on error.
+   */
+  public function get_id();
+
+  /**
+   * Gets a placeholder name, generated from the prefix and id.
+   *
+   * @return c_base_return_string|c_base_return_null
+   *   A value is returned on success.
+   *   NULL is returned if not assigned.
+   *   NULL with the error bit set is returned on error.
+   */
+  public function get_name();
+
+  /**
+   * Gets the prefix used for generating the placeholder name.
+   *
+   * @return c_base_return_string|c_base_return_null
+   *   A value is returned on success.
+   *   NULL with the error bit set is returned on error.
+   */
+  public function get_placeholder();
+
+   /**
+   * Assign the placeholder value.
+   *
+   * @param $value
+   *   The data to assign.
+   *   The allowed data type is specific to implementing classes.
+   *   Set to NULL to assign a value of NULL to the data.
+   *   (NULL does not unassign this and is considered data.)
+   *
+   * @return bool
+   *   TRUE on success, FALSE otherwise.
+   */
+  public function set_value($value);
+
+  /**
+   * Assign the placeholder name id.
+   *
+   * @param int $id
+   *   The id to use for generating the placeholder name.
+   *
+   * @return c_base_return_status
+   *   TRUE on success, FALSE otherwise.
+   *   FALSE with the error bit set is returned on error.
+   */
+  public function set_id($id);
+
+  /**
+   * Assign the placeholder name prefix.
+   *
+   * @param string $prefix
+   *   The prefix to use for generating the placeholder name.
+   *
+   * @return c_base_return_status
+   *   TRUE on success, FALSE otherwise.
+   *   FALSE with the error bit set is returned on error.
+   */
+  public function set_prefix($prefix);
+}
index 11664506752392882469f1fe42ae3cce1e8275c9..8732dd630b459033a99908846fb017629c3476bf 100644 (file)
@@ -3,7 +3,9 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
+ * These traits are associated with actions
+ *
+ * @fixme: redesign/rewrite/replace this.
  *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
index 117d51e8b5bb9f2b864ee14c80eca23b814df8a1..061cb310d1e4ae34876e00434fad65d79b59099c 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -59,7 +57,13 @@ trait t_database_add_user {
       $this->add_user['type'] = $name;
     }
     else {
-      $this->add_user['names'][] = $name;
+      $placeholder = $this->add_placeholder($name);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $this->add_user['names'][] = $placeholder;
+      unset($placeholder);
     }
 
     return new c_base_return_true();
@@ -78,7 +82,7 @@ trait t_database_add_user {
       return new c_base_return_null();
     }
 
-    if (is_array($this->add_use)) {
+    if (is_array($this->add_user)) {
         return c_base_return_array::s_new($this->add_user);
     }
 
@@ -104,7 +108,7 @@ trait t_database_add_user {
       else if ($name === e_database_user::SESSION) {
         $values[] = c_database_string::SESSION;
       }
-      else if (is_string($name)) {
+      else {
         $values[] = $name;
       }
     }
index d2b431dd2c80473c2ab104767c12b918ac1be085..177c674d74514eeaaaf498cf3af3b4b42a735b9a 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with argument_type.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -69,11 +67,24 @@ trait t_database_argument_type {
       $this->argument_type = [];
     }
 
+    $placeholder_type = $this->add_placeholder($argument_type);
+    if ($placeholder_type->has_error()) {
+      return c_base_return_error::s_false($placeholder_type->get_error());
+    }
+
+    $placeholder_name = $this->add_placeholder($argument_name);
+    if ($placeholder_name->has_error()) {
+      unset($placeholder_type);
+      return c_base_return_error::s_false($placeholder_name->get_error());
+    }
+
     $this->argument_type[] = [
-      'type' => $argument_type,
-      'name' => $argument_name,
+      'type' => $placeholder_type,
+      'name' => $placeholder_name,
       'mode' => $argument_mode,
     ];
+    unset($placeholder_type);
+    unset($placeholder_name);
 
     return new c_base_return_true();
   }
@@ -86,8 +97,9 @@ trait t_database_argument_type {
    *   When NULL, all argument type are returned.
    *
    * @return c_base_return_array|c_base_return_null
-   *   A code representing the argument_type on success.
-   *   NULL is returned if not set (argument_type tablespace is not to be used).
+   *   An array representing the argument type at the $index.
+   *   An array representing all argument types when $index is NULL.
+   *   NULL is returned if not set (argument type tablespace is not to be used).
    *   NULL with the error bit set is returned on error.
    */
   public function get_argument_type($index = NULL) {
@@ -99,7 +111,7 @@ trait t_database_argument_type {
       return c_base_return_array::s_new($this->argument_type);
     }
     else if (isset($this->argument_type[$index]) && is_array($this->argument_type[$index])) {
-      return c_base_return_int::s_new($this->argument_type[$index]);
+      return c_base_return_array::s_new($this->argument_type[$index]);
     }
     else {
       $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'argument_type', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
index da059312488e7ba985b67f3109ac8f76a41fbac4..e99bf5dceff6f81cceac9af106308347fa496d8c 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with cascade.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
diff --git a/common/database/traits/database_cluster_on.php b/common/database/traits/database_cluster_on.php
new file mode 100644 (file)
index 0000000..e1b4c2e
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+/**
+ * @file
+ * Provides traits for specific Postgesql Queries.
+ *
+ * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
+ */
+namespace n_koopa;
+
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+
+/**
+ * Provide the sql NAME functionality.
+ */
+trait t_database_cluster_on {
+  protected $cluster_on;
+
+  /**
+   * Set the OID settings.
+   *
+   * @param string|null $index_name
+   *   The index name to use.
+   *   Set to NULL to disable.
+   *
+   * @return c_base_return_status
+   *   TRUE on success, FALSE otherwise.
+   *   FALSE with the error bit set is returned on error.
+   */
+  public function set_cluster_on($index_name) {
+    if (is_null($index_name)) {
+      $this->cluster_on = NULL;
+      return new c_base_return_true();
+    }
+
+    if (is_string($index_name)) {
+      $placeholder = $this->add_placeholder($index_name);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $this->cluster_on = $placeholder;
+      unset($placeholder);
+
+      return new c_base_return_true();
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'index_name', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+    return c_base_return_error::s_false($error);
+  }
+
+  /**
+   * Get the currently assigned index name.
+   *
+   * @return i_database_query_placeholder|c_base_return_null
+   *   A index name query placeholder on success.
+   *   NULL is returned if not set.
+   *   NULL with the error bit set is returned on error.
+   */
+  public function get_cluster_on() {
+    if (is_null($this->cluster_on)) {
+      return new c_base_return_null();
+    }
+
+    if (isset($this->cluster_on)) {
+      return clone($this->cluster_on);
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'cluster_on', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    return c_base_return_error::s_null($error);
+  }
+
+  /**
+   * Perform the common build process for this trait.
+   *
+   * As an internal trait method, the caller is expected to perform any appropriate validation.
+   *
+   * @return string|null
+   *   A string is returned on success.
+   *   NULL is returned if there is nothing to process or there is an error.
+   */
+  protected function p_do_build_cluster_on() {
+    return strval($this->cluster_on);
+  }
+}
index 53a3da7da8afa2a89d591ae57d5609cf40256e34..ce7dcdc3d197358610ed4b63ad48c08ed280c666 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with COLUMN_RESET attribute_option.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -52,14 +50,21 @@ trait t_database_column_reset {
       case e_database_attribute_option::N_DISTINCT:
       case e_database_attribute_option::N_DISTINCT_INHERITED:
         break;
+      case NULL:
+        break;
       default:
         $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'attribute_option', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
         return c_base_return_error::s_false($error);
     }
 
     if (is_string($name)) {
+      $placeholder = $this->add_placeholder($name);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
       if (is_array($this->column_reset)) {
-        $this->column_reset['name'] = $name;
+        $this->column_reset['name'] = $placeholder;
       }
       else {
         $this->column_reset = [
@@ -68,8 +73,9 @@ trait t_database_column_reset {
         ];
       }
     }
+    unset($placeholder);
 
-    if (!is_null($attribute_option)) {
+    if (is_int($attribute_option)) {
       $this->column_reset['values'][] = $attribute_option;
     }
 
@@ -103,7 +109,7 @@ trait t_database_column_reset {
         return c_base_return_int::s_new($this->column_reset['values'][$index]);
       }
 
-      $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'column_reset[index]', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'column_reset[values][index]', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
       return c_base_return_error::s_null($error);
     }
 
index dcf82b7b02a45cc41df102bc6ba8da13e306d8af..acb3ff0352cc4413980d860ea7e7048e5a4298ae 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with SET index attribute_option.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -66,8 +64,13 @@ trait t_database_column_set {
     }
 
     if (is_string($name)) {
+      $placeholder = $this->add_placeholder($name);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
       if (is_array($this->column_set)) {
-        $this->column_set['name'] = $name;
+        $this->column_set['name'] = $placeholder;
       }
       else {
         $this->column_set = [
@@ -76,6 +79,7 @@ trait t_database_column_set {
         ];
       }
     }
+    unset($placeholder);
 
     if (!is_null($attribute_option)) {
       $this->column_set['values'][] = [
index 490ed65b9d209c5a4be4356a2fc80ce56456c5dc..deb6ecd95e8187724f7d4429fecd8808b859b561 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -46,10 +44,16 @@ trait t_database_column_set_statistics {
     }
 
     if (is_int($column_set_statistics)) {
+      $placeholder = $this->add_placeholder($name);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
       $this->column_set_statistics = [
-        'name' => $name,
+        'name' => $placeholder,
         'value' => $value,
       ];
+      unset($placeholder);
 
       return new c_base_return_true();
     }
index 103d9217dcf8dcf8e4510711df3a80d43ea7e4c4..544499e5304518cccbd65175848b3a4a95562537 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with column set storage.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -56,10 +54,16 @@ trait t_database_column_set_storage {
         return c_base_return_error::s_false($error);
     }
 
+    $placeholder = $this->add_placeholder($name);
+    if ($placeholder->has_error()) {
+      return c_base_return_error::s_false($placeholder->get_error());
+    }
+
     $this->column_set_storage = [
       'type' => $type,
-      'name' => $name,
+      'name' => $placeholder,
     ];
+    unset($placeholder);
 
     return new c_base_return_true();
   }
@@ -95,7 +99,7 @@ trait t_database_column_set_storage {
    *   NULL is returned if there is nothing to process or there is an error.
    */
   protected function p_do_build_column_set_storage() {
-    $value = c_database_string::COLUMN . ' ' . $this->column_set_storage['name'] . ' ' . c_database_string::SET_STORAGE . ' ';
+    $value = c_database_string::COLUMN . ' ' . $this->column_set_storage['name']->get_name() . ' ' . c_database_string::SET_STORAGE . ' ';
     if ($this->column_set_storage['type'] === e_database_column_set_storage::EXTENDED) {
       return $value . c_database_string::EXTENDED;
     }
index 54789f0fd7bca3500c85d836dc9248a9a702157e..38e4ed8d5375ba77432166e9dc346a39ac1f67e8 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -55,12 +53,18 @@ trait t_database_constraint {
       return c_base_return_error::s_false($error);
     }
 
+    $placeholder = $this->add_placeholder($name);
+    if ($placeholder->has_error()) {
+      return c_base_return_error::s_false($placeholder->get_error());
+    }
+
     $constraint = [
-      'name' => $constraint_name,
+      'name' => $placeholder,
       'type' => $type,
       'exists_or_invalid' => NULL,
       'cascade' => NULL,
     ];
+    unset($placeholder);
 
     if ($type === e_database_constraint::ADD) {
       if (!is_bool($exists_or_invalid)) {
@@ -136,35 +140,29 @@ trait t_database_constraint {
   protected function p_do_build_constraint() {
     $value = NULL;
     if ($this->constraint['type'] === e_database_constraint::ADD) {
-      if (is_string($this->constraint['name'])) {
-        $value = c_database_string::ADD . ' ' . $this->constraint['name'];
+      $value = c_database_string::ADD . ' ' . $this->constraint['name']->get_name();
 
-        if ($this->constraint['exists_or_invalid']) {
-          $value .= ' ' . c_database_string::NOT_VALID;
-        }
+      if ($this->constraint['exists_or_invalid']) {
+        $value .= ' ' . c_database_string::NOT_VALID;
       }
     }
     else if ($this->constraint['type'] === e_database_constraint::DROP) {
-      if (is_string($this->constraint['name'])) {
-        $value = c_database_string::DROP_CONSTRAINT . ' ' . $this->constraint['name'];
-      }
+      $value = c_database_string::DROP_CONSTRAINT . ' ' . $this->constraint['name'];
     }
     else if ($this->constraint['type'] === e_database_constraint::VALIDATE) {
-      if (is_string($this->constraint['name'])) {
-        $value = c_database_string::VALIDATE_CONSTAINT;
+      $value = c_database_string::VALIDATE_CONSTAINT;
 
-        if ($this->constraint['exists_or_invalid']) {
-          $value .= ' ' . c_database_string::NOT_VALID;
-        }
+      if ($this->constraint['exists_or_invalid']) {
+        $value .= ' ' . c_database_string::NOT_VALID;
+      }
 
-        $value .=' ' . $this->constraint['name'];
+      $value .=' ' . $this->constraint['name'];
 
-        if ($this->constraint['cascade'] === e_database_cascade::CASCADE) {
-          $value .= ' ' . c_database_string::CASCADE;
-        }
-        else if ($this->constraint['cascade'] === e_database_cascade::RESTRICT) {
-          $value .= ' ' . c_database_string::RESTRICT;
-        }
+      if ($this->constraint['cascade'] === e_database_cascade::CASCADE) {
+        $value .= ' ' . c_database_string::CASCADE;
+      }
+      else if ($this->constraint['cascade'] === e_database_cascade::RESTRICT) {
+        $value .= ' ' . c_database_string::RESTRICT;
       }
     }
 
index 20449e63841a715645924c128123842f7ae1c745..334addfe75e608963dc6340d0c42c4202de79ceb 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -37,14 +35,19 @@ trait t_database_depends_on_extension {
       return c_base_return_error::s_false($error);
     }
 
-    $this->depends_on_extension = $depends_on_extension;
+    $placeholder = $this->add_placeholder($depends_on_extension);
+    if ($placeholder->has_error()) {
+      return c_base_return_error::s_false($placeholder->get_error());
+    }
+
+    $this->depends_on_extension = $placeholder;
     return new c_base_return_true();
   }
 
   /**
    * Get the currently assigned schema name to set to.
    *
-   * @return c_base_return_string|c_base_return_null
+   * @return i_database_query_placeholder|c_base_return_null
    *   An extension name on success.
    *   NULL is returned if not set (depends on extension is not to be used).
    *   NULL with the error bit set is returned on error.
@@ -54,8 +57,8 @@ trait t_database_depends_on_extension {
       return new c_base_return_null();
     }
 
-    if (is_string($this->depends_on_extension)) {
-      return c_base_return_string::s_new($this->depends_on_extension);
+    if (isset($this->depends_on_extension)) {
+      return clone($this->depends_on_extension);
     }
 
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'depends_on_extension', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
index 7610db4ec1a585792ce3a3467d80ec0042b5f188..3350fdfb3023d31c55dc83113a0151a9bb2ac0af 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -61,6 +59,11 @@ trait t_database_enable_trigger {
           $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'name', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
           return c_base_return_error::s_false($error);
         }
+
+        $use_name = $this->add_placeholder($name);
+        if ($use_name->has_error()) {
+          return c_base_return_error::s_false($placeholder->get_error());
+        }
         break;
       case e_database_enable_trigger::ALL:
         $use_name = c_database_string::ALL;
index 279acb4c9665643057100ed42bd4d06910f3d86c..eb9f933a3264231dfa1ec2b89aa12f956bf30a44 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -47,7 +45,13 @@ trait t_database_for_role {
       $this->for_role = [];
     }
 
-    $this->for_role[] = $for_role;
+    $placeholder = $this->add_placeholder($for_role);
+    if ($placeholder->has_error()) {
+      return c_base_return_error::s_false($placeholder->get_error());
+    }
+
+    $this->for_role[] = $placeholder;
+    unset($placeholder);
     return new c_base_return_true();
   }
 
@@ -58,9 +62,9 @@ trait t_database_for_role {
    *   (optional) Get the for role at the specified index.
    *   When NULL, all for role values are returned.
    *
-   * @return c_base_return_string|c_base_return_array|c_base_return_null
+   * @return i_database_query_placeholder|c_base_return_array|c_base_return_null
    *   An array of for roles or NULL if not defined.
-   *   A single for role is returned if $index is an integer.
+   *   A single for role query placeholder is returned if $index is an integer.
    *   NULL with the error bit set is returned on error.
    */
   public function get_for_role($index = NULL) {
@@ -74,8 +78,8 @@ trait t_database_for_role {
       }
     }
     else {
-      if (is_int($index) && array_key_exists($index, $this->for_role) && is_string($this->for_role[$index])) {
-        return c_base_return_string::s_new($this->for_role[$index]);
+      if (is_int($index) && array_key_exists($index, $this->for_role) && isset($this->for_role[$index])) {
+        return clone($this->for_role[$index]);
       }
 
       $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'for_role[index]', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
index 9a3b2625f2fc707a5c307f462ea4abee13db9e70..ab72f787db1455950de72a955fe213cb543dca11 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with function_action.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -103,8 +101,22 @@ trait t_database_function_action {
         return c_base_return_error::s_false($error);
       }
 
-      $action['parameter_1'] = $parameter_1;
-      $action['parameter_2'] = $parameter_2;
+      $placeholder = $this->add_placeholder($parameter_1);
+      if ($placeholder->has_error()) {
+        unset($action);
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $action['parameter_1'] = $placeholder;
+
+      $placeholder = $this->add_placeholder($parameter_2);
+      if ($placeholder->has_error()) {
+        unset($action);
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $action['parameter_2'] = $placeholder;
+      unset($placeholder);
     }
     else if ($function_action === e_database_function_action::SET_FROM || $function_action === e_database_function_action::RESET) {
       if (!is_string($parameter_1)) {
@@ -113,7 +125,14 @@ trait t_database_function_action {
         return c_base_return_error::s_false($error);
       }
 
-      $action['parameter_1'] = $parameter_1;
+      $placeholder = $this->add_placeholder($parameter_1);
+      if ($placeholder->has_error()) {
+        unset($action);
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $action['parameter_1'] = $placeholder;
+      unset($placeholder);
     }
 
     $this->function_action = $action;
index dfcc90ea90bf34accf94291178b4b8dade012985..84e713912efeb0d44a516b4bc1c095f5fac40a33 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
index 28eb80b34740e85537725e7887cfee25740f16b2..5904180969905830658463fb46839b2aa74223c9 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
index ec2c05bbbefb7e71b3bbfc15e7b8822011ac1206..2345eefe4c902baf3c9d767a652b305cdad63a6b 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -14,9 +12,10 @@ require_once('common/base/classes/base_return.php');
 
 require_once('common/database/classes/database_string.php');
 
+require_once('common/database/interfaces/database_query_placeholder.php');
+
 /**
  * Provide the sql GROUP BY functionality.
- * @fixme: doesn't group by support multiple arguments?
  */
 trait t_database_group_by {
   protected $group_by;
@@ -25,7 +24,7 @@ trait t_database_group_by {
    * Set the GROUP BY settings.
    *
    * @param string|null $group_by
-   *   The name to rename to.
+   *   The name to group by.
    *   Set to NULL to disable.
    *
    * @return c_base_return_status
@@ -38,30 +37,55 @@ trait t_database_group_by {
       return new c_base_return_true();
     }
 
-    if (is_string($group_by)) {
-      $this->group_by = $group_by;
-      return new c_base_return_true();
+    if (!is_string($group_by)) {
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'group_by', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+      return c_base_return_error::s_false($error);
     }
 
-    $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'group_by', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
-    return c_base_return_error::s_false($error);
+    if (!is_array($this->group_by)) {
+      $this->group_by = [];
+    }
+
+    $placeholder = $this->add_placeholder($group_by);
+    if ($placeholder->has_error()) {
+      return c_base_return_error::s_false($placeholder->get_error());
+    }
+
+    $this->group_by[] = $placeholder;
+    unset($placeholder);
+
+    return new c_base_return_true();
   }
 
   /**
-   * Get the currently assigned name to group by.
+   * Get the currently assigned for group by value.
+   *
+   * @param int|null $index
+   *   (optional) Get the group by at the specified index.
+   *   When NULL, all group by values are returned.
    *
-   * @return c_base_return_string|c_base_return_null
-   *   A name on success.
-   *   NULL is returned if not set (group by is not to be used).
+   * @return i_database_query_placeholder|c_base_return_array|c_base_return_null
+   *   An array of group by values or NULL if not defined.
+   *   A single group by query placeholder is returned if $index is an integer.
    *   NULL with the error bit set is returned on error.
    */
-  public function get_group_by() {
+  public function get_group_by($index = NULL) {
     if (is_null($this->group_by)) {
       return new c_base_return_null();
     }
 
-    if (is_string($this->group_by)) {
-      return c_base_return_string::s_new($this->group_by);
+    if (is_null($index)) {
+      if (is_array($this->group_by)) {
+        return c_base_return_array::s_new($this->group_by);
+      }
+    }
+    else {
+      if (is_int($index) && array_key_exists($index, $this->group_by) && isset($this->group_by[$index])) {
+        return clone($this->group_by[$index]);
+      }
+
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'group_by[index]', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+      return c_base_return_error::s_null($error);
     }
 
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'group_by', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
@@ -78,6 +102,6 @@ trait t_database_group_by {
    *   NULL is returned if there is nothing to process or there is an error.
    */
   protected function p_do_build_group_by() {
-    return c_database_string::GROUP_BY . $this->group_by;
+    return c_database_string::GROUP_BY . implode(', ', $this->group_by);
   }
 }
index 0bd4b54c0fc303d7e615dec49a7447928fa4afcd..46fcca62dfcd0743f81eb767156df3c0daf581f4 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with handler.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -41,10 +39,17 @@ trait t_database_handler {
 
     if ($handler === e_database_handler::HANDLER) {
       if (is_string($handler_function)) {
+        $placeholder = $this->add_placeholder($handler_function);
+        if ($placeholder->has_error()) {
+          unset($action);
+          return c_base_return_error::s_false($placeholder->get_error());
+        }
+
         $this->handler = [
           'type' => $handler,
-          'name' => $handler_function,
+          'name' => $placeholder,
         ];
+        unset($placeholder);
 
         return new c_base_return_true();
       }
index edf041ec6b917c0a6d562bccbc57cbf7855716ae..bfd899a9c5c5a2641dfa9bb1d865dc485a1edeeb 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -43,7 +41,14 @@ trait t_database_in_schema {
         $this->in_schema = [];
       }
 
-      $this->in_schema[] = $schema_name;
+      $placeholder = $this->add_placeholder($schema_name);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $this->in_schema[] = $placeholder;
+      unset($placeholder);
+
       return new c_base_return_true();
     }
 
@@ -58,9 +63,9 @@ trait t_database_in_schema {
    *   (optional) Get the schema name at the specified index.
    *   When NULL, all schema names are returned.
    *
-   * @return c_base_return_string|c_base_return_array|c_base_return_null
+   * @return i_database_query_placeholder|c_base_return_array|c_base_return_null
    *   An array of schema names or NULL if not defined.
-   *   A single schema name is returned if $index is an integer.
+   *   A single schema name query placeholder is returned if $index is an integer.
    *   NULL with the error bit set is returned on error.
    */
   public function get_in_schema($index = NULL) {
@@ -74,8 +79,8 @@ trait t_database_in_schema {
       }
     }
     else {
-      if (is_int($index) && array_key_exists($index, $this->in_schema) && is_string($this->in_schema[$index])) {
-        return c_base_return_string::s_new($this->in_schema[$index]);
+      if (is_int($index) && array_key_exists($index, $this->in_schema) && isset($this->in_schema[$index])) {
+        return clone($this->in_schema[$index]);
       }
 
       $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'in_schema[index]', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
index ce2370c128dacd2b9c19e69bf3239e789b2b9111..b6a0d4a78aee03d28c707ac9fc38873f5d1e99d2 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -45,10 +43,16 @@ trait t_database_inherit {
       return c_base_return_error::s_false($error);
     }
 
+    $placeholder = $this->add_placeholder($name);
+    if ($placeholder->has_error()) {
+      return c_base_return_error::s_false($placeholder->get_error());
+    }
+
     $this->inherit = [
-      'name' => $name,
+      'name' => $placeholder,
       'inherit' => $inherit,
     ];
+    unset($placeholder);
 
     return new c_base_return_true();
   }
index 401f59a338ed570f1161f12d07821f15cd968614..dc3fa7793e7dd6362b86048a5a2f3f5be2b2eaa8 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -36,7 +34,14 @@ trait t_database_name {
     }
 
     if (is_string($name)) {
-      $this->name = $name;
+      $placeholder = $this->add_placeholder($name);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $this->name = $placeholder;
+      unset($placeholder);
+
       return new c_base_return_true();
     }
 
@@ -47,8 +52,8 @@ trait t_database_name {
   /**
    * Get the currently assigned name.
    *
-   * @return c_base_return_string|c_base_return_null
-   *   A name on success.
+   * @return i_database_query_placeholder|c_base_return_null
+   *   A name query placeholder on success.
    *   NULL is returned if not set.
    *   NULL with the error bit set is returned on error.
    */
@@ -57,8 +62,8 @@ trait t_database_name {
       return new c_base_return_null();
     }
 
-    if (is_string($this->name)) {
-      return c_base_return_string::s_new($this->name);
+    if (isset($this->name)) {
+      return clone($this->name);
     }
 
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'name', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
@@ -75,6 +80,6 @@ trait t_database_name {
    *   NULL is returned if there is nothing to process or there is an error.
    */
   protected function p_do_build_name() {
-    return $this->name;
+    return strval($this->name);
   }
 }
index 666230d279204b454251d850e6712039dc7bbb3a..2046f0e3a5d72ed92c3b8e22e3d761eef53b4da7 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -38,13 +36,13 @@ trait t_database_no_wait {
       return new c_base_return_true();
     }
 
-    if (!is_bool($no_wait)) {
-      $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'no_wait', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
-      return c_base_return_error::s_false($error);
+    if (is_bool($no_wait)) {
+      $this->no_wait = $no_wait;
+      return new c_base_return_true();
     }
 
-    $this->no_wait = $no_wait;
-    return new c_base_return_true();
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'no_wait', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+    return c_base_return_error::s_false($error);
   }
 
   /**
index c5c862edd256dc08edd5201a36b35b4fc80b38a8..a98db9ee7248320f3b9c46714a8004888c9a01f6 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -36,7 +34,88 @@ trait t_database_oid {
     }
 
     if (is_string($oid)) {
-      $this->oid = $oid;
+      $placeholder = $this->add_placeholder($oid);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $this->oid = $placeholder;
+      unset($placeholder);
+
+      return new c_base_return_true();
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'oid', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+    return c_base_return_error::s_false($error);
+  }
+
+  /**
+   * Get the currently assigned oid.
+   *
+   * @return i_database_query_placeholder|c_base_return_null
+   *   A oid query placeholder on success.
+   *   NULL is returned if not set.
+   *   NULL with the error bit set is returned on error.
+   */
+  public function get_oid() {
+    if (is_null($this->oid)) {
+      return new c_base_return_null();
+    }
+
+    if (isset($this->oid)) {
+      return clone($this->oid);
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'oid', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    return c_base_return_error::s_null($error);
+  }
+
+  /**
+   * Perform the common build process for this trait.
+   *
+   * As an internal trait method, the caller is expected to perform any appropriate validation.
+   *
+   * @return string|null
+   *   A string is returned on success.
+   *   NULL is returned if there is nothing to process or there is an error.
+   */
+  protected function p_do_build_oid() {
+    return strval($this->oid);
+  }
+}
+
+/**
+ * Provide the sql NAME functionality.
+ */
+trait t_database_oid {
+  protected $oid;
+
+  /**
+   * Set the OID settings.
+   *
+   * @param string|null $oid
+   *   The oid to use.
+   *   Set to NULL to disable.
+   *
+   * @return c_base_return_status
+   *   TRUE on success, FALSE otherwise.
+   *   FALSE with the error bit set is returned on error.
+   */
+  public function set_oid($oid) {
+    if (is_null($oid)) {
+      $this->oid = NULL;
+      return new c_base_return_true();
+    }
+
+    if (is_string($oid)) {
+      $placeholder = $this->add_placeholder($oid);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $this->oid = $placeholder;
+      unset($placeholder);
+
       return new c_base_return_true();
     }
 
@@ -47,8 +126,8 @@ trait t_database_oid {
   /**
    * Get the currently assigned oid.
    *
-   * @return c_base_return_string|c_base_return_null
-   *   A oid on success.
+   * @return i_database_query_placeholder|c_base_return_null
+   *   A oid query placeholder on success.
    *   NULL is returned if not set.
    *   NULL with the error bit set is returned on error.
    */
@@ -57,8 +136,8 @@ trait t_database_oid {
       return new c_base_return_null();
     }
 
-    if (is_string($this->oid)) {
-      return c_base_return_string::s_new($this->oid);
+    if (isset($this->oid)) {
+      return clone($this->oid);
     }
 
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'oid', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
@@ -75,6 +154,6 @@ trait t_database_oid {
    *   NULL is returned if there is nothing to process or there is an error.
    */
   protected function p_do_build_oid() {
-    return $this->oid;
+    return strval($this->oid);
   }
 }
index 37f53601ed7bb502884c5ccda065e2f0774b29f8..5172baba151f290817d923a1f0c95a36631ecf4b 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with on.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
diff --git a/common/database/traits/database_operand_left.php b/common/database/traits/database_operand_left.php
new file mode 100644 (file)
index 0000000..ce76d72
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+/**
+ * @file
+ * Provides traits for specific Postgesql Queries.
+ *
+ * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
+ */
+namespace n_koopa;
+
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+
+require_once('common/database/classes/database_string.php');
+
+require_once('common/database/enumerations/database_operand.php');
+
+/**
+ * Provide the sql (left) operand functionality.
+ */
+trait t_database_operand_left {
+  protected $operand_left;
+
+  /**
+   * Set the (left) operand settings.
+   *
+   * @param int|string|null $type
+   *   The operand to assign.
+   *   Can be set to e_database_operand::NONE.
+   *   Set to NULL to disable.
+   *
+   * @return c_base_return_status
+   *   TRUE on success, FALSE otherwise.
+   *   FALSE with the error bit set is returned on error.
+   */
+  public function set_operand_left($type) {
+    if (is_null($type)) {
+      $this->operand_left = NULL;
+      return new c_base_return_true();
+    }
+
+    if (is_int($type)) {
+      if ($type !== e_database_operand::NONE) {
+        $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'type', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+        return c_base_return_error::s_false($error);
+      }
+
+      $this->operand_left = e_database_operand::NONE;
+      return new c_base_return_true();
+    }
+    else if (is_string($type)) {
+      $placeholder = $this->add_placeholder($type);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $this->operand_left = $placeholder;
+      unset($placeholder);
+
+      return new c_base_return_true();
+    }
+
+    return new c_base_return_false();
+  }
+
+  /**
+   * Get the currently assigned operand_left settings.
+   *
+   * @return i_database_query_placeholder|c_base_return_int|c_base_return_null
+   *   The operand int or query placeholder on success.
+   *   NULL is returned if not set (operand left is not to be used).
+   *   NULL with the error bit set is returned on error.
+   */
+  public function get_operand_left() {
+    if (is_null($this->operand_left)) {
+      return new c_base_return_null();
+    }
+
+    if (is_int($this->operand_left)) {
+      return c_base_return_int::s_new($this->operand_left);
+    }
+    else if (isset($this->operand_left)) {
+      return clone($this->operand_left);
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'operand_left', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    return c_base_return_error::s_null($error);
+  }
+
+  /**
+   * Perform the common build process for this trait.
+   *
+   * As an internal trait method, the caller is expected to perform any appropriate validation.
+   *
+   * @return string|null
+   *   A string is returned on success.
+   *   NULL is returned if there is nothing to process or there is an error.
+   */
+  protected function p_do_build_operand_left() {
+    if ($this->operand_left === e_database_operand::NONE) {
+      return c_database_string::NONE;
+    }
+
+    return strval($this->operand_left);
+  }
+}
diff --git a/common/database/traits/database_operand_right.php b/common/database/traits/database_operand_right.php
new file mode 100644 (file)
index 0000000..c5619b9
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+/**
+ * @file
+ * Provides traits for specific Postgesql Queries.
+ *
+ * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
+ */
+namespace n_koopa;
+
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+
+require_once('common/database/classes/database_string.php');
+
+require_once('common/database/enumerations/database_operand.php');
+
+/**
+ * Provide the sql (right) operand functionality.
+ */
+trait t_database_operand_right {
+  protected $operand_right;
+
+  /**
+   * Set the (right) operand settings.
+   *
+   * @param int|string|null $type
+   *   The operand to assign.
+   *   Can be set to e_database_operand::NONE.
+   *   Set to NULL to disable.
+   *
+   * @return c_base_return_status
+   *   TRUE on success, FALSE otherwise.
+   *   FALSE with the error bit set is returned on error.
+   */
+  public function set_operand_right($type) {
+    if (is_null($type)) {
+      $this->operand_right = NULL;
+      return new c_base_return_true();
+    }
+
+    if (is_int($type)) {
+      if ($type !== e_database_operand::NONE) {
+        $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'type', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+        return c_base_return_error::s_false($error);
+      }
+
+      $this->operand_right = e_database_operand::NONE;
+      return new c_base_return_true();
+    }
+    else if (is_string($type)) {
+      $placeholder = $this->add_placeholder($type);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $this->operand_right = $placeholder;
+      unset($placeholder);
+
+      return new c_base_return_true();
+    }
+
+    return new c_base_return_false();
+  }
+
+  /**
+   * Get the currently assigned operand_right settings.
+   *
+   * @return i_database_query_placeholde|c_base_return_int|c_base_return_null
+   *   The operand int or query placeholder on success.
+   *   NULL is returned if not set (operand right is not to be used).
+   *   NULL with the error bit set is returned on error.
+   */
+  public function get_operand_right() {
+    if (is_null($this->operand_right)) {
+      return new c_base_return_null();
+    }
+
+    if (is_int($this->operand_right)) {
+      return c_base_return_int::s_new($this->operand_right);
+    }
+    else if (isset($this->operand_right)) {
+      return clone($this->operand_right);
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'operand_right', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    return c_base_return_error::s_null($error);
+  }
+
+  /**
+   * Perform the common build process for this trait.
+   *
+   * As an internal trait method, the caller is expected to perform any appropriate validation.
+   *
+   * @return string|null
+   *   A string is returned on success.
+   *   NULL is returned if there is nothing to process or there is an error.
+   */
+  protected function p_do_build_operand_right() {
+    if ($this->operand_right === e_database_operand::NONE) {
+      return c_database_string::NONE;
+    }
+
+    return strval($this->operand_right);
+  }
+}
index c3816ea6de2ab842bcd98cbb507cf038e423b9b0..ef936a9ee85ea93ef71524f2f834fa359b36d241 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -60,10 +58,16 @@ trait t_database_options {
       $this->options = [];
     }
 
+    $placeholder = $this->add_placeholder($value);
+    if ($placeholder->has_error()) {
+      return c_base_return_error::s_false($placeholder->get_error());
+    }
+
     $this->options[] = [
       'type' => $options_type,
-      'value' => $value,
+      'value' => $placeholder,
     ];
+    unset($placeholder);
 
     return new c_base_return_true();
   }
@@ -91,7 +95,7 @@ trait t_database_options {
       }
     }
     else {
-      if (is_int($index) && array_key_exists($index, $this->options) && is_arrray($this->options[$index])) {
+      if (is_int($index) && array_key_exists($index, $this->options) && is_array($this->options[$index])) {
         return c_base_return_array::s_new($this->options[$index]);
       }
 
index 80ee53ee248233f2ebe7526c37ea3e6e5ee38d87..523f55d97df558611ddcaaafacdaadcf6b7c0a62 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -16,16 +14,15 @@ require_once('common/database/classes/database_string.php');
 
 /**
  * Provide the sql ORDER BY functionality.
- * @fixme: doesn't order by accept multiple arguments?
  */
 trait t_database_order_by {
   protected $order_by;
 
   /**
-   * Set the ORDER BY settings.
+   * Set the GROUP BY settings.
    *
    * @param string|null $order_by
-   *   The name to rename to.
+   *   The name to group by.
    *   Set to NULL to disable.
    *
    * @return c_base_return_status
@@ -38,30 +35,55 @@ trait t_database_order_by {
       return new c_base_return_true();
     }
 
-    if (is_string($order_by)) {
-      $this->order_by = $order_by;
-      return new c_base_return_true();
+    if (!is_string($order_by)) {
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'order_by', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+      return c_base_return_error::s_false($error);
+    }
+
+    if (!is_array($this->order_by)) {
+      $this->order_by = [];
+    }
+
+    $placeholder = $this->add_placeholder($order_by);
+    if ($placeholder->has_error()) {
+      return c_base_return_error::s_false($placeholder->get_error());
     }
 
-    $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'order_by', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
-    return c_base_return_error::s_false($error);
+    $this->order_by[] = $placeholder;
+    unset($placeholder);
+
+    return new c_base_return_true();
   }
 
   /**
-   * Get the currently assigned name to order by.
+   * Get the currently assigned for group by value.
+   *
+   * @param int|null $index
+   *   (optional) Get the group by at the specified index.
+   *   When NULL, all group by values are returned.
    *
-   * @return c_base_return_string|c_base_return_null
-   *   A name on success.
-   *   NULL is returned if not set (order by to is not to be used).
+   * @return i_database_query_placeholder|c_base_return_array|c_base_return_null
+   *   An array of group by values or NULL if not defined.
+   *   A single group by query placeholder is returned if $index is an integer.
    *   NULL with the error bit set is returned on error.
    */
-  public function get_order_by() {
+  public function get_order_by($index = NULL) {
     if (is_null($this->order_by)) {
       return new c_base_return_null();
     }
 
-    if (is_string($this->order_by)) {
-      return c_base_return_string::s_new($this->order_by);
+    if (is_null($index)) {
+      if (is_array($this->order_by)) {
+        return c_base_return_array::s_new($this->order_by);
+      }
+    }
+    else {
+      if (is_int($index) && array_key_exists($index, $this->order_by) && isset($this->order_by[$index])) {
+        return clone($this->order_by[$index]);
+      }
+
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'order_by[index]', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+      return c_base_return_error::s_null($error);
     }
 
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'order_by', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
@@ -78,6 +100,6 @@ trait t_database_order_by {
    *   NULL is returned if there is nothing to process or there is an error.
    */
   protected function p_do_build_order_by() {
-    return c_database_string::ORDER_BY . ' ' . $this->order_by;
+    return c_database_string::ORDER_BY . ' ' . implode(', ', $this->order_by);
   }
 }
index b2dd05541d6a1996f93ca63b6e8595a02da9abe3..809a4ad7207de65e0f8e5b902dfdb0eb33c2fbe2 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -50,7 +48,13 @@ trait t_database_owned_by {
         $this->owned_by = [];
       }
 
-      $this->owned_by[] = $owned_by;
+      $placeholder = $this->add_placeholder($owned_by);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $this->owned_by[] = $placeholder;
+      unset($placeholder);
     }
 
     $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'owned_by', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
@@ -64,7 +68,7 @@ trait t_database_owned_by {
    *   (optional) Get the owned_by at the specified index.
    *   When NULL, all owned_by are returned.
    *
-   * @return c_base_return_int|c_base_return_string|c_base_return_array|c_base_return_null
+   * @return c_base_return_int|i_database_query_placeholder|c_base_return_array|c_base_return_null
    *   An array of owned_by or NULL if not defined.
    *   A single owned_by is returned if $index is an integer.
    *   NULL with the error bit set is returned on error.
@@ -87,8 +91,8 @@ trait t_database_owned_by {
         if (is_int($this->owned_by[$index])) {
           return c_base_return_int::s_new($this->owned_by[$index]);
         }
-        else if (is_string($this->owned_by[$index])) {
-          return c_base_return_string::s_new($this->owned_by[$index]);
+        else if (isset($this->owned_by[$index])) {
+          return clone($this->owned_by[$index]);
         }
       }
       else {
index 7d8770c0b12cf7569281ce5ea56226cd387ffcd5..20e7fddd3a8abdf5d0d09786523d30faeeeba9bf 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -54,10 +52,16 @@ trait t_database_owner_to {
         return c_base_return_error::s_false($error);
       }
 
+      $placeholder = $this->add_placeholder($user_name);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
       $this->owner_to = [
         'type' => $owner_to,
-        'value' => $user_name,
+        'value' => $placeholder,
       ];
+      unset($placeholder);
 
       return new c_base_return_true();
     }
diff --git a/common/database/traits/database_placeholder.php b/common/database/traits/database_placeholder.php
new file mode 100644 (file)
index 0000000..98e2f97
--- /dev/null
@@ -0,0 +1,110 @@
+<?php
+/**
+ * @file
+ * Provides traits for specific Postgesql Queries.
+ *
+ * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
+ */
+namespace n_koopa;
+
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+
+
+/**
+ * Provide the placeholder name functionality.
+ *
+ * This expects the implementing class to have $this->value assigned, which is assumed to be from t_base_return_value.
+ */
+trait t_database_placeholder {
+  private $assigned;
+  private $id;
+  private $prefix;
+
+
+  /**
+   * Implements do_reset().
+   */
+  public function do_reset() {
+    $this->assigned = FALSE;
+    $this->id = NULL;
+    $this->prefix = NULL;
+    $this->value = NULL;
+
+    return new c_base_return_true();
+  }
+
+  /**
+   * Implements get_id().
+   */
+  public function get_id() {
+    if (is_int($this->id)) {
+      return c_base_return_int::s_new($this->id);
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'id', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    return c_base_return_error::s_null($error);
+  }
+
+  /**
+   * Implements get_name().
+   */
+  public function get_name() {
+    if (!is_int($this->id)) {
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'id', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+      return c_base_return_error::s_null($error);
+    }
+
+    if (!is_string($this->prefix)) {
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'prefix', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+      return c_base_return_error::s_null($error);
+    }
+
+    return c_base_return_string::s_new($this->prefix . $this->id);
+  }
+
+  /**
+   * Implements get_prefix().
+   */
+  public function get_prefix() {
+    if (is_string($this->prefix)) {
+      return c_base_return_string::s_new($this->prefix);
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'prefix', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    return c_base_return_error::s_null($error);
+  }
+
+  /**
+   * Implements has_value().
+   */
+  public function has_value() {
+    return $this->assigned === TRUE;
+  }
+
+  /**
+   * Implements set_id().
+   */
+  public function set_id($id) {
+    if (!is_int($id)) {
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'id', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+      return c_base_return_error::s_false($error);
+    }
+
+    $this->id = $id;
+    return new c_base_return_true();
+  }
+
+  /**
+   * Implements set_prefix().
+   */
+  public function set_prefix($prefix) {
+    if (!is_string($prefix)) {
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'prefix', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+      return c_base_return_error::s_false($error);
+    }
+
+    $this->prefix = $prefix;
+    return new c_base_return_true();
+  }
+}
index 1908f021bf6c6c5716a074298ab44e3eaad229fe..1261782fba648df0377041e4102b125d6a4cdd44 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
index a6017db52f7652ceb39138c51972f05414bff3a9..07dac9e11e036e93ec6de7dce4ce3fa89cd9f98d 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
index eab1ca0e83d1452d2a14464dbfb741fd4f6d9f99..ec3aa41629097791529ba6aa0647fb89086c1567 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -49,10 +47,24 @@ trait t_database_rename_column {
       return c_base_return_error::s_false($error);
     }
 
+    $placeholder_from = $this->add_placeholder($from_name);
+    if ($placeholder_from->has_error()) {
+      return c_base_return_error::s_false($placeholder_from->get_error());
+    }
+
+    $placeholder_to = $this->add_placeholder($to_name);
+    if ($placeholder_to->has_error()) {
+      unset($placeholder_from);
+      return c_base_return_error::s_false($placeholder_to->get_error());
+    }
+
     $this->rename_column = [
-      'from' => $from_name,
-      'to' => $to_name,
+      'from' => $placeholder_from,
+      'to' => $placeholder_to,
     ];
+    unset($placeholder_from);
+    unset($placeholder_to);
+
     return new c_base_return_true();
   }
 
@@ -87,6 +99,6 @@ trait t_database_rename_column {
    *   NULL is returned if there is nothing to process or there is an error.
    */
   protected function p_do_build_rename_column() {
-    return c_database_string::RENAME_COLUMN . ' ' . $this->rename_column['from'] . ' ' . c_database_string::TO . $this->rename_column['to'];
+    return c_database_string::RENAME_COLUMN . ' ' . $this->rename_column['from'] . ' ' . c_database_string::TO . ' ' . $this->rename_column['to'];
   }
 }
index 009baabd7a891b95a6252757caa82147d0727192..9a145495c1dd5ce136b6d6be7892e71d4eaae0b6 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -37,15 +35,22 @@ trait t_database_rename_to {
       return c_base_return_error::s_false($error);
     }
 
-    $this->rename_to = $rename_to;
+    $placeholder = $this->add_placeholder($rename_to);
+    if ($placeholder->has_error()) {
+      return c_base_return_error::s_false($placeholder->get_error());
+    }
+
+    $this->rename_to = $placeholder;
+    unset($placeholder);
+
     return new c_base_return_true();
   }
 
   /**
    * Get the currently assigned name to rename to.
    *
-   * @return c_base_return_string|c_base_return_null
-   *   A name on success.
+   * @return i_database_query_placeholder|c_base_return_null
+   *   A name query placeholder.
    *   NULL is returned if not set (rename to is not to be used).
    *   NULL with the error bit set is returned on error.
    */
@@ -54,8 +59,8 @@ trait t_database_rename_to {
       return new c_base_return_null();
     }
 
-    if (is_string($this->rename_to)) {
-      return c_base_return_string::s_new($this->rename_to);
+    if (isset($this->rename_to)) {
+      return clone($this->rename_to);
     }
 
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'rename_to', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
index 6179936231cec487354c3d33102c31d48a79d903..985a90d4cc0384efcda9a6ad7279982f85267180 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with reset.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -48,16 +46,22 @@ trait t_database_reset {
       return c_base_return_error::s_false($error);
     }
 
-    if ($reset == e_database_reset::PARAMETER) {
+    if ($reset === e_database_reset::PARAMETER) {
       if (!is_null($parameter) || !is_string($parameter)) {
         $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'parameter', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
         return c_base_return_error::s_false($error);
       }
 
+      $placeholder = $this->add_placeholder($parameter);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
       $this->reset = [
         'type' => $reset,
-        'value' => $parameter,
+        'value' => $placeholder,
       ];
+      unset($placeholder);
 
       return new c_base_return_true();
     }
@@ -106,9 +110,7 @@ trait t_database_reset {
   protected function p_do_build_reset() {
     $value = NULL;
     if ($this->reset['type'] === e_database_reset::PARAMETER) {
-      if (is_string($this->reset['value'])) {
-        $value = c_database_string::RESET . ' ' . $this->reset['value'];
-      }
+      $value = c_database_string::RESET . ' ' . $this->reset['value'];
     }
     else if ($this->reset['type'] === e_database_reset::ALL) {
       $value = c_database_string::RESET . ' ' . c_database_string::ALL;
index 8dcfe5dee5b32d6d1f41416d60b422cfffb64b16..9144a2403624fdebeeb295c36e853bd5dc01a2f4 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with RESET storage_parameter.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
index 126f4b81e2e37ed6f175d68916c5abfb1ee16fa3..9c306e906b1244cb064c2a66acb78ddd5c1c080d 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
index b49f7759500087ebde66972bdc364f6115528e22..9fab20201b6cd8d18fd616c57af3a15108c32768 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -41,20 +39,30 @@ trait t_database_role_specification {
       return new c_base_return_true();
     }
 
-    if (!is_string($name) && $name !== e_database_role::CURRENT && $name !== e_database_role::SESSION) {
+    if (is_string($name)) {
+      $placeholder = $this->add_placeholder($name);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $this->role_specification = $placeholder;
+      unset($placeholder);
+    }
+    else if ($name !== e_database_role::CURRENT && $name !== e_database_role::SESSION) {
       $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'name', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
       return c_base_return_error::s_false($error);
+
+      $this->role_specification = $name;
     }
 
-    $this->role_specification = $name;
     return new c_base_return_true();
   }
 
   /**
    * Get the role specification.
    *
-   * @return c_base_return_int|c_base_return_string|c_base_return_null
-   *   A role name string or an integer representing either e_database_role::CURRENT or e_database_role::SESSION on success.
+   * @return c_base_return_int|i_database_query_placeholder|c_base_return_null
+   *   A role name query placeholder or an integer representing either e_database_role::CURRENT or e_database_role::SESSION on success.
    *   NULL is returned if not set.
    *   NULL with the error bit set is returned on error.
    */
@@ -63,12 +71,12 @@ trait t_database_role_specification {
       return new c_base_return_null();
     }
 
-    if (is_string($this->role_specification)) {
-      return c_base_return_array::s_new($this->role_specification);
-    }
-    else if ($this->role_specification === e_database_role::CURRENT || $this->role_specification === e_database_role::SESSION) {
+    if ($this->role_specification === e_database_role::CURRENT || $this->role_specification === e_database_role::SESSION) {
       return c_base_return_int::s_new($this->role_specification);
     }
+    else if (isset($this->role_specification)) {
+      return clone($this->role_specification);
+    }
 
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'role_specification', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
     return c_base_return_error::s_null($error);
@@ -95,6 +103,6 @@ trait t_database_role_specification {
       $value = c_database_string::SESSION;
     }
 
-    return $value;
+    return strval($value);
   }
 }
index 1c83d7cf2c300db8db3da359758ac5badd777d13..5aeee772c1701bbeb0fb8897ef08dd8744c44ee6 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with set.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -31,10 +29,11 @@ trait t_database_set {
    *   Set to NULL to disable.
    * @param string|null $parameter
    *   (optional) When non-NULL this is the configuration parameter.
-   *   When NULL, DEFAULT is used if applicablem otherwise this is ignored.
+   *   When NULL, this and $value are ignored.
+   *   Some values of $set may require this to be a non-NULL.
    * @param string|null $value
    *   (optional) When non-NULL this is the value associated with the parameter.
-   *   When NULL, this is ignored.
+   *   When NULL, DEFAULT is used, if applicable, otherwise this is ignored.
    *
    * @return c_base_return_status
    *   TRUE on success, FALSE otherwise.
@@ -52,7 +51,7 @@ trait t_database_set {
     }
 
     if ($set === e_database_set::TO || $set === e_database_set::EQUAL) {
-      if (!is_null($parameter) || !is_string($parameter)) {
+      if (!is_string($parameter)) {
         $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'parameter', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
         return c_base_return_error::s_false($error);
       }
@@ -62,12 +61,31 @@ trait t_database_set {
         return c_base_return_error::s_false($error);
       }
 
-      $this->set = [
+      $placeholder = $this->add_placeholder($parameter);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $set = [
         'type' => $set,
-        'parameter' => $parameter,
-        'value' => $value,
+        'parameter' => $placeholder,
+        'value' => NULL,
       ];
 
+      if (is_string($value)) {
+        $placeholder = $this->add_placeholder($value);
+        if ($placeholder->has_error()) {
+          unset($set);
+          return c_base_return_error::s_false($placeholder->get_error());
+        }
+
+        $set['value'] = $placeholder;
+        unset($placeholder);
+      }
+
+      $this->set = $set;
+      unset($set);
+
       return new c_base_return_true();
     }
     else if ($set == e_database_set::FROM_CURRENT) {
@@ -76,6 +94,7 @@ trait t_database_set {
         'parameter' => NULL,
         'value' => NULL,
       ];
+
       return new c_base_return_true();
     }
 
@@ -115,25 +134,25 @@ trait t_database_set {
   protected function p_do_build_set() {
     $value = NULL;
     if ($this->set['type'] === e_database_set::TO) {
-      if (is_null($this->set['parameter'])) {
-        $value = c_database_string::SET . ' ' . $this->set['parameter'] . ' ' . c_database_string::TO . ' ' . c_database_string::DEFAULT;
+      $value = c_database_string::SET . ' ' . $this->set['parameter'] . ' ' . c_database_string::TO . ' ';
+      if (is_null($this->set['value'])) {
+        $value .= c_database_string::DEFAULT;
       }
-      else if (is_string($this->set['parameter']) && is_string($this->set['value'])) {
-        $value = c_database_string::SET . ' ' . $this->set['parameter'] . ' ' . c_database_string::TO . ' ' . $this->set['value'];
+      else {
+        $value = $this->set['value'];
       }
     }
     else if ($this->set['type'] === e_database_set::EQUAL) {
-      if (is_null($this->set['parameter'])) {
-        $value = c_database_string::SET . ' ' . $this->set['parameter'] . ' = ' . c_database_string::DEFAULT;
+      $value = c_database_string::SET . ' ' . $this->set['parameter'] . ' = ';
+      if (is_null($this->set['value'])) {
+        $value .= c_database_string::DEFAULT;
       }
-      else if (is_string($this->set['parameter']) && is_string($this->set['value'])) {
-        $value = c_database_string::SET . ' ' . $this->set['parameter'] . ' = ' . $this->set['value'];
+      else if (isset($this->set['parameter']) && isset($this->set['value'])) {
+        $value .= $this->set['value'];
       }
     }
     else if ($this->set['type'] == e_database_set::FROM_CURRENT) {
-      if (is_string($this->set['parameter'])) {
-        $value = c_database_string::SET . ' ' . $this->set['parameter'] . ' = ' . c_database_string::FROM_CURRENT;
-      }
+      $value = c_database_string::SET . ' ' . $this->set['parameter'] . ' = ' . c_database_string::FROM_CURRENT;
     }
 
     return $value;
diff --git a/common/database/traits/database_set_operator.php b/common/database/traits/database_set_operator.php
new file mode 100644 (file)
index 0000000..55eb62c
--- /dev/null
@@ -0,0 +1,145 @@
+<?php
+/**
+ * @file
+ * Provides traits for specific Postgesql Queries.
+ *
+ * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
+ */
+namespace n_koopa;
+
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+
+require_once('common/database/enumerations/database_set_operator.php');
+
+require_once('common/database/classes/database_string.php');
+
+/**
+ * Provide the sql (operator) SET functionality.
+ */
+trait t_database_set_operator {
+  protected $set_operator;
+
+  /**
+   * Set the (operator) SET settings.
+   *
+   * @param int|null $parameter
+   *   The SET code to assign.
+   *   Should be one of: e_database_set_operator.
+   *   Set to NULL to disable.
+   *   When NULLm this will remove all values.
+   * @param string|null $value
+   *   (optional) The value associated with the parameter.
+   *   When NULL, a value of 'NONE' is used.
+   *
+   * @return c_base_return_status
+   *   TRUE on success, FALSE otherwise.
+   *   FALSE with the error bit set_operator is returned on error.
+   */
+  public function set_set_operator($parameter, $value = NULL) {
+    if (is_null($set_operator)) {
+      $this->set_operator = NULL;
+      return new c_base_return_true();
+    }
+
+    if ($parameter !== e_database_set_operator::RESTRICT && $parameter !== e_database_set_operator::JOIN) {
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'paramete', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+      return c_base_return_error::s_false($error);
+    }
+
+    if (!is_string($value) && !is_null($value)) {
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'value', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+      return c_base_return_error::s_false($error);
+    }
+
+    if (!is_array($this->set_operator)) {
+      $this->set_operator = [];
+    }
+
+    $set_operator = [
+      'parameter' => $parameter,
+      'value' => NULL,
+    ];
+
+    if (is_string($value)) {
+      $placeholder = $this->add_placeholder($value);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $set_operator['value'] = $placeholder;
+      unset($placeholder);
+    }
+
+    $this->set_operator[] = $set_operator;
+    unset($set_operator);
+
+    return new c_base_return_true();
+  }
+
+  /**
+   * Get the (operator) SET values.
+   *
+   * @param int|null $index
+   *   (optional) Get the set parameter and value at the specified index.
+   *   When NULL, all parameters and values are returned.
+   *
+   * @return c_base_return_array|c_base_return_null
+   *   An array of parameters and values or NULL if not defined.
+   *   A single parameters and value array is returned if $index is an integer.
+   *   NULL with the error bit set is returned on error.
+   */
+  public function get_set_operator($index = NULL) {
+    if (is_null($this->set_operator)) {
+      return new c_base_return_null();
+    }
+
+    if (is_null($index)) {
+      if (is_array($this->set_operator)) {
+        return c_base_return_array::s_new($this->set_operator);
+      }
+    }
+    else {
+      if (is_int($index) && array_key_exists($index, $this->set_operator)) {
+        return c_base_return_array::s_new($this->set_operator[$index]);
+      }
+
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'set_operator[index]', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+      return c_base_return_error::s_null($error);
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'set_operator', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    return c_base_return_error::s_null($error);
+  }
+
+  /**
+   * Perform the common build process for this trait.
+   *
+   * As an internal trait method, the caller is expected to perform any appropriate validation.
+   *
+   * @return string|null
+   *   A string is returned on success.
+   *   NULL is returned if there is nothing to process or there is an error.
+   */
+  protected function p_do_build_set_operator() {
+    $value = NULL;
+
+    if (is_array($this->set_operator) && !empty($this->set_operator)) {
+      $values = [];
+      foreach ($this->set_operator as $set) {
+        if (is_null($set['value'])) {
+          $values[] = $set['parameter'] . ' = ' . c_database_string::NONE;
+        }
+        else {
+          $values[] = $set['parameter'] . ' = ' . $set['value'];
+        }
+      }
+      unset($set);
+
+      $value = c_database_string::SET . ' ' . implode(', ', $values);
+      unset($values);
+    }
+
+    return $value;
+  }
+}
index 52df4674dd8ff19d7d0b597d99d00c0dd4c36855..670dc2355d8dc5d6d0c8b20c475d9132309a019f 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -37,14 +35,21 @@ trait t_database_set_schema {
       return c_base_return_error::s_false($error);
     }
 
-    $this->set_schema = $set_schema;
+    $placeholder = $this->add_placeholder($set_schema);
+    if ($placeholder->has_error()) {
+      return c_base_return_error::s_false($placeholder->get_error());
+    }
+
+    $this->set_schema = $placeholder;
+    unset($placeholder);
+
     return new c_base_return_true();
   }
 
   /**
    * Get the currently assigned schema name to set to.
    *
-   * @return c_base_return_string|c_base_return_null
+   * @return i_database_query_placeholder|c_base_return_null
    *   A schema name on success.
    *   NULL is returned if not set (set schema is not to be used).
    *   NULL with the error bit set is returned on error.
@@ -54,8 +59,8 @@ trait t_database_set_schema {
       return new c_base_return_null();
     }
 
-    if (is_string($this->set_schema)) {
-      return c_base_return_string::s_new($this->set_schema);
+    if (isset($this->set_schema)) {
+      return clone($this->set_schema);
     }
 
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'set_schema', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
index 44f96b4c9959c17a233931cba48ee4ab116cfa31..467bf3f0c8c748c819b927544c700a0c9b0cace3 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with SET index storage_parameter.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -66,10 +64,17 @@ trait t_database_set_storage_parameter {
       $this->set_storage_parameter = [];
     }
 
+    $placeholder = $this->add_placeholder($value);
+    if ($placeholder->has_error()) {
+      return c_base_return_error::s_false($placeholder->get_error());
+    }
+
     $this->set_storage_parameter[] = [
       'type' => $storage_parameter,
-      'value' => $value,
+      'value' => $placeholder,
     ];
+    unset($placeholder);
+
     return new c_base_return_true();
   }
 
@@ -96,7 +101,7 @@ trait t_database_set_storage_parameter {
       }
     }
     else {
-      if (is_int($index) && array_key_exists($index, $this->set_storage_parameter) && is_int($this->set_storage_parameter[$index])) {
+      if (is_int($index) && array_key_exists($index, $this->set_storage_parameter)) {
         return c_base_return_array::s_new($this->set_storage_parameter[$index]);
       }
 
index 98c13b4839a9da2f2bf4602d650e6c2e57cf6fbe..5ba34fd442a54488fd556a9acd2b74d3b870b576 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -37,14 +35,21 @@ trait t_database_set_tablespace {
       return c_base_return_error::s_false($error);
     }
 
-    $this->set_tablespace = $set_tablespace;
+    $placeholder = $this->add_placeholder($set_tablespace);
+    if ($placeholder->has_error()) {
+      return c_base_return_error::s_false($placeholder->get_error());
+    }
+
+    $this->set_tablespace = $placeholder;
+    unset($placeholder);
+
     return new c_base_return_true();
   }
 
   /**
    * Get the currently assigned tablespace name to set to.
    *
-   * @return c_base_return_string|c_base_return_null
+   * @return i_database_query_placeholder|c_base_return_null
    *   A tablespace name on success.
    *   NULL is returned if not set (set tablespace is not to be used).
    *   NULL with the error bit set is returned on error.
@@ -54,8 +59,8 @@ trait t_database_set_tablespace {
       return new c_base_return_null();
     }
 
-    if (is_string($this->set_tablespace)) {
-      return c_base_return_string::s_new($this->set_tablespace);
+    if (isset($this->set_tablespace)) {
+      return clone($this->set_tablespace);
     }
 
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'set_tablespace', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
index e8dd20b37cd079e3d5b48f98c1c7a739f35c4512..da76ffae353113993b773835ec1b3b9f0021eaa6 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
index 766204d0971bca46a96d2f9841626588a0e9a931..7fc3235b77994e5680d416d3cc935403de2c26fe 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
index 724935c019938e5acd2500c57d7b69fb542d8ce2..16523436039e888da6c5ba909405e800b07b3ab1 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -57,10 +55,17 @@ trait t_database_to_role {
         $this->to_role = [];
       }
 
+      $placeholder = $this->add_placeholder($role_name);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
       $this->to_role[] = [
         'type' => $role_type,
-        'name' => $role_name,
+        'name' => $placeholder,
       ];
+      unset($placeholder);
+
       return new c_base_return_true();
     }
 
@@ -91,7 +96,7 @@ trait t_database_to_role {
       }
     }
     else {
-      if (is_int($index) && array_key_exists($index, $this->to_role) && is_array($this->to_role[$index])) {
+      if (is_int($index) && array_key_exists($index, $this->to_role)) {
         return c_base_return_array::s_new($this->to_role[$index]);
       }
 
diff --git a/common/database/traits/database_using.php b/common/database/traits/database_using.php
new file mode 100644 (file)
index 0000000..a77b254
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+/**
+ * @file
+ * Provides traits for specific Postgesql Queries.
+ *
+ * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
+ */
+namespace n_koopa;
+
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+
+/**
+ * Provide the sql USING functionality.
+ */
+trait t_database_using {
+  protected $using;
+
+  /**
+   * Set the USING settings.
+   *
+   * @param string|null $using
+   *   The using to use.
+   *   Set to NULL to disable.
+   *
+   * @return c_base_return_status
+   *   TRUE on success, FALSE otherwise.
+   *   FALSE with the error bit set is returned on error.
+   */
+  public function set_using($using) {
+    if (is_null($using)) {
+      $this->using = NULL;
+      return new c_base_return_true();
+    }
+
+    if (is_string($using)) {
+      $placeholder = $this->add_placeholder($using);
+      if ($placeholder->has_error()) {
+        return c_base_return_error::s_false($placeholder->get_error());
+      }
+
+      $this->using = $placeholder;
+      unset($placeholder);
+
+      return new c_base_return_true();
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'using', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+    return c_base_return_error::s_false($error);
+  }
+
+  /**
+   * Get the currently assigned using.
+   *
+   * @return i_database_query_placeholder|c_base_return_null
+   *   A using query placeholder on success.
+   *   NULL is returned if not set.
+   *   NULL with the error bit set is returned on error.
+   */
+  public function get_using() {
+    if (is_null($this->using)) {
+      return new c_base_return_null();
+    }
+
+    if (isset($this->using)) {
+      return clone($this->using);
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'using', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    return c_base_return_error::s_null($error);
+  }
+
+  /**
+   * Perform the common build process for this trait.
+   *
+   * As an internal trait method, the caller is expected to perform any appropriate validation.
+   *
+   * @return string|null
+   *   A string is returned on success.
+   *   NULL is returned if there is nothing to process or there is an error.
+   */
+  protected function p_do_build_using() {
+    return strval($this->using);
+  }
+}
index 6a8ebb9ed26d198d3951158a011b52a84806233b..46f5d240981bb3e03795a18a7dc25301425c8551 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with validator.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;
@@ -41,10 +39,16 @@ trait t_database_validator {
 
     if ($validator === e_database_validator::VALIDATOR) {
       if (is_string($validator_function)) {
+        $placeholder = $this->add_placeholder($validator_function);
+        if ($placeholder->has_error()) {
+          return c_base_return_error::s_false($placeholder->get_error());
+        }
+
         $this->validator = [
           'type' => $validator,
-          'name' => $validator_function,
+          'name' => $placeholder,
         ];
+        unset($placeholder);
 
         return new c_base_return_true();
       }
@@ -82,7 +86,7 @@ trait t_database_validator {
       return c_base_return_array::s_new($this->validator);
     }
 
-    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'name', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'validator', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
     return c_base_return_error::s_null($error);
   }
 
index 70b60ab2e5cc096563c86a93bc6337416dfa918f..6ccefa8a65b3968bc74f4f825c0b86d55c562783 100644 (file)
@@ -3,8 +3,6 @@
  * @file
  * Provides traits for specific Postgesql Queries.
  *
- * These traits are associated with actions.
- *
  * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
  */
 namespace n_koopa;