Archive: Namaste PHP AMQP framework v1.0 (2017-2020)
952 days continuous production uptime, 40k+ tp/s single node. Original corpo Bitbucket history not included — clean archive commit.
This commit is contained in:
217
classes/templates/deprecated/xxxLogs.class.inc
Normal file
217
classes/templates/deprecated/xxxLogs.class.inc
Normal file
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class gatLog
|
||||
*
|
||||
* This is the logging class definition that records framework-generated event messages.
|
||||
*
|
||||
* Design Notes:
|
||||
* -------------
|
||||
* because this is a log, who's events are processed by a FnF queue, we're not going to cache, or use auditing.
|
||||
* History is limited to the created event and deletes are HARD.
|
||||
* Only one status is supported: ACTIVE and there are no updates allowed making record-locking unnecessary.
|
||||
* To reduce overhead, we're not enabling cache timers because recursion.
|
||||
* The collection does not need GUID tokens but we are storing the passed Broker Event ID
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 2.1.3
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-07-17 mks original coding
|
||||
*
|
||||
*
|
||||
*/
|
||||
class xxxLogs
|
||||
{
|
||||
public $service = CONFIG_DATABASE_DDB_APPSERVER; // defines the nosql server service configuration
|
||||
public $schema = TEMPLATE_DB_DDB; // defines the storage schema for the class
|
||||
public $collection = COLLECTION_MONGO_LOGS; // sets the collection (table) name
|
||||
public $seqKey = COLLECTION_NOSQL_LOGS_SQK; // sets the sequence key identifier
|
||||
public $extension = COLLECTION_MONGO_LOGS_EXT; // sets the extension for the collection
|
||||
public $setCache = false; // set to true to cache class data
|
||||
public $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public $setJournaling = false; // set to true to allow journaling
|
||||
public $setUpdates = false; // set to true to allow record updates
|
||||
public $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public $setLocking = false; // set to true to enable record locking for collection
|
||||
public $setTimers = false; // set to true to enable collection query timers
|
||||
public $setPKeyType = DB_TOKEN; // sets the primary key type: either ID or TOKEN
|
||||
|
||||
/*
|
||||
* tokens are guids -- if you're using a guid as the pkey for the class, then this value should be false.
|
||||
* if you're using an integer pkey, and you want a token, you have to explicitly declare
|
||||
* the token fields in $fields and set this value to true.
|
||||
* if you're using an integer pkey and you don't want a token, set this value to false.
|
||||
*/
|
||||
public $setTokens = false; // set to true: adds the idToken field functionality
|
||||
public $selfDestruct = true; // set to false if the class contains methods
|
||||
public $cacheTimer = 0; // number of seconds a tuple will remain in-cache
|
||||
public $setEnv = ENV_ALL; // defines the env where this class can be accessed
|
||||
public $setMeta = false; // defines if we'll use the meta package for history
|
||||
|
||||
public $fields = [
|
||||
DB_PKEY => DDB_TYPE_STRING, // GUID because setPKeyType == DB_TOKEN
|
||||
LOG_FILE => DDB_TYPE_STRING,
|
||||
LOG_METHOD => DDB_TYPE_STRING,
|
||||
LOG_LINE => DDB_TYPE_NUMBER,
|
||||
LOG_CLASS => DDB_TYPE_STRING,
|
||||
LOG_LEVEL => DDB_TYPE_STRING,
|
||||
LOG_MESSAGE => DDB_TYPE_STRING,
|
||||
LOG_STACK_TRACE => DDB_TYPE_LIST,
|
||||
DB_STATUS => DDB_TYPE_STRING,
|
||||
DB_HISTORY => DDB_TYPE_LIST,
|
||||
LOG_IS_EVENT => DDB_TYPE_BOOLEAN,
|
||||
LOG_EVENT_GUID => DDB_TYPE_STRING,
|
||||
LOG_CREATED => DDB_TYPE_NUMBER
|
||||
];
|
||||
|
||||
public $fieldTypes = [
|
||||
DB_PKEY => DATA_TYPE_STRING, // guid
|
||||
LOG_FILE => DATA_TYPE_STRING,
|
||||
LOG_METHOD => DATA_TYPE_STRING,
|
||||
LOG_LINE => DATA_TYPE_INTEGER,
|
||||
LOG_CLASS => DATA_TYPE_STRING,
|
||||
LOG_LEVEL => DATA_TYPE_STRING,
|
||||
LOG_MESSAGE => DATA_TYPE_STRING,
|
||||
LOG_STACK_TRACE => DATA_TYPE_ARRAY,
|
||||
DB_STATUS => DATA_TYPE_STRING,
|
||||
DB_TIMER => DATA_TYPE_DOUBLE,
|
||||
DB_HISTORY => DATA_TYPE_ARRAY,
|
||||
LOG_IS_EVENT => DATA_TYPE_BOOL,
|
||||
LOG_EVENT_GUID => DATA_TYPE_STRING,
|
||||
LOG_CREATED => DATA_TYPE_INTEGER
|
||||
];
|
||||
|
||||
// in the ddb world, this is the primary composite key for this table
|
||||
public $indexes = [ DB_PKEY => DDB_INDEX_HASH, LOG_CREATED => DDB_INDEX_RANGE ];
|
||||
|
||||
/*
|
||||
* declaring global and local secondary indexes:
|
||||
*
|
||||
* Limit: 5 of each
|
||||
*
|
||||
* General Format:
|
||||
* ---------------
|
||||
* Each tuple, up to the limit, is a record that contains the following array structure:
|
||||
*
|
||||
* [[
|
||||
* 'name' => INDEX_NAME, // REQUIRED
|
||||
* 'indexes' => [ KEY_NAME => HASH {, KEY_NAME => RANGE } ], // REQUIRED
|
||||
* 'projectionType' => { KEYS_ONLY | INCLUDE | ALL }, // REQUIRED
|
||||
* 'nka' => { [ list of one or more non-key attributes !>20 ] }, // REQUIRED if projection = INCLUDE
|
||||
* 'throughput' => [ 'rcu' => <integer>, 'wcu' => <integer> ] // REQUIRED for GLOBAL only
|
||||
* ],....];
|
||||
*
|
||||
* secondary index keys must use the key literals as shown above. ('name', 'indexes', 'projectionType', etc.)
|
||||
*
|
||||
*/
|
||||
public $globalIndexes = array(
|
||||
[
|
||||
// this creates a partition key based on the log level (fatal, warn, debug, etc.) with a sort key
|
||||
// based on the method (the class method that created the log event).
|
||||
// query example: give me all fatal errors
|
||||
// give me all warnings generate by the method: _fetchData()
|
||||
// Since the base keys (id, date) are projected onto this index, I am (awaiting testing) assuming
|
||||
// that you could also range your query based on the creation date.
|
||||
STRING_NAME => 'index_log_level',
|
||||
STRING_INDEXES => [ LOG_LEVEL => DDB_INDEX_HASH, LOG_METHOD => DDB_INDEX_RANGE ],
|
||||
DDB_STRING_PT => DDB_PT_ALL,
|
||||
STRING_THROUGHPUT => [ CONFIG_DATABASE_READ_CAPACITY_UNITS => 100, CONFIG_DATABASE_WRITE_CAPACITY_UNITS => 100 ]
|
||||
],
|
||||
[
|
||||
// lets add a second global index: key will be the created date, and the sort will be the error level
|
||||
// this will allow us to answer queries like:
|
||||
// give me all errors in the last hour
|
||||
// give me all fatal errors for January
|
||||
STRING_NAME => 'index_log_created',
|
||||
STRING_INDEXES => [ LOG_CREATED => DDB_INDEX_HASH, LOG_LEVEL => DDB_INDEX_RANGE ],
|
||||
DDB_STRING_PT => DDB_PT_INCLUDE,
|
||||
DDB_STRING_NON_KEY_ATTRIBUTE => [ LOG_FILE, LOG_CLASS, LOG_METHOD, LOG_LINE ],
|
||||
STRING_THROUGHPUT => [ CONFIG_DATABASE_READ_CAPACITY_UNITS => 100, CONFIG_DATABASE_WRITE_CAPACITY_UNITS => 100 ]
|
||||
]
|
||||
);
|
||||
|
||||
public $localIndexes = array(
|
||||
[
|
||||
// create secondary index using the log-level as the range value making the assumption that the
|
||||
// base index hash will be used as the local secondary hash
|
||||
STRING_NAME => 'index_sec_level',
|
||||
STRING_INDEXES => [ DB_PKEY => DDB_INDEX_HASH, LOG_LEVEL => DDB_INDEX_RANGE ],
|
||||
DDB_STRING_PT => DDB_PT_ALL
|
||||
]
|
||||
);
|
||||
|
||||
public $exposedFields = null; // list of fields exposed to clients
|
||||
public $cacheMap = null; // k->v paired array mapping fields -> cachedField Names
|
||||
public $binFields = null; // binary fields that have to be encoded
|
||||
|
||||
// these fields aren't used in DDB, but are used in mongo, so are here only for code-compatibility
|
||||
public $uniqueIndexes = null;
|
||||
public $sparseIndexes = null;
|
||||
public $subCollections = null;
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-07-17 mks original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-07-17 mks original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-07-17 mks original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
185
classes/templates/deprecated/xxxMetrics.class.inc
Normal file
185
classes/templates/deprecated/xxxMetrics.class.inc
Normal file
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class pgtMetrics
|
||||
*
|
||||
* This is the metrics class definition that records timer events, usually database queries.
|
||||
*
|
||||
* Design Notes:
|
||||
* -------------
|
||||
* Metrics is identical to Logs, who's events are processed by a FnF queue, we're not going to cache, or use auditing.
|
||||
* History is limited to the created event and deletes are HARD.
|
||||
* Only one status is supported: ACTIVE and there are no updates allowed making record-locking unnecessary.
|
||||
* To reduce overhead, we're not enabling cache timers because recursive.
|
||||
* The collection does not need GUID tokens but we are storing the passed session ID in the meta payload for the
|
||||
* create event - which is the only history event required or logged.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-07-17 mks code complete
|
||||
*
|
||||
*/
|
||||
class xxxMetrics
|
||||
{
|
||||
public $service = CONFIG_DATABASE_DDB_APPSERVER; // defines the nosql server service configuration
|
||||
public $schema = TEMPLATE_DB_DDB; // defines the storage schema for the class
|
||||
public $collection = COLLECTION_MONGO_METRICS; // sets the collection (table) name
|
||||
public $seqKey = COLLECTION_NOSQL_METRICS_SQK; // sets the sequence key identifier
|
||||
public $extension = COLLECTION_MONGO_METRICS_EXT; // sets the extension for the collection
|
||||
public $setCache = false; // set to true to cache class data
|
||||
public $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public $setJournaling = false; // set to true to enable journaling
|
||||
public $setUpdates = false; // set to true to allow record updates
|
||||
public $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public $setLocking = false; // set to true to enable record locking for collection
|
||||
public $setTimers = false; // set to true to enable collection query timers
|
||||
public $setPKeyType = DB_TOKEN; // sets the primary key type: either ID or TOKEN
|
||||
/*
|
||||
* tokens are guids -- if you're using a guid as the pkey for the class, then this value should be false.
|
||||
* if you're using an integer pkey, and you want a token, you have to explicitly declare
|
||||
* the token fields in $fields and set this value to true.
|
||||
* if you're using an integer pkey and you don't want a token, set this value to false.
|
||||
*/
|
||||
public $setTokens = false; // set to true: adds the idToken field functionality
|
||||
public $selfDestruct = true; // set to false if the class contains methods
|
||||
public $cacheTimer = 0; // number of seconds a tuple will remain in-cache
|
||||
public $setEnv = ENV_ALL; // defines the env where this class can be accessed
|
||||
public $setMeta = false; // defines if we'll use the meta package for history
|
||||
|
||||
public $fields = [
|
||||
DB_PKEY => DDB_TYPE_STRING, // GUID because setPKeyType == DB_TOKEN
|
||||
LOG_FILE => DDB_TYPE_STRING,
|
||||
LOG_METHOD => DDB_TYPE_STRING,
|
||||
LOG_LINE => DDB_TYPE_NUMBER,
|
||||
LOG_CLASS => DDB_TYPE_STRING,
|
||||
LOG_LEVEL => DDB_TYPE_STRING,
|
||||
LOG_MESSAGE => DDB_TYPE_STRING,
|
||||
LOG_STACK_TRACE => DDB_TYPE_LIST,
|
||||
DB_STATUS => DDB_TYPE_STRING,
|
||||
DB_TIMER => DDB_TYPE_NUMBER,
|
||||
DB_HISTORY => DDB_TYPE_LIST,
|
||||
LOG_IS_EVENT => DDB_TYPE_BOOLEAN,
|
||||
LOG_EVENT_GUID => DDB_TYPE_STRING,
|
||||
LOG_CREATED => DDB_TYPE_NUMBER
|
||||
];
|
||||
|
||||
public $fieldTypes = [
|
||||
DB_PKEY => DATA_TYPE_STRING, // guid
|
||||
LOG_FILE => DATA_TYPE_STRING,
|
||||
LOG_METHOD => DATA_TYPE_STRING,
|
||||
LOG_LINE => DATA_TYPE_INTEGER,
|
||||
LOG_CLASS => DATA_TYPE_STRING,
|
||||
LOG_LEVEL => DATA_TYPE_STRING,
|
||||
LOG_MESSAGE => DATA_TYPE_STRING,
|
||||
LOG_STACK_TRACE => DATA_TYPE_ARRAY,
|
||||
DB_STATUS => DATA_TYPE_STRING,
|
||||
DB_TIMER => DATA_TYPE_DOUBLE,
|
||||
DB_HISTORY => DATA_TYPE_ARRAY,
|
||||
LOG_IS_EVENT => DATA_TYPE_BOOL,
|
||||
LOG_EVENT_GUID => DATA_TYPE_STRING,
|
||||
LOG_CREATED => DATA_TYPE_INTEGER
|
||||
];
|
||||
|
||||
// in the ddb world, this is the primary composite key for this table
|
||||
public $indexes = [ DB_PKEY => DDB_INDEX_HASH, LOG_CREATED => DDB_INDEX_RANGE ];
|
||||
|
||||
/*
|
||||
* declaring global and local secondary indexes:
|
||||
*
|
||||
* Limit: 5 of each
|
||||
*
|
||||
* General Format:
|
||||
* ---------------
|
||||
* Each tuple, up to the limit, is a record that contains the following array structure:
|
||||
*
|
||||
* [[
|
||||
* 'name' => INDEX_NAME, // REQUIRED
|
||||
* 'indexes' => [ KEY_NAME => HASH {, KEY_NAME => RANGE } ], // REQUIRED
|
||||
* 'projectionType' => { KEYS_ONLY | INCLUDE | ALL }, // REQUIRED
|
||||
* 'nka' => { [ list of one or more non-key attributes !>20 ] }, // REQUIRED if projection = INCLUDE
|
||||
* 'throughput' => [ 'rcu' => <integer>, 'wcu' => <integer> ] // REQUIRED for GLOBAL only
|
||||
* ],....];
|
||||
*
|
||||
* secondary index keys must use the key literals as shown above. ('name', 'indexes', 'projectionType', etc.)
|
||||
*
|
||||
*/
|
||||
public $globalIndexes = null;
|
||||
public $localIndexes = null;
|
||||
|
||||
public $exposedFields = null; // list of fields exposed to clients
|
||||
public $cacheMap = null; // k->v paired array mapping fields -> cachedField Names
|
||||
public $binFields = null; // binary fields that have to be encoded
|
||||
|
||||
// these fields aren't used in DDB, but are used in mongo, so are here only for code-compatibility
|
||||
public $uniqueIndexes = null;
|
||||
public $sparseIndexes = null;
|
||||
public $subCollections = null;
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-07-17 mks original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-07-17 mks original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-07-17 mks original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
87
classes/templates/deprecated/xxxTestMySQL.class.inc
Normal file
87
classes/templates/deprecated/xxxTestMySQL.class.inc
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class: gatTestMySQL
|
||||
*
|
||||
* This is the definition for a mysql/mariadb-based test class. Intended usage is for unit-testing for basic CRUD
|
||||
* operations.
|
||||
*
|
||||
* This template should also serve as a guide, or documentation, for creating mysql/mariadb template classes.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-30-17 mks original coding
|
||||
*
|
||||
*/
|
||||
class gatTestMySQL
|
||||
{
|
||||
public $version = 1;
|
||||
public $schema = TEMPLATE_DB_PDO; // defines the storage schema for the class
|
||||
public $collection = COLLECTION_MYSQL_TEST; // sets the collection (table) name
|
||||
public $seqKey = COLLECTION_MYSQL_TEST_SQK; // sets the sequence key identifier
|
||||
public $extension = COLLECTION_MYSQL_TEST_EXT; // sets the extension for the collection
|
||||
public $setCache = true; // set to true to cache class data
|
||||
public $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public $setJournaling = false; // set to true to allow journaling
|
||||
public $setUpdates = true; // set to true to allow record updates
|
||||
public $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public $setLocking = false; // set to true to enable record locking for collection
|
||||
public $setTimers = true; // set to true to enable collection query timers
|
||||
public $setPKey = DB_PKEY; // sets the primary key for the collection
|
||||
public $selfDestruct = true; // set to false if this class contains methods
|
||||
|
||||
/*
|
||||
* tokens are guids -- if you're using a guid as the pkey for the class, then this value should be false.
|
||||
* if you're using an integer pkey, and you want a token, you have to explicitly declare
|
||||
* the token fields in $fields and set this value to true.
|
||||
* if you're using an integer pkey and you don't want a token, set this value to false.
|
||||
*/
|
||||
public $setTokens = false; // set to true: adds the idToken field functionality
|
||||
public $cacheTimer = 0; // number of seconds a tuple will remain in-cache
|
||||
public $setEnv = ENV_ALL; // defines the env where this class can be accessed
|
||||
public $setMeta = false; // defines if we'll use the meta package for history
|
||||
|
||||
public $fields = [
|
||||
DB_PKEY => DATA_TYPE_INTEGER, // pkey (integer) used internally and is REQUIRED
|
||||
TEST_FIELD_TEST_STRING => DATA_TYPE_STRING,
|
||||
TEST_FIELD_TEST_DOUBLE => DATA_TYPE_DOUBLE,
|
||||
TEST_FIELD_TEST_INT => DATA_TYPE_INTEGER,
|
||||
TEST_FIELD_TEST_BOOL => DATA_TYPE_BOOL,
|
||||
TEST_FIELD_TEST_OBJECT => DATA_TYPE_OBJECT,
|
||||
DB_TOKEN => DATA_TYPE_STRING // unique key (string) exposed externally and is REQUIRED
|
||||
];
|
||||
|
||||
// cache-map constants are in ./common/cacheMaps.php
|
||||
public $cacheMap = [
|
||||
DB_TOKEN => CM_TST_TOKEN,
|
||||
TEST_FIELD_TEST_STRING => CM_TST_FIELD_TEST_STRING,
|
||||
TEST_FIELD_TEST_DOUBLE => CM_TST_FIELD_TEST_DOUBLE,
|
||||
TEST_FIELD_TEST_INT => CM_TST_FIELD_TEST_INT,
|
||||
TEST_FIELD_TEST_BOOL => CM_TST_FIELD_TEST_BOOL,
|
||||
TEST_FIELD_TEST_OBJECT => CM_TST_FIELD_TEST_OBJ
|
||||
];
|
||||
|
||||
// for mysql, all indexed fields are listed in this container regardless of index type. If an field appears but
|
||||
// is not a unique or compound index, then it is just a regular index.
|
||||
public $indexes = [ DB_PKEY, TEST_FIELD_TEST_INT, DB_TOKEN ];
|
||||
|
||||
// unique indexes listed as an indexed array
|
||||
public $uniqueIndexes = [ DB_TOKEN ];
|
||||
|
||||
// compound indexes are listed as sub-arrays:
|
||||
// [ [ col-1, ..., col-n ], ..., [] ]
|
||||
public $compoundIndexes = null;
|
||||
|
||||
// exposed fields are mutually exclusive with cacheMaps; one or the other but not both
|
||||
public $exposedFields = null;
|
||||
|
||||
// binary fields require special handling (encoding) and have to be listed here
|
||||
public $binaryFields = null;
|
||||
}
|
||||
529
classes/templates/gatAudit.class.inc
Normal file
529
classes/templates/gatAudit.class.inc
Normal file
@@ -0,0 +1,529 @@
|
||||
<?php
|
||||
/**
|
||||
* gatAudit Class Template -- mongo template class
|
||||
*
|
||||
* This is the template class for the Audit table - the auditing sub-system for Namaste.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 10-16-18 mks DB-57: original coding
|
||||
* 11-13-18 mks DB-63: added template field to collection fields/schema
|
||||
* 01-13-20 mks DB-150: PHP7.4 member type casting
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
*
|
||||
*/
|
||||
|
||||
class gatAudit
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version - not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_ADMIN; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_AUDIT; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_AUDIT; // sets the collection (table) name
|
||||
public ?string $whTemplate = TEMPLATE_CLASS_AUDIT; // name of the warehouse template (not collection)
|
||||
public string $extension = COLLECTION_MONGO_AUDIT_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = false; // set to true to cache class data
|
||||
public bool $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public bool $setJournaling = false; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = true; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
// fields specific to the collection
|
||||
MONGO_ID => DATA_TYPE_OBJECT, // sorting by the id is just like sorting by createdDate
|
||||
AUDIT_SYS_EV_GUID => DATA_TYPE_STRING, // GUID passed from the System Event Manager
|
||||
AUDIT_SESSION_GUID => DATA_TYPE_STRING, // Session GUID (pulled from meta payload)
|
||||
AUDIT_SESSION_IP => DATA_TYPE_STRING, // Session IP (pulled from meta payload)
|
||||
AUDIT_USER_GUID => DATA_TYPE_STRING, // User GUID (pulled from meta payload)
|
||||
AUDIT_JOURNAL_GUID => DATA_TYPE_STRING, // (optional) Journal Event GUID
|
||||
AUDIT_SERVICE => DATA_TYPE_STRING, // service of the collection/record under audit
|
||||
AUDIT_SCHEMA => DATA_TYPE_STRING, // schema type for the accessed collection/table
|
||||
AUDIT_TEMPLATE => DATA_TYPE_STRING, // the template name used to instantiate the data class
|
||||
AUDIT_DB => DATA_TYPE_STRING, // name of the DB being accessed
|
||||
AUDIT_COLLECTION => DATA_TYPE_STRING, // name of the collection/table being accessed
|
||||
AUDIT_COLLECTION_EXT => DATA_TYPE_STRING, // Namaste extension of the targeted table (todo: not sure yet why I need/want this)
|
||||
AUDIT_RECORD_TOKEN => DATA_TYPE_STRING, // record GUID
|
||||
AUDIT_SNAPSHOT => DATA_TYPE_STRING, // JSON-encoded copy of the record prior to access
|
||||
AUDIT_QUERY => DATA_TYPE_STRING, // copy of the query used to access the record
|
||||
AUDIT_ACCESS_CLIENT => DATA_TYPE_STRING, // name of the application/client used to access the record
|
||||
AUDIT_ACCESS_USER => DATA_TYPE_STRING, // name of the user accessing the record (if available)
|
||||
AUDIT_USER_ROLE => DATA_TYPE_STRING, // role of the user accessing the record (if available)
|
||||
AUDIT_OPERATION => DATA_TYPE_STRING, // name of the operation access the record (CRUD)
|
||||
AUDIT_ACCESS_ALLOWED => DATA_TYPE_BOOL, // if the access was granted or blocked
|
||||
// generic mongo constants
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key (string) exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER // epoch time
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
// todo -- code a condition where ALL fields are protected using the * symbol (DB-58)
|
||||
public ?array $protectedFields = [
|
||||
MONGO_ID, AUDIT_SYS_EV_GUID, AUDIT_SESSION_GUID, AUDIT_USER_GUID, AUDIT_JOURNAL_GUID, AUDIT_SERVICE,
|
||||
AUDIT_SCHEMA, AUDIT_DB, AUDIT_COLLECTION, AUDIT_COLLECTION_EXT, AUDIT_SNAPSHOT, AUDIT_QUERY,
|
||||
AUDIT_ACCESS_CLIENT, AUDIT_ACCESS_USER, AUDIT_USER_ROLE, AUDIT_OPERATION, AUDIT_ACCESS_ALLOWED,
|
||||
DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_STATUS, DB_ACCESSED, AUDIT_RECORD_TOKEN, AUDIT_TEMPLATE
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_CREATED, DB_TOKEN, DB_ACCESSED, DB_EVENT_GUID, AUDIT_SYS_EV_GUID, AUDIT_USER_GUID,
|
||||
AUDIT_JOURNAL_GUID, AUDIT_ACCESS_ALLOWED, AUDIT_SESSION_GUID, AUDIT_SESSION_IP, AUDIT_RECORD_TOKEN
|
||||
];
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_CREATED => -1, // assuming we want LIFO
|
||||
DB_ACCESSED => -1, // assuming we want LIFO
|
||||
DB_EVENT_GUID => 1, // event guid should always be indexed
|
||||
AUDIT_ACCESS_ALLOWED => 1,
|
||||
AUDIT_SESSION_IP => 1,
|
||||
AUDIT_RECORD_TOKEN => 1
|
||||
];
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = null;
|
||||
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = null;
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
DB_TOKEN => 1, // MONGO_TOKEN should always appear
|
||||
AUDIT_SESSION_GUID => 1,
|
||||
AUDIT_JOURNAL_GUID => 1,
|
||||
AUDIT_USER_GUID => 1,
|
||||
AUDIT_SYS_EV_GUID => 1
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null;
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = null;
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
* SubC fields do not need to be indexed.
|
||||
*
|
||||
*/
|
||||
public ?array $subC = null;
|
||||
|
||||
//=================================================================================================================
|
||||
// MIGRATION DECLARATIONS
|
||||
// ----------------------
|
||||
// Data in this section is used to handle migrations -- when we're pulling from legacy tables into the Namaste
|
||||
// framework. See online doc for more info.
|
||||
//=================================================================================================================
|
||||
|
||||
/**
|
||||
* The migration map is an associative array that maps the Namaste fields (keys) to the corresponding
|
||||
* (remote) legacy fields in the source table to be migrated to Namaste.
|
||||
*
|
||||
* For example, if we were migrating a mysql table in the legacy production database to Namaste::mongo, then
|
||||
* the keys of the migration map would be the Namaste::mongo->fieldNames and the values would be the mysql
|
||||
* column names in the legacy table.
|
||||
*
|
||||
* If there is a value which cannot be mapped to a key, then set it to null.
|
||||
*
|
||||
* Fields that will be dropped in the migration are not listed as values or as keys.
|
||||
*
|
||||
* This map will only exist in the template object and will never be imported into the class widget.
|
||||
*
|
||||
* This is a required field.
|
||||
*
|
||||
*/
|
||||
public ?array $migrationMap = null;
|
||||
|
||||
/*
|
||||
* the migrationSortKey defines the SOURCE field by which the fetch query will be sorted. ALL sort fields are
|
||||
* in ASC order so all we need to list here is the name of the field -- which MUST BE IN THE SOURCE TABLE.
|
||||
*
|
||||
* Populating this field may require preliminary examination of the data - what we want is a field that has
|
||||
* zero NULL values.
|
||||
*
|
||||
* This is a required field.
|
||||
*
|
||||
*/
|
||||
public ?array $migrationSortKey = null;
|
||||
|
||||
/*
|
||||
* The migrationStatusKey defines the status field/column in the source table -- if the user requires that
|
||||
* soft-deleted records not be migrated, then this field must be set. Otherwise, set the value to null.
|
||||
*
|
||||
* The format is in the form of a key-value paired array. The key specifies the name of the column and the value
|
||||
* specifies the "deleted" value that, if found, will cause that row from the SOURCE data to be omitted from the
|
||||
* DESTINATION table.
|
||||
*
|
||||
* e.g.: $migrationStatusKV = [ 'some_field' => 'deleted' ]
|
||||
*
|
||||
* Note that both the key and the value are case-sensitive!
|
||||
*
|
||||
* This is an optional field.
|
||||
*
|
||||
*/
|
||||
public ?array $migrationStatusKV = null;
|
||||
|
||||
// The $migrationSourceSchema defines the remote schema for the source table
|
||||
public ?string $migrationSourceSchema = null; // or STRING_MONGO
|
||||
|
||||
// The source table in the remote repos (default defined in the XML) must be declared here
|
||||
public ?string $migrationSourceTable = null;
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => true, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'Q', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => true, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
WH_INDEXES => [DB_CREATED, DB_WH_CREATED],
|
||||
WH_TEMPLATE => '',
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [ OPERAND_NULL => [ OPERATOR_LT => [ null ] ] ],
|
||||
DB_STATUS => [ OPERAND_NULL => [ OPERATOR_EQ => [ STATUS_ACTIVE ]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 10-16-18 mks DB-57: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 10-16-18 mks DB-57: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 10-16-18 mks DB-57: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
808
classes/templates/gatConsolidatedSanctionsList.class.inc
Normal file
808
classes/templates/gatConsolidatedSanctionsList.class.inc
Normal file
@@ -0,0 +1,808 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class gatConsolidatedSanctionsList -- mongo class
|
||||
*
|
||||
* This class is used to store the US DHS Consolidated Sanctions list found at:
|
||||
* https://home.treasury.gov/policy-issues/financial-sanctions/consolidated-sanctions-list-data-files
|
||||
* This collection is populated from the file: consolidated.xml, an XML version of the Consolidated Sanctions list
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-03-20 mks DB-179: original coding
|
||||
*
|
||||
*/
|
||||
class gatConsolidatedSanctionsList
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version; not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_SEGUNDO; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_CSL; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_CSL; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_CSL_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = false; // set to false to allow partner instantiations
|
||||
public bool $setCache = true; // set to true to cache class data
|
||||
public bool $setDeletes = false; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_DESTRUCTIVE; // set to AUDIT_value constant (nondestructive = reads(yes))
|
||||
public bool $setJournaling = false; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = true; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search statusz
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = true; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
public array $fields = [
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER, // epoch time
|
||||
COLLECTION_MONGO_CSL_ADDRESS => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_ADDRESS1 => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_ADDRESS2 => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_ADDRESS3 => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_ADDR_LIST => DATA_TYPE_ARRAY,
|
||||
COLLECTION_MONGO_CSL_AKA => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_AKA_LIST => DATA_TYPE_ARRAY,
|
||||
COLLECTION_MONGO_CSL_CATEGORY => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_CITIZENSHIP => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_CITIZENSHIP_LIST => DATA_TYPE_ARRAY,
|
||||
COLLECTION_MONGO_CSL_CITY => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_COUNTRY => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_DOB => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_DOB_LIST => DATA_TYPE_ARRAY,
|
||||
COLLECTION_MONGO_CSL_FN => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_LN => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_ID => DATA_TYPE_INTEGER,
|
||||
COLLECTION_MONGO_CSL_ID_COUNTRY => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_ID_LIST => DATA_TYPE_ARRAY,
|
||||
COLLECTION_MONGO_CSL_ID_NUMBER => DATA_TYPE_STRING, // because leading zeros
|
||||
COLLECTION_MONGO_CSL_ID_TYPE => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_MAIN_ENTRY => DATA_TYPE_BOOL,
|
||||
COLLECTION_MONGO_CSL_POB => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_POB_LIST => DATA_TYPE_ARRAY,
|
||||
COLLECTION_MONGO_CSL_POSTAL_CODE => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_PRG => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_PRG_LIST => DATA_TYPE_ARRAY,
|
||||
COLLECTION_MONGO_CSL_REMARKS => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_SOP => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_TYPE => DATA_TYPE_STRING,
|
||||
COLLECTION_MONGO_CSL_UID => DATA_TYPE_INTEGER,
|
||||
COLLECTION_MONGO_CSL_SDN_TYPE => DATA_TYPE_STRING
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED, DB_STATUS
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_CREATED, DB_EVENT_GUID, DB_ACCESSED, MONGO_ID, DB_STATUS
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_TOKEN, DB_CREATED, DB_STATUS, DB_EVENT_GUID, COLLECTION_MONGO_CSL_AKA_LIST,
|
||||
COLLECTION_MONGO_CSL_DOB_LIST, COLLECTION_MONGO_CSL_ADDR_LIST, COLLECTION_MONGO_CSL_SDN_TYPE
|
||||
];
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = ['EntityNameIndex'];
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_TOKEN => 1,
|
||||
DB_CREATED => -1,
|
||||
DB_STATUS => 1,
|
||||
COLLECTION_MONGO_CSL_SDN_TYPE => 1
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = [
|
||||
'EntityNameIndex' => [COLLECTION_MONGO_CSL_SDN_TYPE, COLLECTION_MONGO_CSL_LN, COLLECTION_MONGO_CSL_LN]
|
||||
];
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Sparse indexes only add the row to the index if the column referenced satisfies the conditions specified
|
||||
// in the query condition (expr2).
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
DB_TOKEN => 1 // MONGO_TOKEN should always appear
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null;
|
||||
|
||||
// cache maps are required for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
DB_TOKEN => CM_TOKEN,
|
||||
DB_CREATED => CM_DATE_CREATED,
|
||||
DB_ACCESSED => CM_DATE_ACCESSED,
|
||||
DB_STATUS => CM_STATUS,
|
||||
DB_EVENT_GUID => CM_EVENT_GUID,
|
||||
CM_CSL_ADDR => COLLECTION_MONGO_CSL_ADDRESS,
|
||||
CM_CSL_ADDR1 => COLLECTION_MONGO_CSL_ADDRESS1,
|
||||
CM_CSL_ADDR2 => COLLECTION_MONGO_CSL_ADDRESS2,
|
||||
CM_CSL_ADDR3 => COLLECTION_MONGO_CSL_ADDRESS3,
|
||||
CM_CSL_ADDR_LIST => COLLECTION_MONGO_CSL_ADDR_LIST,
|
||||
CM_CSL_AKA => COLLECTION_MONGO_CSL_AKA,
|
||||
CM_CSL_AKA_LIST => COLLECTION_MONGO_CSL_AKA_LIST,
|
||||
CM_CSL_CAT => COLLECTION_MONGO_CSL_CATEGORY,
|
||||
CM_CSL_CITIZENSHIP => COLLECTION_MONGO_CSL_CITIZENSHIP,
|
||||
CM_CSL_CITIZENSHIP_LIST => COLLECTION_MONGO_CSL_CITIZENSHIP_LIST,
|
||||
CM_CSL_CITY => COLLECTION_MONGO_CSL_CITY,
|
||||
CM_CSL_COUNTRY => COLLECTION_MONGO_CSL_COUNTRY,
|
||||
CM_CSL_DOB => COLLECTION_MONGO_CSL_DOB,
|
||||
CM_CSL_DOB_LIST => COLLECTION_MONGO_CSL_DOB_LIST,
|
||||
CM_CSL_FIRST_NAME => COLLECTION_MONGO_CSL_FN,
|
||||
CM_CSL_LAST_NAME => COLLECTION_MONGO_CSL_LN,
|
||||
CM_CSL_ID => COLLECTION_MONGO_CSL_ID,
|
||||
CM_CSL_ID_COUNTRY => COLLECTION_MONGO_CSL_ID_COUNTRY,
|
||||
CM_CSL_ID_LIST => COLLECTION_MONGO_CSL_ID_LIST,
|
||||
CM_CSL_ID_NUM => COLLECTION_MONGO_CSL_ID_NUMBER,
|
||||
CM_CSL_ID_TYPE => COLLECTION_MONGO_CSL_ID_TYPE,
|
||||
CM_CSL_MAIN_ENTRY => COLLECTION_MONGO_CSL_MAIN_ENTRY,
|
||||
CM_CSL_POB => COLLECTION_MONGO_CSL_POB,
|
||||
CM_CSL_POB_LIST => COLLECTION_MONGO_CSL_POB_LIST,
|
||||
CM_CSL_POST_CODE => COLLECTION_MONGO_CSL_POSTAL_CODE,
|
||||
CM_CSL_PRG => COLLECTION_MONGO_CSL_PRG,
|
||||
CM_CSL_PRG_LIST => COLLECTION_MONGO_CSL_PRG_LIST,
|
||||
CM_CSL_REM => COLLECTION_MONGO_CSL_REMARKS,
|
||||
CM_CSL_STATE_OR_PROVINCE => COLLECTION_MONGO_CSL_SOP,
|
||||
CM_CSL_TYPE => COLLECTION_MONGO_CSL_TYPE,
|
||||
CM_CSL_UID => COLLECTION_MONGO_CSL_UID,
|
||||
CM_CSL_SDN_TYPE => COLLECTION_MONGO_CSL_SDN_TYPE
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as the associative array: $exposedFields. Only those fields,
|
||||
* enumerated within this container, will be exposed to the client.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
*/
|
||||
// sub-collection fields must be declared here (need not be indexed)
|
||||
public ?array $subC = [
|
||||
COLLECTION_MONGO_CSL_ADDR_LIST => [
|
||||
COLLECTION_MONGO_CSL_UID,
|
||||
COLLECTION_MONGO_CSL_ADDRESS1,
|
||||
COLLECTION_MONGO_CSL_ADDRESS2,
|
||||
COLLECTION_MONGO_CSL_ADDRESS3,
|
||||
COLLECTION_MONGO_CSL_CITY,
|
||||
COLLECTION_MONGO_CSL_POSTAL_CODE,
|
||||
COLLECTION_MONGO_CSL_COUNTRY,
|
||||
COLLECTION_MONGO_CSL_SOP
|
||||
],
|
||||
COLLECTION_MONGO_CSL_AKA_LIST => [
|
||||
COLLECTION_MONGO_CSL_UID,
|
||||
COLLECTION_MONGO_CSL_TYPE,
|
||||
COLLECTION_MONGO_CSL_CATEGORY,
|
||||
COLLECTION_MONGO_CSL_LN,
|
||||
COLLECTION_MONGO_CSL_FN
|
||||
],
|
||||
COLLECTION_MONGO_CSL_ID_LIST => [
|
||||
COLLECTION_MONGO_CSL_UID,
|
||||
COLLECTION_MONGO_CSL_ID_TYPE,
|
||||
COLLECTION_MONGO_CSL_ID_NUMBER
|
||||
]
|
||||
// COLLECTION_MONGO_CSL_DOB_LIST => [
|
||||
// COLLECTION_MONGO_CSL_UID,
|
||||
// COLLECTION_MONGO_CSL_DOB,
|
||||
// COLLECTION_MONGO_CSL_MAIN_ENTRY
|
||||
// ],
|
||||
// COLLECTION_MONGO_CSL_POB_LIST => [
|
||||
// COLLECTION_MONGO_CSL_UID,
|
||||
// COLLECTION_MONGO_CSL_POB,
|
||||
// COLLECTION_MONGO_CSL_MAIN_ENTRY
|
||||
// ],
|
||||
// COLLECTION_MONGO_CSL_PRG_LIST => [
|
||||
// COLLECTION_MONGO_CSL_PRG
|
||||
// ]
|
||||
];
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [OPERAND_NULL => [OPERATOR_LT => [null]]],
|
||||
DB_STATUS => [OPERAND_NULL => [OPERATOR_EQ => [STATUS_ACTIVE]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* Constructor in this template not only registers the shutdown method, but also allows us to generate a custom
|
||||
* GUID string during instantiation by use of the input parameters:
|
||||
*
|
||||
* $_getGUID - boolean, defaults to false but, if true, will generate a GUID value and store it in the class member
|
||||
* $_lc - boolean, defaults to false but, if true, will generate a GUID using lower-case alpha characters
|
||||
*
|
||||
* If we generate a GUID on instantiation, the GUID will be stored in the class member. This allows us to both
|
||||
* instantiate a session class object and a GUID value, (the most requested, post-instantiation, action), at the
|
||||
* same time. All the efficient.
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-03-20 mks DB-179: original coding
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* processCONSList() -- public template method
|
||||
*
|
||||
* This template method is accessible through the factory widget->template object only.
|
||||
*
|
||||
* The CONS list is available from the US Treasure Department and contains a list of Individuals and Entities
|
||||
* that have sanctions applied that prohibits the transfer of funds.
|
||||
*
|
||||
* The list, available at:
|
||||
* https://home.treasury.gov/policy-issues/financial-sanctions/consolidated-sanctions-list-data-files
|
||||
* and known as: consolidated.xml, contains the entire sanctions list.
|
||||
*
|
||||
* The format of the list is not conducive to efficient data storage so we're going to manipulate some of the
|
||||
* columnar elements, which are lists (arrays), s.t. we're removed the superflous and redundant sub-container
|
||||
* headers so that all lists are associative arrays of indexed arrays.
|
||||
*
|
||||
* The function requires the following input parameters:
|
||||
*
|
||||
* $_file - the fqfn file containing the CONS XML list
|
||||
* $_errs - a call-by-reference parameter that will return processing errors back to the calling client
|
||||
* $_lastUpdated - a call-by-reference parameter that returns the date when the list was updated last
|
||||
* $_recCount - a call-by-reference parameter containing the total number of records as report by USDoT
|
||||
*
|
||||
* On successful processing, the function returns an array, the processed cons list with the header removed
|
||||
* and the sub-arrays all nice and homogeneous.
|
||||
*
|
||||
* If there was an error raised in processing, we'll store a copy of the error in $_errs and return a null
|
||||
* value back to the calling client.
|
||||
*
|
||||
* If an exception is raised, a null will be returned and the error(s) logged to the db and to the console.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
*
|
||||
* @param string $_file
|
||||
* @param array|null $_errs
|
||||
* @param string $_lastUpdated
|
||||
* @param int $_recCount
|
||||
* @return array|null
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-07-20 mks DB-180: original coding
|
||||
*
|
||||
*/
|
||||
public function processCONSList(string $_file, ?array &$_errs, string &$_lastUpdated = '', int &$_recCount = 0): ?array
|
||||
{
|
||||
$method = basename(__METHOD__);
|
||||
$aryRetData = null;
|
||||
if (empty($_file)) {
|
||||
$hdr = sprintf(INFO_LOC, $method, __LINE__);
|
||||
$_errs[] = $hdr . ERROR_PARAM_404 . STRING_LIST;
|
||||
return null;
|
||||
}
|
||||
// see if we can open the file for reading
|
||||
$fp = simplexml_load_file($_file);
|
||||
if (false === $fp) {
|
||||
$hdr = sprintf(INFO_LOC, $method, __LINE__);
|
||||
$_errs[] = $hdr . ERROR_OPEN_XML_FILE . $_file;
|
||||
return null;
|
||||
} else {
|
||||
try {
|
||||
if (is_null($consData = objectToArray($fp))) {
|
||||
$hdr = sprintf(INFO_LOC, $method, __LINE__);
|
||||
$_errs[] = $hdr . ERROR_DATA_OBJ_2_ARY_FAIL;
|
||||
return null;
|
||||
}
|
||||
} catch (Throwable | TypeError $t) {
|
||||
$hdr = sprintf(INFO_LOC, $method, __LINE__);
|
||||
@handleExceptionMessaging($hdr, $t->getMessage(), $_errs, true);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// at this point, we have successfully loaded the CONS XML file and have stored it, as an array, in $consData
|
||||
// we need to clean up the "lists" embedded as sub-arrays since they XML introduced an artificial layer
|
||||
// pointing to the data: $consData['sdnEntry']['akaList']['aka'][0, ..., n]
|
||||
// ^^^^^ <--- this is the layer to be removed
|
||||
$records = $consData[CONS_SDN_ENTRY];
|
||||
$consMeta = $consData[CONS_PUB_INFO];
|
||||
$_lastUpdated = $consMeta[CONS_PUB_DATE];
|
||||
$_recCount = intval($consMeta[CONS_REC_COUNT]);
|
||||
// list of list (entities) -- these are the sub-collections as opposed to sub-arrays
|
||||
$lol = [COLLECTION_MONGO_CSL_AKA_LIST => COLLECTION_MONGO_CSL_AKA,
|
||||
COLLECTION_MONGO_CSL_ADDR_LIST => COLLECTION_MONGO_CSL_ADDRESS,
|
||||
COLLECTION_MONGO_CSL_ID_LIST => COLLECTION_MONGO_CSL_ID,
|
||||
COLLECTION_MONGO_CSL_PRG_LIST => COLLECTION_MONGO_CSL_PRG,
|
||||
COLLECTION_MONGO_CSL_DOB_LIST => COLLECTION_MONGO_CSL_DOB_ITEM,
|
||||
COLLECTION_MONGO_CSL_POB_LIST => COLLECTION_MONGO_CSL_POB_ITEM
|
||||
];
|
||||
try {
|
||||
foreach ($records as &$record) {
|
||||
foreach ($record as $field => $fieldValue) {
|
||||
if (is_array($fieldValue) and array_key_exists($field, $lol)) {
|
||||
if (is_array($record[$field][$lol[$field]]) and is_numeric(key($record[$field][$lol[$field]]))) {
|
||||
// sub-array has multiple elements
|
||||
foreach ($record[$field][$lol[$field]] as $subRecord) {
|
||||
$record[$field][] = $subRecord;
|
||||
}
|
||||
} else {
|
||||
// sub-array has but a single element
|
||||
$record[$field][] = $record[$field][$lol[$field]];
|
||||
}
|
||||
unset($record[$field][$lol[$field]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable | TypeError $t) {
|
||||
$hdr = sprintf(INFO_LOC, basename(__METHOD__), __LINE__);
|
||||
@handleExceptionMessaging($hdr, $t->getMessage(), $_errs, true);
|
||||
return null;
|
||||
}
|
||||
return $records;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* saveCONSList() -- public template method
|
||||
*
|
||||
* This method has the following input parameters:
|
||||
*
|
||||
* $_data -- this is the broker request data array
|
||||
* $_errs -- a call-by-reference parameter for returning processing errors back to the calling client
|
||||
*
|
||||
* The method will return a null value when there are errors in parsing the input parameters, or from saving
|
||||
* the XML file to disk.
|
||||
*
|
||||
* Otherwise, on success, the method returns the FQFN of the saved XML file.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @param array $_data
|
||||
* @param array|null $_errs
|
||||
* @return string|null
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-09-20 mks DB-180: original programming
|
||||
*
|
||||
*/
|
||||
public function saveCONSList(array $_data, ?array &$_errs): ?string
|
||||
{
|
||||
$method = basename(__METHOD__);
|
||||
if (empty($_data)) {
|
||||
$hdr = sprintf(INFO_LOC, $method, __LINE__);
|
||||
@handleExceptionMessaging($hdr, ERROR_DATA_ARRAY_EMPTY, $_errs, true);
|
||||
return null;
|
||||
}
|
||||
if (!is_array($_data)) {
|
||||
$hdr = sprintf(INFO_LOC, $method, __LINE__);
|
||||
@handleExceptionMessaging($hdr, ERROR_DATA_ARRAY_NOT_ARRAY . STRING_DATA, $_errs, true);
|
||||
return null;
|
||||
}
|
||||
if (!array_key_exists(STRING_DATA, $_data) or empty($_data[STRING_DATA])) {
|
||||
$hdr = sprintf(INFO_LOC, $method, __LINE__);
|
||||
@handleExceptionMessaging($hdr, ERROR_DATA_ARRAY_EMPTY . COLON . STRING_DATA, $_errs, true);
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
// extract the XML file from the data payload
|
||||
$xmlFile = $_data[STRING_DATA];
|
||||
// write the file to tmp storage
|
||||
$guid = guid();
|
||||
$fqfn = DIR_TMP . SLASH . $guid . DOT . FILE_TYPE_XML;
|
||||
if (false === file_put_contents($fqfn, $xmlFile)) {
|
||||
$hdr = sprintf(INFO_LOC, $method, __LINE__);
|
||||
@handleExceptionMessaging($hdr, ERROR_SAVE_XML_FILE . $fqfn, $_errs, true);
|
||||
return null;
|
||||
}
|
||||
} catch (Throwable | TypeError $t) {
|
||||
$hdr = sprintf(INFO_LOC, $method, __LINE__);
|
||||
@handleExceptionMessaging($hdr, $t->getMessage(), $_errs, true);
|
||||
return null;
|
||||
}
|
||||
return $fqfn;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* cleanUp() -- public template method
|
||||
*
|
||||
* This file has a single, required, input parameter: the FQFN of the original XML file. Once validated, we'll
|
||||
* load the XML file into a variable and use that string as the VALUE value in the system-data table for row #2.
|
||||
*
|
||||
* This means that the last CONS list added to the Segundo collection has been stored (for archival and validation
|
||||
* purposes) as a flat-file in a column in a mongo table.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @param string $_file
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-15-20 mks DB-180: original coding
|
||||
*
|
||||
*/
|
||||
public function cleanUp(string $_file = ''):void
|
||||
{
|
||||
$errors = [];
|
||||
try {
|
||||
if (strlen($_file) and file_exists($_file)) {
|
||||
$contents = file_get_contents($_file);
|
||||
if (false === $contents) {
|
||||
consoleLog('CONS: ', CON_ERROR, ERROR_OPEN_XML_FILE . $_file);
|
||||
return;
|
||||
}
|
||||
// delete the XML file
|
||||
unlink($_file);
|
||||
|
||||
// instantiate a system-data widget
|
||||
$meta = [
|
||||
META_TEMPLATE => TEMPLATE_CLASS_SYS_DATA,
|
||||
META_CLIENT => CLIENT_SYSTEM,
|
||||
META_EVENT_GUID => guid()
|
||||
];
|
||||
/** @var gacMongoDB $widget */
|
||||
if (is_null($widget = grabWidget($meta, '', $errors))) {
|
||||
consoleLog('CONS: ', CON_ERROR, ERROR_FAILED_TO_INSTANTIATE . TEMPLATE_CLASS_SYS_DATA);
|
||||
} else {
|
||||
// save the XML data to the system-data table
|
||||
$data = [
|
||||
DATA_KEY => DATA_CONS,
|
||||
DATA_VALUE => $contents,
|
||||
ROW_ID => SYS_DATA_ROW_ID_CONS
|
||||
];
|
||||
$bc = new gacWorkQueueClient( basename(__METHOD__) . AT . __LINE__);
|
||||
if (!$bc->status) {
|
||||
$hdr = sprintf(INFO_LOC, basename(__METHOD__), __LINE__);
|
||||
@handleExceptionMessaging($hdr, sprintf(ERROR_BROKER_CLIENT_INSTANTIATION, BROKER_QUEUE_AI, null, true));
|
||||
} else {
|
||||
$payload = [
|
||||
BROKER_REQUEST => BROKER_REQUEST_CREATE,
|
||||
BROKER_DATA => [$data],
|
||||
BROKER_META_DATA => $meta
|
||||
];
|
||||
if (false === $bc->call(gzcompress(json_encode($payload))))
|
||||
consoleLog('CONS: ', CON_ERROR, sprintf(ERROR_MDB_QUERY_FAIL, STRING_UPSERT));
|
||||
}
|
||||
if (is_object($bc)) $bc->__destruct();
|
||||
unset($bc);
|
||||
}
|
||||
}
|
||||
} catch (TypeError | Throwable $t) {
|
||||
$hdr = sprintf(INFO_LOC, basename(__FILE__), __LINE__);
|
||||
@handleExceptionMessaging($hdr, $t->getMessage(), $errors, true);
|
||||
}
|
||||
if (isset($widget) and is_object($widget)) {
|
||||
$widget->__destruct();
|
||||
unset($widget);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-03-20 mks DB-179: original coding
|
||||
*
|
||||
* @version 1.0
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-03-20 mks DB-179: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
// blank
|
||||
}
|
||||
}
|
||||
450
classes/templates/gatDonors.class.inc
Normal file
450
classes/templates/gatDonors.class.inc
Normal file
@@ -0,0 +1,450 @@
|
||||
<?php
|
||||
/** @noinspection PhpUnused */
|
||||
|
||||
/**
|
||||
* Class gatDonors -- mongo data-template class
|
||||
*
|
||||
* This template defines the donors collection, part of the integrated partnerships sub-system.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-06-20 mks DB-147: original coding
|
||||
* 06-01-20 mks ECI-108: support for authToken
|
||||
*/
|
||||
|
||||
class gatDonors
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version - not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_APPSERVER; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_DONORS; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_DONORS; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_DONORS_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = true; // set to true to cache class data
|
||||
public bool $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NONDESTRUCTIVE; // set to AUDIT_value constant (nondestructive = reads(yes))
|
||||
public bool $setJournaling = true; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = true; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = false; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
MONGO_ID => DATA_TYPE_INTEGER, // sorting by the id is just like sorting by createdDate
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique pkey exposed externally and is REQUIRED
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER, // epoch time
|
||||
DONORS_TRANS_COUNT => DATA_TYPE_INTEGER, // transaction count
|
||||
DONORS_DTCC => DATA_TYPE_INTEGER, // donations to current cause
|
||||
DONORS_TOTAL_DONATIONS => DATA_TYPE_DOUBLE, // dollar amount of total donations
|
||||
DONORS_SDWC => DATA_TYPE_BOOL, // share data with cause
|
||||
DONORS_CID => DATA_TYPE_STRING, // foreign key to somewhere
|
||||
DONORS_CAUSE_TITLE => DATA_TYPE_STRING,
|
||||
DONORS_UNK_FOREIGN_ID => DATA_TYPE_INTEGER // unknown generic foreign key
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED, MONGO_ID
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_CREATED, DONORS_CID, DB_STATUS, DB_TOKEN
|
||||
];
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = null;
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_CREATED => -1,
|
||||
DONORS_CID => 1
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = null;
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Sparse indexes only add the row to the index if the column referenced satisfies the conditions specified
|
||||
// in the query condition (expr2).
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
DB_TOKEN => 1 // MONGO_TOKEN should always appear
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null; // ttl indexes appear in $indexFields
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
DB_TOKEN => CM_TST_TOKEN,
|
||||
DB_STATUS => CM_TST_FIELD_TEST_STATUS,
|
||||
DB_EVENT_GUID => CM_TST_EVENT_GUID,
|
||||
DB_CREATED => CM_TST_FIELD_TEST_CDATE,
|
||||
DB_ACCESSED => CM_TST_FIELD_TEST_ADATE,
|
||||
DONORS_TRANS_COUNT => CM_DONORS_TC,
|
||||
DONORS_DTCC => CM_DONORS_DTCC,
|
||||
DONORS_TOTAL_DONATIONS => CM_DONORS_TD,
|
||||
DONORS_SDWC => CM_DONORS_SDWC,
|
||||
DONORS_CID => CM_DONORS_CID,
|
||||
DONORS_CAUSE_TITLE => CM_DONORS_CT,
|
||||
DONORS_UNK_FOREIGN_ID => CM_DONORS_FI
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
*/
|
||||
// sub-collection fields must be declared here (need not be indexed)
|
||||
public ?array $subC = null;
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [OPERAND_NULL => [OPERATOR_LT => [null]]],
|
||||
DB_STATUS => [OPERAND_NULL => [OPERATOR_EQ => [STATUS_ACTIVE]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-06-20 mks DB-147: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-06-20 mks DB-147: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-06-20 mks DB-147: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
459
classes/templates/gatFailedSessions.class.inc
Normal file
459
classes/templates/gatFailedSessions.class.inc
Normal file
@@ -0,0 +1,459 @@
|
||||
<?php
|
||||
/** @noinspection PhpUnused */
|
||||
|
||||
/**
|
||||
* Class gatFailedSessions -- mongo class
|
||||
*
|
||||
* This is an admin class that tracks failed session closures. Currently, this is limited to AT(1)-based events.
|
||||
* Entries in this collection allow us to trigger a batch job at night where we can have a second go at processing the
|
||||
* event requests that previously failed.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-13-20 mks DB-168: Original coding
|
||||
*/
|
||||
|
||||
class gatFailedSessions
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version; not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_TERCERO; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_FAILED_SESSIONS; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_FAILED_SESSIONS; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_FAILED_SESSIONS_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = false; // set to false to allow partner instantiations
|
||||
public bool $setCache = true; // set to true to cache class data
|
||||
public bool $setDeletes = false; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant (nondestructive = reads(yes))
|
||||
public bool $setJournaling = false; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = false; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER, // epoch time
|
||||
// fields specific to systemEvents collection
|
||||
MONGO_FAILED_EVENT_GUID => DATA_TYPE_STRING,
|
||||
MONGO_FAILED_EVENT_NAME => DATA_TYPE_STRING,
|
||||
MONGO_FAILED_EVENT_DESC => DATA_TYPE_STRING,
|
||||
MONGO_FAILED_EVENT_SEV => DATA_TYPE_STRING,
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED, DB_STATUS
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_CREATED, DB_EVENT_GUID, DB_ACCESSED, MONGO_ID, DB_STATUS
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_TOKEN, DB_CREATED, DB_STATUS, DB_EVENT_GUID,
|
||||
MONGO_FAILED_EVENT_GUID, MONGO_FAILED_EVENT_NAME, MONGO_FAILED_EVENT_SEV
|
||||
];
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = null;
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_TOKEN => 1,
|
||||
DB_CREATED => -1,
|
||||
DB_STATUS => 1,
|
||||
DB_EVENT_GUID => 1,
|
||||
MONGO_FAILED_EVENT_NAME => 1,
|
||||
MONGO_FAILED_EVENT_SEV => 1
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = null;
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Sparse indexes only add the row to the index if the column referenced satisfies the conditions specified
|
||||
// in the query condition (expr2).
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
DB_TOKEN => 1, // MONGO_TOKEN should always appear
|
||||
DB_EVENT_GUID => 1,
|
||||
MONGO_FAILED_EVENT_GUID => 1
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null;
|
||||
|
||||
// cache maps are required for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
DB_TOKEN => CM_TOKEN,
|
||||
DB_CREATED => CM_DATE_CREATED,
|
||||
DB_ACCESSED => CM_DATE_ACCESSED,
|
||||
DB_STATUS => CM_STATUS,
|
||||
DB_EVENT_GUID => CM_EVENT_GUID,
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as the associative array: $exposedFields. Only those fields,
|
||||
* enumerated within this container, will be exposed to the client.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
*/
|
||||
// sub-collection fields must be declared here (need not be indexed)
|
||||
public ?array $subC = null;
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [OPERAND_NULL => [OPERATOR_LT => [null]]],
|
||||
DB_STATUS => [OPERAND_NULL => [OPERATOR_EQ => [STATUS_ACTIVE]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-13-20 mks DB-169: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* Constructor in this template not only registers the shutdown method, but also allows us to generate a custom
|
||||
* GUID string during instantiation by use of the input parameters:
|
||||
*
|
||||
* $_getGUID - boolean, defaults to false but, if true, will generate a GUID value and store it in the class member
|
||||
* $_lc - boolean, defaults to false but, if true, will generate a GUID using lower-case alpha characters
|
||||
*
|
||||
* If we generate a GUID on instantiation, the GUID will be stored in the class member. This allows us to both
|
||||
* instantiate a session class object and a GUID value, (the most requested, post-instantiation, action), at the
|
||||
* same time. All the efficient.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-13-20 mks DB-169: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-13-20 mks DB-169: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
// move on lookie-loo....
|
||||
}
|
||||
|
||||
}
|
||||
458
classes/templates/gatGraphs.class.inc
Normal file
458
classes/templates/gatGraphs.class.inc
Normal file
@@ -0,0 +1,458 @@
|
||||
<?php
|
||||
/**
|
||||
* Class gatGraphs
|
||||
*
|
||||
* This is the class used for feeding the Namaste graphing dashboard.
|
||||
*
|
||||
* Design Notes:
|
||||
* -------------
|
||||
* The graphs collection is designed to be "open" with respect to the data captured. Graphs was originally intended
|
||||
* to be a time-series based collection. However, I wanted to expand the definition to include almost any type of
|
||||
* data.
|
||||
*
|
||||
* The main columns are the ones labeled key and value. These are the pivotal columns - the key defines the name of
|
||||
* data element, and value defines the metric value.
|
||||
*
|
||||
* For example, if I was graphing query metrics, I would receive a key of 'queryTime' and a value of 0.089. Combined
|
||||
* with the date/time field, I could submit this data as time-series. However, the key "queryTime" represents an
|
||||
* arbitrary event as we don't know which query this was measured against, what schema, etc.
|
||||
*
|
||||
* The remaining fields, then, help narrow the scope of the event.
|
||||
*
|
||||
* Another example, this time working the other way, is that I want to record the number of event requests that are
|
||||
* being received by the brokers.
|
||||
*
|
||||
* I could use a key of 'brokerEvent', with the value being the time the event took to process. Supporting values may
|
||||
* include service, broker, and event so that we now which service the event was processed on, which broker on that
|
||||
* service processed the event, and which event was processed. This combination of data allows us to start building
|
||||
* a history of efficiency of a particular service, broker or event.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 09-29-19 mks DB-136: original coding
|
||||
* 01-13-20 mks DB-150: PHP7.4 member type-casting
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
*
|
||||
*/
|
||||
|
||||
class gatGraphs
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1;
|
||||
public string $service = CONFIG_DATABASE_SERVICE_ADMIN; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_GRAPHS; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_GRAPHS; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_GRAPHS_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = false; // set to true to cache class data
|
||||
public bool $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public bool $setJournaling = false; // set to true to enable journaling
|
||||
public bool $setUpdates = false; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = false; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 0; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = true; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
MONGO_ID => DATA_TYPE_INTEGER, // sorting by the id is just like sorting by createdDate
|
||||
GRAPH_KEY => DATA_TYPE_STRING, // primary value: the metric being recorded
|
||||
GRAPH_VALUE => DATA_TYPE_MIXED, // primary value: the value of the metric
|
||||
GRAPH_SCHEMA => DATA_TYPE_STRING, // (optional) what was the db schema?
|
||||
GRAPH_SERVICE => DATA_TYPE_STRING, // (optional) what service handled the event?
|
||||
GRAPH_LOCATION => DATA_TYPE_ARRAY, // array containing file:method:line info
|
||||
GRAPH_FILE => DATA_TYPE_STRING, // sub-array label for the file
|
||||
GRAPH_METHOD => DATA_TYPE_STRING, // sub-array label for the method
|
||||
GRAPH_LINE => DATA_TYPE_INTEGER, // sub-array label for the line
|
||||
GRAPH_COMMENT => DATA_TYPE_STRING, // (optional) free-form text description
|
||||
GRAPH_LABEL => DATA_TYPE_STRING, // (optional) suggestion for a graph label
|
||||
GRAPH_COLLECTION => DATA_TYPE_STRING, // (optional) the db collection involved
|
||||
GRAPH_DBO => DATA_TYPE_STRING, // (optional) the database object involved
|
||||
GRAPH_EVENT => DATA_TYPE_STRING, // (optional) the name of the broker event
|
||||
GRAPH_BROKER => DATA_TYPE_STRING, // (optional) the name of the broker
|
||||
GRAPH_TIMER => DATA_TYPE_DOUBLE, // (optional) timer values go here because double
|
||||
GRAPH_DATE => DATA_TYPE_DATETIME, // (optional) cleartext data because grafana likes 'em
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key (string) exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER // epoch time
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [MONGO_ID, GRAPH_KEY, GRAPH_SERVICE, GRAPH_COLLECTION, GRAPH_DBO,
|
||||
GRAPH_EVENT, GRAPH_BROKER, DB_TOKEN, DB_EVENT_GUID, DB_CREATED ];
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_CREATED => -1,
|
||||
DB_TOKEN => 1,
|
||||
GRAPH_KEY => 1
|
||||
];
|
||||
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = [ 'graphServiceIDX', 'graphBrokerIDX' ];
|
||||
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = [
|
||||
'graphServiceIDX' => [ GRAPH_SERVICE => 1, GRAPH_COLLECTION => 1, GRAPH_DBO => 1 ],
|
||||
'graphBrokerIDX' => [ GRAPH_BROKER => 1, GRAPH_EVENT => 1 ]
|
||||
];
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = null; // token is not required for system collections
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null; // ttl indexes appear in $indexFields
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = null; // key-value paired array of field-names mapped to cache-names
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null; // lists the fields that will be sent to clients; null => all data
|
||||
// cache map, if defined, will always override.
|
||||
// mongo IDs are NEVER returned
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
*/
|
||||
// sub-collection fields must be declared here (need not be indexed)
|
||||
public ?array $subC = null; // sub-collection fields must be declared here
|
||||
// see gatTestMongo.class.inc for explanation & examples
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [OPERAND_NULL => [OPERATOR_LT => [null]]],
|
||||
DB_STATUS => [OPERAND_NULL => [OPERATOR_EQ => [STATUS_ACTIVE]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 09-29-19 mks DB-136: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 09-29-19 mks DB-136: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 09-29-19 mks DB-136: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
593
classes/templates/gatJournaling.class.inc
Normal file
593
classes/templates/gatJournaling.class.inc
Normal file
@@ -0,0 +1,593 @@
|
||||
<?php
|
||||
/**
|
||||
* gatJournaling.class.inc -- mongo template class
|
||||
*
|
||||
* This template defines the journaling collection - a Namaste subsystem that bestows point-in-time recovery
|
||||
* at the record level for supported data classes.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 10-16-18 mks DB-57: original coding
|
||||
* 02-07-19 mks DB-115: JOURNAL_AUD_TOK is now a unique indexed field
|
||||
* 01-13-20 msk DB-150: PHP7.4 class member type-casting
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
*
|
||||
*/
|
||||
|
||||
class gatJournaling
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version - not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_ADMIN; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_JOURNAL; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_JOURNAL; // sets the collection (table) name
|
||||
public ?string $whTemplate = TEMPLATE_CLASS_JOURNAL; // name of the warehouse template (not collection)
|
||||
public string $extension = COLLECTION_MONGO_JOURNAL_EXT;// sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = false; // set to true to cache class data
|
||||
public bool $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public bool $setJournaling = false; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = true; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
// fields specific to the collection
|
||||
MONGO_ID => DATA_TYPE_OBJECT, // sorting by the id is just like sorting by createdDate
|
||||
JOURNAL_SYSEV_TOK => DATA_TYPE_STRING, // systemEvent GUID
|
||||
JOURNAL_AUD_TOK => DATA_TYPE_STRING, // audit GUID
|
||||
JOURNAL_RECORD_GUID => DATA_TYPE_STRING, // GUID of the change record (table data in audit rec)
|
||||
JOURNAL_RESTORE_QUERY => DATA_TYPE_STRING, // Namaste-derived query to restore the record
|
||||
JOURNAL_HISTORY => DATA_TYPE_ARRAY, // sub-collection containing the journal-access history
|
||||
JOURNAL_HISTORY_DATE_RESTORED => DATA_TYPE_STRING, // sub-collection field: date record restored
|
||||
JOURNAL_HISTORY_RESTORED_EVENT_GUID => DATA_TYPE_STRING, // sub-collection field: restore request event GUID
|
||||
JOURNAL_HISTORY_RESTORED_BY => DATA_TYPE_STRING, // sub-collection field: name/GUID requesting user
|
||||
JOURNAL_HISTORY_RESTORED_REASON => DATA_TYPE_STRING, // sub-collection field: client supplied text
|
||||
// generic mongo constants
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key (string) exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER // epoch time
|
||||
];
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = null;
|
||||
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
// todo -- code a condition where ALL fields are protected using the * symbol (DB-58)
|
||||
public ?array $protectedFields = [
|
||||
MONGO_ID, JOURNAL_SYSEV_TOK, JOURNAL_RESTORE_QUERY, JOURNAL_HISTORY, JOURNAL_AUD_TOK,
|
||||
DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_STATUS, DB_ACCESSED, JOURNAL_RECORD_GUID
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_CREATED, DB_TOKEN, DB_ACCESSED, JOURNAL_RECORD_GUID, JOURNAL_AUD_TOK,
|
||||
JOURNAL_SYSEV_TOK, DB_EVENT_GUID
|
||||
];
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_CREATED => -1, // assuming we want LIFO
|
||||
DB_ACCESSED => -1, // assuming we want LIFO
|
||||
DB_EVENT_GUID => 1, // event guid should always be indexed
|
||||
JOURNAL_RECORD_GUID => 1
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = null;
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
DB_TOKEN => 1, // MONGO_TOKEN should always appear
|
||||
JOURNAL_SYSEV_TOK => 1,
|
||||
JOURNAL_AUD_TOK => 1 // Journal -> Audit is 1:1 so this key must be unique
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null;
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = null;
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
* SubC fields do not need to be indexed.
|
||||
*
|
||||
*/
|
||||
public ?array $subC = [
|
||||
JOURNAL_HISTORY => [
|
||||
JOURNAL_HISTORY_DATE_RESTORED,
|
||||
JOURNAL_HISTORY_RESTORED_BY,
|
||||
JOURNAL_HISTORY_RESTORED_EVENT_GUID,
|
||||
JOURNAL_HISTORY_RESTORED_REASON
|
||||
]
|
||||
];
|
||||
|
||||
//=================================================================================================================
|
||||
// MIGRATION DECLARATIONS
|
||||
// ----------------------
|
||||
// Data in this section is used to handle migrations -- when we're pulling from legacy tables into the Namaste
|
||||
// framework. See online doc for more info.
|
||||
//=================================================================================================================
|
||||
|
||||
/**
|
||||
* The migration map is an associative array that maps the Namaste fields (keys) to the corresponding
|
||||
* (remote) legacy fields in the source table to be migrated to Namaste.
|
||||
*
|
||||
* For example, if we were migrating a mysql table in the legacy production database to Namaste::mongo, then
|
||||
* the keys of the migration map would be the Namaste::mongo->fieldNames and the values would be the mysql
|
||||
* column names in the legacy table.
|
||||
*
|
||||
* If there is a value which cannot be mapped to a key, then set it to null.
|
||||
*
|
||||
* Fields that will be dropped in the migration are not listed as values or as keys.
|
||||
*
|
||||
* This map will only exist in the template object and will never be imported into the class widget.
|
||||
*
|
||||
* This is a required field.
|
||||
*
|
||||
*/
|
||||
public ?array $migrationMap = null;
|
||||
|
||||
/*
|
||||
* the migrationSortKey defines the SOURCE field by which the fetch query will be sorted. ALL sort fields are
|
||||
* in ASC order so all we need to list here is the name of the field -- which MUST BE IN THE SOURCE TABLE.
|
||||
*
|
||||
* Populating this field may require preliminary examination of the data - what we want is a field that has
|
||||
* zero NULL values.
|
||||
*
|
||||
* This is a required field.
|
||||
*
|
||||
*/
|
||||
public ?array $migrationSortKey = null;
|
||||
|
||||
/*
|
||||
* The migrationStatusKey defines the status field/column in the source table -- if the user requires that
|
||||
* soft-deleted records not be migrated, then this field must be set. Otherwise, set the value to null.
|
||||
*
|
||||
* The format is in the form of a key-value paired array. The key specifies the name of the column and the value
|
||||
* specifies the "deleted" value that, if found, will cause that row from the SOURCE data to be omitted from the
|
||||
* DESTINATION table.
|
||||
*
|
||||
* e.g.: $migrationStatusKV = [ 'some_field' => 'deleted' ]
|
||||
*
|
||||
* Note that both the key and the value are case-sensitive!
|
||||
*
|
||||
* This is an optional field.
|
||||
*
|
||||
*/
|
||||
public ?array $migrationStatusKV = null;
|
||||
|
||||
// The $migrationSourceSchema defines the remote schema for the source table
|
||||
public ?string $migrationSourceSchema = null; // or STRING_MONGO
|
||||
|
||||
// The source table in the remote repos (default defined in the XML) must be declared here
|
||||
public ?string $migrationSourceTable = null;
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => true, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'Q', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => true, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
WH_INDEXES => [DB_CREATED, DB_WH_CREATED],
|
||||
WH_TEMPLATE => '',
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [ OPERAND_NULL => [ OPERATOR_LT => [ null ] ] ],
|
||||
DB_STATUS => [ OPERAND_NULL => [ OPERATOR_EQ => [ STATUS_ACTIVE ]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 10-16-18 mks DB-57: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}/** @noinspection PhpUnused */
|
||||
|
||||
|
||||
/**
|
||||
* buildJournalData() -- template method
|
||||
*
|
||||
* This template method should only be called from the AdminIN broker when creating a journal record. It's sole
|
||||
* purpose is to build the data payload (record) that will be saved to the mongo database. As such, there are
|
||||
* four input parameters to the method:
|
||||
*
|
||||
* $_sysEvTok -- string value containing the system event token value
|
||||
* $_audTok -- string value containing the audit event token value
|
||||
* $_journalData -- indexed array containing two associative arrays containing the recovery queries and token list
|
||||
* $_es -- call-by-reference array parameter used to send error messages back to the calling client
|
||||
*
|
||||
* Processing errors will be raised if any of the first three input values are missing or invalid. Also, we compare
|
||||
* the count of the the number of elements in the $_journalData array -- this array should have to keys:
|
||||
* STRING_JOURNAL_TOKEN_LIST and STRING_JOURNAL_QUERY_LIST and the same number of elements must be in both.
|
||||
*
|
||||
* If errors are encountered during processing, then an error message is returned (implicitly) and a null value is
|
||||
* explicitly returned to the caller.
|
||||
*
|
||||
* Otherwise, we return an indexed array of records that will be inserted into the journal collection.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @param string $_sysEvTok
|
||||
* @param string $_audTok
|
||||
* @param array $_journalData
|
||||
* @param array $_es
|
||||
* @return array|null
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 10-25-18 mks DB-74: original coding
|
||||
*
|
||||
*/
|
||||
public function buildJournalData(string $_sysEvTok, string $_audTok, array $_journalData, array &$_es): ?array
|
||||
{
|
||||
$res = 'JRNL: ';
|
||||
$data = null;
|
||||
if (!validateGUID($_sysEvTok)) {
|
||||
$msg = ERROR_INVALID_GUID . $_sysEvTok;
|
||||
consoleLog($res, CON_SYSTEM, $msg);
|
||||
$_es[] = $msg;
|
||||
return $data;
|
||||
}
|
||||
if (!validateGUID($_audTok)) {
|
||||
$msg = ERROR_INVALID_GUID . $_audTok;
|
||||
consoleLog($res, CON_SYSTEM, $msg);
|
||||
$_es[] = $msg;
|
||||
return $data;
|
||||
}
|
||||
if (count($_journalData[STRING_JOURNAL_QUERY_LIST]) < 1 or count($_journalData[STRING_JOURNAL_QUERY_LIST]) != count($_journalData[STRING_JOURNAL_TOKEN_LIST])) {
|
||||
$msg = ERROR_AUDIT_COUNT;
|
||||
consoleLog($res, CON_SYSTEM, $msg);
|
||||
$_es[] = $msg;
|
||||
return $data;
|
||||
}
|
||||
for ($i = 0, $max = count($_journalData[STRING_JOURNAL_TOKEN_LIST]); $i < $max; $i++) {
|
||||
$data[$i][JOURNAL_SYSEV_TOK] = $_sysEvTok;
|
||||
$data[$i][JOURNAL_AUD_TOK] = $_audTok;
|
||||
$data[$i][JOURNAL_RECORD_GUID] = $_journalData[STRING_JOURNAL_TOKEN_LIST][$i];
|
||||
$data[$i][JOURNAL_RESTORE_QUERY] = $_journalData[STRING_JOURNAL_QUERY_LIST][$i];
|
||||
}
|
||||
consoleLog($res, CON_SUCCESS, sprintf(STUB_PROCESSED, $max, STRING_JOURNAL));
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 10-16-18 mks DB-57: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 10-16-18 mks DB-57: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
434
classes/templates/gatLogs.class.inc
Normal file
434
classes/templates/gatLogs.class.inc
Normal file
@@ -0,0 +1,434 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class gatLog
|
||||
*
|
||||
* This is the logging class definition that records application-generated events.
|
||||
*
|
||||
* Design Notes:
|
||||
* -------------
|
||||
* because this is a log, and log events are processed by a FnF queue, we're not going to cache, or use auditing.
|
||||
* History is not recorded for this class.
|
||||
* Only one status is supported: ACTIVE and there are no updates allowed making record-locking unnecessary.
|
||||
* Cache timers on the class are disabled because recursion.
|
||||
* id's (auto-incrementing integers) are deprecated and replaced by the native _id.
|
||||
* The created date is stored an epoch time (integer).
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 07-06-17 mks CORE-463: code complete (refactor from ddb to mdb)
|
||||
* 07-12-17 mks added log-level value column to collection for ranged searching
|
||||
* 08-04-17 mks added version control, partialIndexes
|
||||
* 08-11-17 mks CORE-467: indexes brought up to mongo 3.2 standards and made consistent
|
||||
* 04-19-18 mks _INF-188: warehousing section added
|
||||
* 01-13-20 mks DB-150: PHP7.4 class member type-casting
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
*
|
||||
*/
|
||||
class gatLogs {
|
||||
public int $version = 1;
|
||||
public string $service = CONFIG_DATABASE_SERVICE_ADMIN; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_LOGS; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_LOGS; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_LOGS_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = false; // set to true to cache class data
|
||||
public bool $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public bool $setJournaling = false; // set to true to allow journaling
|
||||
public bool $setUpdates = false; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = false; // set to true to enable collection query timers
|
||||
public string $setPKey = MONGO_ID; // sets the primary key for the collection
|
||||
public bool $setTokens = false; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = true; // set to false if the class contains methods
|
||||
public int $cacheTimer = 0; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = true; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
MONGO_ID => DATA_TYPE_OBJECT, // sorting by the id is just like sorting by createdDate
|
||||
LOG_FILE => DATA_TYPE_STRING,
|
||||
LOG_METHOD => DATA_TYPE_STRING,
|
||||
LOG_LINE => DATA_TYPE_INTEGER,
|
||||
LOG_CLASS => DATA_TYPE_STRING,
|
||||
LOG_LEVEL => DATA_TYPE_STRING,
|
||||
LOG_VALUE => DATA_TYPE_INTEGER,
|
||||
LOG_MESSAGE => DATA_TYPE_STRING,
|
||||
DB_STATUS => DATA_TYPE_STRING,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING,
|
||||
LOG_CREATED => DATA_TYPE_INTEGER
|
||||
];
|
||||
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = null;
|
||||
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [ MONGO_ID, LOG_CREATED, LOG_VALUE, LOG_FILE, LOG_LEVEL, DB_EVENT_GUID ];
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
LOG_CREATED => -1,
|
||||
LOG_VALUE => 1,
|
||||
LOG_FILE => 1,
|
||||
LOG_LEVEL => 1,
|
||||
DB_EVENT_GUID => 1
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = null;
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = null; // token is not required for system collections
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null; // ttl indexes appear in $indexFields
|
||||
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null; // lists the fields that will be sent to clients; null => all data
|
||||
// cache map, if defined, will always override.
|
||||
// mongo IDs are NEVER returned
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
*/
|
||||
// sub-collection fields must be declared here (need not be indexed)
|
||||
public ?array $subC = null; // sub-collection fields must be declared here
|
||||
// see gatTestMongo.class.inc for explanation & examples
|
||||
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [ OPERAND_NULL => [ OPERATOR_LT => [ null ] ] ],
|
||||
DB_STATUS => [ OPERAND_NULL => [ OPERATOR_EQ => [ STATUS_ACTIVE ]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 07-06-17 mks CORE-463: code complete (refactor from ddb to mdb)
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 07-06-17 mks CORE-463: code complete (refactor from ddb to mdb)
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 07-06-17 mks CORE-463: code complete (refactor from ddb to mdb)
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
433
classes/templates/gatMetrics.class.inc
Normal file
433
classes/templates/gatMetrics.class.inc
Normal file
@@ -0,0 +1,433 @@
|
||||
<?php /** @noinspection PhpUnused */
|
||||
|
||||
/**
|
||||
* Class gatMetrics
|
||||
*
|
||||
* This is the metrics class definition that records timer events, usually database queries.
|
||||
*
|
||||
* Design Notes:
|
||||
* -------------
|
||||
* Metrics is identical to Logs, who's events are processed by a FnF queue, we're not going to cache, or use auditing.
|
||||
* History is not recorded for this class.
|
||||
* Only one status is supported: ACTIVE and there are no updates allowed making record-locking unnecessary.
|
||||
* Cache timers on the class are disabled because recursion.
|
||||
* id's (auto-incrementing integers) are deprecated and replaced by the native _id.
|
||||
* The created date is stored an epoch time (integer).
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 07-06-17 mks CORE-463: code complete (refactor from ddb to mdb)
|
||||
* 08-04-17 mks added version control, partialIndexes
|
||||
* 08-11-17 mks CORE-467: indexes brought up to mongo 3.2 standards and made consistent
|
||||
* 04-19-18 mks _INF-188: warehousing section added
|
||||
* 11-04-19 mks DB-136: Added DB_TIMER single-field index to indexFields container
|
||||
* 01-13-20 mks DB-150: PHP7.4 class member type-casting
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
*
|
||||
*/
|
||||
class gatMetrics
|
||||
{
|
||||
public int $version = 1;
|
||||
public string $service = CONFIG_DATABASE_SERVICE_ADMIN; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_METRICS; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_METRICS; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_METRICS_EXT;// sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = false; // set to true to cache class data
|
||||
public bool $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public bool $setJournaling = false; // set to true to enable journaling
|
||||
public bool $setUpdates = false; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = false; // set to true to enable collection query timers
|
||||
public string $setPKey = MONGO_ID; // sets the primary key for the collection
|
||||
public bool $setTokens = false; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = true; // set to false if the class contains methods
|
||||
public int $cacheTimer = 0; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = true; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
MONGO_ID => DATA_TYPE_INTEGER, // sorting by the id is just like sorting by createdDate
|
||||
LOG_FILE => DATA_TYPE_STRING,
|
||||
LOG_METHOD => DATA_TYPE_STRING,
|
||||
LOG_LINE => DATA_TYPE_INTEGER,
|
||||
LOG_CLASS => DATA_TYPE_STRING,
|
||||
LOG_LEVEL => DATA_TYPE_STRING,
|
||||
LOG_MESSAGE => DATA_TYPE_STRING,
|
||||
DB_STATUS => DATA_TYPE_STRING,
|
||||
DB_TIMER => DATA_TYPE_DOUBLE,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING,
|
||||
LOG_CREATED => DATA_TYPE_INTEGER
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [ MONGO_ID, LOG_CREATED, LOG_LEVEL, DB_EVENT_GUID, DB_TIMER ];
|
||||
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = null;
|
||||
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
LOG_CREATED => -1,
|
||||
LOG_LEVEL => 1,
|
||||
DB_EVENT_GUID => 1,
|
||||
DB_TIMER => -1
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = null;
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = null; // token is not required for system collections
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null; // ttl indexes appear in $indexFields
|
||||
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = null; // key-value paired array of field-names mapped to cache-names
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null; // lists the fields that will be sent to clients; null => all data
|
||||
// cache map, if defined, will always override.
|
||||
// mongo IDs are NEVER returned
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
*/
|
||||
// sub-collection fields must be declared here (need not be indexed)
|
||||
public ?array $subC = null; // sub-collection fields must be declared here
|
||||
// see gatTestMongo.class.inc for explanation & examples
|
||||
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [ OPERAND_NULL => [ OPERATOR_LT => [ null ] ] ],
|
||||
DB_STATUS => [ OPERAND_NULL => [ OPERATOR_EQ => [ STATUS_ACTIVE ]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 07-06-17 mks CORE-463: code complete (refactor from ddb to mdb)
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 07-06-17 mks CORE-463: code complete (refactor from ddb to mdb)
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 07-06-17 mks CORE-463: code complete (refactor from ddb to mdb)
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
471
classes/templates/gatMigrations.class.inc
Normal file
471
classes/templates/gatMigrations.class.inc
Normal file
@@ -0,0 +1,471 @@
|
||||
<?php
|
||||
/**
|
||||
* gatMigrations -- mongo template class
|
||||
*
|
||||
* This template is used internally to record migration process for a source table to it's destination. This table
|
||||
* records the new records created so that, in the event of failure, we can back-out the newly-created records from
|
||||
* the mongo collection.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 01-30-18 mks _INF-139: original coding
|
||||
* 04-19-18 mks _INF-188: warehousing section added
|
||||
* 11-04-19 mks DB-136: added missing DB_EVENT_GUID index to $indexFields
|
||||
* 01-13-20 mks DB-150: PHP7.4 member class type-casting
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
*/
|
||||
|
||||
class gatMigrations
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version - not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_ADMIN; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_MIGRATIONS; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_MIGRATIONS; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_MIGRATIONS_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = false; // set to true to cache class data
|
||||
public bool $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public bool $setJournaling = false; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = false; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 0; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = true; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
MONGO_ID => DATA_TYPE_INTEGER, // sorting by the id is just like sorting by createdDate
|
||||
MWH_SOURCE_SCHEMA => DATA_TYPE_STRING, // name of the source schema
|
||||
MWH_SOURCE_TABLE => DATA_TYPE_STRING, // name of the source table
|
||||
MWH_DEST_SCHEMA => DATA_TYPE_STRING, // name of the destination schema
|
||||
MWH_DEST_TABLE => DATA_TYPE_STRING, // name of the destination table
|
||||
MWH_QUERY => DATA_TYPE_STRING, // (first) query used to migrate the data
|
||||
MWH_DATE_STARTED => DATA_TYPE_INTEGER, // when the migration started (epoch time)
|
||||
MWH_NUM_RECS_SOURCE => DATA_TYPE_STRING, // number of records in the source table
|
||||
MWH_NUM_RECS_MOVED => DATA_TYPE_INTEGER, // number of records migrated
|
||||
MWH_NUM_RECS_DROPPED => DATA_TYPE_INTEGER, // number of records that were dropped
|
||||
MWH_LAST_REC_WRITTEN => DATA_TYPE_STRING, // json-encoded string of the last record written
|
||||
MWH_DATE_COMPLETED => DATA_TYPE_INTEGER, // when migration completed (epoch time)
|
||||
MWH_STOP_REASON => DATA_TYPE_STRING, // reason why migration failed
|
||||
MWH_ERROR_CAT => DATA_TYPE_ARRAY, // array of errors
|
||||
MWH_REPORT => DATA_TYPE_STRING, // stores the generated wh report
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key (GUID) exposed externally and is REQUIRED
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER // epoch time
|
||||
];
|
||||
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_EVENT_GUID, DB_CREATED, MONGO_ID, MWH_SOURCE_SCHEMA,
|
||||
MWH_SOURCE_TABLE, MIGRATION_DEST_SCHEMA, MIGRATION_DEST_TABLE,
|
||||
MWH_NUM_RECS_SOURCE, MWH_DATE_STARTED
|
||||
];
|
||||
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_CREATED, DB_TOKEN, MWH_SOURCE_TABLE, DB_STATUS, MWH_DEST_TABLE,
|
||||
MWH_DEST_SCHEMA, MWH_SOURCE_SCHEMA, DB_EVENT_GUID
|
||||
];
|
||||
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = null;
|
||||
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_CREATED => 1,
|
||||
DB_STATUS => 1,
|
||||
DB_EVENT_GUID => 1,
|
||||
MWH_SOURCE_TABLE => 1,
|
||||
MWH_DEST_TABLE => 1,
|
||||
MWH_DEST_SCHEMA => 1,
|
||||
MWH_SOURCE_SCHEMA => 1
|
||||
];
|
||||
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = null;
|
||||
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
DB_TOKEN => 1 // MONGO_TOKEN should always appear
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null;
|
||||
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = null; // todo -- test this setting
|
||||
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
* SubC fields do not need to be indexed.
|
||||
*
|
||||
*/
|
||||
public ?array $subC = null;
|
||||
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [ OPERAND_NULL => [ OPERATOR_LT => [ null ] ] ],
|
||||
DB_STATUS => [ OPERAND_NULL => [ OPERATOR_EQ => [ STATUS_ACTIVE ]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 01-30-18 mks _INF-139: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 01-30-18 mks _INF-139: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 01-30-18 mks _INF-139: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
655
classes/templates/gatProdRegistrations.class.inc
Normal file
655
classes/templates/gatProdRegistrations.class.inc
Normal file
@@ -0,0 +1,655 @@
|
||||
<?php
|
||||
/**
|
||||
* gatProdRegistrations.class -- Namaste mySQL Data Template
|
||||
*
|
||||
* This is the template file for the Namaste mySQL version of product-registration. This template was created for the
|
||||
* purpose of testing mysql->mysql data migration.
|
||||
*
|
||||
* There is another prod-reg template: gatProductRegistrations.class.inc -- which is a mongo data template.
|
||||
*
|
||||
* Once version 1.0.0 of Namaste is launched, please remember to deprecate either this, or the other, template class
|
||||
* so that there is no potential for confusion.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 03-23-18 mks CORE-852: original coding
|
||||
* 04-18-18 mks _INF-188: warehousing section added
|
||||
* 06-12-18 mks CORE-1043: updated PDO objects to add SQL statements for table create, update
|
||||
* 01-13-20 mks DB-150: PHP7.4 class member type-casting
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
*
|
||||
*/
|
||||
|
||||
class gatProdRegistrations
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public int $version = 1; // template version: not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_APPSERVER; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_PDO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_PROD_REGS; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_PDO_PROD_REGS; // sets the collection (table) name
|
||||
public ?string $whTemplate = TEMPLATE_CLASS_WHC1_PROD_REG; // name of the warehouse template (not collection)
|
||||
public string $extension = COLLECTION_PDO_PROD_REGS_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = false; // set to true to cache class data
|
||||
public bool $setDeletes = false; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public bool $setJournaling = false; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set 2 true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if class contains methods or migration
|
||||
public int $cacheTimer = 0; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = false; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
//
|
||||
// Note that for PDO-type tables, the data type is more ... homogeneous... e.g.: data types define the data
|
||||
// type only. It does not define the actual column type in-use. For example, there is no distinction made
|
||||
// between a tinyInt, Int, or BigInt. As far as the framework is concerned, they're all just integers.
|
||||
//
|
||||
public array $fields = [
|
||||
PDO_ID => DATA_TYPE_INTEGER, // sorting by the id is just like sorting by createdDate
|
||||
PRG_TYPE => DATA_TYPE_STRING,
|
||||
PRG_IID => DATA_TYPE_STRING,
|
||||
PRG_EAV => DATA_TYPE_STRING,
|
||||
PRG_PLATFORM => DATA_TYPE_STRING,
|
||||
PRG_BROWSER => DATA_TYPE_STRING,
|
||||
PRG_MAJOR_VERSION => DATA_TYPE_INTEGER,
|
||||
PRG_MINOR_VERSION => DATA_TYPE_INTEGER,
|
||||
PRG_IS_MOBILE => DATA_TYPE_INTEGER,
|
||||
PRG_IS_TABLET => DATA_TYPE_INTEGER,
|
||||
PRG_FIRST_SEEN => DATA_TYPE_STRING,
|
||||
PRG_LAST_SEEN => DATA_TYPE_STRING,
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key (string) exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_STRING, // dateTime type
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_STRING // dateTime type
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED, PDO_ID
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public array $indexFields = [
|
||||
PDO_ID => 1,
|
||||
PRG_EAV => 1,
|
||||
PRG_IID => 1,
|
||||
PRG_TYPE => 1,
|
||||
DB_CREATED => 1,
|
||||
DB_STATUS => 1, // status should only be indexed if soft-deletes are enabled (just saying)
|
||||
DB_EVENT_GUID => 1, // event guid should always be indexed
|
||||
DB_TOKEN => 1
|
||||
];
|
||||
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = [ 'cIdx1Test'];
|
||||
|
||||
|
||||
// the primary key index is declared in the class properties section as $setPKey
|
||||
|
||||
// unique indexes are to be used a values stored in these columns have to be unique to the table. Note that
|
||||
// null values are permissible in unique-index columns. Do not declare MONGO_ID here, regardless of how badly
|
||||
// you may want to.
|
||||
public ?array $uniqueIndexes = [ DB_TOKEN => 1 ];
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index (index, multi)
|
||||
// the format for the single-field index declaration is a simple indexed array.
|
||||
public ?array $singleFields = [
|
||||
PRG_EAV, PRG_IID, PRG_TYPE, DB_EVENT_GUID
|
||||
];
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $compoundIndexes = [
|
||||
'cIdx1Test' => [ DB_CREATED, DB_STATUS ]
|
||||
];
|
||||
|
||||
|
||||
// NOTE: foreign-key indexes are not explicitly enumerated in a template -- that relationship is defined in the
|
||||
// schema for the table. Foreign-key indexes appear implicitly in the indexing declarations above.
|
||||
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
PRG_TYPE => CM_PRG_TYPE,
|
||||
PRG_IID => CM_PRG_IID,
|
||||
PRG_EAV => CM_PRG_EAV,
|
||||
PRG_PLATFORM => CM_PRG_PLATFORM,
|
||||
PRG_BROWSER => CM_PRG_BROWSER,
|
||||
PRG_MAJOR_VERSION => CM_PRG_MAJ_VER,
|
||||
PRG_MINOR_VERSION => CM_PRG_MIN_VER,
|
||||
PRG_IS_MOBILE => CM_PRG_IS_MOBILE,
|
||||
PRG_IS_TABLET => CM_PRG_IS_TABLET,
|
||||
PRG_FIRST_SEEN => CM_PRG_FIRST_SEEN,
|
||||
PRG_LAST_SEEN => CM_PRG_LAST_SEEN,
|
||||
DB_TOKEN => CM_TST_TOKEN,
|
||||
DB_STATUS => CM_TST_FIELD_TEST_STATUS,
|
||||
DB_EVENT_GUID => CM_TST_EVENT_GUID,
|
||||
DB_CREATED => CM_TST_FIELD_TEST_CDATE,
|
||||
DB_ACCESSED => CM_TST_FIELD_TEST_ADATE
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it a null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = [
|
||||
PRG_TYPE => 1,
|
||||
PRG_IID => 1,
|
||||
PRG_EAV => 1,
|
||||
PRG_PLATFORM => 1,
|
||||
PRG_BROWSER => 1,
|
||||
PRG_MAJOR_VERSION => 1,
|
||||
PRG_MINOR_VERSION => 1,
|
||||
PRG_IS_MOBILE => 1,
|
||||
PRG_IS_TABLET => 1,
|
||||
PRG_FIRST_SEEN => 1,
|
||||
PRG_LAST_SEEN => 1,
|
||||
DB_TOKEN => 1,
|
||||
DB_CREATED => 1, // epoch time
|
||||
DB_STATUS => 1, // record status
|
||||
DB_ACCESSED => 1 // epoch time
|
||||
];
|
||||
|
||||
// in PDO-land, binary fields are your basic data blobs. All binary fields require special handling and so
|
||||
// need to be enumerated here as an indexed array.
|
||||
public ?array $binFields = null;
|
||||
|
||||
|
||||
// DB SQL:
|
||||
// -------
|
||||
// PDO SQL is stored in the template and is keyed by the current namaste version (defined in the XML file) during
|
||||
// execution of the deployment script. Each version denotes a container of SQL commands that will be executed
|
||||
// for the targeted version.
|
||||
//
|
||||
// SQL is versioned in parallel with the Namaste (XML->application->id->version) version. Each PDO_SQL
|
||||
// sub-container has several fields - one of which has the version identifier. When the deployment script
|
||||
// executes, the release versions are compared and, if they're an exact match, the SQL is submitted for execution.
|
||||
//
|
||||
// The PDO_SQL container consists of these sub-containers:
|
||||
//
|
||||
// PDO_SQL_VERSION --> this is a float value in the form of x.y as namaste only supports versions as a major
|
||||
// and minor release number. (Patch releases are minor release increments.)
|
||||
// PDO_TABLE --> string value containing the full table name.
|
||||
// PDO_SQL_FC --> the FC means "first commit" -- when the table is first created, it will execute the
|
||||
// SQL in this block, if it exists, and if the version number for the sub-container
|
||||
// exactly matched the version number in the configuration XML.
|
||||
// PDO_SQL_UPDATE --> When the sub-container PDO_SQL_VERSION value exactly matches the XML release value,
|
||||
// then the ALTER-TABLE sql in this update block will be executed.
|
||||
// STRING_DROP_CODE_IDX --> The boilerplate code for dropping the indexes of the table.
|
||||
// STRING_DROP_CODE_DEV --> For version 1.0 only, this points to code to drop the entire table.
|
||||
//
|
||||
// Again, containers themselves are indexed arrays under the PDO_SQL tag. Within the container, data is stored
|
||||
// as an associative array with the keys enumerated above.
|
||||
//
|
||||
//
|
||||
// DB OBJECTS:
|
||||
// -----------
|
||||
// DB objects are: views, procedures, functions and events.
|
||||
// All such objects assigned to a class are declared in this array under the appropriate header.
|
||||
// This is a safety-feature that prevents a one class (table) from invoking another class object.
|
||||
// The name of the object is stored as an indexed-array under the appropriate header.
|
||||
//
|
||||
// The format for these structures is basically the same. Each DBO is stored in an associative array with the
|
||||
// key defining the name of the object. Within each object, there are embedded associative arrays that have the
|
||||
// name of the object as the key and the object definition (text) and the value:
|
||||
//
|
||||
// objectType => [ objectName => [ objectContent ], ... ]
|
||||
//
|
||||
// Each created object should also have the directive to remove it's predecessor using a DROP statement.
|
||||
//
|
||||
// todo -- unset these objects post-instantiation so that schema is not revealed
|
||||
//
|
||||
// VIEWS:
|
||||
// ------
|
||||
// Every namaste table will have at least one view which limits the data fetched from the table. At a minimum,
|
||||
// the id_{ext} field is filtered from the resulting data set via the view. Other fields can be withheld as well
|
||||
// but that is something that is individually set-up for each table.
|
||||
//
|
||||
// The basic view has the following syntax for declaring it's name:
|
||||
// view_basic_{tableName_ext}
|
||||
// All views start with the word "view" so as to self-identify the object, followed by the view type which,
|
||||
// optimally, you should try to limit to a single, descriptive word.
|
||||
//
|
||||
// Following this label, which points to a sub-array containing three elements:
|
||||
// STRING_VIEW ----------> this is the SQL code that defines the view as a single string value
|
||||
// STRING_TYPE_LIST -----> null or an array of types that corresponds to variable markers ('?') in the sql
|
||||
// STRING_DESCRIPTION' --> a string that describes the purpose of the view.
|
||||
//
|
||||
// At a minimum, every class definition should contain at-least a basic view as all queries that don't specify
|
||||
// a named view or other DBO, will default to the the basic view in the FROM clause of the generated SQL.
|
||||
//
|
||||
// PROCEDURES:
|
||||
// -----------
|
||||
// For stored procedures, which are entirely optional, the array definition contains the following elements:
|
||||
// STRING_PROCEDURE -------> the SQL code that defined the stored procedure as a single string value
|
||||
// STRING_DROP_CODE -------> the sql code that drops the procedure (required for procedures!)
|
||||
// STRING_TYPE_LIST -------> an associative array of associative arrays -- in the top level, the key is the name
|
||||
// of the parameter that points to a sub-array that contains the parameter direction
|
||||
// as the key, and the parameter type as the value. There should be an entry for each
|
||||
// parameter to be passed to the stored procedure/function.
|
||||
//
|
||||
// ------------------------------------------------------
|
||||
// | NOTE: IN params must precede INOUT and OUT params! |
|
||||
// ------------------------------------------------------
|
||||
//
|
||||
// STRING_SP_EVENT_TYPE ---> Assign one of the DB_EVENT constants to this field to indicate the type of
|
||||
// query the stored-procedure will execute.
|
||||
// NOTE: there is not a defined PDO::PARAM constant for type float: use string.
|
||||
// STRING_DESCRIPTION -----> clear-text definition of the procedure's purpose
|
||||
//
|
||||
// Note that all of these containers are required; empty containers should contain a null placeholder.
|
||||
//
|
||||
// When a stored procedure contains a join of two or more tables/views, the first table listed is considered
|
||||
// to be the "owning" table and the procedure will be declared in the class template for that table, but it will
|
||||
// not be duplicated in other template classes referenced in the join.
|
||||
//
|
||||
public ?array $dbObjects = [
|
||||
PDO_SQL => [
|
||||
[
|
||||
PDO_VERSION => 1.0,
|
||||
PDO_TABLE => 'gaProductRegistrations_prg',
|
||||
PDO_SQL_FC => "
|
||||
--
|
||||
-- Table structure for table `gaProductRegistrations_prg`
|
||||
--
|
||||
|
||||
CREATE TABLE `gaProductRegistrations_prg` (
|
||||
`id_prg` int(10) UNSIGNED NOT NULL,
|
||||
`type_prg` char(16) NOT NULL,
|
||||
`iid_prg` char(64) NOT NULL,
|
||||
`eav_prg` char(16) DEFAULT NULL,
|
||||
`platform_prg` char(32) DEFAULT NULL,
|
||||
`browser_prg` char(32) DEFAULT NULL,
|
||||
`majorVersion_prg` int(11) DEFAULT NULL,
|
||||
`minorVersion_prg` int(11) DEFAULT NULL,
|
||||
`isMobile_prg` tinyint(3) UNSIGNED DEFAULT NULL,
|
||||
`isTablet_prg` tinyint(3) UNSIGNED DEFAULT NULL,
|
||||
`firstSeen_prg` datetime DEFAULT NULL,
|
||||
`lastSeen_prg` datetime DEFAULT NULL,
|
||||
`token_prg` char(36) NOT NULL,
|
||||
`eventGUID_prg` char(36) DEFAULT NULL,
|
||||
`createdDate_prg` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`lastAccessedDate_prg` datetime DEFAULT NULL,
|
||||
`status_prg` varchar(25) NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
",
|
||||
PDO_SQL_UPDATE => "
|
||||
--
|
||||
-- Indexes for table `gaProductRegistrations_prg`
|
||||
--
|
||||
ALTER TABLE `gaProductRegistrations_prg`
|
||||
ADD PRIMARY KEY (`id_prg`),
|
||||
ADD UNIQUE KEY `token_prg` (`token_prg`),
|
||||
ADD KEY `type_prg` (`type_prg`,`iid_prg`),
|
||||
ADD KEY `createdDate_prg` (`createdDate_prg`,`lastAccessedDate_prg`,`status_prg`),
|
||||
ADD KEY `iid_prg` (`iid_prg`,`eav_prg`),
|
||||
ADD KEY `eventGUID_prg` (`eventGUID_prg`);
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT for table `gaProductRegistrations_prg`
|
||||
--
|
||||
ALTER TABLE `gaProductRegistrations_prg`
|
||||
MODIFY `id_prg` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
|
||||
",
|
||||
/*
|
||||
* example query return:
|
||||
* ---------------------
|
||||
* ALTER TABLE gaTest_tst DROP INDEX gaTest_tst_createdDate_tst_status_tst_index, DROP INDEX
|
||||
* gaTest_tst_lastAccessedDate_tst_index, DROP INDEX testInteger_tst, DROP INDEX
|
||||
* gaTest_tst_eventGuid_tst_index, DROP INDEX testDouble_tst, DROP INDEX testString_tst;
|
||||
*
|
||||
* NOTE:
|
||||
* -----
|
||||
* The sql comment code tag (--) will be removed during mysqlConfig's run time processing
|
||||
*/
|
||||
STRING_DROP_CODE_IDX => "--
|
||||
SELECT CONCAT('ALTER TABLE ', `Table`, ' DROP INDEX ', GROUP_CONCAT(`Index` SEPARATOR ', DROP INDEX '),';' )
|
||||
FROM (
|
||||
SELECT table_name AS `Table`, index_name AS `Index`
|
||||
FROM information_schema.statistics
|
||||
WHERE INDEX_NAME != 'PRIMARY'
|
||||
AND table_schema = 'XXXDROP_DB_NAMEXXX'
|
||||
AND table_name = 'XXXDROP_TABLE_NAMEXXX'
|
||||
GROUP BY `Table`, `Index`) AS tmp
|
||||
GROUP BY `Table`;
|
||||
",
|
||||
STRING_DROP_CODE_DEV => "DROP TABLE IF EXISTS gaProductRegistrations_prg;" // only executed if declared
|
||||
]
|
||||
],
|
||||
PDO_VIEWS => [
|
||||
'view_basic_gaProductRegistrations' => [
|
||||
STRING_VIEW =>
|
||||
"DROP VIEW IF EXISTS view_basic_gaProductRegistrations;
|
||||
CREATE VIEW view_basic_gaProductRegistrations_prg AS
|
||||
SELECT type_prg, iid_prg, eav_prg, platform_prg, browser_prg, majorVersion_prg, minorVersion_prg,
|
||||
isMobile_prg, isTablet_prg, firstSeen_prg, lastSeen_prg, eventGUID_prg, createdDate_prg,
|
||||
lastAccessedDate_prg, status_prg, token_prg
|
||||
FROM gaProductRegistrations_prg
|
||||
WHERE status_prg <> \"DELETE\";",
|
||||
STRING_TYPE_LIST => null,
|
||||
STRING_DESCRIPTION => 'basic query'
|
||||
],
|
||||
],
|
||||
PDO_PROCEDURES => [],
|
||||
PDO_FUNCTIONS => [],
|
||||
PDO_EVENTS => [],
|
||||
PDO_TRIGGERS => []
|
||||
];
|
||||
|
||||
|
||||
//=================================================================================================================
|
||||
// MIGRATION DECLARATIONS
|
||||
// ----------------------
|
||||
// Data in this section is used to handle migrations -- when we're pulling from legacy tables into the Namaste
|
||||
// framework. See online doc for more info.
|
||||
//=================================================================================================================
|
||||
|
||||
/**
|
||||
* The migration map is an associative array that maps the Namaste fields (keys) to the corresponding
|
||||
* (remote) legacy fields in the source table to be migrated to Namaste.
|
||||
*
|
||||
* For example, if we were migrating a mysql table in the legacy production database to Namaste::mongo, then
|
||||
* the keys of the migration map would be the Namaste::mongo->fieldNames and the values would be the mysql
|
||||
* column names in the legacy table.
|
||||
*
|
||||
* If there is a value which cannot be mapped to a key, then set it to null.
|
||||
*
|
||||
* Fields that will be dropped in the migration are not listed as values or as keys.
|
||||
*
|
||||
* This map will only exist in the template object and will never be imported into the class widget.
|
||||
*
|
||||
* This is a required field.
|
||||
*
|
||||
*/
|
||||
public ?array $migrationMap = [
|
||||
PDO_ID => null, // created on insert
|
||||
PRG_TYPE => 'type',
|
||||
PRG_IID => 'iid',
|
||||
PRG_EAV => 'eav',
|
||||
PRG_PLATFORM => 'platform',
|
||||
PRG_BROWSER => 'browser',
|
||||
PRG_MAJOR_VERSION => 'major_version',
|
||||
PRG_MINOR_VERSION => 'minor_version',
|
||||
PRG_IS_MOBILE => 'is_mobile',
|
||||
PRG_IS_TABLET => 'is_tablet',
|
||||
PRG_FIRST_SEEN => 'first_seen',
|
||||
PRG_LAST_SEEN => 'last_seen',
|
||||
DB_TOKEN => null, // created on insert
|
||||
DB_EVENT_GUID => null, // generated by broker event
|
||||
DB_CREATED => 'kinsert_date', // epoch time
|
||||
DB_STATUS => null, // record status
|
||||
DB_ACCESSED => 'kupdate_date' // epoch time
|
||||
];
|
||||
|
||||
/*
|
||||
* the migrationSortKey defines the SOURCE field by which the fetch query will be sorted. ALL sort fields are
|
||||
* in ASC order so all we need to list here is the name of the field -- which MUST BE IN THE SOURCE TABLE.
|
||||
*
|
||||
* Populating this field may require preliminary examination of the data - what we want is a field that has
|
||||
* zero NULL values.
|
||||
*
|
||||
* This is a required field.
|
||||
*
|
||||
*/
|
||||
public ?string $migrationSortKey = 'last_seen';
|
||||
|
||||
/*
|
||||
* The migrationStatusKey defines the status field/column in the source table -- if the user requires that
|
||||
* soft-deleted records not be migrated, then this field must be set. Otherwise, set the value to null.
|
||||
*
|
||||
* The format is in the form of a key-value paired array. The key specifies the name of the column and the value
|
||||
* specifies the "deleted" value that, if found, will cause that row from the SOURCE data to be omitted from the
|
||||
* DESTINATION table.
|
||||
*
|
||||
* e.g.: $migrationStatusKV = [ 'some_field' => 'deleted' ]
|
||||
*
|
||||
* Note that both the key and the value are case-sensitive!
|
||||
*
|
||||
* This is an optional field.
|
||||
*
|
||||
*/
|
||||
public ?array $migrationStatusKV = null;
|
||||
|
||||
// The $migrationSourceSchema defines the remote schema for the source table, and is set in the constructor
|
||||
public ?string $migrationSourceSchema;
|
||||
|
||||
// The source table in the remote repos (default defined in the XML) must be declared here, set in the constructor
|
||||
public ?string $migrationSourceTable;
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => true, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => true, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => true, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => true, // true to allow an ad-hoc query filter or if WH_REMOTE_SUPPORT is true
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [ OPERAND_NULL => [ OPERATOR_LT => [ null ] ] ],
|
||||
DB_STATUS => [ OPERAND_NULL => [ OPERATOR_EQ => [ STATUS_ACTIVE ]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 03-23-18 mks CORE-852: original coding
|
||||
* 09-09-19 mks DB-111: initialization of migration members moved to constructor b/c IDE warnings.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
$this->migrationSourceSchema = STRING_MYSQL; // or STRING_MONGO
|
||||
$this->migrationSourceTable = 'product_registrations';
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 03-23-18 mks CORE-852: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 03-23-18 mks CORE-852: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
// empty by design
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
550
classes/templates/gatProductRegistrations.class.inc
Normal file
550
classes/templates/gatProductRegistrations.class.inc
Normal file
@@ -0,0 +1,550 @@
|
||||
<?php
|
||||
/**
|
||||
* gatProductRegistrations -- mongo template class
|
||||
*
|
||||
* This is the mongo template for givva.product_registrations, previously a mySQL-schema based table.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-20-17 mks CORE-681: original coding
|
||||
* 01-13-20 mks DB-150: PHP7.4 class member type-casting
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
*
|
||||
*/
|
||||
|
||||
class gatProductRegistrations
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version: not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_APPSERVER; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_PRODUCT_REG; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_PROD_REGS; // sets the collection (table) name
|
||||
public ?string $whTemplate = TEMPLATE_CLASS_WHC1_PROD_REG; // name of the warehouse template (not collection)
|
||||
public string $extension = COLLECTION_MONGO_PROD_REG_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = true; // set to true to cache class data
|
||||
public bool $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public bool $setJournaling = false; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set 2 true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = false; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
MONGO_ID => DATA_TYPE_OBJECT, // sorting by the id is just like sorting by createdDate
|
||||
PRG_TYPE => DATA_TYPE_STRING,
|
||||
PRG_IID => DATA_TYPE_STRING,
|
||||
PRG_EAV => DATA_TYPE_STRING,
|
||||
PRG_PLATFORM => DATA_TYPE_STRING,
|
||||
PRG_BROWSER => DATA_TYPE_STRING,
|
||||
PRG_MAJOR_VERSION => DATA_TYPE_INTEGER,
|
||||
PRG_MINOR_VERSION => DATA_TYPE_INTEGER,
|
||||
PRG_IS_MOBILE => DATA_TYPE_INTEGER,
|
||||
PRG_IS_TABLET => DATA_TYPE_INTEGER,
|
||||
PRG_FIRST_SEEN => DATA_TYPE_STRING,
|
||||
PRG_LAST_SEEN => DATA_TYPE_STRING,
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key (string) exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER // epoch time
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
PRG_IID, DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED, MONGO_ID
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_CREATED, DB_TOKEN, DB_ACCESSED, DB_STATUS, PRG_TYPE, PRG_IID, PRG_EAV, DB_EVENT_GUID
|
||||
];
|
||||
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = null;
|
||||
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
PRG_EAV => 1,
|
||||
PRG_IID => 1,
|
||||
PRG_TYPE => 1,
|
||||
DB_CREATED => 1,
|
||||
DB_STATUS => 1,
|
||||
DB_EVENT_GUID => 1 // event guid should always be indexed
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = null;
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
PRG_IID => 1,
|
||||
DB_TOKEN => 1 // MONGO_TOKEN should always appear
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null;
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
PRG_TYPE => CM_PRG_TYPE,
|
||||
PRG_IID => CM_PRG_IID,
|
||||
PRG_EAV => CM_PRG_EAV,
|
||||
PRG_PLATFORM => CM_PRG_PLATFORM,
|
||||
PRG_BROWSER => CM_PRG_BROWSER,
|
||||
PRG_MAJOR_VERSION => CM_PRG_MAJ_VER,
|
||||
PRG_MINOR_VERSION => CM_PRG_MIN_VER,
|
||||
PRG_IS_MOBILE => CM_PRG_IS_MOBILE,
|
||||
PRG_IS_TABLET => CM_PRG_IS_TABLET,
|
||||
PRG_FIRST_SEEN => CM_PRG_FIRST_SEEN,
|
||||
PRG_LAST_SEEN => CM_PRG_LAST_SEEN,
|
||||
DB_TOKEN => CM_TST_TOKEN,
|
||||
DB_STATUS => CM_TST_FIELD_TEST_STATUS,
|
||||
DB_EVENT_GUID => CM_TST_EVENT_GUID,
|
||||
DB_CREATED => CM_TST_FIELD_TEST_CDATE,
|
||||
DB_ACCESSED => CM_TST_FIELD_TEST_ADATE
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
* SubC fields do not need to be indexed.
|
||||
*
|
||||
*/
|
||||
public ?array $subC = null;
|
||||
|
||||
//=================================================================================================================
|
||||
// MIGRATION DECLARATIONS
|
||||
// ----------------------
|
||||
// Data in this section is used to handle migrations -- when we're pulling from legacy tables into the Namaste
|
||||
// framework. See online doc for more info.
|
||||
//=================================================================================================================
|
||||
|
||||
/**
|
||||
* The migration map is an associative array that maps the Namaste fields (keys) to the corresponding
|
||||
* (remote) legacy fields in the source table to be migrated to Namaste.
|
||||
*
|
||||
* For example, if we were migrating a mysql table in the legacy production database to Namaste::mongo, then
|
||||
* the keys of the migration map would be the Namaste::mongo->fieldNames and the values would be the mysql
|
||||
* column names in the legacy table.
|
||||
*
|
||||
* If there is a value which cannot be mapped to a key, then set it to null.
|
||||
*
|
||||
* Fields that will be dropped in the migration are not listed as values or as keys.
|
||||
*
|
||||
* This map will only exist in the template object and will never be imported into the class widget.
|
||||
*
|
||||
* This is a required field.
|
||||
*
|
||||
*/
|
||||
public ?array $migrationMap = [
|
||||
MONGO_ID => null, // created on insert
|
||||
PRG_TYPE => 'type',
|
||||
PRG_IID => 'iid',
|
||||
PRG_EAV => 'eav',
|
||||
PRG_PLATFORM => 'platform',
|
||||
PRG_BROWSER => 'browser',
|
||||
PRG_MAJOR_VERSION => 'major_version',
|
||||
PRG_MINOR_VERSION => 'minor_version',
|
||||
PRG_IS_MOBILE => 'is_mobile',
|
||||
PRG_IS_TABLET => 'is_tablet',
|
||||
PRG_FIRST_SEEN => 'first_seen',
|
||||
PRG_LAST_SEEN => 'last_seen',
|
||||
DB_TOKEN => null, // created on insert
|
||||
DB_EVENT_GUID => null, // generated by broker event
|
||||
DB_CREATED => 'kinsert_date', // epoch time
|
||||
DB_STATUS => null, // record status
|
||||
DB_ACCESSED => 'kupdate_date' // epoch time
|
||||
];
|
||||
|
||||
/*
|
||||
* the migrationSortKey defines the SOURCE field by which the fetch query will be sorted. ALL sort fields are
|
||||
* in ASC order so all we need to list here is the name of the field -- which MUST BE IN THE SOURCE TABLE.
|
||||
*
|
||||
* Populating this field may require preliminary examination of the data - what we want is a field that has
|
||||
* zero NULL values.
|
||||
*
|
||||
* This is a required field.
|
||||
*
|
||||
*/
|
||||
public ?string $migrationSortKey = 'last_seen';
|
||||
|
||||
/*
|
||||
* The migrationStatusKey defines the status field/column in the source table -- if the user requires that
|
||||
* soft-deleted records not be migrated, then this field must be set. Otherwise, set the value to null.
|
||||
*
|
||||
* The format is in the form of a key-value paired array. The key specifies the name of the column and the value
|
||||
* specifies the "deleted" value that, if found, will cause that row from the SOURCE data to be omitted from the
|
||||
* DESTINATION table.
|
||||
*
|
||||
* e.g.: $migrationStatusKV = [ 'some_field' => 'deleted' ]
|
||||
*
|
||||
* Note that both the key and the value are case-sensitive!
|
||||
*
|
||||
* This is an optional field.
|
||||
*
|
||||
*/
|
||||
public ?array $migrationStatusKV = null;
|
||||
|
||||
// The $migrationSourceSchema defines the remote schema for the source table, and is set in the constructor
|
||||
public ?string $migrationSourceSchema;
|
||||
|
||||
// The source table in the remote repos (default defined in the XML) must be declared here, set in the constructor
|
||||
public ?string $migrationSourceTable;
|
||||
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => true, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => true, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => true, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => true, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
WH_INDEXES => [DB_CREATED, DB_WH_CREATED],
|
||||
WH_TEMPLATE => '',
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [ OPERAND_NULL => [ OPERATOR_LT => [ null ] ] ],
|
||||
DB_STATUS => [ OPERAND_NULL => [ OPERATOR_EQ => [ STATUS_ACTIVE ]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-20-17 mks CORE-681: original coding
|
||||
* 09-09-19 mks DB-111: initialization of migration members moved to constructor b/c IDE warnings.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
$this->migrationSourceSchema = STRING_MYSQL; // or STRING_MONGO
|
||||
$this->migrationSourceTable = 'product_registrations';
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-20-17 mks CORE-681: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-20-17 mks CORE-681: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
451
classes/templates/gatProductSessionUsers.class.inc
Normal file
451
classes/templates/gatProductSessionUsers.class.inc
Normal file
@@ -0,0 +1,451 @@
|
||||
<?php
|
||||
/**
|
||||
* gatProductSessionUsers -- mongo template class
|
||||
*
|
||||
* This is the mongo template for givva.product_session_users, previously a mySQL-schema based table.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-20-17 mks CORE-681: original coding
|
||||
* 04-19-18 mks _INF-188: warehousing section added
|
||||
* 11-04-19 mks DB-136: fixed error where indexFields was missing a member element from singleIndex
|
||||
* 01-13-20 mks DB-150: PHP7.4 class member type-casting
|
||||
*
|
||||
*/
|
||||
class gatProductSessionUsers
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version - not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_APPSERVER; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_PRODUCT_SES_USR; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_PSU; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_PSU_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = true; // set to true to cache class data
|
||||
public bool $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public bool $setJournaling = false; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = false; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
MONGO_ID => DATA_TYPE_INTEGER, // sorting by the id is just like sorting by createdDate
|
||||
PSU_SID => DATA_TYPE_STRING,
|
||||
PSU_UID => DATA_TYPE_STRING,
|
||||
PSU_FIRST_SEEN => DATA_TYPE_STRING,
|
||||
PSU_LAST_SEEN => DATA_TYPE_STRING,
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key (string) exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER // epoch time
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
PSU_SID, PSU_UID, DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED, MONGO_ID
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_CREATED, DB_TOKEN, DB_ACCESSED, DB_STATUS, PSU_UID, PSU_SID, DB_EVENT_GUID
|
||||
];
|
||||
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = [ 'cIdx1UserSession' ];
|
||||
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_CREATED => 1,
|
||||
DB_STATUS => 1,
|
||||
DB_EVENT_GUID => 1 // event guid should always be indexed
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = [
|
||||
'cIdx1UserSession' => [ PSU_UID => 1, PSU_SID => 1]
|
||||
];
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
DB_TOKEN => 1 // MONGO_TOKEN should always appear
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null;
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
PSU_SID => CM_PSU_SID,
|
||||
PSU_UID => CM_PSU_UID,
|
||||
PSU_FIRST_SEEN => CM_PSU_FIRST_SEEN,
|
||||
PSU_LAST_SEEN => CM_PSU_LAST_SEEN,
|
||||
DB_TOKEN => CM_TST_TOKEN,
|
||||
DB_STATUS => CM_TST_FIELD_TEST_STATUS,
|
||||
DB_EVENT_GUID => CM_TST_EVENT_GUID,
|
||||
DB_CREATED => CM_TST_FIELD_TEST_CDATE,
|
||||
DB_ACCESSED => CM_TST_FIELD_TEST_ADATE
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
* SubC fields do not need to be indexed.
|
||||
*
|
||||
*/
|
||||
public ?array $subC = null;
|
||||
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [ OPERAND_NULL => [ OPERATOR_LT => [ null ] ] ],
|
||||
DB_STATUS => [ OPERAND_NULL => [ OPERATOR_EQ => [ STATUS_ACTIVE ]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-20-17 mks CORE-681: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-20-17 mks CORE-681: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-20-17 mks CORE-681: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
456
classes/templates/gatProductSessions.class.inc
Normal file
456
classes/templates/gatProductSessions.class.inc
Normal file
@@ -0,0 +1,456 @@
|
||||
<?php
|
||||
/**
|
||||
* gatProductSessions -- mongo template class
|
||||
*
|
||||
* This is the mongo template for givva.product_sessions, previously a mySQL-schema based table.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-20-17 mks CORE-681: original coding
|
||||
* 04-19-18 mks _INF-188: warehousing section added
|
||||
* 01-13-20 mks DB-150: PHP7.4 class member type-casting
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
*
|
||||
*/
|
||||
|
||||
class gatProductSessions
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version - not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_APPSERVER; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_PRODUCT_SES; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_PROD_SESS; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_PROD_SESS_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = true; // set to true to cache class data
|
||||
public bool $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public bool $setJournaling = false; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = false; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
MONGO_ID => DATA_TYPE_INTEGER, // sorting by the id is just like sorting by createdDate
|
||||
PSE_SID => DATA_TYPE_STRING,
|
||||
PSE_IID => DATA_TYPE_STRING,
|
||||
PSE_IP => DATA_TYPE_STRING,
|
||||
PSE_FIRST_SEEN => DATA_TYPE_STRING,
|
||||
PSE_LAST_SEEN => DATA_TYPE_STRING,
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key (string) exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER // epoch time
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
PSE_IID, PSE_SID, DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED, MONGO_ID
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_CREATED, DB_TOKEN, DB_ACCESSED, DB_STATUS, PSE_IP, PSE_SID, PSE_IID, DB_EVENT_GUID
|
||||
];
|
||||
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = null;
|
||||
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
PSE_IID => 1,
|
||||
PSE_SID => 1,
|
||||
PSE_IP => 1,
|
||||
DB_CREATED => 1,
|
||||
DB_STATUS => 1,
|
||||
DB_EVENT_GUID => 1 // event guid should always be indexed
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = null;
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
PSE_SID => 1,
|
||||
DB_TOKEN => 1 // MONGO_TOKEN should always appear
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null;
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
PSE_SID => CM_PSE_SID,
|
||||
PSE_IID => CM_PSE_IID,
|
||||
PSE_IP => CM_PSE_IP,
|
||||
PSE_FIRST_SEEN => CM_PSE_FIRST_SEEN,
|
||||
PSE_LAST_SEEN => CM_PSE_LAST_SEEN,
|
||||
DB_TOKEN => CM_TST_TOKEN,
|
||||
DB_STATUS => CM_TST_FIELD_TEST_STATUS,
|
||||
DB_EVENT_GUID => CM_TST_EVENT_GUID,
|
||||
DB_CREATED => CM_TST_FIELD_TEST_CDATE,
|
||||
DB_ACCESSED => CM_TST_FIELD_TEST_ADATE
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
* SubC fields do not need to be indexed.
|
||||
*
|
||||
*/
|
||||
public ?array $subC = null;
|
||||
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [ OPERAND_NULL => [ OPERATOR_LT => [ null ] ] ],
|
||||
DB_STATUS => [ OPERAND_NULL => [ OPERATOR_EQ => [ STATUS_ACTIVE ]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-20-17 mks CORE-681: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-20-17 mks CORE-681: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-20-17 mks CORE-681: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
490
classes/templates/gatSMAXAPI.class.inc
Normal file
490
classes/templates/gatSMAXAPI.class.inc
Normal file
@@ -0,0 +1,490 @@
|
||||
<?php
|
||||
/**
|
||||
* gatSMAXAPI -- template class
|
||||
*
|
||||
* This template definition is for the Saarvus-Maximus (SMAX) API Partner tokens repository. A partner is required to
|
||||
* submit their token (GUID) value with every API request. This collection tracks those entries.
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 04-20-20 mks ECI-101: original coding
|
||||
* 06-01-20 mks ECI-108: support for auth tokens
|
||||
* 06-11-20 mks ECI-164: new field: TLTI
|
||||
*
|
||||
*/
|
||||
/** @noinspection PhpUnused */
|
||||
|
||||
class gatSMAXAPI
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version - not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_APPSERVER; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_SMAXAPI; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_SMAXAPI; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_SMAXAPI_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = false; // set to true to cache class data
|
||||
public bool $setDeletes = false; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_DESTRUCTIVE; // set to AUDIT_value constant (nondestructive = reads(yes))
|
||||
public bool $setJournaling = true; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = true; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
MONGO_ID => DATA_TYPE_INTEGER, // sorting by the id is just like sorting by createdDate
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique pkey exposed externally and is REQUIRED
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER, // epoch time
|
||||
SMAX_COMPANY_NAME => DATA_TYPE_STRING, // Name of company receiving API Key
|
||||
SMAX_COMPANY_CONTACT_INFO => DATA_TYPE_ARRAY, // array column, not a sub-collection
|
||||
SMAX_COMPANY_CONTACT_INFO_ADDRESS1 => DATA_TYPE_STRING,
|
||||
SMAX_COMPANY_CONTACT_INFO_ADDRESS2 => DATA_TYPE_STRING,
|
||||
SMAX_COMPANY_CONTACT_INFO_CITY => DATA_TYPE_STRING,
|
||||
SMAX_COMPANY_CONTACT_INFO_STATE => DATA_TYPE_STRING,
|
||||
SMAX_COMPANY_CONTACT_INFO_ZIP => DATA_TYPE_STRING,
|
||||
SMAX_COMPANY_PHONES => DATA_TYPE_OBJECT,
|
||||
SMAX_COMPANY_PHONES_VOICE => DATA_TYPE_STRING,
|
||||
SMAX_COMPANY_PHONES_FAX => DATA_TYPE_STRING,
|
||||
SMAX_COMPANY_CONTACTS => DATA_TYPE_ARRAY, // this is a sub-collection
|
||||
SMAX_COMPANY_CONTACTS_EMPLOYEE_NAME => DATA_TYPE_STRING,
|
||||
SMAX_COMPANY_CONTACTS_EMPLOYEE_EMAIL => DATA_TYPE_STRING,
|
||||
SMAX_COMPANY_CONTACTS_EMPLOYEE_PHONE_VOICE => DATA_TYPE_STRING,
|
||||
SMAX_COMPANY_CONTACTS_EMPLOYEE_PHONE_FAX => DATA_TYPE_STRING,
|
||||
SMAX_COMPANY_REGISTERED => DATA_TYPE_INTEGER,
|
||||
SMAX_COMPANY_LICENSE_DURATION => DATA_TYPE_INTEGER,
|
||||
SMAX_COMPANY_AUTHORIZED_BY => DATA_TYPE_STRING,
|
||||
SMAX_COMPANY_INTERNAL_NOTES => DATA_TYPE_STRING,
|
||||
SMAX_LICENSE_TYPE => DATA_TYPE_STRING,
|
||||
SMAX_TLTI => DATA_TYPE_STRING
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED, MONGO_ID, SMAX_COMPANY_REGISTERED,
|
||||
SMAX_COMPANY_LICENSE_DURATION, SMAX_LICENSE_TYPE, SMAX_TLTI
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_CREATED, DB_STATUS, DB_TOKEN, SMAX_COMPANY_NAME,
|
||||
SMAX_COMPANY_AUTHORIZED_BY, SMAX_LICENSE_TYPE, SMAX_TLTI
|
||||
];
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = [
|
||||
'cIdxCompanyNameStatus', 'cIdxCompanyJWTStatus', 'cIdxCompanyLicenseType'
|
||||
];
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_CREATED => -1,
|
||||
SMAX_COMPANY_NAME => 1,
|
||||
SMAX_COMPANY_AUTHORIZED_BY => 1
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = [
|
||||
'cIdxCompanyNameStatus' => [ SMAX_COMPANY_NAME => 1, DB_STATUS => 1],
|
||||
'cIdxCompanyLicenseType' => [ SMAX_LICENSE_TYPE => 1, DB_STATUS => 1]
|
||||
];
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Sparse indexes only add the row to the index if the column referenced satisfies the conditions specified
|
||||
// in the query condition (expr2).
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
DB_TOKEN => 1, // MONGO_TOKEN should always appear
|
||||
SMAX_TLTI => 1 // Two-Letter Template Identifier must be unique
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null; // ttl indexes appear in $indexFields
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
DB_TOKEN => CM_TST_TOKEN,
|
||||
DB_STATUS => CM_TST_FIELD_TEST_STATUS,
|
||||
DB_EVENT_GUID => CM_TST_EVENT_GUID,
|
||||
DB_CREATED => CM_TRANSACTIONS_CREATED_AT,
|
||||
DB_ACCESSED => CM_TRANSACTIONS_UPDATED_AT,
|
||||
SMAX_COMPANY_NAME => CM_SMAX_COMPANY_NAME,
|
||||
SMAX_COMPANY_CONTACT_INFO => CM_SMAX_COMPANY_CONTACT_INFO,
|
||||
SMAX_COMPANY_CONTACT_INFO_ADDRESS1 => CM_SMAX_COMPANY_ADDR1,
|
||||
SMAX_COMPANY_CONTACT_INFO_ADDRESS2 => CM_SMAX_COMPANY_ADDR2,
|
||||
SMAX_COMPANY_CONTACT_INFO_CITY => CM_SMAX_COMPANY_CITY,
|
||||
SMAX_COMPANY_CONTACT_INFO_STATE => CM_SMAX_COMPANY_STATE,
|
||||
SMAX_COMPANY_CONTACT_INFO_ZIP => CM_SMAX_COMPANY_ZIP,
|
||||
SMAX_COMPANY_PHONES_VOICE => CM_SMAX_COMPANY_VOICE,
|
||||
SMAX_COMPANY_PHONES_FAX => CM_SMAX_COMPANY_FAX,
|
||||
SMAX_COMPANY_CONTACTS => CM_SMAX_CONTACTS,
|
||||
SMAX_COMPANY_CONTACTS_EMPLOYEE_NAME => CM_SMAX_CONTACT_NAME,
|
||||
SMAX_COMPANY_CONTACTS_EMPLOYEE_EMAIL => CM_SMAX_CONTACT_EMAIL,
|
||||
SMAX_COMPANY_CONTACTS_EMPLOYEE_PHONE_VOICE => CM_SMAX_CONTACT_VOICE,
|
||||
SMAX_COMPANY_CONTACTS_EMPLOYEE_PHONE_FAX => CM_SMAX_CONTACT_FAX,
|
||||
SMAX_COMPANY_AUTHORIZED_BY => CM_SMAX_AUTH_BY,
|
||||
SMAX_COMPANY_INTERNAL_NOTES => CM_SMAX_NOTES,
|
||||
SMAX_LICENSE_TYPE => CM_SMAX_ACCOUNT_TYPE,
|
||||
SMAX_TLTI => CM_SMAX_TLTI
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
*/
|
||||
// sub-collection fields must be declared here (need not be indexed)
|
||||
public ?array $subC = [
|
||||
SMAX_COMPANY_CONTACTS => [
|
||||
SMAX_COMPANY_CONTACTS_EMPLOYEE_NAME,
|
||||
SMAX_COMPANY_CONTACTS_EMPLOYEE_EMAIL,
|
||||
SMAX_COMPANY_CONTACTS_EMPLOYEE_PHONE_VOICE,
|
||||
SMAX_COMPANY_CONTACTS_EMPLOYEE_PHONE_FAX
|
||||
]
|
||||
];
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [OPERAND_NULL => [OPERATOR_LT => [null]]],
|
||||
DB_STATUS => [OPERAND_NULL => [OPERATOR_EQ => [STATUS_ACTIVE]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 03-10-20 mks original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 03-10-20 mks original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 03-10-20 mks original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
// does nothing
|
||||
}
|
||||
|
||||
}
|
||||
634
classes/templates/gatSessions.class.inc
Normal file
634
classes/templates/gatSessions.class.inc
Normal file
@@ -0,0 +1,634 @@
|
||||
<?php /** @noinspection PhpUnused */
|
||||
|
||||
/**
|
||||
* Class gatSessions -- mongo class
|
||||
*
|
||||
* This class is used to store user sessions (assuming that the Users table is also a mongo collection). Sessions
|
||||
* are required for all communication with Namaste and must be linked to an active user, either external or internal,
|
||||
* account.
|
||||
*
|
||||
* Questions requiring resolution:
|
||||
* --------------------------------
|
||||
* -- what is the hard-expiration for a user session?
|
||||
* -- can a user have more than a single session open at a time?
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-03-20 mks DB-147: initial coding
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
*
|
||||
*/
|
||||
|
||||
class gatSessions
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version; not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_TERCERO; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_SESSIONS; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_SESSIONS; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_SESS_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = false; // set to false to allow partner instantiations
|
||||
public bool $setCache = true; // set to true to cache class data
|
||||
public bool $setDeletes = false; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant (nondestructive = reads(yes))
|
||||
public bool $setJournaling = false; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = true; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// non-standard template member variables
|
||||
public ?string $guid = null; // internal container for a guid value on instantiation
|
||||
public string $res = 'tSES: '; // resource identifier for logging
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
MONGO_ID => DATA_TYPE_INTEGER,
|
||||
SESSION_EXPIRES => DATA_TYPE_DATETIME, // user-friendly time-stamp
|
||||
SESSION_CLOSED => DATA_TYPE_STRING, // timestamp for when the session was actually closed
|
||||
SESSION_DURATION => DATA_TYPE_INTEGER, // length of session in seconds
|
||||
SESSION_FK_USER => DATA_TYPE_STRING, // fk-link to users.token_usr
|
||||
SESSION_LEVEL => DATA_TYPE_INTEGER, // defines the session level (user, csr, etc.)
|
||||
SESSION_CUSTOM_FIELD => DATA_TYPE_STRING, // user-defined KEY
|
||||
SESSION_CUSTOM_VALUE => DATA_TYPE_STRING, // user-defined VALUE
|
||||
SESSION_CREATED_WITH => DATA_TYPE_OBJECT, // legacy-data container for json-looking stuff
|
||||
SESSION_ACTION => DATA_TYPE_STRING,
|
||||
SESSION_AUTH_PROVIDER => DATA_TYPE_STRING,
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER // epoch time
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_CREATED, DB_ACCESSED, SESSION_FK_USER, SESSION_LEVEL, SESSION_EXPIRES,
|
||||
SESSION_DURATION, MONGO_ID, DB_STATUS
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_TOKEN, SESSION_FK_USER, DB_STATUS, DB_EVENT_GUID
|
||||
];
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = [
|
||||
'cIdxSession1'
|
||||
];
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_TOKEN => 1,
|
||||
DB_STATUS => 1,
|
||||
DB_EVENT_GUID => 1
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = [
|
||||
'cIdxSession1' => [ SESSION_FK_USER, DB_STATUS ]
|
||||
];
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Sparse indexes only add the row to the index if the column referenced satisfies the conditions specified
|
||||
// in the query condition (expr2).
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
DB_TOKEN => 1, // MONGO_TOKEN should always appear
|
||||
DB_EVENT_GUID => 1
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null;
|
||||
|
||||
// cache maps are required for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
DB_TOKEN => CM_TOKEN,
|
||||
DB_CREATED => CM_DATE_CREATED,
|
||||
SESSION_CLOSED => CM_DATA_CLOSED,
|
||||
DB_ACCESSED => CM_DATE_ACCESSED,
|
||||
DB_STATUS => CM_STATUS,
|
||||
DB_EVENT_GUID => CM_EVENT_GUID,
|
||||
SESSION_EXPIRES => CM_SESSION_EXPIRES,
|
||||
SESSION_DURATION => CM_SESSION_DURATION,
|
||||
SESSION_LEVEL => CM_SESSION_LEVEL,
|
||||
SESSION_FK_USER => CM_SESSION_UID,
|
||||
SESSION_CUSTOM_FIELD => CM_SESSION_CUSTOM_KEY,
|
||||
SESSION_CUSTOM_VALUE => CM_SESSION_CUSTOM_VAL,
|
||||
SESSION_CREATED_WITH => CM_SESSION_CW,
|
||||
SESSION_ACTION => CM_SESSION_ACTION,
|
||||
SESSION_AUTH_PROVIDER => CM_SESSION_AP
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as the associative array: $exposedFields. Only those fields,
|
||||
* enumerated within this container, will be exposed to the client.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
*/
|
||||
// sub-collection fields must be declared here (need not be indexed)
|
||||
public ?array $subC = [
|
||||
SESSION_ACTION => [ SESSION_ACTION, SESSION_CREATED_WITH ]
|
||||
];
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [OPERAND_NULL => [OPERATOR_LT => [null]]],
|
||||
DB_STATUS => [OPERAND_NULL => [OPERATOR_EQ => [STATUS_ACTIVE]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* Constructor in this template not only registers the shutdown method, but also allows us to generate a custom
|
||||
* GUID string during instantiation by use of the input parameters:
|
||||
*
|
||||
* $_getGUID - boolean, defaults to false but, if true, will generate a GUID value and store it in the class member
|
||||
* $_lc - boolean, defaults to false but, if true, will generate a GUID using lower-case alpha characters
|
||||
*
|
||||
* If we generate a GUID on instantiation, the GUID will be stored in the class member. This allows us to both
|
||||
* instantiate a session class object and a GUID value, (the most requested, post-instantiation, action), at the
|
||||
* same time. All the efficient.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @param bool $_getGUID
|
||||
* @param bool $_lc
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-03-20 mks DB-147: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct(bool $_getGUID = false, bool $_lc = false)
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
if ($_getGUID) $this->guid = static::getGUID($_lc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* buildExpireSessionPayload() -- template function
|
||||
*
|
||||
* This is a "hidden function" for the session template class requiring the following input parameters:
|
||||
*
|
||||
* $_data -- the is the request payload as received by the tercero broker
|
||||
* $_errors -- call-by-reference container for error messaging
|
||||
*
|
||||
* The function will validate that $_data contains the $requiredArrayKeys, generating an error message if any
|
||||
* are not present in the _data array and returning a null value to the calling client if so.
|
||||
*
|
||||
* Depending on the value for STRING_TOK_TYPE stored in $_data, we'll build the query against DB_TOKEN or the
|
||||
* DB_EVENT_GUID.
|
||||
*
|
||||
* Then we just assemble the rest of the query and return the array to the calling client, presumably the sBroker.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @param array $_data
|
||||
* @param array|null $_errors
|
||||
* @return array|null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 10-02-20 mks DB-168: original coding
|
||||
*
|
||||
*/
|
||||
public function buildExpireSessionPayload(array $_data, ?array &$_errors = null):?array
|
||||
{
|
||||
$requiredArrayKeys = [ STRING_GUID_KEY, STRING_TOK_TYPE ];
|
||||
$missingKey = false;
|
||||
try {
|
||||
$logger = new gacErrorLogger();
|
||||
// _data validation
|
||||
foreach ($requiredArrayKeys as $requiredKey) {
|
||||
if (!array_key_exists($requiredKey, $_data)) {
|
||||
$hdr = sprintf(INFO_LOC, basename(__METHOD__), __LINE__);
|
||||
$msg = ERROR_ARRAY_KEY_404 . $requiredKey;
|
||||
$_errors[] = $msg;
|
||||
$logger->data($hdr . $msg);
|
||||
$missingKey = true;
|
||||
}
|
||||
}
|
||||
if ($missingKey) return null;
|
||||
switch ($_data[STRING_TOK_TYPE]) {
|
||||
case STRING_TOK_TYPE_EVE :
|
||||
$searchDiscriminant = DB_EVENT_GUID;
|
||||
break;
|
||||
case STRING_TOK_TYPE_SES :
|
||||
case STRING_TOK_TYPE_TOK :
|
||||
$searchDiscriminant = DB_TOKEN;
|
||||
break;
|
||||
default :
|
||||
$hdr = sprintf(INFO_LOC, basename(__METHOD__), __LINE__);
|
||||
$msg = ERROR_DATA_FIELD_NOT_MEMBER . $_data[STRING_TOK_TYPE];
|
||||
$_errors[] = $msg;
|
||||
$logger->data($hdr . $msg);
|
||||
return null;
|
||||
break;
|
||||
}
|
||||
$query = [$searchDiscriminant => [ OPERAND_NULL => [ OPERATOR_EQ => [$_data[STRING_GUID_KEY]]]]];
|
||||
$update = [ DB_STATUS => STATUS_EXPIRED, SESSION_CLOSED => time() ];
|
||||
return [STRING_QUERY_DATA => $query, STRING_UPDATE_DATA => $update];
|
||||
} catch (Throwable | TypeError $t) {
|
||||
$hdr = sprintf(INFO_LOC, basename(__METHOD__), __LINE__);
|
||||
@handleExceptionMessaging($hdr, $t->getMessage(), $_errors, true);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* buidlCloseSysEventPayload() -- public function
|
||||
*
|
||||
* This function requires a single input parameter:
|
||||
*
|
||||
* $_guid -- the session guid (foreign key value) in the system event record we're updating
|
||||
*
|
||||
* The method takes this information and build an update-record payload that will be returned to the adminIn
|
||||
* broker to close the system-event record that recorded the original session-expiry event.
|
||||
*
|
||||
* The function returns a string, which is the compress json query payload to be send immediately to the broker.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @param string $_guid
|
||||
* @return string|null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 10-23-20 mks DB-168: original coding
|
||||
*
|
||||
*/
|
||||
public function buildCloseSysEventPayload(string $_guid):string
|
||||
{
|
||||
$payload = [
|
||||
SYSTEM_EVENT_STATUS => STATUS_CLOSED,
|
||||
DB_ACCESSED => time(),
|
||||
];
|
||||
$meta = [
|
||||
META_TEMPLATE => TEMPLATE_CLASS_SYS_EVENTS,
|
||||
META_CLIENT => CLIENT_SYSTEM,
|
||||
META_DO_CACHE => 0
|
||||
];
|
||||
$request = [
|
||||
BROKER_REQUEST => BROKER_REQUEST_UPDATE,
|
||||
BROKER_DATA => [
|
||||
STRING_QUERY_DATA => [ SYSTEM_EVENT_FK_SESSION_GUID => [ OPERAND_NULL => [OPERATOR_EQ => [$_guid]]]],
|
||||
STRING_UPDATE_DATA => $payload
|
||||
],
|
||||
BROKER_META_DATA => $meta
|
||||
];
|
||||
return gzcompress(json_encode($request));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* getGUID() -- public static template method
|
||||
*
|
||||
* This method calls the generic function method (guid()) which generates a random GUID (36-char format).
|
||||
*
|
||||
* The method has one input parameter:
|
||||
*
|
||||
* $_lc -- boolean: default set to false but, if true, converts the alpha chars in the guid string to lower-case.
|
||||
*
|
||||
* The method returns a string back to the calling client containing the 36-character GUID.
|
||||
*
|
||||
*
|
||||
* @param bool $_lc - defaults to false, submit true if your want the guid's alpha chars converted to lower-case
|
||||
* @return string
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-04-20 mks DB-147: original coding
|
||||
*
|
||||
*/
|
||||
public static function getGUID(bool $_lc = false):string
|
||||
{
|
||||
return (($_lc) ? strtolower(guid()) : guid());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-03-20 mks DB-147: original coding
|
||||
*
|
||||
* @version 1.0
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-03-20 mks DB-147: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
// does nothing
|
||||
}
|
||||
}
|
||||
501
classes/templates/gatSystemData.class.inc
Normal file
501
classes/templates/gatSystemData.class.inc
Normal file
@@ -0,0 +1,501 @@
|
||||
<?php
|
||||
/**
|
||||
* gatSystemData -- mongo template class
|
||||
*
|
||||
* This is the mongo data template for the system data class. The system data class resides on the Admin service
|
||||
* and consists of a table with multiple rows. There's row identifier for "known" rows (states,status) and
|
||||
* "generic" columns for random key-value pairs.
|
||||
*
|
||||
* The systemData table is read and cached during IPL.
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 00-00-00 mks Original coding
|
||||
* 01-14-20 mks DB-150: PHP7.4 class member type-casting
|
||||
* 06-01-20 mks ECI-108: support for auth tokens
|
||||
*
|
||||
*/
|
||||
|
||||
class gatSystemData
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version - not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_ADMIN; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_SYS_DATA; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_SYS_DATA; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // name of the warehouse template (not collection)
|
||||
public string $extension = COLLECTION_MONGO_SYS_DATA_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = true; // set to true to cache class data
|
||||
public bool $setDeletes = false; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public bool $setJournaling = false; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = true; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
MONGO_ID => DATA_TYPE_OBJECT, // sorting by the id is just like sorting by createdDate
|
||||
ROW_ID => DATA_TYPE_INTEGER, // simple, imposed, identifier for well-known rows
|
||||
DATA_KEY => DATA_TYPE_STRING, // label for key->value pair
|
||||
DATA_VALUE => DATA_TYPE_STRING, // value for key->value pair
|
||||
VALID_STATES => DATA_TYPE_ARRAY,
|
||||
VALID_STATUS => DATA_TYPE_ARRAY,
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key (string) exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER // epoch time
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED, MONGO_ID, ROW_ID
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, ROW_ID, DATA_KEY
|
||||
];
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = null;
|
||||
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
public ?array $singleFields = [DATA_KEY => 1];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = null;
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [ROW_ID => 1];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null;
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
VALID_STATUS => VALID_STATUS,
|
||||
VALID_STATES => VALID_STATES,
|
||||
ROW_ID => ROW_ID,
|
||||
DATA_KEY => DATA_KEY,
|
||||
DATA_VALUE => DATA_VALUE,
|
||||
DB_TOKEN => CM_TST_TOKEN,
|
||||
DB_STATUS => CM_TST_FIELD_TEST_STATUS,
|
||||
DB_EVENT_GUID => CM_TST_EVENT_GUID,
|
||||
DB_CREATED => CM_TST_FIELD_TEST_CDATE,
|
||||
DB_ACCESSED => CM_TST_FIELD_TEST_ADATE
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
* SubC fields do not need to be indexed.
|
||||
*
|
||||
*/
|
||||
public ?array $subC = null;
|
||||
|
||||
//=================================================================================================================
|
||||
// MIGRATION DECLARATIONS
|
||||
// ----------------------
|
||||
// Data in this section is used to handle migrations -- when we're pulling from legacy tables into the Namaste
|
||||
// framework. See online doc for more info.
|
||||
//=================================================================================================================
|
||||
|
||||
/**
|
||||
* The migration map is an associative array that maps the Namaste fields (keys) to the corresponding
|
||||
* (remote) legacy fields in the source table to be migrated to Namaste.
|
||||
*
|
||||
* For example, if we were migrating a mysql table in the legacy production database to Namaste::mongo, then
|
||||
* the keys of the migration map would be the Namaste::mongo->fieldNames and the values would be the mysql
|
||||
* column names in the legacy table.
|
||||
*
|
||||
* If there is a value which cannot be mapped to a key, then set it to null.
|
||||
*
|
||||
* Fields that will be dropped in the migration are not listed as values or as keys.
|
||||
*
|
||||
* This map will only exist in the template object and will never be imported into the class widget.
|
||||
*
|
||||
* This is a required field.
|
||||
*
|
||||
*/
|
||||
public ?array $migrationMap = null;
|
||||
|
||||
/*
|
||||
* the migrationSortKey defines the SOURCE field by which the fetch query will be sorted. ALL sort fields are
|
||||
* in ASC order so all we need to list here is the name of the field -- which MUST BE IN THE SOURCE TABLE.
|
||||
*
|
||||
* Populating this field may require preliminary examination of the data - what we want is a field that has
|
||||
* zero NULL values.
|
||||
*
|
||||
* This is a required field.
|
||||
*
|
||||
*/
|
||||
public ?string $migrationSortKey = 'last_seen';
|
||||
|
||||
/*
|
||||
* The migrationStatusKey defines the status field/column in the source table -- if the user requires that
|
||||
* soft-deleted records not be migrated, then this field must be set. Otherwise, set the value to null.
|
||||
*
|
||||
* The format is in the form of a key-value paired array. The key specifies the name of the column and the value
|
||||
* specifies the "deleted" value that, if found, will cause that row from the SOURCE data to be omitted from the
|
||||
* DESTINATION table.
|
||||
*
|
||||
* e.g.: $migrationStatusKV = [ 'some_field' => 'deleted' ]
|
||||
*
|
||||
* Note that both the key and the value are case-sensitive!
|
||||
*
|
||||
* This is an optional field.
|
||||
*
|
||||
*/
|
||||
public ?string $migrationStatusKV = null;
|
||||
|
||||
// The $migrationSourceSchema defines the remote schema for the source table
|
||||
public ?string $migrationSourceSchema = ''; // or STRING_MONGO
|
||||
|
||||
// The source table in the remote repos (default defined in the XML) must be declared here
|
||||
public ?string $migrationSourceTable = '';
|
||||
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
// todo -- add an "enabled" option to this block
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
WH_INDEXES => null,
|
||||
WH_TEMPLATE => '',
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => null
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-20-17 mks CORE-681: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-20-17 mks CORE-681: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 12-20-17 mks CORE-681: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
// empty
|
||||
}
|
||||
}
|
||||
486
classes/templates/gatSystemEvents.class.inc
Normal file
486
classes/templates/gatSystemEvents.class.inc
Normal file
@@ -0,0 +1,486 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Template: gatSystemEvents
|
||||
* -------------------------------
|
||||
* This template defines the storage (mongo) for system-events.
|
||||
*
|
||||
* System events record data about routine and exception events that occur during normal processing/execution of
|
||||
* the Namaste framework. As such, it is strictly an administrative table and accessible via the admin system only.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-16-17 mks CORE-500: original programming
|
||||
* 04-19-18 mks _INF-188: warehousing section added
|
||||
* 11-04-19 mks DB-136: added DB_STATUS field to $indexFields, removed duplicate key from $fields
|
||||
* 01-14-20 mks DB-150: PHP7.4 class member type-casting
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
* 08-14-20 mks DB-168: added event status which is binary: success | fail
|
||||
*
|
||||
*/
|
||||
|
||||
class gatSystemEvents
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1;
|
||||
public string $service = CONFIG_DATABASE_SERVICE_ADMIN; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_SYS_EVENTS; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_SYS_EVENTS; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_SYS_EVENTS_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = false; // set to true to cache class data
|
||||
public bool $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public bool $setJournaling = false; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = false; // set to true to enable collection query timers
|
||||
public string $setPKey = SYSTEM_EVENT_FK_SESSION_GUID; // sets the primary key for the collection
|
||||
public bool $setTokens = false; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = true; // set to false if the class contains methods
|
||||
public int $cacheTimer = 0; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = true; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// all column names are defined as key->value pairs with the value being type specified by the given constant
|
||||
// all key names should also be declared constants.
|
||||
// note that key names do NOT have their extensions appended!
|
||||
|
||||
public array $fields = [
|
||||
// generic mongo constants
|
||||
MONGO_ID => DATA_TYPE_INTEGER,
|
||||
DB_STATUS => DATA_TYPE_STRING, // status of this record
|
||||
DB_CREATED => DATA_TYPE_INTEGER,
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING,
|
||||
// fields specific to systemEvents collection
|
||||
SYSTEM_EVENT_NAME => DATA_TYPE_STRING, // name of the event (pre-defined constant)
|
||||
SYSTEM_EVENT_STATUS => DATA_TYPE_STRING, // status of the event, not this record
|
||||
SYSTEM_EVENT_TYPE => DATA_TYPE_STRING, // event type (BROKER, TIMER, FATAL, etc.)
|
||||
SYSTEM_EVENT_CLASS => DATA_TYPE_STRING, // which class, if any, generated the event
|
||||
SYSTEM_EVENT_START => DATA_TYPE_INTEGER, // event starting value (memory)
|
||||
SYSTEM_EVENT_END => DATA_TYPE_INTEGER, // event ending value (memory)
|
||||
SYSTEM_EVENT_PEAK => DATA_TYPE_INTEGER, // event peak value (memory)
|
||||
SYSTEM_EVENT_TIMER => DATA_TYPE_DOUBLE, // Spot-timer for the event, absolute/real time
|
||||
SYSTEM_EVENT_AT_RESULTS => DATA_TYPE_ARRAY, // container for results of the AT(1) command
|
||||
SYSTEM_EVENT_DURATION => DATA_TYPE_INTEGER, // length of time for the event implying expiry
|
||||
SYSTEM_EVENT_BROKER_EVENT => DATA_TYPE_STRING, // the name of the broker event
|
||||
SYSTEM_EVENT_OGUID => DATA_TYPE_STRING, // the original guid (for cross-queue events)
|
||||
SYSTEM_EVENT_FK_SESSION_GUID => DATA_TYPE_STRING, // if we have a session GUID, store it here
|
||||
SYSTEM_EVENT_FK_USER_GUID => DATA_TYPE_STRING, // if we have a user GUID, store it here
|
||||
SYSTEM_EVENT_BROKER_GUID => DATA_TYPE_STRING, // broker (child) identifying guid
|
||||
SYSTEM_EVENT_COUNT => DATA_TYPE_INTEGER, // this event is event number...
|
||||
SYSTEM_EVENT_COUNT_TOTAL => DATA_TYPE_INTEGER, // ... out of this many events
|
||||
SYSTEM_EVENT_BROKER_ROOT_GUID => DATA_TYPE_STRING, // broker (parent) identifying guid
|
||||
SYSTEM_EVENT_NUM_EVENTS => DATA_TYPE_INTEGER, // number of discrete sub-events (child broker)
|
||||
SYSTEM_EVENT_CODE_LOC => DATA_TYPE_STRING, // identified the code-location launching the event
|
||||
SYSTEM_EVENT_KEY => DATA_TYPE_STRING, // (optional) free-form key
|
||||
SYSTEM_EVENT_VAL => DATA_TYPE_INTEGER, // (optional) free-form value matched to key
|
||||
SYSTEM_EVENT_ERROR_STACK => DATA_TYPE_ARRAY, // (optional) the error-stack generated
|
||||
SYSTEM_EVENT_META_DATA => DATA_TYPE_ARRAY, // (optional) the meta-data received for the event
|
||||
SYSTEM_EVENT_NOTES => DATA_TYPE_STRING // (optional) free-form text
|
||||
|
||||
/*
|
||||
* other candidate fields for later expansion include, but are not limited to:
|
||||
*
|
||||
* -- mail GUID did we generate an outbound email?
|
||||
* -- AT_OUT output from AT(1) daemon on timer events
|
||||
* -- Severity? classify events by their assigned severity
|
||||
* -- responded if an event required intervention, when was it responded to?
|
||||
* -- respondedBy if an event required intervention, who was assigned to the event?
|
||||
* -- closed if an event required intervention, when was it closed?
|
||||
* -- resolution if an event required intervention, what was the resolution?
|
||||
*/
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID,
|
||||
DB_CREATED,
|
||||
DB_EVENT_GUID,
|
||||
SYSTEM_EVENT_BROKER_EVENT,
|
||||
SYSTEM_EVENT_BROKER_ROOT_GUID,
|
||||
SYSTEM_EVENT_OGUID,
|
||||
SYSTEM_EVENT_FK_SESSION_GUID,
|
||||
SYSTEM_EVENT_BROKER_GUID,
|
||||
SYSTEM_EVENT_TYPE,
|
||||
SYSTEM_EVENT_NAME,
|
||||
SYSTEM_EVENT_STATUS,
|
||||
SYSTEM_EVENT_CLASS,
|
||||
DB_STATUS
|
||||
];
|
||||
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = [
|
||||
'cIdx1SEV',
|
||||
'cIdx2GUID',
|
||||
'cIdx2TYPE',
|
||||
'cIdx1SESS'
|
||||
];
|
||||
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_EVENT_GUID => 1,
|
||||
DB_CREATED => -1,
|
||||
SYSTEM_EVENT_BROKER_EVENT => 1,
|
||||
SYSTEM_EVENT_BROKER_GUID => 1,
|
||||
SYSTEM_EVENT_STATUS => 1,
|
||||
SYSTEM_EVENT_BROKER_ROOT_GUID => 1,
|
||||
SYSTEM_EVENT_TYPE => 1
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = [
|
||||
'cIdx1SEV' => [SYSTEM_EVENT_NAME => 1, SYSTEM_EVENT_CLASS => 1 ],
|
||||
'cIdx2GUID' => [ SYSTEM_EVENT_OGUID => 1, SYSTEM_EVENT_BROKER_GUID => 1 ],
|
||||
'cIdx2TYPE' => [ SYSTEM_EVENT_TYPE => 1, SYSTEM_EVENT_STATUS => 1],
|
||||
'cIdx1SESS' => [ SYSTEM_EVENT_FK_SESSION_GUID => 1, DB_STATUS => 1]
|
||||
];
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = null; // mongo TOKEN does not appear b/c system table
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null; // ttl indexes appear in $indexFields
|
||||
|
||||
// cache maps are required for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = null;
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
*/
|
||||
// sub-collection fields must be declared here (need not be indexed)
|
||||
public ?array $subC = null;
|
||||
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [ OPERAND_NULL => [ OPERATOR_LT => [ null ] ] ],
|
||||
DB_STATUS => [ OPERAND_NULL => [ OPERATOR_EQ => [ STATUS_ACTIVE ]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-16-17 mks CORE-500: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-16-17 mks CORE-500: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-16-17 mks CORE-500: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
// does nothing
|
||||
}
|
||||
}
|
||||
545
classes/templates/gatTestMongo.class.inc
Normal file
545
classes/templates/gatTestMongo.class.inc
Normal file
@@ -0,0 +1,545 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* gatTestMongo() -- mongo test class
|
||||
*
|
||||
* This class is used for testing mongo operations. It has it's own collection in the database and is used in testing
|
||||
* during development and in unit-testing.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 07-10-17 mks original coding
|
||||
* 08-04-17 mks added version control, partialIndexes
|
||||
* 09-12-17 mks CORE-558: protected fields
|
||||
* 04-19-18 mks _INF-188: warehousing section added
|
||||
* 01-14-20 mks DB-150: PHP7.4 class member type-casting
|
||||
* 06-01-20 mks ECI-120: support for auth token
|
||||
*
|
||||
*/
|
||||
class gatTestMongo
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version - not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_APPSERVER; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_TEST_MONGO; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_TEST; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_TEST_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = true; // set to true to cache class data
|
||||
public bool $setDeletes = false; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NONDESTRUCTIVE; // set to AUDIT_value constant (nondestructive = reads(yes))
|
||||
public bool $setJournaling = true; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = false; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
MONGO_ID => DATA_TYPE_INTEGER, // sorting by the id is just like sorting by createdDate
|
||||
TEST_FIELD_TEST_STRING => DATA_TYPE_STRING,
|
||||
TEST_FIELD_TEST_DOUBLE => DATA_TYPE_DOUBLE,
|
||||
TEST_FIELD_TEST_INT => DATA_TYPE_INTEGER,
|
||||
TEST_FIELD_TEST_NIF => DATA_TYPE_INTEGER, // used in unit testing for testing non-indexed queries
|
||||
TEST_FIELD_TEST_BOOL => DATA_TYPE_BOOL,
|
||||
TEST_FIELD_TEST_OBJECT => DATA_TYPE_OBJECT,
|
||||
TEST_FIELD_TEST_ARRAY => DATA_TYPE_ARRAY, // array of data (flat)
|
||||
TEST_FIELD_TEST_SUBC => DATA_TYPE_ARRAY, // subCollection (array of arrays which may contain arrays)
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key (string) exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER // epoch time
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED, MONGO_ID
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_CREATED, TEST_FIELD_TEST_INT, DB_TOKEN, TEST_FIELD_TEST_BOOL, DB_EVENT_GUID,
|
||||
TEST_FIELD_TEST_DOUBLE, DB_ACCESSED, TEST_FIELD_TEST_STRING, DB_STATUS, TEST_FIELD_TEST_OBJECT
|
||||
];
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = [
|
||||
'cIdx1Test',
|
||||
'mIdx1Test',
|
||||
];
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
TEST_FIELD_TEST_BOOL => 1,
|
||||
TEST_FIELD_TEST_STRING => 1,
|
||||
DB_CREATED => -1,
|
||||
DB_STATUS => -1,
|
||||
DB_EVENT_GUID => 1 // event guid should always be indexed
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = [
|
||||
'cIdx1Test' => [TEST_FIELD_TEST_INT => 1, TEST_FIELD_TEST_DOUBLE => -1 ]
|
||||
];
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = [ 'mIdx1Test' => [TEST_FIELD_TEST_ARRAY. DOT . TEST_FIELD_TEST_INT => 1]];
|
||||
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Sparse indexes only add the row to the index if the column referenced satisfies the conditions specified
|
||||
// in the query condition (expr2).
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = [
|
||||
// this is a really bad example, but an example nonetheless, of a partial index
|
||||
[[ TEST_FIELD_TEST_OBJECT => 1], [ MONGO_STRING_PARTIAL_FE => [ DB_CREATED => [ MONGO_EXISTS => false ]]]],
|
||||
[[ TEST_FIELD_TEST_OBJECT => 1], [ MONGO_STRING_PARTIAL_FE => [ DB_CREATED => [ MONGO_EXISTS => true ]]]]
|
||||
];
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
DB_TOKEN => 1 // MONGO_TOKEN should always appear
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = [DB_CREATED => 86400]; // ttl indexes appear in $indexFields
|
||||
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
TEST_FIELD_TEST_STRING => CM_TST_FIELD_TEST_STRING,
|
||||
TEST_FIELD_TEST_DOUBLE => CM_TST_FIELD_TEST_DOUBLE,
|
||||
TEST_FIELD_TEST_INT => CM_TST_FIELD_TEST_INT,
|
||||
TEST_FIELD_TEST_NIF => CM_TST_FIELD_TEST_NIF,
|
||||
TEST_FIELD_TEST_BOOL => CM_TST_FIELD_TEST_BOOL,
|
||||
TEST_FIELD_TEST_OBJECT => CM_TST_FIELD_TEST_OBJ,
|
||||
TEST_FIELD_TEST_ARRAY => CM_TST_FIELD_TEST_ARY,
|
||||
TEST_FIELD_TEST_SUBC => CM_TST_FIELD_TEST_SUBC,
|
||||
DB_TOKEN => CM_TST_TOKEN,
|
||||
DB_STATUS => CM_TST_FIELD_TEST_STATUS,
|
||||
DB_EVENT_GUID => CM_TST_EVENT_GUID,
|
||||
DB_CREATED => CM_TST_FIELD_TEST_CDATE,
|
||||
DB_ACCESSED => CM_TST_FIELD_TEST_ADATE
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = [ TEST_FIELD_TEST_STRING ];
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
*/
|
||||
// sub-collection fields must be declared here (need not be indexed)
|
||||
public ?array $subC = [
|
||||
TEST_FIELD_TEST_SUBC => [
|
||||
TEST_FIELD_TEST_INT,
|
||||
TEST_FIELD_TEST_DOUBLE,
|
||||
TEST_FIELD_TEST_STRING,
|
||||
TEST_FIELD_TEST_BOOL,
|
||||
DB_TOKEN
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [ OPERAND_NULL => [ OPERATOR_LT => [ null ] ] ],
|
||||
DB_STATUS => [ OPERAND_NULL => [ OPERATOR_EQ => [ STATUS_ACTIVE ]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 07-10-17 mks CORE-463: code complete (refactor from ddb to mdb)
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = '79344859-5403-1556-7663-4E34D6B4CBE4'; // SMAX-API record token
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* buildTestData() -- public static method
|
||||
*
|
||||
* this method is used to build an array structure of random data. There is only input parameter to the method
|
||||
* specifies the number of records to return to the calling client.
|
||||
*
|
||||
* The input parameter specifies how many records (indexes in the array) should be returned to the calling client
|
||||
* and should be a reasonable integer between one and one-hundred (1 - 100). If the passed-value for the number
|
||||
* of records is outside of this range, on either side, then the passed-value will be replaced with the range
|
||||
* limit for the appropriate "side".
|
||||
*
|
||||
* We then spin through a loop which populates an indexed array with the elements, from the test class,
|
||||
* with the appropriate extension as the sub-array key value.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @param int $_records
|
||||
* @return null|array
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 07-10-17 mks original coding
|
||||
* 07-12-17 mks added object field to test data generation: a copy of the current record's data
|
||||
* 07-20-17 mks moved to gatTestMongo class where it belongs (testing selfDestruct feature in templates)
|
||||
* 04-15-19 mks DB-116: header re-formatted for PHP7 (type casting enforced)
|
||||
*
|
||||
*/
|
||||
public static function buildTestData(int $_records = 0): ?array
|
||||
{
|
||||
if ($_records < 1) $_records = 1;
|
||||
if ($_records > 1000) $_records = 1000;
|
||||
$retData = null;
|
||||
mt_srand();
|
||||
for ($index = 0; $index < $_records; $index++) {
|
||||
$sentenceCount = mt_rand(1, 20);
|
||||
$retData[$index][CM_TST_FIELD_TEST_INT] = $sentenceCount;
|
||||
$retData[$index][CM_TST_FIELD_TEST_NIF] = 1;
|
||||
$retData[$index][CM_TST_FIELD_TEST_DOUBLE] = floatval((1 / mt_rand(1, 10000)) * 100);
|
||||
$retData[$index][CM_TST_FIELD_TEST_BOOL] = (mt_rand(0, 1) == 1) ? true : false;
|
||||
$retData[$index][CM_TST_FIELD_TEST_STRING] = lorumIpsum($sentenceCount, 0);
|
||||
$retData[$index][CM_TST_FIELD_TEST_ARY] = [[
|
||||
CM_TST_FIELD_TEST_INT => rand(0,100),
|
||||
CM_TST_FIELD_TEST_STRING => STRING_DATA
|
||||
], [
|
||||
CM_TST_FIELD_TEST_INT => rand(100,200),
|
||||
CM_TST_FIELD_TEST_STRING => INFO_INTERNAL_REQUEST
|
||||
]];
|
||||
$retData[$index][CM_TST_FIELD_TEST_OBJ] = (object) [
|
||||
CM_TST_FIELD_TEST_INT => rand(0, 100),
|
||||
CM_TST_FIELD_TEST_STRING => STRING_DATA
|
||||
];
|
||||
$retData[$index][CM_TST_FIELD_TEST_SUBC][] = [
|
||||
CM_TST_FIELD_TEST_INT => $sentenceCount,
|
||||
CM_TST_FIELD_TEST_DOUBLE => $retData[$index][CM_TST_FIELD_TEST_DOUBLE],
|
||||
CM_TST_FIELD_TEST_BOOL => $retData[$index][CM_TST_FIELD_TEST_BOOL],
|
||||
CM_TST_FIELD_TEST_STRING => $retData[$index][CM_TST_FIELD_TEST_STRING]
|
||||
];
|
||||
}
|
||||
return ($retData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 07-10-17 mks CORE-463: code complete (refactor from ddb to mdb)
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 07-10-17 mks CORE-463: code complete (refactor from ddb to mdb)
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
701
classes/templates/gatTestPDO.class.inc
Normal file
701
classes/templates/gatTestPDO.class.inc
Normal file
@@ -0,0 +1,701 @@
|
||||
<?php
|
||||
/**
|
||||
* Class gatTestPDO -- PDO Test Class
|
||||
*
|
||||
* This class is a test class for PDO operations. It is used for stub and unit-testing, references it's own
|
||||
* database table, and is for development/QA use only.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 09-13-17 mks CORE-562: original coding
|
||||
* 04-19-18 mks _INF-188: warehousing section added
|
||||
* 06-13-18 mks CORE-1044: making a consistent, sample, PDO template
|
||||
* 01-18-19 mks DB-105: updated for audit/journaling unit testing
|
||||
* 02-05-19 mks DB-107: created audit_view for cross-broker queries by the audit service
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
*
|
||||
*/
|
||||
class gatTestPDO
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version - not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_APPSERVER; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_PDO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_TEST_PDO; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_PDO_TEST; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_PDO_TEST_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = true; // set to true to cache class data
|
||||
public bool $setDeletes = false; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NONDESTRUCTIVE; // set to AUDIT_value constant
|
||||
public bool $setJournaling = true; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = false; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
//
|
||||
// Note that for PDO-type tables, the data type is more ... homogeneous... e.g.: data types define the data
|
||||
// type only. It does not define the actual column type in-use. For example, there is no distinction made
|
||||
// between a tinyInt, Int, or BigInt. As far as the framework is concerned, they're all just integers.
|
||||
//
|
||||
public array $fields = [
|
||||
PDO_ID => DATA_TYPE_INTEGER, // sorting by the id is just like sorting by createdDate
|
||||
TEST_FIELD_TEST_STRING => DATA_TYPE_STRING,
|
||||
TEST_FIELD_TEST_DOUBLE => DATA_TYPE_DOUBLE,
|
||||
TEST_FIELD_TEST_INT => DATA_TYPE_INTEGER,
|
||||
TEST_FIELD_TEST_BOOL => DATA_TYPE_INTEGER, // BOOLs in PDO are really tinyInt(1)
|
||||
TEST_FIELD_TEST_NIF => DATA_TYPE_INTEGER, // used in unit-testing -- never index this field
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key (string) exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_STRING, // dateTime type
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_STRING // dateTime type
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED, PDO_ID
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public array $indexFields = [
|
||||
PDO_ID, // implicitly indexed as pkey when table is created
|
||||
DB_CREATED, DB_STATUS, // compound index
|
||||
DB_TOKEN, // unique index
|
||||
TEST_FIELD_TEST_STRING, // for unit-testing
|
||||
TEST_FIELD_TEST_INT, DB_EVENT_GUID, // single field indexes...
|
||||
DB_ACCESSED, TEST_FIELD_TEST_DOUBLE
|
||||
];
|
||||
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = [ 'cIdx1ITest' ];
|
||||
|
||||
// the primary key index is declared in the class properties section as $setPKey
|
||||
|
||||
// unique indexes are to be used a values stored in these columns have to be unique to the table. Note that
|
||||
// null values are permissible in unique-index columns.
|
||||
public ?array $uniqueIndexes = [ DB_TOKEN ];
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index (index, multi)
|
||||
// the format for the single-field index declaration is a simple indexed array.
|
||||
public ?array $singleFields = [
|
||||
TEST_FIELD_TEST_INT, DB_ACCESSED, DB_EVENT_GUID, TEST_FIELD_TEST_DOUBLE, TEST_FIELD_TEST_STRING
|
||||
];
|
||||
|
||||
// multi-column (or compound) indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME1, FIELD_NAME2, ..., FIELD_NAMEn ]]
|
||||
// where INDEX-NAME is a unique string
|
||||
//
|
||||
// PDO compound-indexes are left-most indexes - if it cannot use the entire index, the db must be able to use
|
||||
// one, or more, of the left-most fields in the index.
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = [
|
||||
'cIdx1Test' => [ DB_CREATED, DB_STATUS ]
|
||||
];
|
||||
|
||||
|
||||
// NOTE: foreign-key indexes are not explicitly enumerated in a template -- that relationship is defined in the
|
||||
// schema for the table. Foreign-key indexes appear implicitly in the indexing declarations above.
|
||||
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
TEST_FIELD_TEST_STRING => CM_TST_FIELD_TEST_STRING,
|
||||
TEST_FIELD_TEST_DOUBLE => CM_TST_FIELD_TEST_DOUBLE,
|
||||
TEST_FIELD_TEST_INT => CM_TST_FIELD_TEST_INT,
|
||||
TEST_FIELD_TEST_BOOL => CM_TST_FIELD_TEST_BOOL,
|
||||
TEST_FIELD_TEST_NIF => CM_TST_FIELD_TEST_NIF,
|
||||
DB_TOKEN => CM_TST_TOKEN,
|
||||
DB_STATUS => CM_TST_FIELD_TEST_STATUS,
|
||||
DB_EVENT_GUID => CM_TST_EVENT_GUID,
|
||||
DB_CREATED => CM_TST_FIELD_TEST_CDATE,
|
||||
DB_ACCESSED => CM_TST_FIELD_TEST_ADATE
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
// in PDO-land, binary fields are your basic data blobs. All binary fields require special handling and so
|
||||
// need to be enumerated here as an indexed array.
|
||||
public ?array $binFields = null;
|
||||
|
||||
// DB SQL:
|
||||
// -------
|
||||
// PDO SQL is stored in the template and is keyed by the current namaste version (defined in the XML file) during
|
||||
// execution of the deployment script. Each version denotes a container of SQL commands that will be executed
|
||||
// for the targeted version.
|
||||
//
|
||||
// SQL is versioned in parallel with the Namaste (XML->application->id->version) version. Each PDO_SQL
|
||||
// sub-container has several fields - one of which has the version identifier. When the deployment script
|
||||
// executes, the release versions are compared and, if they're an exact match, the SQL is submitted for execution.
|
||||
//
|
||||
// The PDO_SQL container consists of these sub-containers:
|
||||
//
|
||||
// PDO_SQL_VERSION --> this is a float value in the form of x.y as namaste only supports versions as a major
|
||||
// and minor release number. (Patch releases are minor release increments.)
|
||||
// PDO_TABLE --> string value containing the full table name.
|
||||
// PDO_SQL_FC --> the FC means "first commit" -- when the table is first created, it will execute the
|
||||
// SQL in this block, if it exists, and if the version number for the sub-container
|
||||
// exactly matched the version number in the configuration XML.
|
||||
// PDO_SQL_UPDATE --> When the sub-container PDO_SQL_VERSION value exactly matches the XML release value,
|
||||
// then the ALTER-TABLE sql in this update block will be executed.
|
||||
// STRING_DROP_CODE_IDX --> The boilerplate code for dropping the indexes of the table.
|
||||
// STRING_DROP_CODE_DEV --> For version 1.0 only, this points to code to drop the entire table.
|
||||
//
|
||||
// Again, containers themselves are indexed arrays under the PDO_SQL tag. Within the container, data is stored
|
||||
// as an associative array with the keys enumerated above.
|
||||
//
|
||||
//
|
||||
// DB OBJECTS:
|
||||
// -----------
|
||||
// DB objects are: views, procedures, functions and events.
|
||||
// All such objects assigned to a class are declared in this array under the appropriate header.
|
||||
// This is a safety-feature that prevents a one class (table) from invoking another class object.
|
||||
// The name of the object is stored as an indexed-array under the appropriate header.
|
||||
//
|
||||
// The format for these structures is basically the same. Each DBO is stored in an associative array with the
|
||||
// key defining the name of the object. Within each object, there are embedded associative arrays that have the
|
||||
// name of the object as the key and the object definition (text) and the value:
|
||||
//
|
||||
// objectType => [ objectName => [ objectContent ], ... ]
|
||||
//
|
||||
// Each created object should also have the directive to remove it's predecessor using a DROP statement.
|
||||
//
|
||||
// todo -- unset these objects post-instantiation so that schema is not revealed
|
||||
//
|
||||
// VIEWS:
|
||||
// ------
|
||||
// Every namaste table will have at least one view which limits the data fetched from the table. At a minimum,
|
||||
// the id_{ext} field is filtered from the resulting data set via the view. Other fields can be withheld as well
|
||||
// but that is something that is individually set-up for each table.
|
||||
//
|
||||
// The basic view has the following syntax for declaring it's name:
|
||||
// view_basic_{tableName_ext}
|
||||
// All views start with the word "view" so as to self-identify the object, followed by the view type which,
|
||||
// optimally, you should try to limit to a single, descriptive word.
|
||||
//
|
||||
// Following this label, which points to a sub-array containing three elements:
|
||||
// STRING_VIEW ----------> this is the SQL code that defines the view as a single string value
|
||||
// STRING_TYPE_LIST -----> null or an array of types that corresponds to variable markers ('?') in the sql
|
||||
// STRING_DESCRIPTION' --> a string that describes the purpose of the view.
|
||||
//
|
||||
// At a minimum, every class definition should contain at-least a basic view as all queries that don't specify
|
||||
// a named view or other DBO, will default to the the basic view in the FROM clause of the generated SQL.
|
||||
//
|
||||
// PROCEDURES:
|
||||
// -----------
|
||||
// For stored procedures, which are entirely optional, the array definition contains the following elements:
|
||||
// STRING_PROCEDURE -------> the SQL code that defined the stored procedure as a single string value
|
||||
// STRING_DROP_CODE -------> the sql code that drops the current database object
|
||||
// STRING_TYPE_LIST -------> an associative array of associative arrays -- in the top level, the key is the name
|
||||
// of the parameter that points to a sub-array that contains the parameter direction
|
||||
// as the key, and the parameter type as the value. There should be an entry for each
|
||||
// parameter to be passed to the stored procedure/function.
|
||||
//
|
||||
// ------------------------------------------------------
|
||||
// | NOTE: IN params must precede INOUT and OUT params! |
|
||||
// ------------------------------------------------------
|
||||
//
|
||||
// STRING_SP_EVENT_TYPE ---> Assign one of the DB_EVENT constants to this field to indicate the type of
|
||||
// query the stored-procedure will execute.
|
||||
// NOTE: there is not a defined PDO::PARAM constant for type float: use string.
|
||||
// STRING_DESCRIPTION -----> clear-text definition of the procedure's purpose
|
||||
//
|
||||
// Note that all of these containers are required; empty containers should contain a null placeholder.
|
||||
//
|
||||
// When a stored procedure contains a join of two or more tables/views, the first table listed is considered
|
||||
// to be the "owning" table and the procedure will be declared in the class template for that table, but it will
|
||||
// not be duplicated in other template classes referenced in the join.
|
||||
//
|
||||
public ?array $dbObjects = [
|
||||
PDO_SQL => [
|
||||
[
|
||||
PDO_VERSION => 1.0,
|
||||
PDO_TABLE => 'gaTest_tst',
|
||||
PDO_SQL_FC => "
|
||||
--
|
||||
-- Table structure for table `gaTest_tst`
|
||||
--
|
||||
CREATE TABLE `gaTest_tst` (
|
||||
`id_tst` int(10) UNSIGNED NOT NULL,
|
||||
`testString_tst` varchar(255) DEFAULT NULL,
|
||||
`testDouble_tst` double DEFAULT NULL,
|
||||
`testInteger_tst` int(11) DEFAULT NULL,
|
||||
`testBoolean_tst` tinyint(1) UNSIGNED DEFAULT NULL,
|
||||
`notIndexedField_tst` int(11) DEFAULT NULL COMMENT 'do not index this field',
|
||||
`createdDate_tst` datetime DEFAULT NULL,
|
||||
`lastAccessedDate_tst` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||
`status_tst` varchar(32) DEFAULT NULL,
|
||||
`eventGUID_tst` char(36) DEFAULT NULL,
|
||||
`token_tst` char(36) NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
",
|
||||
PDO_SQL_UPDATE => "
|
||||
--
|
||||
-- Indexes for table `gaTest_tst`
|
||||
--
|
||||
ALTER TABLE `gaTest_tst`
|
||||
ADD PRIMARY KEY (`id_tst`),
|
||||
ADD UNIQUE KEY `gaTest_tst_token_tst_uindex` (`token_tst`),
|
||||
ADD KEY `gaTest_tst_createdDate_tst_status_tst_index` (`createdDate_tst`,`status_tst`),
|
||||
ADD KEY `gaTest_tst_eventGuid_tst_index` (`eventGUID_tst`),
|
||||
ADD KEY `gaTest_tst_lastAccessedDate_tst_index` (`lastAccessedDate_tst`),
|
||||
ADD KEY `testInteger_tst` (`testInteger_tst`),
|
||||
ADD KEY `testDouble_tst` (`testDouble_tst`),
|
||||
ADD KEY `testString_tst` (`testString_tst`(191));
|
||||
--
|
||||
-- AUTO_INCREMENT for dumped tables
|
||||
--
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT for table `gaTest_tst`
|
||||
--
|
||||
ALTER TABLE `gaTest_tst`
|
||||
MODIFY `id_tst` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
|
||||
",
|
||||
/*
|
||||
* example query return:
|
||||
* ---------------------
|
||||
* ALTER TABLE gaTest_tst DROP INDEX gaTest_tst_createdDate_tst_status_tst_index, DROP INDEX
|
||||
* gaTest_tst_lastAccessedDate_tst_index, DROP INDEX testInteger_tst, DROP INDEX
|
||||
* gaTest_tst_eventGuid_tst_index, DROP INDEX testDouble_tst, DROP INDEX testString_tst;
|
||||
*
|
||||
* NOTE:
|
||||
* -----
|
||||
* The sql comment code tag (--) will be removed during mysqlConfig's run time processing
|
||||
*/
|
||||
STRING_DROP_CODE_IDX => "--
|
||||
SELECT CONCAT('ALTER TABLE ', `Table`, ' DROP INDEX ', GROUP_CONCAT(`Index` SEPARATOR ', DROP INDEX '),';' )
|
||||
FROM (
|
||||
SELECT table_name AS `Table`, index_name AS `Index`
|
||||
FROM information_schema.statistics
|
||||
WHERE INDEX_NAME != 'PRIMARY'
|
||||
AND table_schema = 'XXXDROP_DB_NAMEXXX'
|
||||
AND table_name = 'XXXDROP_TABLE_NAMEXXX'
|
||||
GROUP BY `Table`, `Index`) AS tmp
|
||||
GROUP BY `Table`;
|
||||
",
|
||||
STRING_DROP_CODE_DEV => "DROP TABLE IF EXISTS gaTest_tst;" // only executed if declared
|
||||
]
|
||||
],
|
||||
PDO_VIEWS => [
|
||||
'view_basic_gaTest_tst' => [
|
||||
STRING_VIEW =>
|
||||
"DROP VIEW IF EXISTS view_basic_gaTest_tst;
|
||||
CREATE VIEW view_basic_gaTest_tst AS
|
||||
SELECT token_tst, testString_tst, testDouble_tst, testInteger_tst, testBoolean_tst,
|
||||
notIndexedField_tst, status_tst, createdDate_tst, lastAccessedDate_tst, eventGUID_tst
|
||||
FROM gaTest_tst
|
||||
WHERE status_tst <> 'DELETED';",
|
||||
STRING_TYPE_LIST => null,
|
||||
STRING_DESCRIPTION => 'basic query'
|
||||
],
|
||||
'view_audit_gaTest_tst' => [
|
||||
STRING_VIEW =>
|
||||
"DROP VIEW IF EXISTS view_audit_gaTest_tst;
|
||||
CREATE VIEW view_audit_gaTest_tst AS
|
||||
SELECT token_tst, testString_tst, testDouble_tst, testInteger_tst, testBoolean_tst,
|
||||
notIndexedField_tst, status_tst, createdDate_tst, lastAccessedDate_tst, eventGUID_tst
|
||||
FROM gaTest_tst;",
|
||||
STRING_TYPE_LIST => null,
|
||||
STRING_DESCRIPTION => 'query for cross-broker queries by audit micro-service'
|
||||
]
|
||||
],
|
||||
PDO_PROCEDURES => [
|
||||
'testProc0' => [
|
||||
STRING_DROP_CODE_DEV => "DROP PROCEDURE IF EXISTS testProc0;",
|
||||
STRING_PROCEDURE =>
|
||||
"CREATE PROCEDURE testProc0()
|
||||
READS SQL DATA
|
||||
BEGIN
|
||||
SET @sqlString = 'SELECT COUNT(*) AS recordCount FROM gaTest_tst';
|
||||
|
||||
PREPARE sqlString from @sqlString;
|
||||
EXECUTE sqlString;
|
||||
DEALLOCATE PREPARE sqlString;
|
||||
END",
|
||||
STRING_TYPE_LIST => null,
|
||||
STRING_SP_EVENT_TYPE => DB_EVENT_SELECT,
|
||||
STRING_DESCRIPTION => 'stored procedure to return row-count of the table, demos a zero-param sp'
|
||||
],
|
||||
'testProc1' => [
|
||||
STRING_DROP_CODE_DEV => 'DROP PROCEDURE IF EXISTS testProc1;',
|
||||
STRING_PROCEDURE =>
|
||||
"CREATE PROCEDURE testProc1( IN targetValue INT )
|
||||
READS SQL DATA
|
||||
BEGIN
|
||||
SET @targetVal = targetValue;
|
||||
|
||||
SET @sqlString = CONCAT('
|
||||
SELECT testInteger_tst, count(*) as rowCount
|
||||
FROM gaTest_tst
|
||||
WHERE testInteger_tst is not null
|
||||
GROUP BY testInteger_tst
|
||||
HAVING rowCount > ', @targetVal, '
|
||||
ORDER BY rowCount DESC
|
||||
LIMIT 10');
|
||||
|
||||
PREPARE sqlStatement FROM @sqlString;
|
||||
EXECUTE sqlStatement;
|
||||
DEALLOCATE PREPARE sqlStatement;
|
||||
END",
|
||||
STRING_TYPE_LIST => [
|
||||
'targetValue' => [ STRING_IN => PDO::PARAM_INT ]
|
||||
],
|
||||
STRING_SP_EVENT_TYPE => DB_EVENT_SELECT,
|
||||
STRING_DESCRIPTION => 'stored procedure that return top-10 list of integer-field values by count for all values greater than the supplied input parameter'
|
||||
],
|
||||
'testProc2' => [
|
||||
STRING_DROP_CODE_DEV => 'DROP PROCEDURE IF EXISTS testProc2;',
|
||||
STRING_PROCEDURE =>
|
||||
"CREATE PROCEDURE testProc2( IN intVal INT, OUT avgDouble FLOAT, OUT stdDevDouble FLOAT )
|
||||
READS SQL DATA
|
||||
BEGIN
|
||||
SELECT AVG(testDouble_tst), STDDEV(testDouble_tst)
|
||||
INTO avgDouble, stdDevDouble
|
||||
FROM gaTest_tst
|
||||
WHERE testInteger_tst = intVal;
|
||||
END",
|
||||
STRING_TYPE_LIST => [
|
||||
'intVal' => [ STRING_IN => PDO::PARAM_INT ],
|
||||
'avgDouble' => [ STRING_OUT => PDO::PARAM_STR ],
|
||||
'stdDevDouble' => [ STRING_OUT => PDO::PARAM_STR]
|
||||
],
|
||||
STRING_SP_EVENT_TYPE => DB_EVENT_SELECT,
|
||||
STRING_DESCRIPTION => 'stored procedure that calculates the avg() and stddev() for the floats with a specified integer value'
|
||||
]
|
||||
],
|
||||
PDO_FUNCTIONS => [],
|
||||
PDO_EVENTS => [],
|
||||
PDO_TRIGGERS => []
|
||||
];
|
||||
|
||||
|
||||
//=================================================================================================================
|
||||
// MIGRATION DECLARATIONS
|
||||
// ----------------------
|
||||
// Data in this section is used to handle migrations -- when we're pulling from legacy tables into the Namaste
|
||||
// framework. See online doc for more info.
|
||||
//=================================================================================================================
|
||||
|
||||
/**
|
||||
* The migration map is an associative array that maps the Namaste fields (keys) to the corresponding
|
||||
* (remote) legacy fields in the source table to be migrated to Namaste.
|
||||
*
|
||||
* For example, if we were migrating a mysql table in the legacy production database to Namaste::mongo, then
|
||||
* the keys of the migration map would be the Namaste::mongo->fieldNames and the values would be the mysql
|
||||
* column names in the legacy table.
|
||||
*
|
||||
* If there is a value which cannot be mapped to a key, then set it to null.
|
||||
*
|
||||
* Fields that will be dropped in the migration are not listed as values or as keys.
|
||||
*
|
||||
* This map will only exist in the template object and will never be imported into the class widget.
|
||||
*
|
||||
* This is a required field.
|
||||
*
|
||||
*/
|
||||
public ?array $migrationMap = null;
|
||||
|
||||
/*
|
||||
* the migrationSortKey defines the SOURCE field by which the fetch query will be sorted. ALL sort fields are
|
||||
* in ASC order so all we need to list here is the name of the field -- which MUST BE IN THE SOURCE TABLE.
|
||||
*
|
||||
* Populating this field may require preliminary examination of the data - what we want is a field that has
|
||||
* zero NULL values.
|
||||
*
|
||||
* This is a required field.
|
||||
*
|
||||
*/
|
||||
public ?string $migrationSortKey = '';
|
||||
|
||||
/*
|
||||
* The migrationStatusKey defines the status field/column in the source table -- if the user requires that
|
||||
* soft-deleted records not be migrated, then this field must be set. Otherwise, set the value to null.
|
||||
*
|
||||
* The format is in the form of a key-value paired array. The key specifies the name of the column and the value
|
||||
* specifies the "deleted" value that, if found, will cause that row from the SOURCE data to be omitted from the
|
||||
* DESTINATION table.
|
||||
*
|
||||
* e.g.: $migrationStatusKV = [ 'some_field' => 'deleted' ]
|
||||
*
|
||||
* Note that both the key and the value are case-sensitive!
|
||||
*
|
||||
* This is an optional field.
|
||||
*
|
||||
*/
|
||||
public ?string $migrationStatusKV = null;
|
||||
|
||||
// The $migrationSourceSchema defines the remote schema for the source table, and is set in the constructor
|
||||
public ?string $migrationSourceSchema;
|
||||
|
||||
// The source table in the remote repos (default defined in the XML) must be declared here, set in the constructor
|
||||
public ?string $migrationSourceTable;
|
||||
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [ OPERAND_NULL => [ OPERATOR_LT => [ null ] ] ],
|
||||
DB_STATUS => [ OPERAND_NULL => [ OPERATOR_EQ => [ STATUS_ACTIVE ]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 09-13-17 mks CORE-562: original coding
|
||||
* 09-09-19 mks DB-111: initialization of migration members moved to constructor b/c IDE warnings.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
// these next two lines are so that the IDE doesn't flag the variable declarations as unused </facePalm>
|
||||
$this->migrationSourceSchema = '';
|
||||
$this->migrationSourceTable = '';
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
/**
|
||||
* buildTestData() -- public static method
|
||||
*
|
||||
* this method is used to build an array structure of random data. There are two parameters to the method:
|
||||
*
|
||||
* $_records specifies the number of records to return to the calling client
|
||||
* $_incomplete indicates if we want to generate a partial (not all the fields are provided) record
|
||||
*
|
||||
* The $_incomplete parameter allows us to test the PDO class ability to successfully process partial payloads
|
||||
* on new record creation.
|
||||
*
|
||||
* The input parameter specifies how many records (indexes in the array) should be returned to the calling client
|
||||
* and should be a reasonable integer between one and one-hundred (1 - 100). If the passed-value for the number
|
||||
* of records is outside of this range, on either side, then the passed-value will be replaced with the range
|
||||
* limit for the appropriate "side".
|
||||
*
|
||||
* We then spin through a loop which populates an indexed array with the elements, from the test class,
|
||||
* with the appropriate extension as the sub-array key value.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @param int $_records
|
||||
* @param bool $_incomplete
|
||||
* @return array
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 09-13-17 mks CORE-562: original coding
|
||||
* 10-23-17 mks CORE_585: incomplete option added to skip some of the fields
|
||||
* 11-06-20 mks DB-171: ensuring that the test string length cannot be > 255 (max width of table column)
|
||||
*
|
||||
*/
|
||||
public static function buildTestData(int $_records = 1, bool $_incomplete = false): array
|
||||
{
|
||||
if ($_records < 1) $_records = 1;
|
||||
if ($_records > 1000) $_records = 1000;
|
||||
$retData = null;
|
||||
mt_srand();
|
||||
for ($index = 0; $index < $_records; $index++) {
|
||||
$sentenceCount = mt_rand(1, 20);
|
||||
$coinToss = ($_incomplete) ? mt_rand(0, 1) : 1;
|
||||
if ($coinToss) $retData[$index][CM_TST_FIELD_TEST_INT] = $sentenceCount;
|
||||
$coinToss = ($_incomplete) ? mt_rand(0, 1) : 1;
|
||||
if ($coinToss) $retData[$index][CM_TST_FIELD_TEST_DOUBLE] = floatval((1 / mt_rand(1, 10000)) * 100);
|
||||
$coinToss = ($_incomplete) ? mt_rand(0, 1) : 1;
|
||||
if ($coinToss) {
|
||||
$retData[$index][CM_TST_FIELD_TEST_STRING] = lorumIpsum($sentenceCount, 0);
|
||||
if (strlen($retData[$index][CM_TST_FIELD_TEST_STRING]) > 255)
|
||||
$retData[$index][CM_TST_FIELD_TEST_STRING] = substr($retData[$index][CM_TST_FIELD_TEST_STRING], 0, strpos(wordwrap($retData[$index][CM_TST_FIELD_TEST_STRING], 255), "\n"));
|
||||
|
||||
}
|
||||
$retData[$index][CM_TST_FIELD_TEST_BOOL] = intval(mt_rand(0,1));
|
||||
}
|
||||
return ($retData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 09-13-17 mks CORE-562: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 09-13-17 mks CORE-562: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
// empty by design
|
||||
}
|
||||
|
||||
}
|
||||
478
classes/templates/gatTransactions.class.inc
Normal file
478
classes/templates/gatTransactions.class.inc
Normal file
@@ -0,0 +1,478 @@
|
||||
<?php
|
||||
/** @noinspection PhpUnused */
|
||||
|
||||
/**
|
||||
* Class gatTransactions -- mongo collection template for Namaste
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-11-20 mks DB-147: original coding
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
*
|
||||
*/
|
||||
|
||||
class gatTransactions
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version - not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_APPSERVER; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_TRANSACTIONS; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_TRANSACTIONS; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_TRANSACTIONS_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = true; // set to true to cache class data
|
||||
public bool $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NONDESTRUCTIVE; // set to AUDIT_value constant (nondestructive = reads(yes))
|
||||
public bool $setJournaling = true; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = true; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = false; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
MONGO_ID => DATA_TYPE_INTEGER, // sorting by the id is just like sorting by createdDate
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique pkey exposed externally and is REQUIRED
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER, // epoch time
|
||||
TRANSACTIONS_ORDER_ID => DATA_TYPE_INTEGER,
|
||||
TRANSACTIONS_TYPE => DATA_TYPE_STRING,
|
||||
TRANSACTIONS_DESCRIPTION => DATA_TYPE_STRING,
|
||||
TRANSACTIONS_AMOUNT => DATA_TYPE_DOUBLE,
|
||||
TRANSACTIONS_EVENT_DATE => DATA_TYPE_DATETIME,
|
||||
TRANSACTIONS_START_DATE => DATA_TYPE_DATETIME,
|
||||
TRANSACTIONS_END_DATE => DATA_TYPE_DATETIME,
|
||||
TRANSACTIONS_META_DATA => DATA_TYPE_ARRAY,
|
||||
TRANSACTIONS_MD_TRAVEL_END_DATE => DATA_TYPE_DATETIME,
|
||||
TRANSACTIONS_MD_PARTNER => DATA_TYPE_STRING,
|
||||
TRANSACTION_MD_PRODUCT_ID => DATA_TYPE_INTEGER,
|
||||
TRANSACTIONS_MD_TRAVEL_START_DATE => DATA_TYPE_DATETIME,
|
||||
TRANSACTIONS_MD_CUSTOMER_ID => DATA_TYPE_INTEGER,
|
||||
TRANSACTIONS_MD_OFFER_NUMBER => DATA_TYPE_INTEGER,
|
||||
TRANSACTIONS_MD_ENV => DATA_TYPE_STRING,
|
||||
TRANSACTIONS_DEST_CITY_NAME => DATA_TYPE_STRING,
|
||||
TRANSACTIONS_DEST_STATE_CODE => DATA_TYPE_STRING,
|
||||
TRANSACTIONS_DEST_COUNTRY_CODE => DATA_TYPE_STRING,
|
||||
TRANSACTIONS_DONOR_ID => DATA_TYPE_INTEGER,
|
||||
TRANSACTIONS_CID => DATA_TYPE_STRING,
|
||||
TRANSACTIONS_CAUSE_TITLE => DATA_TYPE_STRING
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED, MONGO_ID
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_CREATED, DB_STATUS, DB_TOKEN
|
||||
];
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = null;
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_CREATED => -1
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = null;
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Sparse indexes only add the row to the index if the column referenced satisfies the conditions specified
|
||||
// in the query condition (expr2).
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
DB_TOKEN => 1 // MONGO_TOKEN should always appear
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null; // ttl indexes appear in $indexFields
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
DB_TOKEN => CM_TST_TOKEN,
|
||||
DB_STATUS => CM_TST_FIELD_TEST_STATUS,
|
||||
DB_EVENT_GUID => CM_TST_EVENT_GUID,
|
||||
DB_CREATED => CM_TRANSACTIONS_CREATED_AT,
|
||||
DB_ACCESSED => CM_TRANSACTIONS_UPDATED_AT,
|
||||
TRANSACTIONS_ORDER_ID => CM_TRANSACTIONS_ORDER_ID,
|
||||
TRANSACTIONS_TYPE => CM_TRANSACTIONS_TYPE,
|
||||
TRANSACTIONS_DESCRIPTION => CM_TRANSACTIONS_DESCRIPTION,
|
||||
TRANSACTIONS_AMOUNT => CM_TRANSACTIONS_AMOUNT,
|
||||
TRANSACTIONS_EVENT_DATE => CM_TRANSACTIONS_EVENT_DATE,
|
||||
TRANSACTIONS_START_DATE => CM_TRANSACTIONS_START_DATE,
|
||||
TRANSACTIONS_END_DATE => CM_TRANSACTIONS_END_DATE,
|
||||
TRANSACTIONS_META_DATA => CM_TRANSACTIONS_META_DATA,
|
||||
TRANSACTIONS_MD_TRAVEL_END_DATE => CM_TRANSACTIONS_MD_TRAVEL_END_DATE,
|
||||
TRANSACTIONS_MD_PARTNER => CM_TRANSACTIONS_MD_PARTNER,
|
||||
TRANSACTION_MD_PRODUCT_ID => CM_TRANSACTIONS_MD_PRODUCT_ID,
|
||||
TRANSACTIONS_MD_TRAVEL_START_DATE => CM_TRANSACTIONS_MD_TRAVEL_START_DATE,
|
||||
TRANSACTIONS_MD_CUSTOMER_ID => CM_TRANSACTIONS_MD_CUSTOMER_ID,
|
||||
TRANSACTIONS_MD_OFFER_NUMBER => CM_TRANSACTIONS_MD_OFFER_NUM,
|
||||
TRANSACTIONS_MD_ENV => CM_TRANSACTIONS_MD_ENV,
|
||||
TRANSACTIONS_DEST_CITY_NAME => CM_TRANSACTIONS_DEST_CITY_NAME,
|
||||
TRANSACTIONS_DEST_STATE_CODE => CM_TRANSACTIONS_DEST_STATE_CODE,
|
||||
TRANSACTIONS_DEST_COUNTRY_CODE => CM_TRANSACTIONS_DEST_COUNTRY_CODE,
|
||||
TRANSACTIONS_DONOR_ID => CM_TRANSACTIONS_DONOR_ID,
|
||||
TRANSACTIONS_CID => CM_TRANSACTIONS_CID,
|
||||
TRANSACTIONS_CAUSE_TITLE => CM_TRANSACTIONS_CAUSE_TITLE
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
*/
|
||||
// sub-collection fields must be declared here (need not be indexed)
|
||||
public ?array $subC = null;
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [OPERAND_NULL => [OPERATOR_LT => [null]]],
|
||||
DB_STATUS => [OPERAND_NULL => [OPERATOR_EQ => [STATUS_ACTIVE]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-11-20 mks DB-147: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-11-20 mks DB-147: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-11-20 mks DB-147: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
660
classes/templates/gatUsers.class.inc
Normal file
660
classes/templates/gatUsers.class.inc
Normal file
@@ -0,0 +1,660 @@
|
||||
<?php
|
||||
/** @noinspection PhpUnused */
|
||||
/**
|
||||
* Class gatUsers -- mongo class
|
||||
*
|
||||
* This class is used to store the user PII data necessary for a GA user account. This collection also stores internal
|
||||
* accounts. (Administrative, CSR, etc.)
|
||||
*
|
||||
* In the legacy (Parse) collection, there were 78 columns, not including the proprietary ACL column. In the first
|
||||
* pass of this migration, we've grouped the original entries into five sub-collections.
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-04-20 mks DB-147: original coding
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
*
|
||||
*/
|
||||
|
||||
class gatUsers
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version; not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_TERCERO; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_USERS; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_USERS; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_USERS_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = false; // set to false to allow partner instantiations
|
||||
public bool $setCache = true; // set to true to cache class data
|
||||
public bool $setDeletes = false; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NONDESTRUCTIVE; // set to AUDIT_value constant (nondestructive = reads(yes))
|
||||
public bool $setJournaling = true; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = true; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = false; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
MONGO_ID => DATA_TYPE_INTEGER,
|
||||
USER_ACCOUNT_SSO => DATA_TYPE_STRING,
|
||||
USER_AUTH_DATA => DATA_TYPE_OBJECT,
|
||||
USER_EMAIL_VERIFIED => DATA_TYPE_BOOL,
|
||||
USER_FBID => DATA_TYPE_STRING,
|
||||
USER_VERIFIED_HUMAN => DATA_TYPE_BOOL,
|
||||
USER_MEMBERSHIP_PLAN => DATA_TYPE_STRING,
|
||||
USER_NOTES => DATA_TYPE_STRING,
|
||||
USER_PARTNER_API_KEY => DATA_TYPE_STRING,
|
||||
USER_PASSWORD => DATA_TYPE_STRING,
|
||||
USER_PASSWORD_UPDATED => DATA_TYPE_INTEGER,
|
||||
USER_PASSWORD_LAST_THREE => DATA_TYPE_ARRAY,
|
||||
USER_PROMO_SIGN_UP_ID => DATA_TYPE_INTEGER,
|
||||
USER_TEMP_PASSWORD => DATA_TYPE_STRING,
|
||||
USER_TZ => DATA_TYPE_DOUBLE,
|
||||
USER_LEAP_CONVERTED => DATA_TYPE_BOOL,
|
||||
USER_USERNAME => DATA_TYPE_STRING,
|
||||
USER_WEBHOOK_RETRIES => DATA_TYPE_INTEGER,
|
||||
USER_TYPE => DATA_TYPE_STRING,
|
||||
USER_FINANCIALS => DATA_TYPE_ARRAY,
|
||||
USER_FINANCIALS_TOTAL_DONATIONS => DATA_TYPE_DOUBLE,
|
||||
USER_FINANCIALS_TOTAL_EARNINGS => DATA_TYPE_DOUBLE,
|
||||
USER_FINANCIALS_CASHBACK_BANK => DATA_TYPE_INTEGER,
|
||||
USER_FINANCIALS_CASHBACK_DONATION => DATA_TYPE_INTEGER,
|
||||
USER_FINANCIALS_CURRENT_BALANCE => DATA_TYPE_DOUBLE,
|
||||
USER_FINANCIALS_EARNING_TIER => DATA_TYPE_STRING,
|
||||
USER_FINANCIALS_PAYMENTS => DATA_TYPE_ARRAY,
|
||||
USER_FINANCIALS_PAYMENTS_ADDRESS1 => DATA_TYPE_STRING,
|
||||
USER_FINANCIALS_PAYMENTS_ADDRESS2 => DATA_TYPE_STRING,
|
||||
USER_FINANCIALS_PAYMENTS_CITY => DATA_TYPE_STRING,
|
||||
USER_FINANCIALS_PAYMENTS_COUNTRY => DATA_TYPE_STRING,
|
||||
USER_FINANCIALS_PAYMENTS_FULL_NAME => DATA_TYPE_STRING,
|
||||
USER_FINANCIALS_PAYMENTS_PLAN => DATA_TYPE_STRING,
|
||||
USER_FINANCIALS_PAYMENTS_STATE => DATA_TYPE_STRING,
|
||||
USER_FINANCIALS_PAYMENTS_STATUS => DATA_TYPE_STRING,
|
||||
USER_FINANCIALS_PAYMENTS_ZIP => DATA_TYPE_STRING,
|
||||
USER_FINANCIALS_PAYMENTS_VERIFIED => DATA_TYPE_BOOL,
|
||||
USER_FINANCIALS_PAYMENTS_META => DATA_TYPE_STRING,
|
||||
USER_FINANCIALS_PAYMENTS_TYPE => DATA_TYPE_STRING,
|
||||
USER_FINANCIALS_PENDING_BALANCE => DATA_TYPE_DOUBLE,
|
||||
USER_FINANCIALS_CUSTOMER_ID => DATA_TYPE_STRING,
|
||||
USER_FINANCIALS_STRIPE_RECIPIENT_VERIFIED => DATA_TYPE_BOOL,
|
||||
USER_FINANCIALS_TIN_FINGERPRINT => DATA_TYPE_STRING,
|
||||
USER_FINANCIALS_TIN_TYPE => DATA_TYPE_STRING,
|
||||
USER_SPORTS => DATA_TYPE_ARRAY,
|
||||
USER_SPORTS_FAV_ATHLETES => DATA_TYPE_OBJECT,
|
||||
USER_SPORTS_FAV_TEAMS => DATA_TYPE_OBJECT,
|
||||
USER_SPORTS_FAV_SPORTS => DATA_TYPE_OBJECT,
|
||||
USER_CHARITIES => DATA_TYPE_ARRAY,
|
||||
USER_CHARITIES_SELECTED_CAMPAIGN => DATA_TYPE_INTEGER,
|
||||
USER_CHARITIES_SELECTED_CAMPAIGN_META => DATA_TYPE_INTEGER,
|
||||
USER_CHARITIES_SELECTED_CAMPAIGN_TITLE => DATA_TYPE_STRING,
|
||||
USER_REFERRALS => DATA_TYPE_ARRAY,
|
||||
USER_REFERRALS_EARNINGS => DATA_TYPE_INTEGER,
|
||||
USER_REFERRALS_CLICKS => DATA_TYPE_INTEGER,
|
||||
USER_REFERRALS_EARNINGS_PENDING => DATA_TYPE_INTEGER,
|
||||
USER_REFERRALS_SIGNUPS => DATA_TYPE_INTEGER,
|
||||
USER_REFERRALS_RID => DATA_TYPE_STRING,
|
||||
USER_PII => DATA_TYPE_ARRAY,
|
||||
USER_PII_ADDRESS => DATA_TYPE_STRING,
|
||||
USER_PII_AGE_RANGE => DATA_TYPE_STRING,
|
||||
USER_PII_BIRTHDAY => DATA_TYPE_DATETIME,
|
||||
USER_PII_COUNTRY_CODE => DATA_TYPE_STRING,
|
||||
USER_PII_EMAIL => DATA_TYPE_STRING,
|
||||
USER_PII_SECONDARY_EMAIL => DATA_TYPE_STRING,
|
||||
USER_PII_FNAME => DATA_TYPE_STRING,
|
||||
USER_PII_GENDER => DATA_TYPE_STRING,
|
||||
USER_PII_HOMETOWN => DATA_TYPE_STRING,
|
||||
USER_PII_LANGUAGES => DATA_TYPE_OBJECT,
|
||||
USER_PII_LNAME => DATA_TYPE_STRING,
|
||||
USER_PII_LEGAL_NAME => DATA_TYPE_STRING,
|
||||
USER_PII_LOCALE => DATA_TYPE_STRING,
|
||||
USER_PII_LOCATION => DATA_TYPE_STRING,
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER // epoch time
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED, DB_STATUS
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_CREATED, DB_EVENT_GUID, DB_ACCESSED, MONGO_ID, DB_STATUS
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_TOKEN, DB_CREATED, DB_STATUS, DB_EVENT_GUID, USER_PII_EMAIL, USER_PII_SECONDARY_EMAIL
|
||||
];
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = [ 'emailsIndex', 'activePartnersIndex' ];
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_TOKEN => 1,
|
||||
DB_CREATED => -1,
|
||||
DB_STATUS => 1,
|
||||
DB_EVENT_GUID => 1
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = [
|
||||
'emailsIndex' => [ USER_PII_EMAIL => 1, USER_PII_SECONDARY_EMAIL => 1 ],
|
||||
'activePartnersIndex' => [ USER_PARTNER_API_KEY => 1, DB_STATUS => 1 ]
|
||||
];
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Sparse indexes only add the row to the index if the column referenced satisfies the conditions specified
|
||||
// in the query condition (expr2).
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
DB_TOKEN => 1, // MONGO_TOKEN should always appear
|
||||
DB_EVENT_GUID => 1,
|
||||
USER_PII_EMAIL => 1
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null;
|
||||
|
||||
// cache maps are required for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
DB_TOKEN => CM_TOKEN,
|
||||
DB_CREATED => CM_DATE_CREATED,
|
||||
DB_ACCESSED => CM_DATE_ACCESSED,
|
||||
DB_STATUS => CM_STATUS,
|
||||
DB_EVENT_GUID => CM_EVENT_GUID,
|
||||
USER_ACCOUNT_SSO => CM_USER_ACCOUNT,
|
||||
USER_AUTH_DATA => CM_USER_API_DATA,
|
||||
USER_EMAIL_VERIFIED => CM_USER_EMAIL_VALIDATED,
|
||||
USER_FBID => CM_USER_FB_KEY,
|
||||
USER_VERIFIED_HUMAN => CM_USER_HUMAN_VALIDATED,
|
||||
USER_MEMBERSHIP_PLAN => CM_USER_MEMBER_PLAN,
|
||||
USER_NOTES => CM_USER_NOTES,
|
||||
USER_PASSWORD => CM_USER_PASSWORD,
|
||||
USER_PROMO_SIGN_UP_ID => CM_USER_PROMO_ID,
|
||||
USER_TEMP_PASSWORD => CM_USER_TEMPORARY_PWD,
|
||||
USER_TZ => CM_USER_TIMEZONE,
|
||||
USER_LEAP_CONVERTED => CM_USER_LEAP_CONVERTED,
|
||||
USER_USERNAME => CM_USER_NAME,
|
||||
USER_WEBHOOK_RETRIES => CM_USER_WEBHOOK_ATTEMPTS,
|
||||
USER_TYPE => CM_USER_TYPE,
|
||||
USER_FINANCIALS => CM_USER_FINANCIALS,
|
||||
USER_FINANCIALS_TOTAL_DONATIONS => CM_USER_FINANCIALS_DONATIONS,
|
||||
USER_FINANCIALS_TOTAL_EARNINGS => CM_USER_FINANCIALS_EARNINGS,
|
||||
USER_FINANCIALS_CASHBACK_BANK => CM_USER_FINANCIALS_CB_BANK,
|
||||
USER_FINANCIALS_CASHBACK_DONATION => CM_USER_FINANCIALS_CB_DONATIONS,
|
||||
USER_FINANCIALS_CURRENT_BALANCE => CM_USER_FINANCIALS_CURR_BAL,
|
||||
USER_FINANCIALS_EARNING_TIER => CM_USER_FINANCIALS_EARNING_TIER,
|
||||
USER_FINANCIALS_PAYMENTS => CM_USER_FINANCIALS_PAYMENTS,
|
||||
USER_FINANCIALS_PAYMENTS_ADDRESS1 => USER_FINANCIALS_PAYMENTS_ADDRESS1,
|
||||
USER_FINANCIALS_PAYMENTS_ADDRESS2 => CM_USER_FINANCIALS_PAYMENTS_ADDR2,
|
||||
USER_FINANCIALS_PAYMENTS_CITY => CM_USER_FINANCIALS_PAYMENTS_CITY,
|
||||
USER_FINANCIALS_PAYMENTS_COUNTRY => CM_USER_FINANCIALS_PAYMENTS_COUNTRY,
|
||||
USER_FINANCIALS_PAYMENTS_FULL_NAME => CM_USER_FINANCIALS_PAYMENTS_FNAME,
|
||||
USER_FINANCIALS_PAYMENTS_PLAN => CM_USER_FINANCIALS_PAYMENTS_PLAN,
|
||||
USER_FINANCIALS_PAYMENTS_STATE => CM_USER_FINANCIALS_PAYMENTS_STATE,
|
||||
USER_FINANCIALS_PAYMENTS_STATUS => CM_USER_FINANCIALS_PAYMENTS_STATUS,
|
||||
USER_FINANCIALS_PAYMENTS_ZIP => CM_USER_FINANCIALS_PAYMENTS_ZIP,
|
||||
USER_FINANCIALS_PAYMENTS_VERIFIED => CM_USER_FINANCIALS_PAYMENTS_VALIDATED,
|
||||
USER_FINANCIALS_PAYMENTS_META => CM_USER_FINANCIALS_PAYMENTS_METADATA,
|
||||
USER_FINANCIALS_PAYMENTS_TYPE => USER_FINANCIALS_PAYMENTS_TYPE,
|
||||
USER_FINANCIALS_PENDING_BALANCE => CM_USER_FINANCIALS_PENDING_BALANCE,
|
||||
USER_FINANCIALS_CUSTOMER_ID => CM_USER_FINANCIALS_CUSTOMER_ID,
|
||||
USER_FINANCIALS_STRIPE_RECIPIENT_VERIFIED => CM_USER_FINANCIALS_STRIPE_VERIFIED,
|
||||
USER_FINANCIALS_TIN_FINGERPRINT => CM_USER_FINANCIALS_TIN_IDENTIFIER,
|
||||
USER_FINANCIALS_TIN_TYPE => CM_USER_FINANCIALS_TIN_TYPE,
|
||||
USER_SPORTS => CM_USER_SPORTS,
|
||||
USER_SPORTS_FAV_ATHLETES => CM_USER_SPORTS_FAVE_ATHLETES,
|
||||
USER_SPORTS_FAV_TEAMS => CM_USER_SPORTS_FAVE_TEAMS,
|
||||
USER_SPORTS_FAV_SPORTS => CM_USER_SPORTS_FAVE_SPORTS,
|
||||
USER_CHARITIES => CM_USER_CHARITIES,
|
||||
USER_CHARITIES_SELECTED_CAMPAIGN => CM_USER_CHARITIES_SEL_CAMPAIGN,
|
||||
USER_CHARITIES_SELECTED_CAMPAIGN_META => CM_USER_CHARITIES_SEL_CAMPAIGN_META,
|
||||
USER_CHARITIES_SELECTED_CAMPAIGN_TITLE => CM_USER_CHARITIES_SEL_CAMPAIGN_TITLE,
|
||||
USER_REFERRALS => CM_USER_REFERRALS,
|
||||
USER_REFERRALS_EARNINGS => CM_USER_REFERRALS_EARNINGS,
|
||||
USER_REFERRALS_CLICKS => CM_USER_REFERRALS_CLICKS,
|
||||
USER_REFERRALS_EARNINGS_PENDING => CM_USER_REFERRALS_PENDING_EARNINGS,
|
||||
USER_REFERRALS_SIGNUPS => CM_USER_REFERRALS_SIGNUPS,
|
||||
USER_REFERRALS_RID => CM_USER_REFERRALS_ID,
|
||||
USER_PII => CM_USER_PII,
|
||||
USER_PII_ADDRESS => CM_USER_PII_ADDR,
|
||||
USER_PII_AGE_RANGE => CM_USER_PII_AGE_RANGE,
|
||||
USER_PII_BIRTHDAY => CM_USER_PII_DOB,
|
||||
USER_PII_COUNTRY_CODE => CM_USER_PII_COUNTRY_CODE,
|
||||
USER_PII_EMAIL => CM_USER_PII_EMAIL,
|
||||
USER_PII_SECONDARY_EMAIL => CM_USER_PII_ALT_EMAIL,
|
||||
USER_PII_FNAME => CM_USER_PII_FNAME,
|
||||
USER_PII_GENDER => CM_USER_PII_GENDER,
|
||||
USER_PII_HOMETOWN => CM_USER_PII_HOMETOWN,
|
||||
USER_PII_LANGUAGES => CM_USER_PII_LANGUAGES,
|
||||
USER_PII_LNAME => CM_USER_PII_LNAME,
|
||||
USER_PII_LEGAL_NAME => CM_USER_PII_LEGAL_NAME,
|
||||
USER_PII_LOCALE => CM_USER_PII_LOCALE,
|
||||
USER_PII_LOCATION => CM_USER_PII_LOCATION
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as the associative array: $exposedFields. Only those fields,
|
||||
* enumerated within this container, will be exposed to the client.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
*/
|
||||
// sub-collection fields must be declared here (need not be indexed)
|
||||
public ?array $subC = [
|
||||
USER_SPORTS => [
|
||||
USER_SPORTS_FAV_ATHLETES,
|
||||
USER_SPORTS_FAV_TEAMS,
|
||||
USER_SPORTS_FAV_SPORTS
|
||||
],
|
||||
USER_CHARITIES => [
|
||||
USER_CHARITIES_SELECTED_CAMPAIGN,
|
||||
USER_CHARITIES_SELECTED_CAMPAIGN_META,
|
||||
USER_CHARITIES_SELECTED_CAMPAIGN_TITLE
|
||||
],
|
||||
USER_REFERRALS => [
|
||||
USER_REFERRALS_EARNINGS,
|
||||
USER_REFERRALS_CLICKS,
|
||||
USER_REFERRALS_EARNINGS_PENDING,
|
||||
USER_REFERRALS_SIGNUPS,
|
||||
USER_REFERRALS_RID
|
||||
],
|
||||
USER_PII => [
|
||||
USER_PII_ADDRESS,
|
||||
USER_PII_AGE_RANGE,
|
||||
USER_PII_BIRTHDAY,
|
||||
USER_PII_COUNTRY_CODE,
|
||||
USER_PII_EMAIL,
|
||||
USER_PII_FNAME,
|
||||
USER_PII_GENDER,
|
||||
USER_PII_HOMETOWN,
|
||||
USER_PII_LANGUAGES,
|
||||
USER_PII_LNAME,
|
||||
USER_PII_LEGAL_NAME,
|
||||
USER_PII_LOCALE,
|
||||
USER_PII_LOCATION
|
||||
],
|
||||
USER_FINANCIALS => [
|
||||
USER_FINANCIALS_TOTAL_DONATIONS,
|
||||
USER_FINANCIALS_TOTAL_EARNINGS,
|
||||
USER_FINANCIALS_CASHBACK_BANK,
|
||||
USER_FINANCIALS_CASHBACK_DONATION,
|
||||
USER_FINANCIALS_CURRENT_BALANCE,
|
||||
USER_FINANCIALS_EARNING_TIER,
|
||||
USER_FINANCIALS_PENDING_BALANCE,
|
||||
USER_FINANCIALS_CUSTOMER_ID,
|
||||
USER_FINANCIALS_STRIPE_RECIPIENT_VERIFIED,
|
||||
USER_FINANCIALS_TIN_FINGERPRINT,
|
||||
USER_FINANCIALS_TIN_TYPE,
|
||||
USER_FINANCIALS_PAYMENTS // <--- note that this is a sub-heading within a sub-heading |
|
||||
], // |
|
||||
USER_FINANCIALS_PAYMENTS => [ // <---------------------------------------------------------|
|
||||
USER_FINANCIALS_PAYMENTS_ADDRESS1,
|
||||
USER_FINANCIALS_PAYMENTS_ADDRESS2,
|
||||
USER_FINANCIALS_PAYMENTS_CITY,
|
||||
USER_FINANCIALS_PAYMENTS_COUNTRY,
|
||||
USER_FINANCIALS_PAYMENTS_FULL_NAME,
|
||||
USER_FINANCIALS_PAYMENTS_PLAN,
|
||||
USER_FINANCIALS_PAYMENTS_STATE,
|
||||
USER_FINANCIALS_PAYMENTS_STATUS,
|
||||
USER_FINANCIALS_PAYMENTS_ZIP,
|
||||
USER_FINANCIALS_PAYMENTS_VERIFIED,
|
||||
USER_FINANCIALS_PAYMENTS_META,
|
||||
USER_FINANCIALS_PAYMENTS_TYPE
|
||||
]
|
||||
];
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [OPERAND_NULL => [OPERATOR_LT => [null]]],
|
||||
DB_STATUS => [OPERAND_NULL => [OPERATOR_EQ => [STATUS_ACTIVE]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* Constructor in this template not only registers the shutdown method, but also allows us to generate a custom
|
||||
* GUID string during instantiation by use of the input parameters:
|
||||
*
|
||||
* $_getGUID - boolean, defaults to false but, if true, will generate a GUID value and store it in the class member
|
||||
* $_lc - boolean, defaults to false but, if true, will generate a GUID using lower-case alpha characters
|
||||
*
|
||||
* If we generate a GUID on instantiation, the GUID will be stored in the class member. This allows us to both
|
||||
* instantiate a session class object and a GUID value, (the most requested, post-instantiation, action), at the
|
||||
* same time. All the efficient.
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-04-20 mks DB-147: original coding
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-04-20 mks DB-147: original coding
|
||||
*
|
||||
* @version 1.0
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 02-04-20 mks DB-147: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
// move on lookie-loo....
|
||||
}
|
||||
|
||||
}
|
||||
469
classes/templates/gatWBList.class.inc
Normal file
469
classes/templates/gatWBList.class.inc
Normal file
@@ -0,0 +1,469 @@
|
||||
<?php
|
||||
/**
|
||||
* Class gatWBList -- template class for Giving Assistant's White/Black List collection.
|
||||
*
|
||||
* This is an tercero-class collection that records white and black-listed email addresses for the email validation
|
||||
* process.
|
||||
*
|
||||
* Rules are simple and as you would guess:
|
||||
* If an email is white listed then the email is always sent
|
||||
* elseif the email is black listed then the email is never sent and generates a system event
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-18-20 mks DB-168: original coding
|
||||
*
|
||||
*/
|
||||
|
||||
class gatWBList
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version; not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_TERCERO; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_WBL; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_WBLIST; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_WBLIST_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = false; // set to false to allow partner instantiations
|
||||
public bool $setCache = false; // set to true to cache class data
|
||||
public bool $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_DESTRUCTIVE; // set to AUDIT_value constant (nondestructive = reads(yes))
|
||||
public bool $setJournaling = true; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = true; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER, // epoch time
|
||||
// fields specific to systemEvents collection
|
||||
MONGO_WBL_TYPE => DATA_TYPE_BOOL, // 1 = white, 0 = black
|
||||
USER_PII_EMAIL => DATA_TYPE_STRING, // email expression to be matched
|
||||
MONGO_WBL_ADDED_BY => DATA_TYPE_STRING, // who added record to list
|
||||
META_SYSTEM_NOTES => DATA_TYPE_STRING // notes about the add event
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED, DB_STATUS
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_CREATED, DB_EVENT_GUID, DB_ACCESSED, MONGO_ID, DB_STATUS,
|
||||
MONGO_WBL_TYPE, USER_PII_EMAIL, MONGO_WBL_ADDED_BY, META_SYSTEM_NOTES
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_TOKEN, DB_CREATED, DB_STATUS, DB_EVENT_GUID,
|
||||
MONGO_WBL_TYPE, USER_PII_EMAIL, MONGO_WBL_ADDED_BY, 'wblType',
|
||||
'wblEmail', 'wblCSR', 'wblEmailCSR'
|
||||
];
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = null;
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_TOKEN => 1,
|
||||
DB_CREATED => -1,
|
||||
DB_STATUS => 1,
|
||||
DB_EVENT_GUID => 1,
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = [
|
||||
'wblType' => [ MONGO_WBL_TYPE => 1, DB_STATUS => 1],
|
||||
'wblEmail' => [ USER_PII_EMAIL => 1, DB_STATUS => 1],
|
||||
'wblCSR' => [ MONGO_WBL_ADDED_BY => 1, DB_STATUS => 1],
|
||||
'wblEmailCSR' => [ USER_PII_EMAIL => 1, MONGO_WBL_ADDED_BY => 1, DB_STATUS => 1]
|
||||
];
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Sparse indexes only add the row to the index if the column referenced satisfies the conditions specified
|
||||
// in the query condition (expr2).
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
DB_TOKEN => 1, // MONGO_TOKEN should always appear
|
||||
DB_EVENT_GUID => 1,
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null;
|
||||
|
||||
// cache maps are required for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
DB_TOKEN => CM_TOKEN,
|
||||
DB_CREATED => CM_DATE_CREATED,
|
||||
DB_ACCESSED => CM_DATE_ACCESSED,
|
||||
DB_STATUS => CM_STATUS,
|
||||
DB_EVENT_GUID => CM_EVENT_GUID,
|
||||
// collection-specific fields
|
||||
MONGO_WBL_TYPE => CM_WBL_TYPE,
|
||||
USER_PII_EMAIL => CM_WBL_EMAIL,
|
||||
MONGO_WBL_ADDED_BY => CM_WBL_ADDED_BY,
|
||||
META_SYSTEM_NOTES => CM_WBL_NOTES
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as the associative array: $exposedFields. Only those fields,
|
||||
* enumerated within this container, will be exposed to the client.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
*/
|
||||
// sub-collection fields must be declared here (need not be indexed)
|
||||
public ?array $subC = null;
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [OPERAND_NULL => [OPERATOR_LT => [null]]],
|
||||
DB_STATUS => [OPERAND_NULL => [OPERATOR_EQ => [STATUS_ACTIVE]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-18-20 mks DB-168: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* Constructor in this template not only registers the shutdown method, but also allows us to generate a custom
|
||||
* GUID string during instantiation by use of the input parameters:
|
||||
*
|
||||
* $_getGUID - boolean, defaults to false but, if true, will generate a GUID value and store it in the class member
|
||||
* $_lc - boolean, defaults to false but, if true, will generate a GUID using lower-case alpha characters
|
||||
*
|
||||
* If we generate a GUID on instantiation, the GUID will be stored in the class member. This allows us to both
|
||||
* instantiate a session class object and a GUID value, (the most requested, post-instantiation, action), at the
|
||||
* same time. All the efficient.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-18-20 mks DB-168: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 08-18-20 mks DB-168: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
// move on lookie-loo....
|
||||
}
|
||||
}
|
||||
527
classes/templates/gatWHC1ProdRegistrations.class.inc
Normal file
527
classes/templates/gatWHC1ProdRegistrations.class.inc
Normal file
@@ -0,0 +1,527 @@
|
||||
<?php
|
||||
/**
|
||||
* gatWHC1ProdRegistrations.class -- Namaste mySQL Data Template for WH Level: COOL
|
||||
*
|
||||
* This is the warehouse data template file for the Namaste mySQL version of product-registration.
|
||||
* This template was created for the purpose of testing mysql->mysql data warehousing.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 05-08-18 mks _INF-188: original coding
|
||||
* 01-15-20 mks DB-150: PHP7.4 class member type-casting
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
*
|
||||
*/
|
||||
class gatWHC1ProdRegistrations
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...```
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version - not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_SEGUNDO; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_PDO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_WHC1_PROD_REG; // defines the clear-text template class name
|
||||
public string $collection = WH_COOL_PDO_PROD_REGS; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_PDO_PROD_REGS_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = false; // set to true to cache class data
|
||||
public bool $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public bool $setJournaling = false; // set to true to allow journaling
|
||||
public bool $setUpdates = false; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = false; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if class contains methods or migration
|
||||
public int $cacheTimer = 0; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = true; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
//
|
||||
// Note that for PDO-type tables, the data type is more ... homogeneous... e.g.: data types define the data
|
||||
// type only. It does not define the actual column type in-use. For example, there is no distinction made
|
||||
// between a tinyInt, Int, or BigInt. As far as the framework is concerned, they're all just integers.
|
||||
//
|
||||
public array $fields = [
|
||||
PDO_ID => DATA_TYPE_INTEGER, // sorting by the id is just like sorting by createdDate
|
||||
PRG_TYPE => DATA_TYPE_STRING,
|
||||
PRG_IID => DATA_TYPE_STRING,
|
||||
PRG_EAV => DATA_TYPE_STRING,
|
||||
PRG_PLATFORM => DATA_TYPE_STRING,
|
||||
PRG_BROWSER => DATA_TYPE_STRING,
|
||||
PRG_MAJOR_VERSION => DATA_TYPE_INTEGER,
|
||||
PRG_MINOR_VERSION => DATA_TYPE_INTEGER,
|
||||
PRG_IS_MOBILE => DATA_TYPE_INTEGER,
|
||||
PRG_IS_TABLET => DATA_TYPE_INTEGER,
|
||||
PRG_FIRST_SEEN => DATA_TYPE_STRING,
|
||||
PRG_LAST_SEEN => DATA_TYPE_STRING,
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key (string) exposed externally and is REQUIRED,
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_STRING, // dateTime type
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_STRING, // dateTime type
|
||||
//_________________________________________________________________________
|
||||
// UP TO HERE IS THE ORIGINAL DATA -- BELOW IS THE WH_CLASS-SPECIFIC DATA
|
||||
//-------------------------------------------------------------------------
|
||||
DB_WH_CREATED => DATA_TYPE_STRING,
|
||||
DB_WH_EVENT_GUID => DATA_TYPE_STRING,
|
||||
DB_WH_TOKEN => DATA_TYPE_STRING
|
||||
];
|
||||
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_EVENT_GUID, DB_CREATED, PDO_ID, DB_WH_EVENT_GUID, DB_WH_CREATED, DB_WH_TOKEN
|
||||
];
|
||||
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public array $indexFields = [
|
||||
DB_CREATED => 1,
|
||||
DB_WH_TOKEN => 1,
|
||||
DB_WH_CREATED => 1,
|
||||
DB_WH_EVENT_GUID => 1
|
||||
];
|
||||
|
||||
|
||||
// the primary key index is declared in the class properties section as $setPKey
|
||||
|
||||
// unique indexes are to be used a values stored in these columns have to be unique to the table. Note that
|
||||
// null values are permissible in unique-index columns. Do not declare PDO_ID here, regardless of how badly
|
||||
// you may want to.
|
||||
public ?array $uniqueIndexes = [ DB_WH_TOKEN, DB_WH_EVENT_GUID ];
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index (index, multi)
|
||||
// the format for the single-field index declaration is a simple indexed array.
|
||||
public ?array $singleFields = [
|
||||
DB_CREATED
|
||||
];
|
||||
|
||||
// multi-column (or compound) indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME1, FIELD_NAME2, ..., FIELD_NAMEn ]]
|
||||
// where INDEX-NAME is a unique string
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
//
|
||||
// PDO compound-indexes are left-most indexes - if it cannot use the entire index, the db must be able to use
|
||||
// one, or more, of the left-most fields in the index.
|
||||
public ?array $compoundIndexes = [
|
||||
'whC1PRG-I1' => [ DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN ]
|
||||
];
|
||||
|
||||
|
||||
// NOTE: foreign-key indexes are not explicitly enumerated in a template -- that relationship is defined in the
|
||||
// schema for the table. Foreign-key indexes appear implicitly in the indexing declarations above.
|
||||
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = null;
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = [
|
||||
PRG_TYPE => 1,
|
||||
PRG_IID => 1,
|
||||
PRG_EAV => 1,
|
||||
PRG_PLATFORM => 1,
|
||||
PRG_BROWSER => 1,
|
||||
PRG_MAJOR_VERSION => 1,
|
||||
PRG_MINOR_VERSION => 1,
|
||||
PRG_IS_MOBILE => 1,
|
||||
PRG_IS_TABLET => 1,
|
||||
PRG_FIRST_SEEN => 1,
|
||||
PRG_LAST_SEEN => 1,
|
||||
DB_CREATED => 1, // epoch time
|
||||
DB_STATUS => 1, // record status
|
||||
DB_ACCESSED => 1, // epoch time
|
||||
DB_WH_EVENT_GUID => 1,
|
||||
DB_WH_CREATED => 1,
|
||||
DB_WH_TOKEN => 1
|
||||
];
|
||||
|
||||
|
||||
// in PDO-land, binary fields are your basic data blobs. All binary fields require special handling and so
|
||||
// need to be enumerated here as an indexed array.
|
||||
public ?array $binFields = null;
|
||||
|
||||
|
||||
// DB SQL:
|
||||
// -------
|
||||
// PDO SQL is stored in the template and is keyed by the current namaste version (defined in the XML file) during
|
||||
// execution of the deployment script. Each version denotes a container of SQL commands that will be executed
|
||||
// for the targeted version.
|
||||
//
|
||||
// SQL is versioned in parallel with the Namaste (XML->application->id->version) version. Each PDO_SQL
|
||||
// sub-container has several fields - one of which has the version identifier. When the deployment script
|
||||
// executes, the release versions are compared and, if they're an exact match, the SQL is submitted for execution.
|
||||
//
|
||||
// The PDO_SQL container consists of these sub-containers:
|
||||
//
|
||||
// PDO_SQL_VERSION --> this is a float value in the form of x.y as namaste only supports versions as a major
|
||||
// and minor release number. (Patch releases are minor release increments.)
|
||||
// PDO_TABLE --> string value containing the full table name.
|
||||
// PDO_SQL_FC --> the FC means "first commit" -- when the table is first created, it will execute the
|
||||
// SQL in this block, if it exists, and if the version number for the sub-container
|
||||
// exactly matched the version number in the configuration XML.
|
||||
// PDO_SQL_UPDATE --> When the sub-container PDO_SQL_VERSION value exactly matches the XML release value,
|
||||
// then the ALTER-TABLE sql in this update block will be executed.
|
||||
// STRING_DROP_CODE_IDX --> The boilerplate code for dropping the indexes of the table.
|
||||
// STRING_DROP_CODE_DEV --> For version 1.0 only, this points to code to drop the entire table.
|
||||
//
|
||||
// Again, containers themselves are indexed arrays under the PDO_SQL tag. Within the container, data is stored
|
||||
// as an associative array with the keys enumerated above.
|
||||
//
|
||||
//
|
||||
// DB OBJECTS:
|
||||
// -----------
|
||||
// DB objects are: views, procedures, functions and events.
|
||||
// All such objects assigned to a class are declared in this array under the appropriate header.
|
||||
// This is a safety-feature that prevents a one class (table) from invoking another class object.
|
||||
// The name of the object is stored as an indexed-array under the appropriate header.
|
||||
//
|
||||
// The format for these structures is basically the same. Each DBO is stored in an associative array with the
|
||||
// key defining the name of the object. Within each object, there are embedded associative arrays that have the
|
||||
// name of the object as the key and the object definition (text) and the value:
|
||||
//
|
||||
// objectType => [ objectName => [ objectContent ], ... ]
|
||||
//
|
||||
// Each created object should also have the directive to remove it's predecessor using a DROP statement.
|
||||
//
|
||||
// todo -- unset these objects post-instantiation so that schema is not revealed
|
||||
//
|
||||
// VIEWS:
|
||||
// ------
|
||||
// Every namaste table will have at least one view which limits the data fetched from the table. At a minimum,
|
||||
// the id_{ext} field is filtered from the resulting data set via the view. Other fields can be withheld as well
|
||||
// but that is something that is individually set-up for each table.
|
||||
//
|
||||
// The basic view has the following syntax for declaring it's name:
|
||||
// view_basic_{tableName_ext}
|
||||
// All views start with the word "view" so as to self-identify the object, followed by the view type which,
|
||||
// optimally, you should try to limit to a single, descriptive word.
|
||||
//
|
||||
// Following this label, which points to a sub-array containing three elements:
|
||||
// STRING_VIEW ----------> this is the SQL code that defines the view as a single string value
|
||||
// STRING_TYPE_LIST -----> null or an array of types that corresponds to variable markers ('?') in the sql
|
||||
// STRING_DESCRIPTION' --> a string that describes the purpose of the view.
|
||||
//
|
||||
// At a minimum, every class definition should contain at-least a basic view as all queries that don't specify
|
||||
// a named view or other DBO, will default to the the basic view in the FROM clause of the generated SQL.
|
||||
//
|
||||
// PROCEDURES:
|
||||
// -----------
|
||||
// For stored procedures, which are entirely optional, the array definition contains the following elements:
|
||||
// STRING_PROCEDURE -------> the SQL code that defined the stored procedure as a single string value
|
||||
// STRING_DROP_CODE -------> the sql code that drops the procedure (required for procedures!)
|
||||
// STRING_TYPE_LIST -------> an associative array of associative arrays -- in the top level, the key is the name
|
||||
// of the parameter that points to a sub-array that contains the parameter direction
|
||||
// as the key, and the parameter type as the value. There should be an entry for each
|
||||
// parameter to be passed to the stored procedure/function.
|
||||
//
|
||||
// ------------------------------------------------------
|
||||
// | NOTE: IN params must precede INOUT and OUT params! |
|
||||
// ------------------------------------------------------
|
||||
//
|
||||
// STRING_SP_EVENT_TYPE ---> Assign one of the DB_EVENT constants to this field to indicate the type of
|
||||
// query the stored-procedure will execute.
|
||||
// NOTE: there is not a defined PDO::PARAM constant for type float: use string.
|
||||
// STRING_DESCRIPTION -----> clear-text definition of the procedure's purpose
|
||||
//
|
||||
// Note that all of these containers are required; empty containers should contain a null placeholder.
|
||||
//
|
||||
// When a stored procedure contains a join of two or more tables/views, the first table listed is considered
|
||||
// to be the "owning" table and the procedure will be declared in the class template for that table, but it will
|
||||
// not be duplicated in other template classes referenced in the join.
|
||||
//
|
||||
public ?array $dbObjects = [
|
||||
PDO_SQL => [
|
||||
[
|
||||
PDO_VERSION => 1.0,
|
||||
PDO_TABLE => 'gaCoolProductRegistrations_prg',
|
||||
PDO_SQL_FC => "
|
||||
--
|
||||
-- Table structure for table `gaCoolProductRegistrations_prg`
|
||||
--
|
||||
|
||||
CREATE TABLE `gaCoolProductRegistrations_prg` (
|
||||
`id_prg` int(10) UNSIGNED NOT NULL,
|
||||
`type_prg` char(16) NOT NULL,
|
||||
`iid_prg` char(64) DEFAULT NULL,
|
||||
`eav_prg` char(16) DEFAULT NULL,
|
||||
`platform_prg` char(32) DEFAULT NULL,
|
||||
`browser_prg` char(32) DEFAULT NULL,
|
||||
`majorVersion_prg` int(11) UNSIGNED DEFAULT NULL,
|
||||
`minorVersion_prg` int(11) UNSIGNED DEFAULT NULL,
|
||||
`isMobile_prg` tinyint(1) DEFAULT NULL,
|
||||
`isTablet_prg` tinyint(1) UNSIGNED DEFAULT NULL,
|
||||
`firstSeen_prg` datetime DEFAULT NULL,
|
||||
`lastSeen_prg` datetime DEFAULT NULL,
|
||||
`token_prg` char(36) DEFAULT NULL,
|
||||
`eventGuid_prg` char(36) DEFAULT NULL,
|
||||
`createdDate_prg` datetime DEFAULT NULL COMMENT 'replaces kinsert_date',
|
||||
`lastAccessedDate_prg` datetime DEFAULT NULL COMMENT 'replaces kupdate_date',
|
||||
`status_prg` varchar(25) DEFAULT NULL,
|
||||
`whCreated_prg` datetime DEFAULT NULL,
|
||||
`whEventGuid_prg` char(36) DEFAULT NULL,
|
||||
`whToken_prg` char(36) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
",
|
||||
PDO_SQL_UPDATE => "
|
||||
--
|
||||
-- Indexes for dumped tables
|
||||
--
|
||||
|
||||
--
|
||||
-- Indexes for table `gaCoolProductRegistrations_prg`
|
||||
--
|
||||
ALTER TABLE `gaCoolProductRegistrations_prg`
|
||||
ADD UNIQUE KEY `whToken_prg` (`whToken_prg`);
|
||||
",
|
||||
/*
|
||||
* example query return:
|
||||
* ---------------------
|
||||
* ALTER TABLE gaTest_tst DROP INDEX gaTest_tst_createdDate_tst_status_tst_index, DROP INDEX
|
||||
* gaTest_tst_lastAccessedDate_tst_index, DROP INDEX testInteger_tst, DROP INDEX
|
||||
* gaTest_tst_eventGuid_tst_index, DROP INDEX testDouble_tst, DROP INDEX testString_tst;
|
||||
*
|
||||
* NOTE:
|
||||
* -----
|
||||
* The sql comment code tag (--) will be removed during mysqlConfig's run time processing
|
||||
*/
|
||||
STRING_DROP_CODE_IDX => "--
|
||||
SELECT CONCAT('ALTER TABLE ', `Table`, ' DROP INDEX ', GROUP_CONCAT(`Index` SEPARATOR ', DROP INDEX '),';' )
|
||||
FROM (
|
||||
SELECT table_name AS `Table`, index_name AS `Index`
|
||||
FROM information_schema.statistics
|
||||
WHERE INDEX_NAME != 'PRIMARY'
|
||||
AND table_schema = 'XXXDROP_DB_NAMEXXX'
|
||||
AND table_name = 'XXXDROP_TABLE_NAMEXXX'
|
||||
GROUP BY `Table`, `Index`) AS tmp
|
||||
GROUP BY `Table`;
|
||||
",
|
||||
STRING_DROP_CODE_DEV => "DROP TABLE IF EXISTS gaCoolProductRegistrations_prg;" // only executed if declared
|
||||
|
||||
]
|
||||
],
|
||||
PDO_VIEWS => [
|
||||
'view_basic_gaWHC1ProductRegistrations' => [
|
||||
STRING_VIEW =>
|
||||
"DROP VIEW IF EXISTS view_basic_gaWHC1ProdRegistrations;
|
||||
CREATE VIEW view_basic_gaWHC1ProdRegistrations_prg AS
|
||||
SELECT type_prg, iid_prg, eav_prg, platform_prg, browser_prg, majorVersion_prg, minorVersion_prg,
|
||||
isMobile_prg, isTablet_prg, firstSeen_prg, lastSeen_prg, eventGUID_prg, createdDate_prg,
|
||||
lastAccessedDate_prg, status_prg, token_prg, whCreated_prg, whEventGuid_prg, whToken_prg
|
||||
FROM gaCoolProductRegistrations_prg;",
|
||||
STRING_TYPE_LIST => null,
|
||||
STRING_DESCRIPTION => 'basic query'
|
||||
],
|
||||
],
|
||||
PDO_PROCEDURES => [],
|
||||
PDO_FUNCTIONS => [],
|
||||
PDO_EVENTS => [],
|
||||
PDO_TRIGGERS => []
|
||||
];
|
||||
|
||||
|
||||
//=================================================================================================================
|
||||
// MIGRATION DECLARATIONS
|
||||
// ----------------------
|
||||
// Data in this section is used to handle migrations -- when we're pulling from legacy tables into the Namaste
|
||||
// framework. See online doc for more info.
|
||||
//
|
||||
// Note -- this section is not supported for WareHouse templates! (all settings should be null or empty)
|
||||
//=================================================================================================================
|
||||
|
||||
/**
|
||||
* The migration map is an associative array that maps the Namaste fields (keys) to the corresponding
|
||||
* (remote) legacy fields in the source table to be migrated to Namaste.
|
||||
*
|
||||
* For example, if we were migrating a mysql table in the legacy production database to Namaste::mongo, then
|
||||
* the keys of the migration map would be the Namaste::mongo->fieldNames and the values would be the mysql
|
||||
* column names in the legacy table.
|
||||
*
|
||||
* If there is a value which cannot be mapped to a key, then set it to null.
|
||||
*
|
||||
* Fields that will be dropped in the migration are not listed as values or as keys.
|
||||
*
|
||||
* This map will only exist in the template object and will never be imported into the class widget.
|
||||
*
|
||||
* This is a required field.
|
||||
*
|
||||
*/
|
||||
public ?array $migrationMap = [
|
||||
PDO_ID => null,
|
||||
PRG_TYPE => 'type',
|
||||
PRG_IID => 'iid',
|
||||
PRG_EAV => 'eav',
|
||||
PRG_PLATFORM => 'platform',
|
||||
PRG_BROWSER => 'browser',
|
||||
PRG_MAJOR_VERSION => 'major_version',
|
||||
PRG_MINOR_VERSION => 'minor_version',
|
||||
PRG_IS_MOBILE => 'is_mobile',
|
||||
PRG_IS_TABLET => 'is_tablet',
|
||||
PRG_FIRST_SEEN => 'first_seen',
|
||||
PRG_LAST_SEEN => 'last_seen',
|
||||
DB_TOKEN => null,
|
||||
DB_EVENT_GUID => null, // generated by broker event
|
||||
DB_CREATED => 'kinsert_date', // epoch time
|
||||
DB_STATUS => null, // record status
|
||||
DB_ACCESSED => 'kupdate_date' // epoch time
|
||||
];
|
||||
|
||||
/*
|
||||
* the migrationSortKey defines the SOURCE field by which the fetch query will be sorted. ALL sort fields are
|
||||
* in ASC order so all we need to list here is the name of the field -- which MUST BE IN THE SOURCE TABLE.
|
||||
*
|
||||
* Populating this field may require preliminary examination of the data - what we want is a field that has
|
||||
* zero NULL values.
|
||||
*
|
||||
* This is a required field.
|
||||
*
|
||||
*/
|
||||
public ?array $migrationSortKey = null;
|
||||
|
||||
/*
|
||||
* The migrationStatusKey defines the status field/column in the source table -- if the user requires that
|
||||
* soft-deleted records not be migrated, then this field must be set. Otherwise, set the value to null.
|
||||
*
|
||||
* The format is in the form of a key-value paired array. The key specifies the name of the column and the value
|
||||
* specifies the "deleted" value that, if found, will cause that row from the SOURCE data to be omitted from the
|
||||
* DESTINATION table.
|
||||
*
|
||||
* e.g.: $migrationStatusKV = [ 'some_field' => 'deleted' ]
|
||||
*
|
||||
* Note that both the key and the value are case-sensitive!
|
||||
*
|
||||
* This is an optional field.
|
||||
*
|
||||
*/
|
||||
public ?array $migrationStatusKV = null;
|
||||
|
||||
// The $migrationSourceSchema defines the remote schema for the source table
|
||||
public $migrationSourceSchema = ''; // or STRING_MONGO
|
||||
|
||||
// The source table in the remote repos (default defined in the XML) must be declared here
|
||||
public $migrationSourceTable = '';
|
||||
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS ARE DISABLED FOR WAREHOUSE CLASS OBJECTS
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
public ?array $wareHouse = null;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 03-23-18 mks CORE-852: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 03-23-18 mks CORE-852: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 03-23-18 mks CORE-852: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
452
classes/templates/gatWarehouse.class.inc
Normal file
452
classes/templates/gatWarehouse.class.inc
Normal file
@@ -0,0 +1,452 @@
|
||||
<?php
|
||||
/**
|
||||
* gatWarehouse -- mongo admin template class
|
||||
*
|
||||
* gatWarehouse is a data-definition file for warehouse meta data - event data about a data warehousing request that,
|
||||
* during and following a warehouse request event, is stored in the wareHouse collection on the Namaste admin service.
|
||||
*
|
||||
* Again, to be crystal clear, this data class stores (progress, completion) data about the warehouse event - it has
|
||||
* nothing to do with the actual warehousing data other than recording the details about the event request.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 04-12-18 mks _INF-188: original coding (version 1)
|
||||
* 11-04-19 mks DB-136: added DB_EVENT_GUID to $indexFields
|
||||
* 01-14-20 mks DB-150: PHP7.4 class member type-casting
|
||||
* 06-01-20 mks ECI-108: support for auth token
|
||||
*
|
||||
*/
|
||||
|
||||
class gatWarehouse
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version - not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_ADMIN; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_CLASS_WAREHOUSE; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_WAREHOUSE; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_MONGO_WAREHOUSE_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = false; // set to true to cache class data
|
||||
public bool $setDeletes = true; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NOT_ENABLED; // set to AUDIT_value constant
|
||||
public bool $setJournaling = false; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = false; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = false; // set to false if the class contains methods
|
||||
public int $cacheTimer = 0; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = true; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you will
|
||||
// need to initialize this member in the constructor (hard-coded)
|
||||
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
MONGO_ID => DATA_TYPE_INTEGER, // sorting by the id is just like sorting by createdDate
|
||||
MWH_SOURCE_URI => DATA_TYPE_STRING, // URI of the data source, if the source is remote
|
||||
MWH_SOURCE_SCHEMA => DATA_TYPE_STRING, // name of the source schema
|
||||
MWH_SOURCE_TABLE => DATA_TYPE_STRING, // name of the source table
|
||||
MWH_DEST_SCHEMA => DATA_TYPE_STRING, // name of the destination schema
|
||||
MWH_DEST_TABLE => DATA_TYPE_STRING, // name of the destination table
|
||||
MWH_QUERY => DATA_TYPE_STRING, // query used to pull the data from source
|
||||
MWH_QUERY_DATA => DATA_TYPE_STRING, // json-ized string of query parameter data
|
||||
MWH_DATE_STARTED => DATA_TYPE_INTEGER, // when the migration started (epoch time)
|
||||
MWH_NUM_RECS_SOURCE => DATA_TYPE_STRING, // number of records in the source table
|
||||
MWH_NUM_RECS_IN_QUERY => DATA_TYPE_INTEGER, // number of records in the (migration/wh) query
|
||||
MWH_NUM_RECS_MOVED => DATA_TYPE_INTEGER, // number of records migrated
|
||||
MWH_NUM_RECS_DROPPED => DATA_TYPE_INTEGER, // number of records that were dropped
|
||||
MWH_DELETE_TYPE => DATA_TYPE_STRING, // should be hard, soft, or none
|
||||
MWH_LAST_REC_WRITTEN => DATA_TYPE_STRING, // json-encoded string of the last record written
|
||||
MWH_DATE_COMPLETED => DATA_TYPE_INTEGER, // when migration completed (epoch time)
|
||||
MWH_STOP_REASON => DATA_TYPE_STRING, // reason why migration failed
|
||||
MWH_ERROR_CAT => DATA_TYPE_ARRAY, // array of errors
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique key (GUID) exposed externally and is REQUIRED
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER // epoch time
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_EVENT_GUID, DB_CREATED, MONGO_ID, MWH_SOURCE_SCHEMA, MWH_SOURCE_URI,
|
||||
MWH_SOURCE_TABLE, MIGRATION_DEST_SCHEMA, MIGRATION_DEST_TABLE, MWH_NUM_RECS_SOURCE, MWH_DATE_STARTED
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_CREATED, DB_TOKEN, MWH_SOURCE_TABLE, DB_STATUS,
|
||||
MWH_DEST_TABLE, MWH_DEST_SCHEMA, MWH_SOURCE_SCHEMA, DB_EVENT_GUID
|
||||
];
|
||||
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = null;
|
||||
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_CREATED => 1,
|
||||
DB_EVENT_GUID => 1,
|
||||
MWH_SOURCE_TABLE => 1,
|
||||
MWH_DEST_TABLE => 1,
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = null;
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
DB_TOKEN => 1 // MONGO_TOKEN should always appear
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null;
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = null;
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
* SubC fields do not need to be indexed.
|
||||
*
|
||||
*/
|
||||
public ?array $subC = null;
|
||||
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_QUALIFIER => null, // query filter for warehousing
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H' // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
];
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 04-12-18 mks _INF-139: original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = NULL_TOKEN;
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 04-12-18 mks _INF-139: original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 04-12-18 mks _INF-139: original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
457
classes/templates/pltDonors.class.inc
Normal file
457
classes/templates/pltDonors.class.inc
Normal file
@@ -0,0 +1,457 @@
|
||||
<?php
|
||||
/** @noinspection PhpUnused */
|
||||
/**
|
||||
* Class pltDonors -- mongo data-template class
|
||||
*
|
||||
* This is the template class for Priceline donors. Priceline fields, as submitted to the SMAX API are defined
|
||||
* as the cache-mapped values s.t. the actual schema remains obfuscated.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-12-20 mks ECI-164: original coding
|
||||
*
|
||||
*/
|
||||
|
||||
class pltDonors
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS PROPERTIES...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int $version = 1; // template version - not the same as the release version
|
||||
public string $service = CONFIG_DATABASE_SERVICE_APPSERVER; // defines the mongo server destination
|
||||
public string $schema = TEMPLATE_DB_MONGO; // defines the storage schema for the class
|
||||
public string $templateClass = TEMPLATE_PL_DONORS; // defines the clear-text template class name
|
||||
public string $collection = COLLECTION_MONGO_PL_DONORS; // sets the collection (table) name
|
||||
public ?string $whTemplate = null; // sets the WH(cool) collection name, null if not wh'd
|
||||
public string $extension = COLLECTION_PL_DONORS_EXT; // sets the extension for the collection
|
||||
public bool $closedClass = true; // set to false to allow partner instantiations
|
||||
public bool $setCache = true; // set to true to cache class data
|
||||
public bool $setDeletes = false; // set to true to allow HARD deletes (otherwise: SOFT)
|
||||
public int $setAuditing = AUDIT_NONDESTRUCTIVE; // set to AUDIT_value constant (nondestructive = reads(yes))
|
||||
public bool $setJournaling = true; // set to true to allow journaling
|
||||
public bool $setUpdates = true; // set to true to allow record updates
|
||||
public bool $setHistory = false; // set to true to enable detailed record history tracking
|
||||
public string $setDefaultStatus = STATUS_ACTIVE; // set the default status for each record
|
||||
public string $setSearchStatus = STATUS_ACTIVE; // set the default search status
|
||||
public bool $setLocking = false; // set to true to enable record locking for collection
|
||||
public bool $setTimers = true; // set to true to enable collection query timers
|
||||
public string $setPKey = DB_TOKEN; // sets the primary key for the collection
|
||||
public bool $setTokens = true; // set to true: adds the idToken field functionality
|
||||
public bool $selfDestruct = true; // set to false if the class contains methods
|
||||
public int $cacheTimer = 300; // number of seconds a tuple will remain in-cache
|
||||
public bool $isGA = false; // set to true is this class is a Namaste internal class
|
||||
public ?string $authToken = null; // if this data class is registered to a partner, you'll
|
||||
// need to initialize this member in the constructor
|
||||
//
|
||||
//
|
||||
// fields: a key-value paired array, defines the field name and the data type for each field. Prior to insertion,
|
||||
// all data is validated for type and membership. Data that does not satisfy these requirements is
|
||||
// silently dropped prior to insertion.
|
||||
public array $fields = [
|
||||
/////// NAMASTE CONSTANTS ////////////////
|
||||
MONGO_ID => DATA_TYPE_INTEGER, // sorting by the id is just like sorting by createdDate
|
||||
DB_TOKEN => DATA_TYPE_STRING, // unique pkey exposed externally and is REQUIRED
|
||||
DB_EVENT_GUID => DATA_TYPE_STRING, // track-back identifier for broker/events
|
||||
DB_CREATED => DATA_TYPE_INTEGER, // epoch time
|
||||
DB_STATUS => DATA_TYPE_STRING, // record status
|
||||
DB_ACCESSED => DATA_TYPE_INTEGER, // epoch time
|
||||
//////////////////////////////////////////
|
||||
PL_CAUSE_TITLE => DATA_TYPE_STRING,
|
||||
PL_CID => DATA_TYPE_STRING,
|
||||
PL_SHARE_DATA_WITH_CAUSE => DATA_TYPE_BOOL,
|
||||
PL_FK => DATA_TYPE_STRING,
|
||||
PL_DONATIONS_TCC => DATA_TYPE_DOUBLE,
|
||||
PL_TOT_DONS => DATA_TYPE_DOUBLE,
|
||||
PL_TRANS_COUNT => DATA_TYPE_INTEGER
|
||||
];
|
||||
|
||||
// protected fields are fields that a client is unable to modify or delete. If a client submits a query that
|
||||
// updates these fields, the query will be rejected (worst case) or the directive to update/delete the field
|
||||
// will be silently dropped (best case). In either way, updating or removing this fields cannot be accomplished.
|
||||
//
|
||||
// Minimally, this array should contain the following fields:
|
||||
// -- DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED
|
||||
// -- the ID field (either PDO_ID or MONGO_ID)
|
||||
// -- DB_WH_CREATED, DB_WH_EVENT_GUID, DB_WH_TOKEN
|
||||
//
|
||||
public ?array $protectedFields = [
|
||||
DB_TOKEN, DB_EVENT_GUID, DB_CREATED, DB_ACCESSED, MONGO_ID
|
||||
];
|
||||
|
||||
// all fields that appear in any of the index declarations must appear in this list as this is the property
|
||||
// that's used in the framework as an authoritative check to qualify discriminant fields as indexes.
|
||||
//
|
||||
// indexes are always declared with the template column name and not the cache-map column name
|
||||
//
|
||||
// warehouse indexes are limited to the original record's created date and the three WH fields only
|
||||
//
|
||||
public array $indexFields = [
|
||||
MONGO_ID, DB_CREATED, DB_STATUS, DB_TOKEN, PL_CID, PL_CAUSE_TITLE, PL_FK
|
||||
];
|
||||
|
||||
// all index names that are explicitly declared in the indexes below must also appear in this array. If there are
|
||||
// no pre-defined index names, then this field should be set to null.
|
||||
//
|
||||
// Note that if you're allowing mysql to generate the index names for you, and if you use a partial index (below)
|
||||
// that references that randomly-generated index name, and that name does not appear in this list, then you will
|
||||
// fail to load that template at run time, every time.
|
||||
//
|
||||
// You have been warned.
|
||||
//
|
||||
public ?array $indexNameList = null;
|
||||
|
||||
// single field index declarations -- since you can have a field in more than one index
|
||||
// (MONGO_ID should NEVER be listed as it's the default single-field index.)
|
||||
// the format for the single-field index declaration is the same format used for all the
|
||||
// index declarations:
|
||||
// [ FIELD_NAME => <SORT-DIRECTION> ] where <SORT_DIR> = [ 1 | -1 ]
|
||||
//
|
||||
// NOTE: if you're going to declare a single column as a property, then do NOT also declare it as a single index!
|
||||
//
|
||||
public ?array $singleFields = [
|
||||
DB_CREATED => -1,
|
||||
PL_CID => 1,
|
||||
PL_CAUSE_TITLE => 1
|
||||
];
|
||||
|
||||
// compound indexes have format of:
|
||||
// [ INDEX-NAME => [ FIELD_NAME => <SORT-DIR>, ... ]]
|
||||
// where INDEX-NAME is a unique string and SORT-DIR = [1|-1]
|
||||
// unless it's for mongoDB -- mongoDB does not use index labels
|
||||
public ?array $compoundIndexes = null;
|
||||
|
||||
// multiKey indexes are indexes on fields that are arrays (not the same as sub-collections) which indexes the
|
||||
// content stored in the array based on the column names.
|
||||
//
|
||||
// mongo, as of 3.4, automatically creates a multi-key index on any field declared as a (sic) index that's
|
||||
// an array. Meaning: we don't need to explicitly create a multi-key index on an array field if that field
|
||||
// is declared as a single-key, compound, or unique index.
|
||||
//
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// NOTES: if you implicitly declare a multi-key index by using the column as a compound-index field, then you
|
||||
// may, at MOST, have one array within the compound index.
|
||||
//
|
||||
// You may NOT declare a multi-key index as a shard key.
|
||||
//
|
||||
// Hashed keys may NOT be multi-key.
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// In other words, if you want to apply an index to ALL of the array element then declare the column as singleField,
|
||||
// or compound, or unique. This will have the multi-key index automagically applied by mongoDB.
|
||||
//
|
||||
// If you want to index a subset of the array, then declare the fields to be indexed by using dot notation:
|
||||
//
|
||||
// [ 'someIndex' => [ arrayColumnName.subField1 => 1, arrayColumnName.subField3 => -1 ... ] ]
|
||||
//
|
||||
// And this will apply the multi-key index property to subField1 and subField3 only.
|
||||
//
|
||||
// multiKey indexes are referenced by an index name in order to remove ambiguity when parsing index-properties
|
||||
// against this and other indexes that may have the same field name. In other words, index-properties that will
|
||||
// be applied to a multiKey index must reference the multiKey index by the index (and not the column) name.
|
||||
//
|
||||
// example:
|
||||
// [ 'mIdx1Test' => [ ARRAY_FIELD_NAME => <1|-1>, ... ]]
|
||||
//
|
||||
public ?array $multiKey = null;
|
||||
|
||||
/*
|
||||
* Valid index-type constants are:
|
||||
* MONGO_INDEX_TYPE_SINGLE
|
||||
* MONGO_INDEX_TYPE_COMPOUND
|
||||
* MONGO_INDEX_TYPE_MULTIKEY
|
||||
*
|
||||
* INDEXES NOT SUPPORTED BY NAMASTE AT THIS TIME:
|
||||
* ----------------------------------------------
|
||||
* geoSpatial
|
||||
* text
|
||||
* hashed
|
||||
*
|
||||
*/
|
||||
|
||||
// =================================================================================================================
|
||||
// INDEX PROPERTIES
|
||||
// ----------------
|
||||
// Index properties are applied to indexes. The supported properties are:
|
||||
// unique, partial and ttl
|
||||
// sparse is not supported because partial
|
||||
//
|
||||
// If a property is not in-use, then you must still declare the property as a class object but the
|
||||
// value of the property will be set to null.
|
||||
//
|
||||
// Sparse property types are not supported in favor of partials.
|
||||
//
|
||||
// =================================================================================================================
|
||||
|
||||
|
||||
// Partial Indexes are supported as of MongoDB 3.2 and replace sparse indexes. Format for declaration is the
|
||||
// column name as an array key, with the value being a sub-array of a mongo operand and a value, all of which is
|
||||
// associated with either an existing column name or index label.
|
||||
//
|
||||
// If an existing column name is used, then that field must be defined (exists) in one of the above index
|
||||
// declarations for single, compound, or multikey indexes.
|
||||
//
|
||||
// Sparse indexes only add the row to the index if the column referenced satisfies the conditions specified
|
||||
// in the query condition (expr2).
|
||||
//
|
||||
// Format:
|
||||
// { expr1 }, { expr2 }
|
||||
// Where:
|
||||
// expr1 is an indexed column and the index direction. e.g.: { created_tst : 1 }
|
||||
// AND
|
||||
// expr2 is the keyword "partialFilterExpression : { [ query ] }
|
||||
// e.g.: { partialFilterExpression : { integer_tst : { $gte : 10 }}
|
||||
//
|
||||
// db.myTable.createIndex({ lastName: -1, firstName : 1 }, { partialFilterExpression : { age : { $gte : 62 }})
|
||||
// The above index would return a list of names (sorted DESC by last name) for people aged 62 or older.
|
||||
//
|
||||
//
|
||||
public ?array $partialIndexes = null;
|
||||
|
||||
// unique indexes cause MongoDB to reject duplicate values for the indexed field. Unique indexes
|
||||
// are functionally interchangeable with other mongo indexes.
|
||||
// Format:
|
||||
// [ < FIELD_NAME | INDEX-NAME > => <SORT_DIR>, ... ]
|
||||
//
|
||||
public ?array $uniqueIndexes = [
|
||||
DB_TOKEN => 1, // MONGO_TOKEN should always appear
|
||||
PL_FK => 1 // foreign key value should be unique b/c key
|
||||
];
|
||||
|
||||
// ttl indexes contain the column name and the time-to-live in seconds (e.g.: MONGO_TOKEN => 3600)
|
||||
// ttl indexes can only be applied to fields that are MongoDB Date() (object) types, or an array that
|
||||
// contains date values.
|
||||
//
|
||||
// If the field is an array, and there are multiple date values in the index, MongoDB uses lowest
|
||||
// (i.e. earliest) date value in the array to calculate the expiration threshold. If the indexed
|
||||
// field in a document is not a date or an array that holds a date value(s), the document will not expire.
|
||||
//
|
||||
// Format:
|
||||
// [ SOME_FIELD_NAME => ExpireVal ]
|
||||
//
|
||||
// Example:
|
||||
// [ SOME_FIELD_NAME => 86400 ] --- record will be sorted ASC and deleted after 1 day
|
||||
//
|
||||
public ?array $ttlIndexes = null; // ttl indexes appear in $indexFields
|
||||
|
||||
// cache maps are requires for namaste service classes. Even if caching is disabled for a class, a cache map is
|
||||
// still required for the class. For PDO classes, the PDO_ID is never included in the mapping, nor is MONGO_ID.
|
||||
public ?array $cacheMap = [
|
||||
///////// NAMASTE CONSTANTS //////////////
|
||||
DB_TOKEN => CM_TST_TOKEN, //
|
||||
DB_STATUS => CM_TST_FIELD_TEST_STATUS, //
|
||||
DB_EVENT_GUID => CM_TST_EVENT_GUID, //
|
||||
DB_CREATED => CM_TST_FIELD_TEST_CDATE, //
|
||||
DB_ACCESSED => CM_TST_FIELD_TEST_ADATE, //
|
||||
//////////////////////////////////////////
|
||||
PL_CID => PL_CM_CID,
|
||||
PL_CAUSE_TITLE => PL_CM_CAUSE_TITLE,
|
||||
PL_DONATIONS_TCC => PL_CM_DTCC,
|
||||
PL_FK => PL_CM_FK,
|
||||
PL_SHARE_DATA_WITH_CAUSE => PL_CM_SDWC,
|
||||
PL_TOT_DONS => PL_CM_TD,
|
||||
PL_TRANS_COUNT => PL_CM_TC
|
||||
];
|
||||
|
||||
/*
|
||||
* if there is no cache-mapping supported for the class, and you want to limit the fields returned,
|
||||
* then those fields are listed here as an associative array.
|
||||
*
|
||||
* NOTE: You can have caching disabled for the class and still have a cache-map -- this controls the labels
|
||||
* assigned to the returned data column names exposed to the client. Schema should never be exposed.
|
||||
*
|
||||
* NOTE: if you do not support caching for the class and this class is one that is returned to a client,
|
||||
* (some classes are limited to internal use only, like logging), then you should (at a minimum)
|
||||
* exclude the primary key field (integer).
|
||||
*
|
||||
*
|
||||
* This array is an associative array -- the key is the native column name and the value doesn't matter. The
|
||||
* important thing is that the keys are the column names that you want to return back to the client.
|
||||
*
|
||||
* If $exposedFields is to be undefined for the class, then assign it to null.
|
||||
*
|
||||
*/
|
||||
public ?array $exposedFields = null;
|
||||
|
||||
public ?array $binFields = null; // binary fields require special handling; define binary fields here
|
||||
|
||||
// regex fields -- within the indexFields array, which fields enable regex searches?
|
||||
// this does not define an index, but rather to control when to use a regex operand in a query...
|
||||
public ?array $regexFields = null;
|
||||
|
||||
/*
|
||||
* sub-collections represent the implementation of a 1:M relationship at the record-entity level in mongoDB.
|
||||
*
|
||||
* A great example of a sub-collection implementation would be a parent collection called questions and
|
||||
* a sub-collection called answers.
|
||||
*
|
||||
* sub-collections are declared as key->value pairs where each key value is, itself, an array of field names:
|
||||
*
|
||||
* public $subC = [
|
||||
* FIELD_ONE => [
|
||||
* SUB_COLLECTION_FIELD_ONE,
|
||||
* SUB_COLLECTION_FIELD_TWO,
|
||||
* ...
|
||||
* ],
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* Each sub-collection field should also appear in both the fields list (to define the types), and in the
|
||||
* cacheMap (if used). If you're not using a cacheMap, and you're limiting the exposed fields, then each
|
||||
* sub-collection field exposed must be listed in the exposed field list. (e.g.: normal rules for exposure
|
||||
* for a collection are applied the same way to a sub-collection.)
|
||||
*
|
||||
* Note that if a sub-Collection key is not listed in either the cacheMap or the exposed field list, then
|
||||
* the entire sub-collection will be invisible to the client. If you list the sub-collection key, you can
|
||||
* limit the sub-collection fields that are exposed by not listing them in either the cacheMap or the
|
||||
* exposed-field lists, respectively.
|
||||
*
|
||||
* Sub-collections are managed within Namaste to allow the sub-collection elements to be either inserted,
|
||||
* or deleted (an update is a delete + insert) without changing the parent field values and, accordingly,
|
||||
* are enabled via discrete class methods.
|
||||
*
|
||||
*/
|
||||
// sub-collection fields must be declared here (need not be indexed)
|
||||
public ?array $subC = null;
|
||||
|
||||
//=================================================================================================================
|
||||
// WAREHOUSE DECLARATIONS
|
||||
// ----------------------
|
||||
// This section handles the warehousing configuration for the class. If a data table is eligible to be ware-
|
||||
// housed, then this section contains all the configuration information, including permissions, for the destination
|
||||
// repository. Note that we need to support bi-directional flow for data.
|
||||
//
|
||||
// Terms/Definitions:
|
||||
// ------------------
|
||||
// HOT -- data is in production
|
||||
// COOL -- data has been warehoused, maintains schema, but with indexing changes.
|
||||
// COLD -- data has been warehoused but formatted to the destination schema, usually CSV.
|
||||
// WARM -- indicates any data moving from COLD -> HOT
|
||||
//
|
||||
// Design Features:
|
||||
// ----------------
|
||||
// Supported
|
||||
// This is a boolean value that indicates if the class supports warehousing. If this is set to false, then
|
||||
// warehousing requests for the class will be rejected.
|
||||
//
|
||||
// Remote Support
|
||||
// --------------
|
||||
// This is a boolean value that indicates if the class will support a warehouse source outside of the Namaste
|
||||
// framework. If this is set to false, and a user submits a request defining the data source as a remote
|
||||
// repository, the request will be rejected.
|
||||
//
|
||||
// Automated
|
||||
// This is a boolean value that indicates if the class allows automated warehousing, meaning that data will be
|
||||
// warehoused once the qualifying condition has been met.
|
||||
//
|
||||
// Dynamic
|
||||
// Boolean value that, if set to true, indicates that the class will accept dynamic requests. Otherwise, the
|
||||
// warehousing operations will follow the interval schedule. Defaults to false.
|
||||
//
|
||||
// Interval
|
||||
// This is a string value that tells the AT_micro-service how often to run automated warehousing on the data.
|
||||
// D = Daily, M = 1st of every month, Q = 1st of every quarter, Y = 1st of every year
|
||||
// The default setting for this value should be monthly (M).
|
||||
//
|
||||
// Qualifier
|
||||
// This is a query string, similar to what you would provide to Namaste for a fetch operation, that establishes
|
||||
// the filter/criteria for moving data to the warehouse. If Supported is set to true, this cannot be blank.
|
||||
//
|
||||
// Override
|
||||
// Boolean value indicating if, and only for dynamic event requests, if the Qualifier can be overridden. If
|
||||
// set to true, the the event request must contain a valid query filter.
|
||||
//
|
||||
// Delete
|
||||
// This is a string value that tells Namaste what to do with the source data once successfully warehoused.
|
||||
// H = hard delete, S = soft delete
|
||||
// Note that this value overrides the $setDeletes setting.
|
||||
//
|
||||
//=================================================================================================================
|
||||
|
||||
public ?array $wareHouse = [
|
||||
WH_SUPPORTED => false, // must be set to true for data class to support any warehousing
|
||||
WH_REMOTE_SUPPORT => false, // must be set to true to import data into this class from remote source
|
||||
WH_AUTOMATED => false, // must be set to true for warehousing to be automatically processed
|
||||
WH_DYNAMIC => false, // must be set to true to allow non-scheduled event requests
|
||||
WH_INTERVAL => 'M', // must be either D, M, Q or A, defaults to M
|
||||
WH_OVERRIDE => false, // must be set to true to allow an ad-hoc query filter
|
||||
WH_DELETE => 'H', // must be either H, or S. Can be reset to T via meta. Default: H
|
||||
|
||||
// default warehouse query to grab records where the date is LT a value and the status is active:
|
||||
// the null value will be replaced with the value provided by the client in the wh request payload.
|
||||
WH_QUALIFIER => [
|
||||
DB_CREATED => [OPERAND_NULL => [OPERATOR_LT => [null]]],
|
||||
DB_STATUS => [OPERAND_NULL => [OPERATOR_EQ => [STATUS_ACTIVE]]],
|
||||
OPERAND_AND => null
|
||||
]
|
||||
];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS...
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* we have a constructor to register the destructor.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-12-20 mks ECI-164: Original coding
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authToken = '136EA67A-B1E2-0A4B-2BD8-EE34D39DFDE1'; // make sure this exists in the SMAX_API collection
|
||||
register_shutdown_function([$this, STRING_DESTRUCTOR]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __clone() -- private function
|
||||
*
|
||||
* Silently disallows cloning of the object
|
||||
*
|
||||
* @return null
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-12-20 mks ECI-164: Original coding
|
||||
*
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* __destruct() -- public function
|
||||
*
|
||||
* As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
*
|
||||
* The destructor is registered as a shut-down function in the constructor -- so any recovery
|
||||
* efforts should go in this method.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-12-20 mks ECI-164: Original coding
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
// empty method
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user