Skip to content

Commit 3ff5835

Browse files
committed
Improve the JSONDB main class
* Change the table structure: Add the link ID, used when linking tables * Link tables with the link ID instead of the row ID * Can now select() data by linking tables * Insert rows using the new table structure
1 parent 0ba2dc7 commit 3ff5835

File tree

1 file changed

+69
-18
lines changed

1 file changed

+69
-18
lines changed

src/JSONDB/JSONDB.php

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ public function createServer($path, $username, $password, $connect = FALSE)
303303
fclose($htaccess);
304304

305305
$htpasswd = fopen(realpath(dirname(__DIR__) . '/config/.htpasswd'), 'a+');
306-
fwrite($htpasswd, $username . ':' . crypt($password) . "\n");
306+
fwrite($htpasswd, $username . ':' . crypt($password, NULL) . "\n");
307307
fclose($htpasswd);
308308

309309
$this->config->addUser(realpath($path), $username, $password);
@@ -428,7 +428,7 @@ public function createTable($name, array $prototype)
428428
}
429429

430430
$fields = array();
431-
$properties = array('last_insert_id' => 0, 'last_valid_row_id' => 0, 'primary_keys' => array(), 'unique_keys' => array());
431+
$properties = array('last_insert_id' => 0, 'last_valid_row_id' => 0, 'last_link_id' => 0, 'primary_keys' => array(), 'unique_keys' => array());
432432
$ai_exist = FALSE;
433433
foreach ($prototype as $field => $prop) {
434434
$has_ai = array_key_exists('auto_increment', $prop);
@@ -666,9 +666,9 @@ protected function _parseValue($value, $properties)
666666
$link_table_path = $this->_getTablePath($link_info[0]);
667667
$link_table_data = $this->getTableData($link_table_path);
668668
$value = $this->_parseValue($value, $link_table_data['properties'][$link_info[1]]);
669-
foreach ((array)$link_table_data['data'] as $data) {
669+
foreach ((array)$link_table_data['data'] as $linkID => $data) {
670670
if ($data[$link_info[1]] === $value) {
671-
return $data['#rowid'];
671+
return $linkID;
672672
}
673673
}
674674
throw new Exception("JSONDB Error: There is no value \"{$value}\" in any rows of the table \"{$link_info[0]}\" at the column \"{$link_info[1]}\".");
@@ -728,6 +728,8 @@ protected function _parseValue($value, $properties)
728728
protected function _select($data)
729729
{
730730
$result = $data['data'];
731+
$field_links = array();
732+
$column_links = array();
731733

732734
foreach ((array)$this->parsedQuery['extensions'] as $name => $parameters) {
733735
switch ($name) {
@@ -755,14 +757,58 @@ protected function _select($data)
755757
case 'limit':
756758
$result = array_slice($result, $parameters[0], $parameters[1]);
757759
break;
760+
761+
case 'on':
762+
if (count($parameters) > 0) {
763+
foreach ((array)$parameters as $field) {
764+
$field_links[] = $field;
765+
}
766+
}
767+
break;
768+
769+
case 'link':
770+
if (count($parameters) > 0) {
771+
foreach ((array)$parameters as $field) {
772+
$column_links[] = $field;
773+
}
774+
}
775+
break;
776+
}
777+
}
778+
779+
if (count($field_links) === count($column_links)) {
780+
$links = array_combine($field_links, $column_links);
781+
} else {
782+
throw new Exception('JSONDB Error: Invalid numbers of links. Given "' . count($field_links) .'" columns to link but receive "' . count($column_links) . '" links');
783+
}
784+
785+
if (count($links) > 0) {
786+
foreach ((array)$result as $index => $result_p) {
787+
foreach ($links as $field => $columns) {
788+
if (preg_match('#link\((.+)\)#', $data['properties'][$field]['type'], $link)) {
789+
$link_info = explode('.', $link[1]);
790+
$link_table_path = $this->_getTablePath($link_info[0]);
791+
$link_table_data = $this->getTableData($link_table_path);
792+
foreach ((array)$link_table_data['data'] as $linkID => $value) {
793+
if ($linkID === $result_p[$field]) {
794+
if (in_array('*', $columns, TRUE)) {
795+
$columns = array_diff($link_table_data['prototype'], array('#rowid'));
796+
}
797+
$result[$index][$field] = array_intersect_key($value, array_flip($columns));
798+
}
799+
}
800+
} else {
801+
throw new Exception("JSONDB Error: Can't link tables with the column \"{$field}\". The column is not of type link.");
802+
}
803+
}
758804
}
759805
}
760806

761807
$temp = array();
762808
if (in_array('last_insert_id', $this->parsedQuery['parameters'], TRUE)) {
763809
$temp['last_insert_id'] = $data['properties']['last_insert_id'];
764810
} elseif (!in_array('*', $this->parsedQuery['parameters'], TRUE)) {
765-
foreach ((array)$result as $line) {
811+
foreach ((array)$result as $linkID => $line) {
766812
$temp[] = array_intersect_key($line, array_flip($this->parsedQuery['parameters']));
767813
}
768814
if (array_key_exists('as', $this->parsedQuery['extensions'])) {
@@ -782,13 +828,12 @@ protected function _select($data)
782828
unset($t);
783829
}
784830
} else {
785-
foreach ((array)$result as $line) {
831+
foreach ((array)$result as $linkID => $line) {
786832
$temp[] = array_diff_key($line, array('#rowid' => '#rowid'));
787833
}
788834
}
789-
$result = $temp;
790835

791-
$this->queryResults = $result;
836+
$this->queryResults = $temp;
792837

793838
return new QueryResult($this->queryResults, $this);
794839
}
@@ -818,9 +863,10 @@ protected function _insert($data)
818863
}
819864
$current_data = $data['data'];
820865
$ai_id = (int)$data['properties']['last_insert_id'];
821-
$insert = array(array('#rowid' => (int)$data['properties']['last_valid_row_id'] + 1));
866+
$lk_id = (int)$data['properties']['last_link_id'] + 1;
867+
$insert = array('#'.$lk_id => array('#rowid' => (int)$data['properties']['last_valid_row_id'] + 1));
822868
foreach ((array)$this->parsedQuery['parameters'] as $key => $value) {
823-
$insert[0][$rows[$key]] = $this->_parseValue($value, $data['properties'][$rows[$key]]);
869+
$insert['#'.$lk_id][$rows[$key]] = $this->_parseValue($value, $data['properties'][$rows[$key]]);
824870
}
825871

826872
if (array_key_exists('and', $this->parsedQuery['extensions'])) {
@@ -833,7 +879,7 @@ protected function _insert($data)
833879
foreach ((array)$values as $key => $value) {
834880
$to_add[$rows[$key]] = $this->_parseValue($value, $data['properties'][$rows[$key]]);
835881
}
836-
$insert[] = $to_add;
882+
$insert['#'.++$lk_id] = $to_add;
837883
}
838884
}
839885

@@ -863,9 +909,10 @@ protected function _insert($data)
863909

864910
$pk_error = FALSE;
865911
$non_pk = array_flip(array_diff($data['prototype'], $data['properties']['primary_keys']));
866-
foreach ($insert as $index => $array_data) {
912+
$i = 0;
913+
foreach ($insert as $array_data) {
867914
$array_data = array_diff_key($array_data, $non_pk);
868-
foreach (array_slice($insert, $index + 1) as $value) {
915+
foreach (array_slice($insert, $i + 1) as $value) {
869916
$value = array_diff_key($value, $non_pk);
870917
$pk_error = $pk_error || ($value === $array_data);
871918
if ($pk_error) {
@@ -874,36 +921,40 @@ protected function _insert($data)
874921
throw new Exception("JSONDB Error: Can't insert value. Duplicate values \"{$values}\" for primary keys \"{$keys}\".");
875922
}
876923
}
924+
$i++;
877925
}
878926

879927
$uk_error = FALSE;
928+
$i = 0;
880929
foreach ((array)$data['properties']['unique_keys'] as $uk) {
881-
foreach ($insert as $index => $array_data) {
930+
foreach ($insert as $array_data) {
882931
$array_data = array_intersect_key($array_data, array($uk => $uk));
883-
foreach (array_slice($insert, $index + 1) as $value) {
932+
foreach (array_slice($insert, $i + 1) as $value) {
884933
$value = array_intersect_key($value, array($uk => $uk));
885934
$uk_error = $uk_error || (!empty($item[$uk]) && ($value === $array_data));
886935
if ($uk_error) {
887936
throw new Exception("JSONDB Error: Can't insert value. Duplicate values \"{$value[$uk]}\" for unique key \"{$uk}\".");
888937
}
889938
}
939+
$i++;
890940
}
891941
}
892942

893-
foreach ($insert as $key => &$line) {
943+
foreach ($insert as &$line) {
894944
uksort($line, function ($after, $now) use ($data) {
895945
return array_search($now, $data['prototype'], TRUE) < array_search($after, $data['prototype'], TRUE);
896946
});
897947
}
898948
unset($line);
899949

900-
usort($insert, function ($after, $now) {
901-
return $now['#rowid'] < $after['#rowid'];
950+
uksort($insert, function ($after, $now) use ($insert) {
951+
return $insert[$now]['#rowid'] < $insert[$after]['#rowid'];
902952
});
903953

904954
$data['data'] = $insert;
905955
$data['properties']['last_valid_row_id'] = $this->_getLastValidRowID($insert, FALSE);
906956
$data['properties']['last_insert_id'] = $ai_id;
957+
$data['properties']['last_link_id'] = $lk_id;
907958

908959
$this->cache->update($this->_getTablePath(), $data);
909960

0 commit comments

Comments
 (0)