@@ -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