952 days continuous production uptime, 40k+ tp/s single node. Original corpo Bitbucket history not included — clean archive commit.
316 lines
13 KiB
Plaintext
316 lines
13 KiB
Plaintext
/**
|
|
* convertCacheMapDataToSchema() -- protected method
|
|
*
|
|
* this method takes an input array of payload data and checks to see if the current-loaded class has cacheMapping
|
|
* set (the cacheMap element has to be an array) and uses the map to convert the data from the public (cachemap)
|
|
* to private (schema) format.
|
|
*
|
|
* method requires two input parameters:
|
|
*
|
|
* - the payload data - which is a indexed array of associative array tuples
|
|
* - boolean toggle indicating if ALL fields are required to pass validation
|
|
*
|
|
* If the current class has cacheMapping, then we're going to spin through each tuple in the $_data parameter
|
|
* and look at each $key in the tuple -- if the $key exists as a member in the cacheMap, pull the key from cacheMap
|
|
* and store the new key and the old value in a temp array. If the key does not exist in the cacheMap then
|
|
* use the current (old) key/value pair.
|
|
*
|
|
* After each tuple is processed,copy the new vector in to a temporary matrix which will eventually be returned
|
|
* to the calling client.
|
|
*
|
|
* in all other (fail) cases, a null is returned.
|
|
*
|
|
* NOTE:
|
|
* -----
|
|
* This method is not to be confused with gasCache->buildMappedDataArray() which converts schema to cacheMap.
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
* @param array $_data
|
|
* @param bool $_allFields
|
|
* @return null|array
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 07-13-17 mks CORE-464: original coding
|
|
* 02-06-18 mks _INF-139: support for disabled caching + no cache map
|
|
* 02-22-18 mks _INF-139: when cache is disabled, need to verify that submitted data included the class
|
|
* extension - if not, replace the old key with the old key + class extension
|
|
* 12-12-18 mks DB-77: fixed error in processing: when we have a journal recovery event, the restore
|
|
* query uses column literals instead of cache-mapped values. Added conditional code
|
|
* to check if the literal appears in the field list and, if so, validate that field
|
|
*/
|
|
protected function convertCacheMapDataToSchema(array $_data, bool $_allFields = false): ?array
|
|
{
|
|
$this->state = STATE_VALIDATION_ERROR;
|
|
$this->status = false;
|
|
$data = false;
|
|
$badData = false;
|
|
|
|
$loggerAvailable = (isset($this->logger) and $this->logger->available);
|
|
|
|
if (!is_array($_data)) {
|
|
$msg = basename(__METHOD__) . AT . __LINE__ . COLON . ERROR_DATA_INVALID_FORMAT;
|
|
if ($loggerAvailable)
|
|
$this->logger->data($msg);
|
|
else
|
|
consoleLog($this->res, CON_ERROR, $msg);
|
|
$this->eventMessages[] = $msg;
|
|
} elseif ($this->useCache and empty($this->cacheMap)) {
|
|
$msg = ERROR_CACHE_MAP_404 . COLON . $this->class;
|
|
if ($loggerAvailable)
|
|
$this->logger->data($msg);
|
|
else
|
|
consoleLog($this->res, CON_ERROR, $msg);
|
|
$this->eventMessages[] = $msg;
|
|
} elseif (!$this->useCache and (!isset($this->cacheMap) or empty($this->cacheMap))) {
|
|
$data = $_data[0];
|
|
foreach ($data as $key => $value) {
|
|
try {
|
|
$newKey = $this->addExtension($key);
|
|
} catch (TypeError $t) {
|
|
$msg = ERROR_TYPE_EXCEPTION . COLON . $t->getMessage();
|
|
if ($loggerAvailable)
|
|
$this->logger->error($msg);
|
|
else
|
|
consoleLog($this->res, CON_ERROR, $msg);
|
|
$this->eventMessages[] = $msg;
|
|
return null;
|
|
}
|
|
if (is_null($newKey)) return null;
|
|
if ($newKey != $key) {
|
|
$data[$newKey] = $value;
|
|
unset($data[$key]);
|
|
}
|
|
}
|
|
$this->state = STATE_SUCCESS;
|
|
$this->status = true;
|
|
return [$data];
|
|
} else {
|
|
$counter = 0;
|
|
for ($index = 0, $last = count($_data); $index < $last; $index++) {
|
|
$row = null;
|
|
foreach ($_data[$index] as $key => $value) {
|
|
$ck = array_search($key, $this->cacheMap);
|
|
if (false === $ck) {
|
|
$ck = array_key_exists($key, $this->cacheMap);
|
|
/*
|
|
* edge case - this case will be encountered in situations where we're using non-cache-mapped
|
|
* keys (e.g.: column literals) in a cached-class query where there exists a cache-map.
|
|
* Journaling saves the recovery query in literal (as opposed to cache-mapped) format... so, we
|
|
* need to accommodate the possibility where the data keys exist only in the $fieldList member
|
|
* and, if so, treat the keys as valid values once we've exhausted cache-map processing
|
|
*/
|
|
if (false === $ck) { // check to see if key is member of $fieldList
|
|
// first - see if we have an extension appended to the key - if not, add one
|
|
$newKey = $this->addExtension($key);
|
|
// then, check if the qualified key exists in the fieldList - if so, update the value of $ck
|
|
$ck = (in_array($newKey, $this->fieldList)) ? $newKey : false;
|
|
}
|
|
if (false === $ck) {
|
|
$msg = ERROR_DATA_INVALID_KEY . $key;
|
|
$this->eventMessages[] = $msg;
|
|
if ($loggerAvailable)
|
|
$this->logger->data($msg);
|
|
else
|
|
consoleLog($this->res, CON_ERROR, $msg);
|
|
if ($_allFields) $badData = true;
|
|
$ck = $key;
|
|
}
|
|
}
|
|
if (is_array($value) and !empty($this->subCollections) and array_key_exists($ck, $this->subCollections)) {
|
|
try {
|
|
$value = $this->convertCacheMapDataToSchema($value);
|
|
} catch (TypeError $t) {
|
|
$msg = ERROR_TYPE_EXCEPTION . COLON . $t->getMessage();
|
|
if ($loggerAvailable)
|
|
$this->logger->error($msg);
|
|
else
|
|
consoleLog($this->res, CON_ERROR, $msg);
|
|
return null;
|
|
}
|
|
if (false === $value) {
|
|
$msg = sprintf(ERROR_SUB_C_V_NULL, $ck);
|
|
$this->logger->warn($msg);
|
|
$this->eventMessages[] = $msg;
|
|
}
|
|
}
|
|
if (false !== $ck) $row[$ck] = $value;
|
|
}
|
|
if (!empty($row)) $data[$counter++] = $row;
|
|
}
|
|
if (($_allFields and !$badData and is_array($data)) or (!$_allFields and is_array($data))) {
|
|
$this->state = STATE_SUCCESS;
|
|
$this->status = true;
|
|
}
|
|
}
|
|
return( ($this->status) ? $data : null );
|
|
}
|
|
|
|
NOTE: dataScrub() wasn't deprecated, just eviscerated...
|
|
|
|
/**
|
|
* dataScrub() -- private method
|
|
*
|
|
* this method parses all of the data stored in the protected $data member and replaces keys with cleaned values
|
|
* (extensions stripped from keys) and critical values removed entirely.
|
|
*
|
|
* $_data -- call-by-reference variable that's the implicitly returned
|
|
*
|
|
* While processing the data rows, we make a recursive call back to this method if we encounter sub-arrays so
|
|
* that the sub-array keys can be stripped (method 1 only!) also.
|
|
*
|
|
* When generating the return data, for every row of data, we check each column to ensure it's not listed in the
|
|
* $hiddenColumns member array and, if it is, we remove it.
|
|
*
|
|
* For nosql-based collections, if we specify that we want the meta data, then we'll return the history
|
|
* sub-collection (aka meta data) so if meta isn't specified, the meta is dropped from the return set.
|
|
*
|
|
* There are no errors raised in this method. The success is implicitly defined in the $_data return structure.
|
|
*
|
|
* NOTE:
|
|
* =====
|
|
* Cache-Key Mapping is located in the private static method gasCache::buildMappedDataArray().
|
|
*
|
|
*
|
|
* @author mikegivingassistant.org
|
|
* @version 1.0
|
|
*
|
|
* @param $_data
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 06-22-17 mks original coding
|
|
* 08-14-17 mks CORE-493: removing meta param support (DB_HISTORY no longer supported)
|
|
*
|
|
*/
|
|
private function dataScrub(array &$_data): void
|
|
{
|
|
if (empty($_data)) {
|
|
$msg = ERROR_DATA_MISSING_ARRAY . STRING_DATA;
|
|
$this->eventMessages[] = $msg;
|
|
if (isset($this->logger) and $this->logger->available)
|
|
$this->logger->error($msg);
|
|
else
|
|
consoleLog($this->res, CON_ERROR, $msg);
|
|
return;
|
|
}
|
|
/*
|
|
* if we're requesting a clean data set, and we've not requested a key-mapping, then
|
|
* clean the data "old-school" style, stripping off extensions, pulling the mongo ID
|
|
* fields, in the return data set.
|
|
*/
|
|
for ($index = 0, $last = count($_data); $index < $last; $index++) {
|
|
if (!empty($_data[$index]) and is_array($_data[$index])) {
|
|
foreach ($_data[$index] as $key => $value) {
|
|
$newKey = str_replace($this->ext, '', $key);
|
|
if (is_array($value)) {
|
|
try {
|
|
$this->dataScrub($value);
|
|
} catch (TypeError $t) {
|
|
$msg = basename(__METHOD__) . AT . __LINE__ . COLON . ERROR_TYPE_EXCEPTION . COLON . $t->getMessage();
|
|
$this->eventMessages[] = $msg;
|
|
if (isset($this->logger) and $this->logger->available)
|
|
$this->logger->error($msg);
|
|
else
|
|
consoleLog($this->res, CON_ERROR, $msg);
|
|
}
|
|
return;
|
|
}
|
|
if ($newKey != $key and !in_array($newKey, $this->hiddenColumns)) {
|
|
$_data[$index][$newKey] = $value;
|
|
unset($_data[$index][$key]);
|
|
} elseif (in_array($newKey, $this->hiddenColumns)) {
|
|
unset($_data[$index][$key]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* cmData() -- public function
|
|
*
|
|
* This public function is a dirty little way to stuff whatever data is defined in $_payload to replace whatever
|
|
* is stored in the protected member: $data.
|
|
*
|
|
* The only requirement is that the input parameter be an array.
|
|
*
|
|
* The purpose of this method is to store the cacheMap key(s) into the $data payload right before the broker
|
|
* event, that generated the data payload, finished processing an releases the class memory assigned to the object.
|
|
*
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
* @param array $_payload
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 03-04-19 mks DB-116: original coding
|
|
*
|
|
*/
|
|
public function cmData(array $_payload): void
|
|
{
|
|
$this->data = $_payload;
|
|
}
|
|
|
|
|
|
/**
|
|
* dumpRecord() -- public core method
|
|
*
|
|
* Sometimes, you need to know what's in the $data payload and, since it's protected, you can't access it directly
|
|
* without going through one of the other methods that filters the payload.
|
|
*
|
|
* This method allows you to dump a row of data from the $data array to stdout. If you don't specify a row (as
|
|
* the only input parameter, then you will dump the first (0th) row in the array. However, if the array is empty,
|
|
* we'll out a message to that effect.
|
|
*
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
* @param int $_row
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 10-24-18 mks DB-67: original coding
|
|
*
|
|
*
|
|
*/
|
|
public function dumpRecord(int $_row = 0): void
|
|
{
|
|
if (empty($this->data))
|
|
echo INFO_NO_DATA_IN_DATA;
|
|
else
|
|
var_export($this->data[$_row]);
|
|
}
|
|
|
|
/**
|
|
* validateStatus() -- public method
|
|
*
|
|
* Simple method that takes a single input parameter, a string, and returns a boolean value corresponding to
|
|
* whether or not the string-value is present in the validStatus member array.
|
|
*
|
|
*
|
|
* @author mike@givingassistant.org
|
|
* @version 1.0
|
|
*
|
|
* @param string $_status
|
|
* @return bool
|
|
*
|
|
*
|
|
* HISTORY:
|
|
* ========
|
|
* 02-12-18 mks _INF-139: original coding
|
|
*
|
|
*/
|
|
public function validateStatus(string $_status): bool
|
|
{
|
|
return (in_array($_status, $this->validStatus));
|
|
}
|