@@ -56,7 +56,7 @@ class Table
5656 /**
5757 * @var
5858 */
59- public $ primary_keys ;
59+ public $ primary_keys = array () ;
6060 /**
6161 * @var
6262 */
@@ -640,22 +640,21 @@ function process_table($table, $fp = null, $state_data = [])
640640 return $ this ->transfer_chunk ($ fp , $ state_data );
641641 }
642642
643- /**
644- * Parses the provided table structure.
645- *
646- * @param array $table_structure
647- *
648- * @return array
649- */
650- function get_structure_info ($ table , $ table_structure = array (), $ state_data = [])
651- {
652- if (empty ($ state_data )) {
653- $ state_data = Persistence::getStateData ();
654- }
643+ /**
644+ * Parses the provided table structure.
645+ *
646+ * @param array $table_structure
647+ *
648+ * @return array
649+ */
650+ public function get_structure_info ( $ table , $ table_structure = array (), $ state_data = [] ) {
651+ if ( empty ( $ state_data ) ) {
652+ $ state_data = Persistence::getStateData ();
653+ }
655654
656- if (empty ($ table_structure) ) {
657- $ table_structure = $ this ->get_table_structure ($ table );
658- }
655+ if ( empty ( $ table_structure ) ) {
656+ $ table_structure = $ this ->get_table_structure ( $ table );
657+ }
659658
660659 if (!is_array ($ table_structure )) {
661660 $ this ->error_log ->log_error ($ this ->error_log ->getError ());
@@ -665,63 +664,65 @@ function get_structure_info($table, $table_structure = array(), $state_data = []
665664 return $ result ;
666665 }
667666
668- // $defs = mysql defaults, looks up the default for that particular column, used later on to prevent empty inserts values for that column
669- // $ints = holds a list of the possible integer types so as to not wrap them in quotation marks later in the insert statements
670- $ defs = array ();
671- $ ints = array ();
672- $ bins = array ();
673- $ bits = array ();
674- $ field_set = array ();
675- $ this ->primary_keys = array ();
676- $ use_primary_keys = true ;
677-
678- foreach ($ table_structure as $ struct ) {
679- if ((0 === strpos ($ struct ->Type , 'tinyint ' )) ||
680- (0 === strpos (strtolower ($ struct ->Type ), 'smallint ' )) ||
681- (0 === strpos (strtolower ($ struct ->Type ), 'mediumint ' )) ||
682- (0 === strpos (strtolower ($ struct ->Type ), 'int ' )) ||
683- (0 === strpos (strtolower ($ struct ->Type ), 'bigint ' ))
684- ) {
685- $ defs [strtolower ($ struct ->Field )] = (null === $ struct ->Default ) ? 'NULL ' : $ struct ->Default ;
686- $ ints [strtolower ($ struct ->Field )] = '1 ' ;
687- } elseif (0 === strpos ($ struct ->Type , 'binary ' ) || apply_filters ('wpmdb_process_column_as_binary ' , false , $ struct )) {
688- $ bins [strtolower ($ struct ->Field )] = '1 ' ;
689- } elseif (0 === strpos ($ struct ->Type , 'bit ' ) || apply_filters ('wpmdb_process_column_as_bit ' , false , $ struct )) {
690- $ bits [strtolower ($ struct ->Field )] = '1 ' ;
691- }
692-
693- $ field_set [] = $ this ->table_helper ->backquote ($ struct ->Field );
694-
695- if ('PRI ' === $ struct ->Key && true === $ use_primary_keys ) {
696- if (false === strpos ($ struct ->Type , 'int ' )) {
697- $ use_primary_keys = false ;
698- $ this ->primary_keys = array ();
699- continue ;
700- }
701- $ this ->primary_keys [$ struct ->Field ] = 0 ;
702- }
703- }
704-
705- if ( ! empty ($ state_data ['primary_keys ' ])) {
706- if ( ! Util::is_json ($ state_data ['primary_keys ' ])) {
707- $ state_data ['primary_keys ' ] = base64_decode (trim ($ state_data ['primary_keys ' ]));
708- }
709- $ this ->primary_keys = json_decode (stripslashes ($ state_data ['primary_keys ' ]), true );
710- if (false !== $ this ->primary_keys && ! empty ($ state_data ['primary_keys ' ])) {
711- $ this ->first_select = false ;
712- }
713- }
667+ // $defs = mysql defaults, looks up the default for that particular column, used later on to prevent empty inserts values for that column
668+ // $ints = holds a list of the possible integer types so as to not wrap them in quotation marks later in the insert statements
669+ $ defs = array ();
670+ $ ints = array ();
671+ $ bins = array ();
672+ $ bits = array ();
673+ $ points = array ();
674+ $ field_set = array ();
675+ $ use_primary_keys = true ;
676+
677+ foreach ( $ table_structure as $ struct ) {
678+ if (
679+ ( 0 === strpos ( $ struct ->Type , 'tinyint ' ) ) ||
680+ ( 0 === strpos ( strtolower ( $ struct ->Type ), 'smallint ' ) ) ||
681+ ( 0 === strpos ( strtolower ( $ struct ->Type ), 'mediumint ' ) ) ||
682+ ( 0 === strpos ( strtolower ( $ struct ->Type ), 'int ' ) ) ||
683+ ( 0 === strpos ( strtolower ( $ struct ->Type ), 'bigint ' ) )
684+ ) {
685+ $ defs [ strtolower ( $ struct ->Field ) ] = ( null === $ struct ->Default ) ? 'NULL ' : $ struct ->Default ;
686+ $ ints [ strtolower ( $ struct ->Field ) ] = '1 ' ;
687+ } elseif (
688+ 0 === strpos ( $ struct ->Type , 'binary ' ) ||
689+ apply_filters ( 'wpmdb_process_column_as_binary ' , false , $ struct )
690+ ) {
691+ $ bins [ strtolower ( $ struct ->Field ) ] = '1 ' ;
692+ } elseif (
693+ 0 === strpos ( $ struct ->Type , 'bit ' ) ||
694+ apply_filters ( 'wpmdb_process_column_as_bit ' , false , $ struct )
695+ ) {
696+ $ bits [ strtolower ( $ struct ->Field ) ] = '1 ' ;
697+ } elseif ( 0 === strpos ( $ struct ->Type , 'point ' ) ) {
698+ $ points [ strtolower ( $ struct ->Field ) ] = '1 ' ;
699+ }
700+
701+ $ field_set [] = $ this ->table_helper ->backquote ( $ struct ->Field );
702+
703+ if ( 'PRI ' === $ struct ->Key && true === $ use_primary_keys ) {
704+ if ( false !== strpos ( $ struct ->Type , 'binary ' ) ) {
705+ $ use_primary_keys = false ;
706+ $ this ->primary_keys = array ();
707+ continue ;
708+ }
709+ $ this ->primary_keys [ $ struct ->Field ] = 0 ;
710+ }
711+ }
714712
715- $ return = array (
716- 'defs ' => $ defs ,
717- 'ints ' => $ ints ,
718- 'bins ' => $ bins ,
719- 'bits ' => $ bits ,
720- 'field_set ' => $ field_set ,
721- );
713+ // Now we have the table structure, set primary keys to last data position
714+ // if we've come round for another slice of data.
715+ $ this ->maybe_update_primary_keys_from_state ( $ state_data );
722716
723- return $ return ;
724- }
717+ return array (
718+ 'defs ' => $ defs ,
719+ 'ints ' => $ ints ,
720+ 'bins ' => $ bins ,
721+ 'bits ' => $ bits ,
722+ 'field_set ' => $ field_set ,
723+ 'points ' => $ points ,
724+ );
725+ }
725726
726727 /**
727728 * Returns the table structure for the provided table.
@@ -794,7 +795,29 @@ function get_current_row($state_data = false)
794795 return $ current_row ;
795796 }
796797
797- /**
798+ /**
799+ * If state data contains primary keys, update internal variables used for data position tracking.
800+ *
801+ * @param array $state_data
802+ *
803+ * @return void
804+ */
805+ private function maybe_update_primary_keys_from_state ( $ state_data = [] ) {
806+ if ( ! empty ( $ state_data ['primary_keys ' ] ) ) {
807+ if ( ! Util::is_json ( $ state_data ['primary_keys ' ] ) ) {
808+ $ state_data ['primary_keys ' ] = base64_decode ( trim ( $ state_data ['primary_keys ' ] ) );
809+ }
810+
811+ $ decoded_primary_keys = json_decode ( stripslashes ( $ state_data ['primary_keys ' ] ), true );
812+
813+ if ( ! empty ( $ decoded_primary_keys ) ) {
814+ $ this ->primary_keys = $ decoded_primary_keys ;
815+ $ this ->first_select = false ;
816+ }
817+ }
818+ }
819+
820+ /**
798821 * Runs before processing the data in a table.
799822 *
800823 * @param string $table
@@ -1476,21 +1499,34 @@ function process_row($table, $replacer, $row, $structure_info, $fp, $state_data)
14761499 continue ;
14771500 }
14781501
1479- $ test_bit_key = strtolower ($ key ) . '__bit ' ;
1480- // Correct null values IF we're not working with a BIT type field, they're handled separately below
1481- if (null === $ value && !property_exists ($ row , $ test_bit_key )) {
1482- $ values [] = 'NULL ' ;
1483- continue ;
1484- }
1485-
1486- // If we have binary data, substitute in hex encoded version and remove hex encoded version from row.
1487- $ hex_key = strtolower ($ key ) . '__hex ' ;
1488- if (isset ($ structure_info ['bins ' ][strtolower ($ key )]) && $ structure_info ['bins ' ][strtolower ($ key )] && isset ($ row ->$ hex_key )) {
1489- $ value = "UNHEX(' " . $ row ->$ hex_key . "') " ;
1490- $ values [] = $ value ;
1491- unset($ row ->$ hex_key );
1492- continue ;
1493- }
1502+ if ( isset ( $ structure_info ['points ' ][ strtolower ( $ key ) ] ) && $ structure_info ['points ' ][ strtolower ( $ key ) ] ) {
1503+ $ unpacked = empty ( $ value ) ? $ value : unpack ( 'x/x/x/x/corder/Ltype/dlon/dlat ' , $ value );
1504+ $ should_create_geom = is_array ( $ unpacked )
1505+ && array_key_exists ( 'lon ' , $ unpacked )
1506+ && array_key_exists ( 'lat ' , $ unpacked );
1507+
1508+ $ values [] = $ should_create_geom ? 'ST_GeomFromText("POINT( ' . $ unpacked ['lon ' ] . ' ' . $ unpacked ['lat ' ] . ')") ' : 'NULL ' ;
1509+ continue ;
1510+ }
1511+
1512+ $ test_bit_key = strtolower ( $ key ) . '__bit ' ;
1513+ $ hex_key = strtolower ( $ key ) . '__hex ' ;
1514+ // Correct null values IF we're not working with a BIT of HEX type field, they're handled separately below
1515+ if (
1516+ null === $ value &&
1517+ ! property_exists ( $ row , $ test_bit_key ) && ! property_exists ( $ row , $ hex_key )
1518+ ) {
1519+ $ values [] = 'NULL ' ;
1520+ continue ;
1521+ }
1522+
1523+ // If we have binary data, substitute in hex encoded version and remove hex encoded version from row.
1524+ if ( isset ( $ structure_info ['bins ' ][ strtolower ( $ key ) ] ) && $ structure_info ['bins ' ][ strtolower ( $ key ) ] && ( isset ( $ row ->$ hex_key ) || null === $ row ->$ hex_key ) ) {
1525+ $ value = null === $ row ->$ hex_key ? 'NULL ' : "UNHEX(' " . $ row ->$ hex_key . "') " ;
1526+ $ values [] = $ value ;
1527+ unset( $ row ->$ hex_key );
1528+ continue ;
1529+ }
14941530
14951531 // If we have bit data, substitute in properly bit encoded version.
14961532 $ bit_key = strtolower ($ key ) . '__bit ' ;
0 commit comments