]> Kevux Git Server - koopa/commitdiff
Progress: continue development on database abstraction layer
authorKevin Day <thekevinday@gmail.com>
Mon, 3 Dec 2018 00:51:01 +0000 (18:51 -0600)
committerKevin Day <thekevinday@gmail.com>
Mon, 3 Dec 2018 00:51:01 +0000 (18:51 -0600)
It seems cleaner to move the trait-specific do_build operations into the traits.
This will simplify the work needed on the actions shared between each DB operation.
This unlike classfull design, this still allows flexibility to do something completely diffeent if needed by the PostgeSQL language.
Begin some cleanup before I start diving into the alter foreign table code (which is quite extensive).
After seeing how if..thens vs switch..cases, I intend to remove the use of switches (they end up way too ugly and hard to read).
I also intend to make sure that $this->value is only ever assigned once the string has been built (preserving the state on error exit).

35 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_default_privileges.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_member_object.php [new file with mode: 0644]
common/database/classes/database_query.php
common/database/classes/database_string.php
common/database/enumerations/database_action.php
common/database/enumerations/database_handler.php [new file with mode: 0644]
common/database/enumerations/database_member_object.php [new file with mode: 0644]
common/database/enumerations/database_options.php [new file with mode: 0644]
common/database/enumerations/database_property.php
common/database/enumerations/database_validator.php [new file with mode: 0644]
common/database/traits/database_action.php
common/database/traits/database_group_by.php
common/database/traits/database_handler.php [new file with mode: 0644]
common/database/traits/database_in_schema.php
common/database/traits/database_option.php
common/database/traits/database_options.php [new file with mode: 0644]
common/database/traits/database_order_by.php
common/database/traits/database_owner_to.php
common/database/traits/database_rename_column_to.php [new file with mode: 0644]
common/database/traits/database_rename_to.php
common/database/traits/database_reset.php
common/database/traits/database_set.php
common/database/traits/database_set_schema.php
common/database/traits/database_set_tablespace.php
common/database/traits/database_validator.php [new file with mode: 0644]
todo.notes [new file with mode: 0644]

index 3b59fd383151efd60290fdc988171ebf13197233..eaabf32f932cc46ed3c505b57389a844a4a5721e 100644 (file)
@@ -30,6 +30,7 @@ class c_database_alter_aggregate extends c_database_query {
 
   protected const pr_QUERY_COMMAND = 'alter aggregate';
 
+  // @todo: move these into their own traits.
   protected $aggregate_signatures;
   protected $order_by_signatures;
 
@@ -211,6 +212,29 @@ class c_database_alter_aggregate extends c_database_query {
   }
 
   /**
+   * Get the total aggregate signatures.
+   *
+   * @return c_base_return_int
+   *   The total number of aggregate signatures.
+   *   0 with the error bit set is returned on error.
+   */
+  public function get_aggregate_signature_count($index = NULL) {
+    if (is_null($this->aggregate_signatures)) {
+      return new c_base_return_null();
+    }
+
+    if (is_null($index)) {
+      return new c_base_return_int(0);
+    }
+    else if (is_array($this->aggregate_signatures)) {
+      return new c_base_return_int(count($this->aggregate_signatures));
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'aggregate_signatures', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    return c_base_return_error::s_value(0, 'c_base_return_int', $error);
+  }
+
+  /**
    * Get the order by aggregate signatures.
    *
    * @param int|null $index
@@ -246,6 +270,29 @@ class c_database_alter_aggregate extends c_database_query {
   }
 
   /**
+   * Get the total order by signatures.
+   *
+   * @return c_base_return_int
+   *   The total number of aggregate signatures.
+   *   0 with the error bit set is returned on error.
+   */
+  public function get_order_by_signature_count($index = NULL) {
+    if (is_null($this->order_by_signatures)) {
+      return new c_base_return_null();
+    }
+
+    if (is_null($index)) {
+      return new c_base_return_int(0);
+    }
+    else if (is_array($this->aggregate_signatures)) {
+      return new c_base_return_int(count($this->aggregate_signatures));
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'aggregate_signatures', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    return c_base_return_error::s_value(0, 'c_base_return_int', $error);
+  }
+
+  /**
    * Implements do_build().
    */
   public function do_build() {
@@ -254,6 +301,7 @@ class c_database_alter_aggregate extends c_database_query {
       return new c_base_return_false();
     }
 
+    // @fixme: use a local variable fo value before assigning.
     $this->value = static::pr_QUERY_COMMAND;
     $this->value .= ' ' . $this->name;
 
@@ -306,13 +354,13 @@ class c_database_alter_aggregate extends c_database_query {
     }
 
     if (is_string($this->rename_to)) {
-      $this->value .= ' ' . $aggregate_signatures . ' ' . c_database_string::RENAME_TO . ' (' . $this->rename_to . ')';
+      $this->value .= ' ' . $aggregate_signatures . ' ' . $this->p_do_build_rename_to();
     }
-    else if (is_string($this->owner_to_user_name)) {
-      $this->value .= ' ' . $aggregate_signatures . ' ' . c_database_string::OWNER_TO . ' (' . $this->owner_to_user_name . ')';
+    else if (is_string($this->owner_to)) {
+      $this->value .= ' ' . $aggregate_signatures . ' ' . $this->p_do_build_owner_to();
     }
     else if (is_string($this->set_schema)) {
-      $this->value .= ' ' . $aggregate_signatures . ' ' . c_database_string::SET_SCHEMA . ' (' . $this->set_schema . ')';
+      $this->value .= ' ' . $aggregate_signatures . ' ' . $this->p_do_build_set_schema();
     }
     else {
       unset($aggregate_signatures);
index 62b0ae170a955a29a95e2d8fb2d96dd07c517d58..d2fbca6c8b8eccbc40d2366f0113e24914c35282 100644 (file)
@@ -133,6 +133,7 @@ class c_database_alter_coalation extends c_database_query {
       return new c_base_return_false();
     }
 
+    // @fixme: use a local variable for value before returning.
     $this->value = static::pr_QUERY_COMMAND;
     $this->value .= ' ' . $this->name;
 
@@ -142,13 +143,13 @@ class c_database_alter_coalation extends c_database_query {
       }
     }
     else if (is_string($this->rename_to)) {
-      $this->value .= ' ' . $this->pr_QUERY_RENAME_TO . ' (' . $this->rename_to . ')';
+      $this->value .= ' ' . $this->p_do_build_rename_to();
     }
-    else if (is_string($this->owner_to_user_name)) {
-      $this->value .= ' ' . $this->pr_QUERY_OWNER_TO . ' (' . $this->owner_to_user_name . ')';
+    else if (is_string($this->owner_to)) {
+      $this->value .= ' ' . $this->p_do_build_owner_to();
     }
     else if (is_string($this->set_schema)) {
-      $this->value .= ' ' . $this->pr_QUERY_SET_SCHEMA . ' (' . $this->set_schema . ')';
+      $this->value .= ' ' . $this->p_do_build_set_schema();
     }
     else {
       $this->value = NULL;
index 4d3b95ea014765ddb2588dfc74d9c11510bda37f..e799c6c9e9871c46f7f61045852c0e49a5b4291a 100644 (file)
@@ -83,17 +83,18 @@ class c_database_alter_conversion extends c_database_query {
       return new c_base_return_false();
     }
 
+    // @fixme: use a local variable for value.
     $this->value = static::pr_QUERY_COMMAND;
     $this->value .= ' ' . $this->name;
 
     if (is_string($this->rename_to)) {
-      $this->value .= ' ' . $this->pr_QUERY_RENAME_TO . ' (' . $this->rename_to . ')';
+      $this->value .= ' ' . $this->p_do_build_rename_to();
     }
-    else if (is_string($this->owner_to_user_name)) {
-      $this->value .= ' ' . $this->pr_QUERY_OWNER_TO . ' (' . $this->owner_to_user_name . ')';
+    else if (is_string($this->owner_to)) {
+      $this->value .= ' ' . $this->p_do_build_owner_to();
     }
     else if (is_string($this->set_schema)) {
-      $this->value .= ' ' . $this->pr_QUERY_SET_SCHEMA . ' (' . $this->set_schema . ')';
+      $this->value .= ' ' . $this->p_do_build_set_schema();
     }
     else {
       $this->value = NULL;
index a4cfc54fe1f1a1b79f3a38c4e59d2f3f135d2a5f..66e6122ede3f842bee9537b6b3ea0286ef783c44 100644 (file)
@@ -44,16 +44,14 @@ class c_database_alter_database extends c_database_query {
   public function __construct() {
     parent::__construct();
 
-    $this->name            = NULL;
-    $this->rename_to       = NULL;
-    $this->owner_to        = NULL;
-    $this->set             = NULL;
-    $this->set_tablespace  = NULL;
-    $this->set_parameter   = NULL;
-    $this->set_value       = NULL;
-    $this->reset           = NULL;
-    $this->reset_parameter = NULL;
-
+    $this->name           = NULL;
+    $this->rename_to      = NULL;
+    $this->owner_to       = NULL;
+    $this->set            = NULL;
+    $this->set_tablespace = NULL;
+    $this->reset          = NULL;
+
+    // TODO: it may be better (and more consistent) to convert option into a trait, just like all of the others.
     $this->option = NULL;
   }
 
@@ -66,10 +64,7 @@ class c_database_alter_database extends c_database_query {
     unset($this->owner_to);
     unset($this->set);
     unset($this->set_tablespace);
-    unset($this->set_parameter);
-    unset($this->set_value);
     unset($this->reset);
-    unset($this->reset_parameter);
 
     unset($this->option);
 
@@ -160,46 +155,19 @@ class c_database_alter_database extends c_database_query {
       $this->value .= ' ' . $this->option->get_value_exact();
     }
     else if (is_string($this->rename_to)) {
-      $this->value .= ' ' . c_database_string::RENAME_TO . ' (' . $this->rename_to . ')';
+      $this->value .= ' ' . $this->p_do_build_rename_to();
     }
-    else if (is_string($this->owner_to_user_name)) {
-      $this->value .= ' ' . c_database_string::OWNER_TO . ' (' . $this->owner_to_user_name . ')';
+    else if (is_string($this->owner_to)) {
+      $this->value .= ' ' . $this->p_do_build_owner_to();
     }
     else if (is_string($this->set_tablespace)) {
-      $this->value .= ' ' . c_database_string::SET_TABLESPACE . ' (' . $this->set_tablespace . ')';
+      $this->value .= ' ' . $this->p_do_build_set_tablespace();
     }
-    else if (is_int($this->set)) {
-      if ($this->set === e_database_set::TO) {
-        if (is_null($this->set_parameter)) {
-          $this->value .= ' ' . c_database_string::SET . ' ' . $this->set_parameter . ' ' . c_database_string::TO . ' ' . c_database_string::DEFAULT;
-        }
-        else if (is_string($this->set_parameter) && is_string($this->set_value)) {
-          $this->value .= ' ' . c_database_string::SET . ' ' . $this->set_parameter . ' ' . c_database_string::TO . ' ' . $this->set_value;
-        }
-      }
-      else if ($this->set === e_database_set::EQUAL) {
-        if (is_null($this->set_parameter)) {
-          $this->value .= ' ' . c_database_string::SET . ' ' . $this->set_parameter . ' = ' . c_database_string::DEFAULT;
-        }
-        else if (is_string($this->set_parameter) && is_string($this->set_value)) {
-          $this->value .= ' ' . c_database_string::SET . ' ' . $this->set_parameter . ' = ' . $this->set_value;
-        }
-      }
-      else if ($this->set == e_database_set::FROM_CURRENT) {
-        if (is_string($this->set_parameter)) {
-          $this->value .= ' ' . c_database_string::SET . ' ' . $this->set_parameter . ' = ' . c_database_string::FROM_CURRENT;
-        }
-      }
+    else if (is_array($this->set)) {
+        $this->value .= ' ' . $this->p_do_build_set();
     }
-    else if (is_string($this->reset)) {
-      if ($this->set === e_database_reset::PARAMETER) {
-        if (is_string($this->set_parameter)) {
-          $this->value .= ' ' . c_database_string::RESET . ' ' . $this->set_parameter;
-        }
-      }
-      else if ($this->set === e_database_reset::ALL) {
-        $this->value .= ' ' . c_database_string::RESET . ' ' . c_database_string::ALL;
-      }
+    else if (is_array($this->reset)) {
+      $this->value .= ' ' . $this->p_do_build_reset();
     }
 
     return new c_base_return_true();
index fa4dfb873a70f716a555cc9093a72f0137734322..a55af00eeb25c24a1dba2fc95ce357947cc03b99 100644 (file)
@@ -46,7 +46,6 @@ class c_database_alter_default_priveleges extends c_database_query {
     $this->in_schema = NULL;
     $this->action    = NULL;
     $this->option    = NULL;
-    $this->for_targets     = NULL;
 
     $this->abbreviated  = NULL;
     $this->option_grant = NULL;
@@ -440,6 +439,7 @@ class c_database_alter_default_priveleges extends c_database_query {
           return new c_base_return_false();
     }
 
+    // @fixme: use a local variable and only assign value once at the end after any potential error cases.
     $this->value = static::pr_QUERY_COMMAND;
 
     // [ FOR ROLE target_role [, ... ] ]
@@ -457,15 +457,7 @@ class c_database_alter_default_priveleges extends c_database_query {
 
     // [ IN SCHEMA schema_name [, ... ] ]
     if (is_array($this->in_schema) && !empty($this->in_schema)) {
-      $this->value .= ' ' . c_database_string::IN . ' ' . c_database_string::SCHEMA;
-
-      $names = NULL;
-      foreach ($this->in_schema as $schema_name) {
-        $names .= ', ' . $schema_name;
-      }
-
-      $this->value .= ltrim($names, ',');
-      unset($names);
+      $this->value .= $this->p_do_build_in_schema();
     }
 
     if ($this->action === e_database_action::ACTION_GRANT) {
@@ -570,12 +562,11 @@ class c_database_alter_default_priveleges extends c_database_query {
     }
     else if ($this->action === e_database_action::REVOKE) {
       // [ CASCADE | RESTRICT ]
-      if ($this->option === e_database_option::CASCADE) {
-        $this->value .= ' ' . c_database_string::CASCADE;
-      }
-      else if ($this->option === e_database_option::RESTRICT) {
-        $this->value .= ' ' . c_database_string::RESTRICT;
+      $option = $this->p_do_build_option();
+      if (is_string($option)) {
+        $this->value .= ' ' . $option;
       }
+      unset($option);
     }
 
     return new c_base_return_true();
index 990ad6bb5a4bf72342601fda03be1fdec32529f2..e5b64e907607b8c7f0a8594fb2b204fb3d987806 100644 (file)
@@ -25,7 +25,7 @@ require_once('common/database/traits/database_option.php');
  *
  * When no argument mode is specified, then a wildcard * is auto-provided for the aggregate_signature parameter.
  *
- * @see: https://www.postgresql.org/docs/current/static/sql-alteraggregate.html
+ * @see: https://www.postgresql.org/docs/current/static/sql-alterdomain.html
  */
 class c_database_alter_coalation extends c_database_query {
   use t_database_name;
@@ -267,12 +267,11 @@ class c_database_alter_coalation extends c_database_query {
 
           $action .= ' ' . $this->constraint;
 
-          if ($this->option === e_database_option::RESTRICT) {
-            $action .= ' ' . c_database_string::RESTRICT;
-          }
-          else if ($this->option === e_database_option::CASCADE) {
-            $action .= ' ' . c_database_string::CASCADE;
+          $option = $this->p_do_build_option();
+          if (is_string($option)) {
+            $action .= ' ' . $option;
           }
+          unset($option);
           break;
 
         case e_database_action::DROP_DEFAULT:
@@ -280,12 +279,12 @@ class c_database_alter_coalation extends c_database_query {
           break;
 
         case e_database_action::OWNER_TO:
-          if (!is_string($this->owner_to_user_name)) {
+          if (!is_string($this->owner_to)) {
             unset($action);
             return new c_base_return_false();
           }
 
-          $action = c_database_string::OWNER_TO . ' (' . $this->owner_to_user_name . ')';
+          $action = $this->p_do_build_owner_to();
           break;
 
         case e_database_action::RENAME_CONSTRAINT:
@@ -303,7 +302,7 @@ class c_database_alter_coalation extends c_database_query {
             return new c_base_return_false();
           }
 
-          $action = c_database_string::RENAME_TO . ' (' . $this->rename_to . ')';
+          $action = $this->p_do_build_rename_to();
           break;
 
         case e_database_action::SET:
@@ -328,7 +327,7 @@ class c_database_alter_coalation extends c_database_query {
             return new c_base_return_false();
           }
 
-          $action = ' ' . c_database_string::SET_SCHEMA . ' (' . $this->set_schema . ')';
+          $action = $this->p_do_build_set_schema();
           break;
 
         case e_database_action::VALIDATE_CONSTRAINT:
index e5bb3acfaa0afe3f0321e0896db6794c711de514..307c4349e75edee627b67c6b96659e6a7905e631 100644 (file)
@@ -20,11 +20,12 @@ require_once('common/database/traits/database_rename_to.php');
  *
  * When no argument mode is specified, then a wildcard * is auto-provided for the aggregate_signature parameter.
  *
- * @see: https://www.postgresql.org/docs/current/static/sql-alteraggregate.html
+ * @see: https://www.postgresql.org/docs/current/static/sql-altereventtrigger.html
  */
 class c_database_alter_coalation extends c_database_query {
   use t_database_action;
   use t_database_action_property;
+  use t_database_action_parameter;
   use t_database_name;
   use t_database_owner_to;
   use t_database_rename_to;
@@ -38,22 +39,24 @@ class c_database_alter_coalation extends c_database_query {
   public function __construct() {
     parent::__construct();
 
-    $this->query_action          = NULL;
-    $this->query_action_property = NULL;
-    $this->query_name            = NULL;
-    $this->query_owner_to        = NULL;
-    $this->query_rename_to       = NULL;
+    $this->action           = NULL;
+    $this->action_property  = NULL;
+    $this->action_parameter = NULL;
+    $this->name             = NULL;
+    $this->owner_to         = NULL;
+    $this->rename_to        = NULL;
   }
 
   /**
    * Class destructor.
    */
   public function __destruct() {
-    unset($this->query_action);
-    unset($this->query_action_property);
-    unset($this->query_name);
-    unset($this->query_owner_to);
-    unset($this->query_rename_to);
+    unset($this->action);
+    unset($this->action_property);
+    unset($this->action_parameter);
+    unset($this->name);
+    unset($this->owner_to);
+    unset($this->rename_to);
 
     parent::__destruct();
   }
@@ -83,9 +86,54 @@ class c_database_alter_coalation extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    $this->value = NULL;
-
-    // @todo
+    if (is_null($this->name)) {
+      return new c_base_return_false();
+    }
+
+    $action = NULL;
+    switch($this->action) {
+      case e_database_action::DISABLE:
+        $this->action = c_database_string::DISABLE;
+        break;
+      case e_database_action::ENABLE:
+        $action = c_database_string::ENABLE;
+        if ($this->action_property === e_database_property::REPLICA) {
+          $action .= ' ' . c_database_string::REPLICA;
+        }
+        else if ($this->action_property === e_database_property::ALWAYS) {
+          $action .= ' ' . c_database_string::ALWAYS;
+        }
+        else {
+          unset($action);
+          return new c_base_return_false();
+        }
+        break;
+      case e_database_action::OWNER_TO:
+        if (is_string($this->owner_to)) {
+          $action = $this->p_do_build_owner_to();
+        }
+        else {
+          unset($action);
+          return new c_base_return_false();
+        }
+        break;
+      case e_database_action::RENAME_TO:
+        if (is_string($this->rename_to)) {
+          $action = $this->p_do_build_rename_to();
+        }
+        else {
+          unset($action);
+          return new c_base_return_false();
+        }
+        break;
+      default:
+        unset($action);
+        return new c_base_return_false();
+    }
+
+    $this->value = static::pr_QUERY_COMMAND;
+    $this->value .= ' ' . $action;
+    unset($action);
 
     return new c_base_return_true();
   }
index a2d73cfbf539d6ab77c7ccb50e33de9f24f97cad..017a7b8cb5338ea3634882ed2b2c9f67483d532f 100644 (file)
@@ -9,6 +9,10 @@ require_once('common/base/classes/base_error.php');
 require_once('common/base/classes/base_return.php');
 
 require_once('common/database/classes/database_query.php');
+require_once('common/database/classes/database_member_object.php');
+
+require_once('common/database/traits/database_action.php');
+require_once('common/database/traits/database_name.php');
 
 
 /**
@@ -16,10 +20,16 @@ require_once('common/database/classes/database_query.php');
  *
  * When no argument mode is specified, then a wildcard * is auto-provided for the aggregate_signature parameter.
  *
- * @see: https://www.postgresql.org/docs/current/static/sql-alteraggregate.html
+ * @see: https://www.postgresql.org/docs/current/static/sql-alterextension.html
  */
-class c_database_alter_coalation extends c_database_query {
-  protected const pr_QUERY_COMMAND = 'alter coalation';
+class c_database_alter_extension extends c_database_query {
+  use t_database_action;
+  use t_database_action_parameter;
+  use t_database_name;
+
+  protected const pr_QUERY_COMMAND = 'alter extension';
+
+  protected $member_object;
 
 
   /**
@@ -27,12 +37,22 @@ class c_database_alter_coalation extends c_database_query {
    */
   public function __construct() {
     parent::__construct();
+
+    $this->action           = NULL;
+    $this->action_parameter = NULL;
+
+    $this->member_object = NULL;
   }
 
   /**
    * Class destructor.
    */
   public function __destruct() {
+    unset($this->action);
+    unset($this->action_parameter);
+
+    unset($this->member_object);
+
     parent::__destruct();
   }
 
@@ -61,9 +81,61 @@ class c_database_alter_coalation extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    $this->value = NULL;
+    if (is_null($this->name)) {
+      return new c_base_return_false();
+    }
 
-    // @todo
+    $action = $this->name . ' ';
+    switch($this->action) {
+      case e_database_action::UPDATE:
+        $action .= c_database_string::UPDATE;
+        if (is_string($this->action_parameter)) {
+          $action .= ' ' . c_database_string::TO . ' ' . $this->action_parameter;
+        }
+        else {
+          unset($action);
+          return new c_base_return_false();
+        }
+        break;
+      case e_database_action::SET_SCHEMA:
+        if (is_string($this->set_schema)) {
+          $action = $this->p_do_build_set_schema();
+        }
+        else {
+          unset($action);
+          return new c_base_return_false();
+        }
+        break;
+      case e_database_action::ADD:
+        $action .= c_database_string::ADD;
+        if ($this->action_parameter instanceof c_database_member_object && $this->action_parameter->do_build() instanceof c_base_return_true) {
+          $action .= ' ' . $this->action_parameter->get_value();
+        }
+        else {
+          unset($action);
+          return new c_base_return_false();
+        }
+        break;
+      case e_database_action::DROP:
+        $action .= c_database_string::DROP;
+        if ($this->action_parameter instanceof c_database_member_object) {
+          if ($this->action_parameter->do_build() instanceof c_base_return_true) {
+            $action .= ' ' . $this->action_parameter->get_value();
+          }
+          else {
+            unset($action);
+            return new c_base_return_false();
+          }
+        }
+        else {
+          unset($action);
+          return new c_base_return_false();
+        }
+        break;
+      default:
+        unset($action);
+        return new c_base_return_false();
+    }
 
     return new c_base_return_true();
   }
index a2d73cfbf539d6ab77c7ccb50e33de9f24f97cad..19a5f3dee5bfb4c77e862345ffbb5a32e182b5ff 100644 (file)
@@ -10,16 +10,31 @@ require_once('common/base/classes/base_return.php');
 
 require_once('common/database/classes/database_query.php');
 
+require_once('common/database/traits/database_action.php');
+require_once('common/database/traits/database_handler.php');
+require_once('common/database/traits/database_name.php');
+require_once('common/database/traits/database_options.php');
+require_once('common/database/traits/database_owner_to.php');
+require_once('common/database/traits/database_rename_to.php');
+require_once('common/database/traits/database_validator.php');
 
 /**
- * The class for building and returning a Postgresql ALTER COALATION query string.
+ * The class for building and returning a Postgresql ALTER FOEIGN DATA WRAPPER query string.
  *
- * When no argument mode is specified, then a wildcard * is auto-provided for the aggregate_signature parameter.
- *
- * @see: https://www.postgresql.org/docs/current/static/sql-alteraggregate.html
+ * @see: https://www.postgresql.org/docs/current/static/sql-alterforeigndatawrapper.html
  */
-class c_database_alter_coalation extends c_database_query {
-  protected const pr_QUERY_COMMAND = 'alter coalation';
+class c_database_alter_foreign_data_wrapper extends c_database_query {
+  use t_database_action;
+  use t_database_action_property;
+  use t_database_action_parameter;
+  use t_database_handler;
+  use t_database_name;
+  use t_database_options;
+  use t_database_owner_to;
+  use t_database_rename_to;
+  use t_database_validator;
+
+  protected const pr_QUERY_COMMAND = 'alter foreign data wrapper';
 
 
   /**
@@ -27,12 +42,32 @@ class c_database_alter_coalation extends c_database_query {
    */
   public function __construct() {
     parent::__construct();
+
+    $this->action           = NULL;
+    $this->action_property  = NULL;
+    $this->action_parameter = NULL;
+    $this->handler          = NULL;
+    $this->name             = NULL;
+    $this->options          = NULL;
+    $this->owner_to         = NULL;
+    $this->rename_to        = NULL;
+    $this->validator        = NULL;
   }
 
   /**
    * Class destructor.
    */
   public function __destruct() {
+    unset($this->action);
+    unset($this->action_property);
+    unset($this->action_parameter);
+    unset($this->handler);
+    unset($this->name);
+    unset($this->options);
+    unset($this->owner_to);
+    unset($this->rename_to);
+    unset($this->validator);
+
     parent::__destruct();
   }
 
@@ -61,9 +96,45 @@ class c_database_alter_coalation extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    $this->value = NULL;
+    if (!is_string($this->name)) {
+      return new c_base_return_false();
+    }
+
+    $action = NULL;
+    if ($this->action === e_database_action::OWNER_TO) {
+      if (is_string($this->owner_to)) {
+        $action = $this->p_do_build_owner_to();
+      }
+      else {
+        unset($action);
+        return new c_base_return_false();
+      }
+    }
+    else if ($this->action === e_database_action::RENAME_TO) {
+      if (is_string($this->rename_to)) {
+        $action = $this->p_do_build_rename_to();
+      }
+      else {
+        unset($action);
+        return new c_base_return_false();
+      }
+    }
+    else {
+      if (is_array($this->handler)) {
+        $action .= ' ' . $this->p_do_build_handler();
+      }
+
+      if (is_array($this->validator)) {
+        $action .= ' ' . $this->p_do_build_validator();
+      }
+
+      $actions .= ' ' . $this->p_do_build_options();
+    }
 
-    // @todo
+    $this->value = static::pr_QUERY_COMMAND;
+    $this->value .= ' ' . $this->name;
+    $this->value .= ' ' . $action;
+    unset($action);
 
     return new c_base_return_true();
   }
index a2d73cfbf539d6ab77c7ccb50e33de9f24f97cad..7b726edf4b2dabb521b36e207e03f409f6b0b01a 100644 (file)
@@ -10,23 +10,68 @@ require_once('common/base/classes/base_return.php');
 
 require_once('common/database/classes/database_query.php');
 
+require_once('common/database/traits/database_action.php');
+require_once('common/database/traits/database_name.php');
+require_once('common/database/traits/database_rename_column_to.php');
+require_once('common/database/traits/database_rename_to.php');
 
 /**
- * The class for building and returning a Postgresql ALTER COALATION query string.
+ * The class for building and returning a Postgresql ALTER FOREIGN TABLE query string.
  *
- * When no argument mode is specified, then a wildcard * is auto-provided for the aggregate_signature parameter.
- *
- * @see: https://www.postgresql.org/docs/current/static/sql-alteraggregate.html
+ * @see: https://www.postgresql.org/docs/current/static/sql-alterforeigntable.html
  */
-class c_database_alter_coalation extends c_database_query {
-  protected const pr_QUERY_COMMAND = 'alter coalation';
+class c_database_alter_foreign_table extends c_database_query {
+  protected const pr_QUERY_COMMAND = 'alter foreign table';
+  use t_database_action;
+  use t_database_action_property;
+  use t_database_action_parameter;
+  use t_database_name;
+  use t_database_rename_column_to;
+  use t_database_rename_to;
+
+  protected $if_exists;
+  protected $include_descendents; // The '*' following 'name'
+  protected $only;
 
+// sub-forms:
+// ADD COLUMN
+// DROP COLUMN
+// SET DATA TYPE
+// SET DEFAULT
+// SET NOT NULL
+// SET STATISTICS
+// SET
+// RESET
+// SET STORAGE
+// ADD ...
+// VALIDATE CONSTRAINT
+// DROP CONSTRAINT
+// DISABLE/ENABLE
+// SET WITH OIDS
+// SET WITHOUT OIDS
+// INHERIT
+// NO INHERIT
+// OWNER
+// OPTIONS
+// RENAME
+// SET SCHEMA
 
   /**
    * Class constructor.
    */
   public function __construct() {
     parent::__construct();
+
+    $this->action           = NULL;
+    $this->action_property  = NULL;
+    $this->action_parameter = NULL;
+    $this->name             = NULL;
+    $this->rename_column_to = NULL;
+    $this->rename_to        = NULL;
+
+    $this->if_exists           = NULL;
+    $this->include_descendents = NULL;
+    $this->only                = NULL;
   }
 
   /**
@@ -34,6 +79,17 @@ class c_database_alter_coalation extends c_database_query {
    */
   public function __destruct() {
     parent::__destruct();
+
+    unset($this->action);
+    unset($this->action_property);
+    unset($this->action_parameter);
+    unset($this->name);
+    unset($this->rename_column_to);
+    unset($this->rename_to);
+
+    unset($this->if_exists);
+    unset($this->include_descendents);
+    unset($this->only);
   }
 
   /**
@@ -61,10 +117,31 @@ class c_database_alter_coalation extends c_database_query {
    * Implements do_build().
    */
   public function do_build() {
-    $this->value = NULL;
+    if (!is_string($this->name)) {
+      return new c_base_return_false();
+    }
+
+    $action = NULL;
+    if ($this->if_exists) {
+      $action = ' ' . c_database_string::IF_EXISTS;
+    }
+
+    if ($this->only) {
+      $action = ' ' . c_database_string::ONLY;
+    }
 
     // @todo
 
+    $this->value = static::pr_QUERY_COMMAND;
+    $this->value .= ' ' . $this->name;
+
+    if ($this->include_descendents) {
+      $this->value .' *';
+    }
+
+    $this->value .= $action;
+    unset($action);
+
     return new c_base_return_true();
   }
 }
diff --git a/common/database/classes/database_member_object.php b/common/database/classes/database_member_object.php
new file mode 100644 (file)
index 0000000..cb7f836
--- /dev/null
@@ -0,0 +1,229 @@
+<?php
+/**
+ * @file
+ * Provides a class for specific Postgesql query: MEMBER_OBJECT.
+ *
+ * TODO: this should either be an argument parameter or a database query.
+ */
+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_query.php');
+
+require_once('common/database/traits/database_action.php');
+require_once('common/database/traits/database_name.php');
+
+/**
+ * The class for building and returning a Postgresql MEMBER OBJECT query string.
+ *
+ * @see: https://www.postgresql.org/docs/current/static/sql-alterextension.html
+ */
+class c_database_member_object extends c_database_query {
+  use t_database_action;
+  use t_database_action_parameter;
+  use t_database_name;
+
+  protected const pr_QUERY_COMMAND = '';
+
+
+  /**
+   * Class constructor.
+   */
+  public function __construct() {
+    parent::__construct();
+
+    $this->action           = NULL;
+    $this->action_parameter = NULL;
+    $this->name             = NULL;
+  }
+
+  /**
+   * Class destructor.
+   */
+  public function __destruct() {
+    unset($this->action);
+    unset($this->action_parameter);
+    unset($this->name);
+
+    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__, '');
+  }
+
+  /**
+   * Implements do_build().
+   */
+  public function do_build() {
+    if (is_null($this->name)) {
+      return new c_base_return_false();
+    }
+
+    $action = NULL;
+    switch($this->action) {
+      case e_database_method_object::ACCESS_METHOD:
+        $action = c_database_string::ACCESS_METHOD . ' ' . $this->name;
+        break;
+      case e_database_method_object::AGGREGATE:
+        $action = c_database_string::AGGREGATE . ' ' . $this->name;
+        // TODO: as a query argument?
+        if ($this->action_parameter instanceof c_database_alter_aggregate && $this->action_parameter->do_build()) {
+          $action .= ' ( ' . $this->action_parameter->get_value() . ' )';
+        }
+        else {
+          unset($action);
+          return new c_base_return_false();
+        }
+        break;
+      case e_database_method_object::CAST:
+        // uses 'name' property to represent AS 'source_type'
+        $action = c_database_string::CAST;
+        if (is_string($this->action_parameter)) {
+          $action .= ' ' . $this->name . ' ' . c_database_string::AS . ' ( ' . $this->action_parameter . ' )';
+        }
+        else {
+          unset($action);
+          return new c_base_return_false();
+        }
+        break;
+      case e_database_method_object::COLLATION:
+        $action = c_database_string::COLLATION . ' ' . $this->name;
+        break;
+      case e_database_method_object::CONVERSION:
+        $action = c_database_string::CONVERSION . ' ' . $this->name;
+        break;
+      case e_database_method_object::DOMAIN:
+        $action = c_database_string::DOMAIN . ' ' . $this->name;
+        break;
+      case e_database_method_object::EVENT_TRIGGER:
+        $action = c_database_string::EVENT_TRIGGER . ' ' . $this->name;
+        break;
+      case e_database_method_object::FOREIGN_DATA_WRAPPER:
+        $action = c_database_string::FOREIGN_DATA_WRAPPER . ' ' . $this->name;
+        break;
+      case e_database_method_object::FOREIGN_TABLE:
+        $action = c_database_string::FOREIGN_TABLE . ' ' . $this->name;
+        break;
+      case e_database_method_object::FUNCTION:
+        $action = c_database_string::FUNCTION . ' ' . $this->name;
+        // TODO: finish adding support for function
+        // TODO: as a query argument?
+        /*if ($this->action_parameter instanceof c_database_function && $this->action_parameter->do_build()) {
+          $action .= ' ( ' . $this->action_parameter->get_value() . ' )';
+        }
+        else {
+          unset($action);
+          return new c_base_return_false();
+        }*/
+        break;
+      case e_database_method_object::MATERIALIZED_VIEW:
+        $action = c_database_string::MATERIALIZED_VIEW . ' ' . $this->name;
+        break;
+      case e_database_method_object::OPERATOR:
+        $action = c_database_string::OPERATOR . ' ' . $this->name;
+        if (isset($this->action_parameter[0]) && is_string($this->action_parameter[0]) && isset($this->action_parameter[1]) && is_string($this->action_parameter[1])) {
+          $action .= ' ' . $this->action_parameter[0] . ' ( ' . $this->action_parameter[0] . ', ' . $this->action_parameter[1] . ' )';
+        }
+        else {
+          unset($action);
+          return new c_base_return_false();
+        }
+        break;
+      case e_database_method_object::OPERATOR_CLASS:
+        $action = c_database_string::OPERATOR_CLASS . ' ' . $this->name;
+        if (is_string($this->action_parameter)) {
+          $action .= ' ' . c_database_string::USING . ' ' . $this->action_parameter;
+        }
+        else {
+          unset($action);
+          return new c_base_return_false();
+        }
+        break;
+      case e_database_method_object::OPERATOR_FAMILY:
+        $action = c_database_string::OPERATOR_FAMILY . ' ' . $this->name;
+        if (is_string($this->action_parameter)) {
+          $action .= ' ' . c_database_string::USING . ' ' . $this->action_parameter;
+        }
+        else {
+          unset($action);
+          return new c_base_return_false();
+        }
+        break;
+      case e_database_method_object::LANGUAGE:
+        $action = c_database_string::LANGUAGE . ' ' . $this->name;
+        break;
+      case e_database_method_object::PROCEDURAL:
+        $action = c_database_string::PROCEDURAL . ' ' . c_database_string::LANGUAGE . ' ' . $this->name;
+        break;
+      case e_database_method_object::SCHEMA:
+        $action = c_database_string::SCHEMA . ' ' . $this->name;
+        break;
+      case e_database_method_object::SEQUENCE:
+        $action = c_database_string::SEQUENCE . ' ' . $this->name;
+        break;
+      case e_database_method_object::SERVER:
+        $action = c_database_string::SERVER . ' ' . $this->name;
+        break;
+      case e_database_method_object::TABLE:
+        $action = c_database_string::TABLE . ' ' . $this->name;
+        break;
+      case e_database_method_object::TEXT_SEARCH_CONFIGURATION:
+        $action = c_database_string::TEXT_SEARCH_CONFIGURATION . ' ' . $this->name;
+        break;
+      case e_database_method_object::TEXT_SEARCH_DICTIONARY:
+        $action = c_database_string::TEXT_SEARCH_DICTIONARY . ' ' . $this->name;
+        break;
+      case e_database_method_object::TEXT_SEARCH_PARSER:
+        $action = c_database_string::TEXT_SEARCH_PARSER . ' ' . $this->name;
+        break;
+      case e_database_method_object::TEXT_SEARCH_TEMPLATE:
+        $action = c_database_string::TEXT_SEARCH_TEMPLATE . ' ' . $this->name;
+        break;
+      case e_database_method_object::TRANSFORM_FOR:
+        $action = c_database_string::TRANSFORM_FOR . ' ' . $this->name;
+        if (is_string($this->action_parameter)) {
+          $action .= ' ' . c_database_string::LANGUAGE . ' ' . $this->action_parameter;
+        }
+        else {
+          unset($action);
+          return new c_base_return_false();
+        }
+        break;
+      case e_database_method_object::TYPE:
+        $action = c_database_string::TYPE . ' ' . $this->name;
+        break;
+      case e_database_method_object::VIEW:
+        $action = c_database_string::VIEW . ' ' . $this->name;
+        break;
+      default:
+        unset($action);
+        return new c_base_return_false();
+    }
+
+    $this->value = static::pr_QUERY_COMMAND;
+    $this->value .= ' ' . $action;
+    unset($action);
+
+    return new c_base_return_true();
+  }
+}
index 2449aa7d58df8e691eb52658035e096a69be5640..d669744cb05c8be858e74e51b9773af522283bd8 100644 (file)
@@ -210,7 +210,7 @@ abstract class c_database_query extends c_base_return_string implements i_databa
     }
 
     $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_value(0, 'c_bae_return_int', $error);
+    return c_base_return_error::s_value(0, 'c_base_return_int', $error);
   }
 
   /**
index 149f87668298f244c1938c027613ef8806276904..adf788657aae092c45eb3c604274b97ab075881f 100644 (file)
@@ -11,64 +11,98 @@ namespace n_koopa;
  * A collection of strings used for generating SQL.
  */
 class c_database_string {
-  public const ADD                 = 'add';
-  public const ALL                 = 'all';
-  public const ALLOW_CONNECTIONS   = 'allow_connections';
-  public const ASCEND              = 'asc';
-  public const CASCADE             = 'cascade';
-  public const CONNECTION_LIMIT    = 'connection limit';
-  public const CREATE              = 'create';
-  public const DELETE              = 'delete';
-  public const DESCEND             = 'desc';
-  public const DROP                = 'drop';
-  public const DROP_CONSTRAINT     = 'drop constraint';
-  public const DROP_DEFAULT        = 'drop default';
-  public const EXECUTE             = 'execute';
-  public const FALSE               = 'false';
-  public const FOR                 = 'for';
-  public const FROM_CURRENT        = 'from current';
-  public const GRANT               = 'grant';
-  public const GRANT_OPTION_FOR    = 'grant option for';
-  public const GROUP               = 'group';
-  public const GROUP_BY            = 'group by';
-  public const IF_EXISTS           = 'if exists';
-  public const IN                  = 'in';
-  public const INSERT              = 'insert';
-  public const IS_TEMPLATE         = 'is_template';
-  public const NOT_NULL            = 'not null';
-  public const NOT_VALID           = 'not valid';
-  public const ORDER_BY            = 'order by';
-  public const OWNER_TO            = 'owner to';
-  public const ON_FUNCTIONS        = 'on functons';
-  public const ON_SCHEMAS          = 'on schemas';
-  public const ON_SEQUENCES        = 'on sequences';
-  public const ON_TABLES_TO        = 'on tables to';
-  public const ON_TYPES            = 'on types';
-  public const PUBLIC              = 'public';
-  public const REFERENCES          = 'references';
-  public const REFRESH_VERSION     = 'refresh version';
-  public const RENAME_TO           = 'rename to';
-  public const RENAME_CONSTRAINT   = 'rename constraint';
-  public const RESET               = 'reset';
-  public const RESET_ALL           = 'reset all';
-  public const RESTRICT            = 'restrict';
-  public const REVOKE              = 'revoke';
-  public const ROLE                = 'role';
-  public const SELECT              = 'select';
-  public const SET                 = 'set';
-  public const SET_DEFAULT         = 'set default';
-  public const SET_SCHEMA          = 'set schema';
-  public const SET_TABLESPACE      = 'set tablespace';
-  public const TRIGGER             = 'trigger';
-  public const TRUE                = 'true';
-  public const TRUNCATE            = 'truncate';
-  public const TO                  = 'to';
-  public const UPDATE              = 'update';
-  public const USAGE               = 'usage';
-  public const USER_CURRENT        = 'current_user';
-  public const USER_SESSION        = 'session_user';
-  public const VALIDATE_CONSTRAINT = 'validate constraint';
-  public const VARIADIC            = 'variadic';
-  public const WITH                = 'with';
-  public const WITH_GRANT_OPTION   = 'with grant option';
+  public const ACCESS_METHOD              = 'access method';
+  public const ADD                        = 'add';
+  public const AGGREGATE                  = 'aggregate';
+  public const ALL                        = 'all';
+  public const ALLOW_CONNECTIONS          = 'allow_connections';
+  public const AS                         = 'as';
+  public const ASCEND                     = 'asc';
+  public const CASCADE                    = 'cascade';
+  public const CAST                       = 'cast';
+  public const COLLATION                  = 'collation';
+  public const CONNECTION_LIMIT           = 'connection limit';
+  public const CONVERSION                 = 'conversion';
+  public const CREATE                     = 'create';
+  public const DELETE                     = 'delete';
+  public const DESCEND                    = 'desc';
+  public const DOMAIN                     = 'domain';
+  public const DROP                       = 'drop';
+  public const DROP_CONSTRAINT            = 'drop constraint';
+  public const DROP_DEFAULT               = 'drop default';
+  public const EVENT_TRIGGER              = 'event trigger';
+  public const EXECUTE                    = 'execute';
+  public const FALSE                      = 'false';
+  public const FOREIGN_DATA_WRAPPER       = 'foreign data wrapper';
+  public const FOREIGN_TABLE              = 'foreign table';
+  public const FOR                        = 'for';
+  public const FROM_CURRENT               = 'from current';
+  public const FUNCTION                   = 'function';
+  public const GRANT                      = 'grant';
+  public const GRANT_OPTION_FOR           = 'grant option for';
+  public const GROUP                      = 'group';
+  public const GROUP_BY                   = 'group by';
+  public const HANDLER                    = 'handler';
+  public const IF_EXISTS                  = 'if exists';
+  public const IN                         = 'in';
+  public const INSERT                     = 'insert';
+  public const IS_TEMPLATE                = 'is_template';
+  public const LANGUAGE                   = 'language';
+  public const MATERIALIZED_VIEW          = 'materialized view';
+  public const NO_HANDLER                 = 'no handler';
+  public const NO_VALIDATOR               = 'no validator';
+  public const NOT_NULL                   = 'not null';
+  public const NOT_VALID                  = 'not valid';
+  public const ON_FUNCTIONS               = 'on functons';
+  public const ON_SCHEMAS                 = 'on schemas';
+  public const ON_SEQUENCES               = 'on sequences';
+  public const ON_TABLES_TO               = 'on tables to';
+  public const ON_TYPES                   = 'on types';
+  public const ONLY                       = 'only';
+  public const OPERATOR_CLASS             = 'operator class';
+  public const OPERATOR_FAMILY            = 'operator family';
+  public const OPTIONS                    = 'options';
+  public const ORDER_BY                   = 'order by';
+  public const OWNER_TO                   = 'owner to';
+  public const PROCEDURAL                 = 'procedural';
+  public const PUBLIC                     = 'public';
+  public const REFERENCES                 = 'references';
+  public const REFRESH_VERSION            = 'refresh version';
+  public const RENAME_TO                  = 'rename to';
+  public const RENAME_CONSTRAINT          = 'rename constraint';
+  public const RESET                      = 'reset';
+  public const RESET_ALL                  = 'reset all';
+  public const RESTRICT                   = 'restrict';
+  public const REVOKE                     = 'revoke';
+  public const ROLE                       = 'role';
+  public const SCHEMA                     = 'schema';
+  public const SELECT                     = 'select';
+  public const SEQUENCE                   = 'sequence';
+  public const SERVER                     = 'server';
+  public const SET                        = 'set';
+  public const SET_DEFAULT                = 'set default';
+  public const SET_SCHEMA                 = 'set schema';
+  public const SET_TABLESPACE             = 'set tablespace';
+  public const TABLE                      = 'table';
+  public const TEXT_SEARCH_CONFIGURATION  = 'text search configuration';
+  public const TEXT_SEARCH_DICTIONARY     = 'text search dictionary';
+  public const TEXT_SEARCH_PARSER         = 'text search parser';
+  public const TEXT_SEARCH_TEMPLATE       = 'text search template';
+  public const TRANSFORM_FOR              = 'transform for';
+  public const TRIGGER                    = 'trigger';
+  public const TRUE                       = 'true';
+  public const TRUNCATE                   = 'truncate';
+  public const TYPE                       = 'type';
+  public const TO                         = 'to';
+  public const UPDATE                     = 'update';
+  public const USAGE                      = 'usage';
+  public const USER_CURRENT               = 'current_user';
+  public const USER_SESSION               = 'session_user';
+  public const USING                      = 'using';
+  public const VALIDATOR                  = 'validator';
+  public const VALIDATE_CONSTRAINT        = 'validate constraint';
+  public const VARIADIC                   = 'variadic';
+  public const VIEW                       = 'view';
+  public const WITH                       = 'with';
+  public const WITH_GRANT_OPTION          = 'with grant option';
 }
index 5868fcddfc9b444666337d13c2c53e336efb9b3b..b2b722a081e75e6bdb29d0e4398919378bd49b27 100644 (file)
@@ -19,11 +19,16 @@ class e_database_action {
   public const DROP_DEFAULT        = 5;
   public const ENABLE              = 6;
   public const GRANT               = 7;
-  public const OWNER_TO            = 8;
-  public const RENAME_CONSTRAINT   = 9;
-  public const RENAME_TO           = 10;
-  public const SET                 = 11;
-  public const SET_DEFAULT         = 12;
-  public const SET_SCHEMA          = 13;
-  public const VALIDATE_CONSTRAINT = 14;
+  public const HANDLER             = 8;
+  public const NO_HANDLER          = 9;
+  public const OPTIONS             = 10;
+  public const OWNER_TO            = 11;
+  public const RENAME_CONSTRAINT   = 12;
+  public const RENAME_TO           = 13;
+  public const SET                 = 14;
+  public const SET_DEFAULT         = 15;
+  public const SET_SCHEMA          = 16;
+  public const VALIDATE_CONSTRAINT = 17;
+  public const VALIDATOR           = 18;
+  public const NO_VALIDATOR        = 19;
 }
diff --git a/common/database/enumerations/database_handler.php b/common/database/enumerations/database_handler.php
new file mode 100644 (file)
index 0000000..8bd6ab0
--- /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 database options.
+ */
+class e_database_handler {
+  public const NONE       = 0;
+  public const HANDLER    = 1;
+  public const NO_HANDLER = 2;
+}
diff --git a/common/database/enumerations/database_member_object.php b/common/database/enumerations/database_member_object.php
new file mode 100644 (file)
index 0000000..9f36278
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/**
+ * @file
+ * Provides enumeration classes for member object methods used for generating specific Postgesql Queries.
+ *
+ * @see: https://www.postgresql.org/docs/current/static/sql-commands.html
+ */
+namespace n_koopa;
+
+/**
+ * Codes associated with database actions.
+ */
+class e_database_member_object {
+  public const NONE                      = 0;
+  public const ACCESS_METHOD             = 1;
+  public const AGGREGATE                 = 2;
+  public const CAST                      = 3;
+  public const COLLATION                 = 4;
+  public const CONVERSION                = 5;
+  public const DOMAIN                    = 6;
+  public const EVENT_TRIGGER             = 7;
+  public const FOREIGN_DATA_WRAPPER      = 8;
+  public const FOREIGN_TABLE             = 9;
+  public const FUNCTION                  = 10;
+  public const MATERIALIZED_VIEW         = 11;
+  public const OPERATOR_CLASS            = 12;
+  public const OPERATOR_FAMILY           = 13;
+  public const SCHEMA                    = 14;
+  public const SEQUENCE                  = 14;
+  public const SERVER                    = 14;
+  public const TABLE                     = 14;
+  public const TEXT_SEARCH_CONFIGURATION = 14;
+  public const TEXT_SEARCH_DICTIONARY    = 14;
+  public const TEXT_SEARCH_PARSER        = 14;
+  public const TEXT_SEARCH_TEMPLATE      = 14;
+  public const TRANSFORM_FOR             = 14;
+  public const TYPE                      = 14;
+  public const VIEW                      = 14;
+}
diff --git a/common/database/enumerations/database_options.php b/common/database/enumerations/database_options.php
new file mode 100644 (file)
index 0000000..4394cb8
--- /dev/null
@@ -0,0 +1,18 @@
+<?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 database options.
+ */
+class e_database_options {
+  public const NONE = 0;
+  public const ADD  = 1;
+  public const DROP = 2;
+  public const SET  = 3;
+}
index 7eed3d55bc1a3cf3bf6267cfb24a373dbf5c20f5..d39aff13ef77ff881af3ac2072e4700ec5766754 100644 (file)
@@ -12,8 +12,11 @@ namespace n_koopa;
  */
 class e_database_property {
   public const NONE      = 0;
-  public const ALWAYS    = 1;
-  public const IF_EXISTS = 2;
-  public const NOT_VALID = 3;
-  public const REPLICA   = 4;
+  public const ADD       = 1;
+  public const ALWAYS    = 2;
+  public const DROP      = 3;
+  public const IF_EXISTS = 4;
+  public const NOT_VALID = 5;
+  public const REPLICA   = 6;
+  public const SET       = 7;
 }
diff --git a/common/database/enumerations/database_validator.php b/common/database/enumerations/database_validator.php
new file mode 100644 (file)
index 0000000..80fce72
--- /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 database options.
+ */
+class e_database_validator {
+  public const NONE         = 0;
+  public const NO_VALIDATOR = 1;
+  public const VALIDATOR    = 2;
+}
index 4dfbb983788ce72d5bf69ccbe023df37f3132e84..c96a0b47f9bd5c76b53d14f043843658fdb60894 100644 (file)
@@ -12,6 +12,8 @@ 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');
+
 /**
  * Provide action support for an SQL query.
  *
@@ -62,6 +64,25 @@ trait t_database_action {
 
     return c_base_return_int::s_new($this->action);
   }
+
+  /**
+   * 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_action() {
+    $value = NULL;
+
+    if (is_string($this->action)) {
+      //$value = c_database_string::RENAME_TO . ' (' . $this->rename_to . ')';
+    }
+
+    return $value;
+  }
 }
 
 /**
@@ -113,4 +134,87 @@ trait t_database_action_property {
 
     return c_base_return_int::s_new($this->action_property);
   }
+
+  /**
+   * 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_action_property() {
+    $value = NULL;
+
+    if (is_string($this->action_property)) {
+      //$value = c_database_string::RENAME_TO . ' (' . $this->rename_to . ')';
+    }
+
+    return $value;
+  }
+}
+
+/**
+ * Provide parameter(s) associated with an action or action property support for an SQL query.
+ *
+ * A single parameter, a database query object, or an array of parameters that are associated with a particular action or action property.
+ */
+trait t_database_action_parameter {
+  protected $action_parameter;
+
+  /**
+   * Assigns this query action parameter(s).
+   *
+   * @param c_base_return_string|c_base_return_array|c_database_query|null $action_parameter
+   *   Whether or not to use a specified action parameter or array of parameters.
+   *   Set to NULL to disable.
+   *
+   * @return c_base_return_status
+   *   TRUE on success, FALSE otherwise.
+   *   FALSE with error bit set is returned on error.
+   */
+  public function set_action_parameter($action_parameter) {
+    if (is_null($action_parameter)) {
+      $this->action_parameter = NULL;
+      return new c_base_return_true();
+    }
+
+    if (is_string($action_parameter)) {
+      $this->action_parameter = $action_parameter;
+      return new c_base_return_true();
+    }
+
+    if (is_array($action_parameter)) {
+      $this->action_parameter = $action_parameter;
+      return new c_base_return_true();
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'action_parameter', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+    return c_base_return_error::s_false($error);
+  }
+
+  /**
+   * Get the currently assigned action parameter.
+   *
+   * @return c_base_return_string|c_base_return_array|c_database_query|c_base_return_null
+   *   String or array representing the action parameters are returned on success.
+   *   NULL is returned if undefined.
+   *   FALSE with error bit set is returned on error.
+   */
+  protected function get_action_parameter() {
+    if (is_null($this->action_parameter)) {
+      return new c_base_return_null();
+    }
+
+    if (is_array($this->action_parameter)) {
+      return c_base_return_array::s_new($this->action_parameter);
+    }
+
+    if ($this->action_parameter instanceof c_database_query) {
+      return clone($this->action_parameter);
+    }
+
+    return c_base_return_string::s_new($this->action_parameter);
+  }
 }
index 07b865e831f31afaa24632a01720de6d6087d8cd..2ecfd4f1ffffbcd1ab4e78bf8a49c5a4f250355c 100644 (file)
@@ -12,8 +12,11 @@ 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');
+
 /**
  * Provide the sql GROUP BY functionality.
+ * @fixme: doesn't group by support multiple arguments?
  */
 trait t_database_group_by {
   protected $group_by;
@@ -64,4 +67,17 @@ trait t_database_group_by {
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'group_by', ':{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_group_by() {
+    //return c_database_string::GROUP_BY . ' (' . $this->group_by . ')';
+  }
 }
diff --git a/common/database/traits/database_handler.php b/common/database/traits/database_handler.php
new file mode 100644 (file)
index 0000000..a155d3a
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+/**
+ * @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;
+
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+
+require_once('common/database/enumerations/database_handler.php');
+
+/**
+ * Provide the sql HANDLER/NO HANDLER functionality.
+ */
+trait t_database_handler {
+  protected $handler;
+
+  /**
+   * Set the HANDLER settings.
+   *
+   * @param int|null $handler
+   *   The intege representing handler/no-handler.
+   *   Set to NULL to disable.
+   * @param string|null $handler_function
+   *   The handler function name or null when NO_HANDLER is specified.
+   *
+   * @return c_base_return_status
+   *   TRUE on success, FALSE otherwise.
+   *   FALSE with the error bit set is returned on error.
+   */
+  public function set_handler($handler, $handler_function) {
+    if (is_null($handler)) {
+      $this->handler = NULL;
+      return new c_base_return_true();
+    }
+
+    if ($handler === e_database_handler::HANDLER) {
+      if (is_string($handler_function)) {
+        $this->handler[
+          'type' => $handler,
+          'name' => $handler_function,
+        ];
+
+        return new c_base_return_true();
+      }
+
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'handler_function', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+      return c_base_return_error::s_false($error);
+    }
+    else if ($handler === e_database_handler::NO_HANDLER) {
+      $this->handler[
+        'type' => $handler,
+        'name' => null,
+      ];
+
+      return new c_base_return_true();
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'handler', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+    return c_base_return_error::s_false($error);
+  }
+
+  /**
+   * Get the currently assigned handler.
+   *
+   * @return c_base_return_array|c_base_return_null
+   *   An array containing the handler data on success.
+   *   NULL is returned if not set.
+   *   NULL with the error bit set is returned on error.
+   */
+  public function get_handler() {
+    if (is_null($this->handler)) {
+      return new c_base_return_null();
+    }
+
+    if (is_array($this->handler)) {
+      return c_base_return_array::s_new($this->handler);
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'name', ':{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_handler() {
+    $value = NULL;
+
+    if (isset($this->handler['type'])) {
+      if ($this->handler['type'] == e_database_handler::HANDLER) {
+        if (isset($this->handler['name'])) {
+          $value = c_database_string::HANDLER . ' ' . $this->handler['name'];
+        }
+      }
+      else if ($this->handler['type'] == e_database_handler::NO_HANDLER) {
+        $value .= c_database_string::NO_HANDLER;
+      }
+    }
+
+    return $value;
+  }
+}
index 5bab3997b19405f60f39b7c7cc63873d0780ee63..27420a9e94aed21467b39df27ebdadfc7f748f62 100644 (file)
@@ -12,6 +12,8 @@ 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');
+
 /**
  * Provide the sql IN SCHEMA functionality.
  */
@@ -97,4 +99,17 @@ trait t_database_in_schema {
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'in_schema', ':{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_in_schema() {
+    return c_database_string::IN . ' ' . c_database_string::SCHEMA . ' ' . implode(', ', $this->in_schema);
+  }
 }
index 9b52def06aec73d54134a1c2c9d095b117a4a931..2fd482bd9b706061429692bbd7d0e5f6e4e6d743 100644 (file)
@@ -12,6 +12,8 @@ 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');
+
 /**
  * Provide option support for an SQL query.
  */
@@ -22,7 +24,7 @@ trait t_database_option {
    * Assigns this query option.
    *
    * @param int|null $option
-   *   Whether or not to use a query option, such as .
+   *   Whether or not to use a query option, such as CASCADE.
    *   Set to NULL to disable.
    *
    * @return c_base_return_status
@@ -30,7 +32,7 @@ trait t_database_option {
    *   FALSE with error bit set is returned on error.
    */
   public function set_option($option) {
-    if (is_null($grant)) {
+    if (is_null($option)) {
       $this->option = NULL;
       return new c_base_return_true();
     }
@@ -59,4 +61,26 @@ trait t_database_option {
 
     return c_base_return_int::s_new($this->option);
   }
+
+  /**
+   * 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_option() {
+    $value = NULL;
+
+    if ($this->option === e_database_option::CASCADE) {
+      $value = c_database_string::CASCADE;
+    }
+    else if ($this->option === e_database_option::RESTRICT) {
+      $value = c_database_string::RESTRICT;
+    }
+
+    return $value;
+  }
 }
diff --git a/common/database/traits/database_options.php b/common/database/traits/database_options.php
new file mode 100644 (file)
index 0000000..7f91ea8
--- /dev/null
@@ -0,0 +1,148 @@
+<?php
+/**
+ * @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;
+
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+
+require_once('common/database/enumerations/database_options.php');
+
+/**
+ * Provide options support for an SQL query.
+ */
+trait t_database_options {
+  protected $options;
+
+  /**
+   * Set the in options.
+   *
+   * @param string|null $options_type
+   *   The option type to use.
+   *   Set to NULL to disable.
+   *   When NULL, this will remove all options regardless of the $append parameter.
+   * @param string $value
+   *   The value to associate with the options_type.
+   *   When options_type is NULL, this is ignored.
+   * @param bool $append
+   *   (optional) When TRUE, the schema name will be appended.
+   *   When FALSE, any existing schema names will be cleared before appending the schema name.
+   *
+   * @return c_base_return_status
+   *   TRUE on success, FALSE otherwise.
+   *   FALSE with error bit set is returned on error.
+   */
+  public function set_options($options_type, $value, $append = TRUE) {
+    if (is_null($options_type)) {
+      $this->options = NULL;
+      return new c_base_return_true();
+    }
+
+    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_bool($append)) {
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'append', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+      return c_base_return_error::s_false($error);
+    }
+
+    switch ($options_type) {
+      case e_database_options::ADD:
+      case e_database_options::DROP:
+      case e_database_options::SET:
+        break;
+      default:
+        $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'schema_name', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+        return c_base_return_error::s_false($error);
+    };
+
+    $options = [
+      'type' => $options_type,
+      'value' => $value,
+    ];
+
+    if ($append) {
+      if (!is_array($this->options)) {
+        $this->options = [];
+      }
+
+      $this->options[] = $options;
+    }
+    else {
+      $this->options = [$options];
+    }
+    unset($options);
+
+    return new c_base_return_true();
+  }
+
+  /**
+   * Get the options.
+   *
+   * @param int|null $index
+   *   (optional) Get the options at the specified index.
+   *   When NULL, all options are returned.
+   *
+   * @return c_base_return_array|c_base_return_null
+   *   An array of options arrays or NULL if not defined.
+   *   A single options array is returned if $index is an integer.
+   *   NULL with the error bit set is returned on error.
+   */
+  public function get_options($index = NULL) {
+    if (is_null($this->options)) {
+      return new c_base_return_null();
+    }
+
+    if (is_null($index)) {
+      if (is_array($this->options)) {
+        return c_base_return_array::s_new($this->options);
+      }
+    }
+    else {
+      if (is_int($index) && array_key_exists($index, $this->options) && is_arrray($this->options[$index])) {
+        return c_base_return_array::s_new($this->options[$index]);
+      }
+
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'options[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}' => 'options', ':{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_options() {
+    $options = [];
+    foreach ($this->options as $options_value) {
+      if ($options_value['type'] == e_database_options::ADD) {
+        $options[] = c_database_string::ADD . ' ' . $options_value['value'];
+      }
+      else if ($options_value['type'] == e_database_options::DROP) {
+        $options[] = c_database_string::DROP . ' ' . $options_value['value'];
+      }
+      else if ($options_value['type'] == e_database_options::SET) {
+        $options[] = c_database_string::SET . ' ' . $options_value['value'];
+      }
+    }
+    unset($options_value);
+
+    return empty($options) ? NULL : c_database_string::OPTIONS . ' ' . implode(', ', $options);
+  }
+}
index bc6a45d69730d279c48b1b032854cc8bb89480e1..80ee53ee248233f2ebe7526c37ea3e6e5ee38d87 100644 (file)
@@ -12,8 +12,11 @@ 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');
+
 /**
  * Provide the sql ORDER BY functionality.
+ * @fixme: doesn't order by accept multiple arguments?
  */
 trait t_database_order_by {
   protected $order_by;
@@ -64,4 +67,17 @@ trait t_database_order_by {
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'order_by', ':{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_order_by() {
+    return c_database_string::ORDER_BY . ' ' . $this->order_by;
+  }
 }
index ed0dcd1a6644dffd1d3c1aa1a1fc4de1135605f6..794f284521e92a74b211ca585c6ef8d5419b13c5 100644 (file)
@@ -21,7 +21,6 @@ require_once('common/database/classes/database_string.php');
  */
 trait t_database_owner_to {
   protected $owner_to;
-  protected $owner_to_user_name;
 
   /**
    * Set the OWNER TO settings.
@@ -41,7 +40,6 @@ trait t_database_owner_to {
   public function set_owner_to($owner_to, $user_name = NULL) {
     if (is_null($owner_to)) {
       $this->owner_to = NULL;
-      $this->owner_to_user_name = NULL;
       return new c_base_return_true();
     }
 
@@ -56,8 +54,11 @@ trait t_database_owner_to {
         return c_base_return_error::s_false($error);
       }
 
-      $this->owner_to = $owner_to;
-      $this->owner_to_user_name = $user_name;
+      $this->owner_to = [
+        'type' => $owner_to,
+        'value' => $user_name,
+      ];
+
       return new c_base_return_true();
     }
 
@@ -66,14 +67,16 @@ trait t_database_owner_to {
       return c_base_return_error::s_false($error);
     }
 
-    $this->owner_to = $owner_to;
-    $this->owner_to_user_name = NULL;
+    $this->owner_to = [
+      'type' => $owner_to,
+      'value' => NULL,
+    ];
 
     if ($owner_type == e_database_user::CURRENT) {
-      $this->owner_to_user_name = c_database_string::USER_CURRENT;
+      $this->owner_to['value'] = c_database_string::USER_CURRENT;
     }
     else if ($owner_type == e_database_user::SESSION) {
-      $this->owner_to_user_name = c_database_string::USER_SESSION;
+      $this->owner_to['value'] = c_database_string::USER_SESSION;
     }
 
     return new c_base_return_true();
@@ -92,11 +95,11 @@ trait t_database_owner_to {
       return new c_base_return_null();
     }
 
-    if (is_int($this->owner_to)) {
-      return c_base_return_int::s_new($this->owner_to);
+    if (is_int($this->owner_to['type'])) {
+      return c_base_return_int::s_new($this->owner_to['type']);
     }
 
-    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'owner_to', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'owner_to[type]', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
     return c_base_return_error::s_null($error);
   }
 
@@ -109,15 +112,28 @@ trait t_database_owner_to {
    *   NULL with the error bit set is returned on error.
    */
   public function get_owner_to_user_name() {
-    if (is_null($this->owner_to_user_name)) {
+    if (is_null($this->owner_to)) {
       return new c_base_return_null();
     }
 
-    if (is_string($this->owner_to_user_name)) {
-      return c_base_return_string::s_new($this->owner_to_user_name);
+    if (is_string($this->owner_to['value'])) {
+      return c_base_return_string::s_new($this->owner_to['value']);
     }
 
-    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'owner_to_user_name', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'owner_to[value]', ':{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_owner_to() {
+    return c_database_string::OWNER_TO . ' ' . $this->owner_to['value'];
+  }
 }
diff --git a/common/database/traits/database_rename_column_to.php b/common/database/traits/database_rename_column_to.php
new file mode 100644 (file)
index 0000000..53c301b
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+/**
+ * @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;
+
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+
+/**
+ * Provide the sql RENAME COLUMN TO functionality.
+ */
+trait t_database_rename_column_to {
+  protected $rename_column_to;
+
+  /**
+   * Set the RENAME COLUMN TO settings.
+   *
+   * @param string|null $rename_column_to
+   *   The name to rename to.
+   *   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_rename_column_to($rename_column_to) {
+    if (!is_null($rename_column_to) && !is_string($rename_column_to)) {
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'rename_column_to', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+      return c_base_return_error::s_false($error);
+    }
+
+    $this->rename_column_to = $rename_column_to;
+    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.
+   *   NULL is returned if not set (rename to is not to be used).
+   *   NULL with the error bit set is returned on error.
+   */
+  public function get_rename_column_to() {
+    if (is_null($this->rename_column_to)) {
+      return new c_base_return_null();
+    }
+
+    if (is_string($this->rename_column_to)) {
+      return c_base_return_string::s_new($this->rename_column_to);
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'rename_column_to', ':{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_rename_column_to() {
+    return c_database_string::RENAME_COLUMN_TO . ' ' . $this->rename_to;
+  }
+}
index 297e08c5143f02dc910b3e0b48909e21e7184c70..009baabd7a891b95a6252757caa82147d0727192 100644 (file)
@@ -12,6 +12,8 @@ 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');
+
 /**
  * Provide the sql RENAME TO functionality.
  */
@@ -59,4 +61,17 @@ trait t_database_rename_to {
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'rename_to', ':{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_rename_to() {
+    return c_database_string::RENAME_TO . ' ' . $this->rename_to;
+  }
 }
index 862f66b169cc552252525b0053c0c93aa1e7babd..5b7f7245008d74039b038f18b5cf4635d367f4d1 100644 (file)
@@ -12,6 +12,8 @@ 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_reset.php');
 
 /**
@@ -19,7 +21,6 @@ require_once('common/database/enumerations/database_reset.php');
  */
 trait t_database_reset {
   protected $reset;
-  protected $reset_parameter;
 
   /**
    * Set the RESET settings.
@@ -39,7 +40,6 @@ trait t_database_reset {
   public function set_reset($reset, $parameter = NULL) {
     if (is_null($reset)) {
       $this->reset = NULL;
-      $this->reset_parameter = NULL;
       return new c_base_return_true();
     }
 
@@ -54,13 +54,19 @@ trait t_database_reset {
         return c_base_return_error::s_false($error);
       }
 
-      $this->reset = $reset;
-      $this->reset_parameter = $parameter;
+      $this->reset = [
+        'type' => $reset,
+        'value' => $parameter,
+      ];
+
       return new c_base_return_true();
     }
     else if ($reset == e_database_reset::ALL) {
-      $this->reset = $reset;
-      $this->reset_parameter = NULL;
+      $this->reset = [
+        'type' => $reset,
+        'value' => NULL,
+      ];
+
       return new c_base_return_true();
     }
 
@@ -80,11 +86,11 @@ trait t_database_reset {
       return new c_base_return_null();
     }
 
-    if (is_int($this->reset)) {
-      return c_base_return_int::s_new($this->reset);
+    if (is_int($this->reset['type'])) {
+      return c_base_return_int::s_new($this->reset['type']);
     }
 
-    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'reset', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'reset[type]', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
     return c_base_return_error::s_null($error);
   }
 
@@ -97,15 +103,39 @@ trait t_database_reset {
    *   NULL with the error bit reset is returned on error.
    */
   public function get_reset_parameter() {
-    if (is_null($this->reset_parameter)) {
+    if (is_null($this->reset) || is_null($this->reset['value'])) {
       return new c_base_return_null();
     }
 
-    if (is_string($this->reset_parameter)) {
-      return c_base_return_string::s_new($this->reset_parameter);
+    if (is_string($this->reset['value'])) {
+      return c_base_return_string::s_new($this->reset['value']);
     }
 
-    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'reset_parameter', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'reset[value]', ':{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_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'];
+      }
+    }
+    else if ($this->reset['type'] === e_database_reset::ALL) {
+      $value = c_database_string::RESET . ' ' . c_database_string::ALL;
+    }
+
+    return $value;
+  }
 }
index 90ebb61edc0014a3da3a171bd21115c9b61d17bf..2e41d78e4c7ebab3d54d5df18c50c232fee7388a 100644 (file)
@@ -14,13 +14,13 @@ require_once('common/base/classes/base_return.php');
 
 require_once('common/database/enumerations/database_set.php');
 
+require_once('common/database/classes/database_string.php');
+
 /**
  * Provide the sql SET functionality.
  */
 trait t_database_set {
   protected $set;
-  protected $set_parameter;
-  protected $set_value;
 
   /**
    * Set the SET settings.
@@ -43,8 +43,6 @@ trait t_database_set {
   public function set_set($set, $parameter = NULL, $value = NULL) {
     if (is_null($set)) {
       $this->set = NULL;
-      $this->set_parameter = NULL;
-      $this->set_value = NULL;
       return new c_base_return_true();
     }
 
@@ -64,15 +62,20 @@ trait t_database_set {
         return c_base_return_error::s_false($error);
       }
 
-      $this->set = $set;
-      $this->set_parameter = $parameter;
-      $this->set_value = $value;
+      $this->set = [
+        'type' => $set,
+        'parameter' => $parameter,
+        'value' => $value,
+      ];
+
       return new c_base_return_true();
     }
     else if ($set == e_database_set::FROM_CURRENT) {
-      $this->set = $set;
-      $this->set_parameter = NULL;
-      $this->set_value = NULL;
+      $this->set = [
+        'type' => $set,
+        'parameter' => NULL,
+        'value' => NULL,
+      ];
       return new c_base_return_true();
     }
 
@@ -92,8 +95,8 @@ trait t_database_set {
       return new c_base_return_null();
     }
 
-    if (is_int($this->set)) {
-      return c_base_return_int::s_new($this->set);
+    if (is_int($this->set['type'])) {
+      return c_base_return_int::s_new($this->set['type']);
     }
 
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'set', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
@@ -109,12 +112,12 @@ trait t_database_set {
    *   NULL with the error bit set is returned on error.
    */
   public function get_set_parameter() {
-    if (is_null($this->set_parameter)) {
+    if (is_null($this->set) || is_null($this->set['parameter'])) {
       return new c_base_return_null();
     }
 
-    if (is_string($this->set_parameter)) {
-      return c_base_return_string::s_new($this->set_parameter);
+    if (is_string($this->set['parameter'])) {
+      return c_base_return_string::s_new($this->set['parameter']);
     }
 
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'set_parameter', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_VARIABLE);
@@ -130,15 +133,52 @@ trait t_database_set {
    *   NULL with the error bit set is returned on error.
    */
   public function get_set_value() {
-    if (is_null($this->set_value)) {
+    if (is_null($this->set) || is_null($this->set['value'])) {
       return new c_base_return_null();
     }
 
-    if (is_string($this->set_value)) {
-      return c_base_return_string::s_new($this->set_value);
+    if (is_string($this->set['value'])) {
+      return c_base_return_string::s_new($this->set['value']);
     }
 
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'set_value', ':{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() {
+    $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;
+      }
+      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 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;
+      }
+      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 ($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;
+      }
+    }
+
+    return $value;
+  }
 }
index aeb5798a7ac555184aa53b0f9f84a0c6dc8a9719..52df4674dd8ff19d7d0b597d99d00c0dd4c36855 100644 (file)
@@ -61,4 +61,17 @@ trait t_database_set_schema {
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'set_schema', ':{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_schema() {
+    return c_database_string::SET_SCHEMA . ' ' . $this->set_schema;
+  }
 }
index b1262717c6eabbc7128bf203b0d82de646b6688d..692911ad00356805aaf01bb45e815fd9c1aa26f3 100644 (file)
@@ -12,6 +12,8 @@ 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');
+
 /**
  * Provide the sql SET TABLESPACE functionality.
  */
@@ -59,4 +61,17 @@ trait t_database_set_tablespace {
     $error = c_base_error::s_log(NULL, ['arguments' => [':{variable_name}' => 'set_tablespace', ':{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_tablespace() {
+    return c_database_string::SET_TABLESPACE . ' (' . $this->set_tablespace . ')';
+  }
 }
diff --git a/common/database/traits/database_validator.php b/common/database/traits/database_validator.php
new file mode 100644 (file)
index 0000000..53b531a
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+/**
+ * @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;
+
+require_once('common/base/classes/base_error.php');
+require_once('common/base/classes/base_return.php');
+
+require_once('common/database/enumerations/database_validator.php');
+
+/**
+ * Provide the sql VALIDATOR/NO VALIDATOR functionality.
+ */
+trait t_database_validator {
+  protected $validator;
+
+  /**
+   * Set the VALIDATOR settings.
+   *
+   * @param int|null $validator
+   *   The intege representing validator/no-validator.
+   *   Set to NULL to disable.
+   * @param string|null $validator_function
+   *   The validator function name or null when NO_VALIDATOR is specified.
+   *
+   * @return c_base_return_status
+   *   TRUE on success, FALSE otherwise.
+   *   FALSE with the error bit set is returned on error.
+   */
+  public function set_validator($validator, $validator_function) {
+    if (is_null($validator)) {
+      $this->validator = NULL;
+      return new c_base_return_true();
+    }
+
+    if ($validator === e_database_validator::VALIDATOR) {
+      if (is_string($validator_function)) {
+        $this->validator[
+          'type' => $validator,
+          'name' => $validator_function,
+        ];
+
+        return new c_base_return_true();
+      }
+
+      $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'validator_function', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+      return c_base_return_error::s_false($error);
+    }
+    else if ($validator === e_database_validator::NO_VALIDATOR) {
+      $this->validator[
+        'type' => $validator,
+        'name' => null,
+      ];
+
+      return new c_base_return_true();
+    }
+
+    $error = c_base_error::s_log(NULL, ['arguments' => [':{argument_name}' => 'validator', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__]], i_base_error_messages::INVALID_ARGUMENT);
+    return c_base_return_error::s_false($error);
+  }
+
+  /**
+   * Get the currently assigned validator.
+   *
+   * @return c_base_return_array|c_base_return_null
+   *   An array containing the validator data on success.
+   *   NULL is returned if not set.
+   *   NULL with the error bit set is returned on error.
+   */
+  public function get_validator() {
+    if (is_null($this->validator)) {
+      return new c_base_return_null();
+    }
+
+    if (is_array($this->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);
+    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_validator() {
+    $value = NULL;
+
+    if (is_array($this->validator) && isset($this->validator['type'])) {
+      if ($this->validator['type'] == e_database_validator::VALIDATOR) {
+        if (isset($this->validator['name'])) {
+          $value = c_database_string::VALIDATOR . ' ' . $this->validator['name'];
+        }
+      }
+      else if ($this->validator['type'] == e_database_validator::NO_VALIDATOR) {
+        $value = c_database_string::NO_VALIDATOR;
+      }
+    }
+
+    return $value;
+  }
+}
diff --git a/todo.notes b/todo.notes
new file mode 100644 (file)
index 0000000..04a1791
--- /dev/null
@@ -0,0 +1,11 @@
+Bugfix: many functions are claiming to return false with error bit set, but are only returning false (no error bit set).
+Investigate: c_base_defaults_global class function s_get_languages_class() is calling get_class() on $this->s_language instead of self::s_language. which is most/more correct?
+
+I have had too much start and stop when writing the postgesql database sql generation classes.
+It looks like I swapped between a few different ways of design.
+To keep progress going, I am just going to continue writing this and plan on returning.
+I need to decided on an approach, implement it fully, and then switch to it.
+One of the problems that I need to review is how I am going to handle argument placeholders:
+1) do it simple and always support passing a string (are the values maintained or are they passed separately?)
+2) use a custom class for representing a parameter (could also store the value).
+3) attempt to automate the process such that parameters are handled internally.