Compare commits
4
Commits
2bb405d741
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68ea44964f | ||
|
|
369f2e2586 | ||
|
|
3a33f07ae7 | ||
|
|
0b057864ae |
@@ -421,6 +421,100 @@ final class CoreLibsCreateHashTest extends TestCase
|
||||
'hash hmac valid'
|
||||
);
|
||||
}
|
||||
|
||||
// MARK: generateImmutableHashForArray
|
||||
|
||||
/**
|
||||
* Data provider for testGenerateImmutableHashForArray.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function generateImmutableHashForArrayProvider(): array
|
||||
{
|
||||
return [
|
||||
'Empty array' => [
|
||||
[],
|
||||
null,
|
||||
'064f01fe',
|
||||
],
|
||||
'Simple array' => [
|
||||
['key' => 'value'],
|
||||
null,
|
||||
'78f40899',
|
||||
],
|
||||
'flat array a' => [
|
||||
[0, 1, 'b', 'c', 'a'],
|
||||
null,
|
||||
'ccec0f5b',
|
||||
],
|
||||
'flat array b' => [
|
||||
['b', 'c', 'a', 1, 0],
|
||||
null,
|
||||
'c6040f5b',
|
||||
],
|
||||
'flat array b, not sorted' => [
|
||||
['b', 'c', 'a', 1, 0],
|
||||
false,
|
||||
'c6040f5b',
|
||||
],
|
||||
'key array a' => [
|
||||
['A' => 0, 'F' => 1, 'C' => 'b', 'K' => 'c', 'B' => 'a'],
|
||||
null,
|
||||
'01f11355',
|
||||
],
|
||||
'key array a, not sorted' => [
|
||||
['A' => 0, 'F' => 1, 'C' => 'b', 'K' => 'c', 'B' => 'a'],
|
||||
false,
|
||||
'04911355',
|
||||
],
|
||||
'key array b' => [
|
||||
['A' => 0, 'B' => 'a', 'C' => 'b', 'F' => 1, 'K' => 'c'],
|
||||
null,
|
||||
'01f11355',
|
||||
],
|
||||
'key array b, not sorted' => [
|
||||
['A' => 0, 'B' => 'a', 'C' => 'b', 'F' => 1, 'K' => 'c'],
|
||||
false,
|
||||
'01f11355',
|
||||
],
|
||||
'complex nested array' => [
|
||||
[
|
||||
'level1' => [
|
||||
'level2' => [
|
||||
'level3' => 'value'
|
||||
]
|
||||
]
|
||||
],
|
||||
null,
|
||||
'd8de1565',
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for generating an immutable hash from an array.
|
||||
*
|
||||
* @covers ::generateImmutableHashForArray
|
||||
* @dataProvider generateImmutableHashForArrayProvider
|
||||
* @testdox generate immutable hash for array with result $expected [$_dataName]
|
||||
*
|
||||
* @param array<mixed> $input
|
||||
* @param string $expected
|
||||
*/
|
||||
public function testGenerateImmutableHashForArray(array $input, ?bool $sort_keys, string $expected): void
|
||||
{
|
||||
if ($sort_keys === null) {
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
\CoreLibs\Create\Hash::generateImmutableHashForArray($input)
|
||||
);
|
||||
} else {
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
\CoreLibs\Create\Hash::generateImmutableHashForArray($input, $sort_keys)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
|
||||
@@ -1007,6 +1007,59 @@ final class CoreLibsDBIOTest extends TestCase
|
||||
$db->dbClose();
|
||||
}
|
||||
|
||||
// MARK: stripAssocOnly
|
||||
|
||||
/**
|
||||
* Data provider for stripAssocOnly tests
|
||||
*
|
||||
* @return array<mixed>
|
||||
*/
|
||||
public function stripAssocOnlyProvider(): array
|
||||
{
|
||||
return [
|
||||
'empty' => [
|
||||
[],
|
||||
[]
|
||||
],
|
||||
'int only' => [
|
||||
[0 => 'foo', 1 => 'bar'],
|
||||
[],
|
||||
],
|
||||
'mixed' => [
|
||||
[0 => 'foo', 'col_a' => 'foo', 1 => 'bar', 'col_b' => 'bar'],
|
||||
['col_a' => 'foo', 'col_b' => 'bar'],
|
||||
],
|
||||
'key only' => [
|
||||
['col_a' => 'foo', 'col_b' => 'bar'],
|
||||
['col_a' => 'foo', 'col_b' => 'bar'],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for stripAssocOnly function
|
||||
*
|
||||
* @covers ::stripAssocOnly
|
||||
* @dataProvider stripAssocOnlyProvider
|
||||
* @testdox strip assoc non string entries from return [$_dataName]
|
||||
*
|
||||
* @param array<mixed> $input
|
||||
* @param array<string,mixed> $expected
|
||||
* @return void
|
||||
*/
|
||||
public function testStripAssocOnly(array $input, array $expected): void
|
||||
{
|
||||
$db = new \CoreLibs\DB\IO(
|
||||
self::$db_config['valid'],
|
||||
self::$log
|
||||
);
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
$db->stripAssocOnly($input)
|
||||
);
|
||||
$db->dbClose();
|
||||
}
|
||||
|
||||
// - string escape tests
|
||||
// dbEscapeString, dbEscapeLiteral, dbEscapeIdentifier,
|
||||
|
||||
|
||||
@@ -342,38 +342,6 @@ print "(ksort): " . DgS::printAr(ArrayHandler::ksortArray($nested)) . "<br>";
|
||||
|
||||
print "<hr>";
|
||||
|
||||
$search_array = [
|
||||
'table_lookup' => [
|
||||
'match' => [
|
||||
['param' => 'access_d_cd', 'data' => 'a_cd', 'time_validation' => 'on_load',],
|
||||
['param' => 'other_block', 'data' => 'b_cd'],
|
||||
['pflaume' => 'other_block', 'data' => 'c_cd'],
|
||||
['param' => 'third_block', 'data' => 'd_cd', 'time_validation' => 'cool'],
|
||||
['special' => 'other_block', 'data' => 'e_cd', 'time_validation' => 'other'],
|
||||
]
|
||||
]
|
||||
];
|
||||
print "Search: " . DgS::printAr($search_array) . "<br>";
|
||||
print "Result (all): " . Dgs::printAr(ArrayHandler::findArraysMissingKey(
|
||||
$search_array,
|
||||
'other_block',
|
||||
'time_validation'
|
||||
)) . "<br>";
|
||||
print "Result (key): " . Dgs::printAr(ArrayHandler::findArraysMissingKey(
|
||||
$search_array,
|
||||
'other_block',
|
||||
'time_validation',
|
||||
'pflaume'
|
||||
)) . "<br>";
|
||||
print "Result (key): " . Dgs::printAr(ArrayHandler::findArraysMissingKey(
|
||||
$search_array,
|
||||
'other_block',
|
||||
['data', 'time_validation'],
|
||||
'pflaume'
|
||||
)) . "<br>";
|
||||
|
||||
print "<hr>";
|
||||
|
||||
$search_array = [
|
||||
'a' => [
|
||||
'lookup' => 1,
|
||||
@@ -528,6 +496,45 @@ $result = ArrayHandler::selectArrayFromOption(
|
||||
);
|
||||
print "*2*Result: " . DgS::printAr($result) . "<br>";
|
||||
|
||||
print "<hr>";
|
||||
|
||||
$search_array = [
|
||||
'table_lookup' => [
|
||||
'match' => [
|
||||
['param' => 'access_d_cd', 'data' => 'a_cd', 'time_validation' => 'on_load',],
|
||||
['param' => 'other_block', 'data' => 'b_cd'],
|
||||
['pflaume' => 'other_block', 'data' => 'c_cd'],
|
||||
['param' => 'third_block', 'data' => 'd_cd', 'time_validation' => 'cool'],
|
||||
['special' => 'other_block', 'data' => 'e_cd', 'time_validation' => 'other'],
|
||||
]
|
||||
]
|
||||
];
|
||||
print "Search: " . DgS::printAr($search_array) . "<br>";
|
||||
print "Result (all, search single): " . DgS::printAr(ArrayHandler::findArraysMissingKey(
|
||||
$search_array,
|
||||
'other_block',
|
||||
'time_validation'
|
||||
)) . "<br>";
|
||||
print "Result (key limit): " . DgS::printAr(ArrayHandler::findArraysMissingKey(
|
||||
$search_array,
|
||||
'other_block',
|
||||
'time_validation',
|
||||
'pflaume'
|
||||
)) . "<br>";
|
||||
print "Result (all, search array): " . DgS::printAr(ArrayHandler::findArraysMissingKey(
|
||||
$search_array,
|
||||
'other_block',
|
||||
['data', 'time_validation'],
|
||||
)) . "<br>";
|
||||
print "Result (key limit, search array): " . DgS::printAr(ArrayHandler::findArraysMissingKey(
|
||||
$search_array,
|
||||
'other_block',
|
||||
['data', 'time_validation'],
|
||||
'pflaume'
|
||||
)) . "<br>";
|
||||
|
||||
print "<hr>";
|
||||
|
||||
print "</body></html>";
|
||||
|
||||
// __END__
|
||||
|
||||
@@ -103,6 +103,20 @@ foreach ($hash_types as $hash_type) {
|
||||
// print "UNIQU ID SHORT : " . Hash::__uniqId() . "<br>";
|
||||
// print "UNIQU ID LONG : " . Hash::__uniqIdLong() . "<br>";
|
||||
|
||||
$tests = [
|
||||
// array diff
|
||||
[0, 1, 'b', 'c', 'a'],
|
||||
['b', 'c', 'a', 1, 0],
|
||||
// key set arrays DO NOT diff
|
||||
['A' => 0, 'F' => 1, 'C' => 'b', 'K' => 'c', 'B' => 'a'],
|
||||
['A' => 0, 'B' => 'a', 'C' => 'b', 'F' => 1, 'K' => 'c'],
|
||||
];
|
||||
foreach ($tests as $test) {
|
||||
print "IMMUTABLE HASH FOR ARRAY: " . Hash::generateImmutableHashForArray($test) . "<br>";
|
||||
print "IMMUTABLE HASH FOR ARRAY: " . Hash::generateImmutableHashForArray($test, sort_keys:false) . "<br>";
|
||||
print "SERIALIZED HASH FOR ARRAY: " . hash(Hash::DEFAULT_HASH, serialize($test)) . "<br>";
|
||||
}
|
||||
|
||||
print "</body></html>";
|
||||
|
||||
// __END__
|
||||
|
||||
@@ -248,12 +248,15 @@ class ArrayHandler
|
||||
* If not found return an array with the array block there the required key is missing,
|
||||
* the path as string with seperator block set and the missing key entry
|
||||
*
|
||||
* @param array<mixed> $in_array
|
||||
* @param string|int|float|bool $search_value
|
||||
* @param string|array<string> $required_key
|
||||
* @param ?string $search_key [null]
|
||||
* @param string $path_separator [DATA_SEPARATOR]
|
||||
* @param string $current_path
|
||||
* alternate to findArraysWithMissingKey (single missing key)
|
||||
*
|
||||
* @param array<mixed> $in_array Array to search in
|
||||
* @param string|int|float|bool $search_value Value that must be set in any
|
||||
* (or with search_key in one entry of the array)
|
||||
* @param string|array<string> $required_key Key or Keys that must be set
|
||||
* @param ?string $search_key [null] limit search_value check to this key
|
||||
* @param string $path_separator [DATA_SEPARATOR] For the path string separator
|
||||
* @param string $current_path [''] Current path in the array (used for recursion)
|
||||
* @return array<array{content?:array<mixed>,path?:string,missing_key?:array<string>}>
|
||||
*/
|
||||
public static function findArraysMissingKey(
|
||||
@@ -272,14 +275,14 @@ class ArrayHandler
|
||||
// Check if this array contains the search value
|
||||
// either any value match or with key
|
||||
if ($search_key === null) {
|
||||
$containsValue = in_array($search_value, $value, true);
|
||||
$contains_value = in_array($search_value, $value, true);
|
||||
} else {
|
||||
$containsValue = array_key_exists($search_key, $value) && $value[$search_key] === $search_value;
|
||||
$contains_value = array_key_exists($search_key, $value) && $value[$search_key] === $search_value;
|
||||
}
|
||||
|
||||
// If it contains the value but doesn't have the required key
|
||||
if (
|
||||
$containsValue &&
|
||||
$contains_value &&
|
||||
(
|
||||
(
|
||||
is_string($required_key) &&
|
||||
|
||||
@@ -8,6 +8,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Create;
|
||||
|
||||
use CoreLibs\Combined\ArrayHandler;
|
||||
|
||||
class Hash
|
||||
{
|
||||
/** @var string default short hash -> deprecated use STANDARD_HASH_SHORT */
|
||||
@@ -210,6 +212,27 @@ class Hash
|
||||
{
|
||||
return self::hash($string, self::STANDARD_HASH);
|
||||
}
|
||||
|
||||
/**
|
||||
* generate a hash over any array data
|
||||
* optional will not sort keys and so create hashes based on the original data.
|
||||
* for correct array comapre it is recommended to keep sort keys on
|
||||
*
|
||||
* @param array<mixed> $data
|
||||
* @param bool $sort_keys [true] Whether to sort the array keys before hashing
|
||||
* @return string
|
||||
*/
|
||||
public static function generateImmutableHashForArray(array $data, bool $sort_keys = true): string
|
||||
{
|
||||
// Create a sorted copy to ensure consistent hashing
|
||||
// Generate hash using serialize for better accuracy
|
||||
return hash(
|
||||
self::DEFAULT_HASH,
|
||||
serialize(
|
||||
$sort_keys ? ArrayHandler::createSortedArrayByKey($data) : $data
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// __END__
|
||||
|
||||
+36
-22
@@ -520,7 +520,7 @@ class IO
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
// PRIVATE METHODS
|
||||
// MARK: PRIVATE METHODS
|
||||
// *************************************************************
|
||||
|
||||
/**
|
||||
@@ -1703,11 +1703,11 @@ class IO
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
// PUBLIC METHODS
|
||||
// MARK: PUBLIC METHODS
|
||||
// *************************************************************
|
||||
|
||||
// ***************************
|
||||
// CLOSE, STATUS, SETTINGS VARIABLE READ
|
||||
// MARK: CLOSE, STATUS, SETTINGS VARIABLE READ
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -1950,7 +1950,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// DEBUG DATA DUMP
|
||||
// MARK: DEBUG DATA DUMP
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -1978,7 +1978,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// CHECK QUERY TYPE
|
||||
// MARK: CHECK QUERY TYPE
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -2035,7 +2035,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// DATA WRITE CONVERSION
|
||||
// MARK: DATA WRITE CONVERSION
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -2156,7 +2156,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// DATA READ/WRITE CONVERSION
|
||||
// MARK: DATA READ/WRITE CONVERSION
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -2194,7 +2194,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// DATA READ CONVERSION
|
||||
// MARK: DATA READ CONVERSION
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -2263,8 +2263,22 @@ class IO
|
||||
return is_array($__db_array_parse) ? $__db_array_parse : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Will strip all single numberic entries from the array.
|
||||
* This is for database return
|
||||
*
|
||||
* @param array<mixed> $res
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function stripAssocOnly(array $res): array
|
||||
{
|
||||
return array_filter($res, function ($key) {
|
||||
return !is_numeric($key);
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// TABLE META DATA READ
|
||||
// MARK: TABLE META DATA READ
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -2290,7 +2304,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// QUERY EXECUSION AND DATA READ
|
||||
// MARK: QUERY EXECUSION AND DATA READ
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -2927,7 +2941,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// CURSOR RETURN
|
||||
// MARK: CURSOR RETURN
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -2941,7 +2955,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// CURSOR EXT CACHE RESET
|
||||
// MARK: CURSOR EXT CACHE RESET
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -2971,7 +2985,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// CURSOR EXT DATA CHECK
|
||||
// MARK: CURSOR EXT DATA CHECK
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -3066,7 +3080,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// MAXIMUM QUERY EXECUTION CHECK HELPERS
|
||||
// MARK: MAXIMUM QUERY EXECUTION CHECK HELPERS
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -3102,7 +3116,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// PREPARED QUERY WORK
|
||||
// MARK: PREPARED QUERY WORK
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -3379,7 +3393,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// ASYNCHRONUS EXECUTION/CHECK
|
||||
// MARK: ASYNCHRONUS EXECUTION/CHECK
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -3539,7 +3553,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// COMPLEX WRITE WITH CONFIG ARRAYS
|
||||
// MARK: COMPLEX WRITE WITH CONFIG ARRAYS
|
||||
// ***************************
|
||||
|
||||
// ** REMARK **
|
||||
@@ -3720,7 +3734,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// INTERNAL SETTINGS READ/CHANGE
|
||||
// MARK: INTERNAL SETTINGS READ/CHANGE
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -4048,7 +4062,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// QUERY DATA AND DB HANDLER
|
||||
// MARK: QUERY DATA AND DB HANDLER
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -4151,7 +4165,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// INTERNAL VARIABLES READ POST QUERY RUN
|
||||
// MARK: INTERNAL VARIABLES READ POST QUERY RUN
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -4442,7 +4456,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// ERROR AND WARNING DATA
|
||||
// MARK: ERROR AND WARNING DATA
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
@@ -4499,7 +4513,7 @@ class IO
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// DEPEREACTED CALLS
|
||||
// MARK: DEPEREACTED CALLS
|
||||
// all call below are no longer in use and throw deprecated errors
|
||||
// ***************************
|
||||
|
||||
|
||||
Reference in New Issue
Block a user