2015-01-13 08:29:44 +00:00
#!/usr/bin/env php
<?php
/**
* This script is designed for assisting core developers working on Migrate to
* regenerate the Migrate dump files. Technically this script can be used to
* dump any database into a PHP representation however that is not its primary
* use case .
*
* Dump files only need to be updated when you' re adding or updating tests which
* need new Drupal 6 data.
*
* - Clone the repository from: https://www.drupal.org/sandbox/benjy/2405029
2015-02-16 16:52:27 +00:00
* - Create a database called d6_migrate and import core/migrate_drupal/src/Tests/d6/d6.gz
2015-02-03 10:08:45 +00:00
* - In drupal_6_migrate/sites/default, copy default.settings.php to settings.php and add an entry for the d6_migrate database, eg: $db_url = 'mysqli://username:password@localhost/d6_migrate' ;
2015-01-13 08:29:44 +00:00
* - Add an entry into your Drupal 8 settings file, eg: $databases [ 'd6_migrate' ] [ 'default' ] = array ( // Credentials ) ;
2015-02-03 10:08:45 +00:00
* - Use the Drupal 6 site to make data changes as needed ( User ID 1 credentials are admin/admin) .
2015-01-13 08:29:44 +00:00
* - Run ./core/scripts/migrate-dump-d6.sh to re-export the tables.
*/
use Doctrine\C ommon\I nflector\I nflector;
use Drupal\C ore\D atabase\D atabase;
use Drupal\C omponent\U tility\V ariable;
use Drupal\C ore\D rupalKernel;
use Drupal\C ore\S ite\S ettings;
use Symfony\C omponent\H ttpFoundation\R equest;
if ( PHP_SAPI != = 'cli' ) {
return ;
}
2015-03-24 11:49:33 +00:00
$autoloader = require __DIR__ . '/../../autoload.php' ;
2015-01-13 08:29:44 +00:00
require_once __DIR__ . '/../includes/bootstrap.inc' ;
$request = Request::createFromGlobals( ) ;
Settings::initialize( dirname( dirname( __DIR__) ) , DrupalKernel::findSitePath( $request ) , $autoloader ) ;
2015-02-16 16:52:27 +00:00
$output_folder = DRUPAL_ROOT . '/core/modules/migrate_drupal/src/Tests/Table/d6' ;
2015-01-13 08:29:44 +00:00
$class_template = ' <?php
/**
* @file
* Contains \D rupal\m igrate_drupal\T ests\D ump\{ { CLASS_NAME} } .
*
* THIS IS A GENERATED FILE. DO NOT EDIT.
*
* @see cores/scripts/dump-database-d6.sh
* @see https://www.drupal.org/sandbox/benjy/2405029
*/
2015-02-16 16:52:27 +00:00
namespace Drupal\m igrate_drupal\T ests\T able\d 6;
2015-01-13 08:29:44 +00:00
2015-02-16 16:52:27 +00:00
use Drupal\m igrate_drupal\T ests\D ump\D rupalDumpBase;
2015-01-13 08:29:44 +00:00
/**
* Generated file to represent the { { TABLE} } table.
*/
2015-02-16 16:52:27 +00:00
class { { CLASS_NAME} } extends DrupalDumpBase {
2015-01-13 08:29:44 +00:00
public function load( ) {
$this ->createTable( "{{TABLE}}" , { { TABLE_DEFINITION} } ) ;
$this ->database->insert( "{{TABLE}}" ) ->fields( { { PHP_FIELDS} } )
{ { PHP_VALUES} } ->execute( ) ;
}
}
' ;
// Generate a list of tables using the 'migrate' db connection.
$connection = Database::getConnection( 'default' , 'd6_migrate' ) ;
$tables = $connection ->query( 'SHOW TABLES' ) ->fetchCol( ) ;
foreach ( $tables as $table ) {
if ( substr( $table , 0, 5) = = = 'cache' || $table = = = 'watchdog' || $table = = = 'menu_router' || $table = = = 'sessions' ) {
continue ;
}
// Generate the class name.
$class = Inflector::classify( $table ) ;
2015-02-17 16:12:50 +00:00
// Order by primary keys
$order = '' ;
$query = " SELECT `COLUMN_NAME` FROM `information_schema`.`COLUMNS`
WHERE ( ` TABLE_SCHEMA` = 'd6_migrate' ) AND ( ` TABLE_NAME` = '{$table}' ) AND ( ` COLUMN_KEY` = 'PRI' )
ORDER BY COLUMN_NAME" ;
$results = $connection ->query( $query ) ;
while ( ( $row = $results ->fetchAssoc( ) ) != = FALSE) {
$order .= '{' . $row [ 'COLUMN_NAME' ] . '}, ' ;
}
if ( !( empty( $order ) ) ) {
$order = rtrim ( $order , ", " ) ;
$order = ' ORDER BY ' . $order ;
}
2015-01-13 08:29:44 +00:00
// Generate the field values.
2015-02-17 16:12:50 +00:00
$query = $connection ->query( _db_get_query( $table ) . $order ) ;
2015-01-13 08:29:44 +00:00
$values = '' ;
while ( ( $row = $query ->fetchAssoc( ) ) != = FALSE) {
$values .= '->values(' . Variable::export( $row , ' ' ) . ')' ;
}
// Generate the field names.
$query = $connection ->query( " SHOW COLUMNS FROM { $table } " ) ;
$definition = [ ] ;
while ( ( $row = $query ->fetchAssoc( ) ) != = FALSE) {
$field_name = $row [ 'Field' ] ;
// Parse out the field type and meta information.
preg_match( '@([a-z]+)(?:\((\d+)(?:,(\d+))?\))?\s*(unsigned)?@' , $row [ 'Type' ] , $matches ) ;
$field_type = _db_field_type_map( $matches [ 1] ) ;
// If it' s auto-increment then make it a serial instead.
if ( $row [ 'Extra' ] = = = 'auto_increment' ) {
$field_type = 'serial' ;
}
// Add primary key entries as needed.
if ( $row [ 'Key' ] = = = 'PRI' ) {
$definition [ 'primary key' ] [ ] = $field_name ;
}
// All fields have a type and not null.
$definition [ 'fields' ] [ $field_name ] = [
'type' = > $field_type ,
'not null' = > $row [ 'Null' ] = = = 'NO' ,
] ;
// If this is a numeric field, the meta will be precision and scale.
if ( isset( $matches [ 2] ) && $field_type = = = 'numeric' ) {
$definition [ 'fields' ] [ $field_name ] [ 'precision' ] = $matches [ 2] ;
$definition [ 'fields' ] [ $field_name ] [ 'scale' ] = $matches [ 3] ;
}
elseif ( $field_type = = = 'time' || $field_type = = = 'datetime' ) {
// We use varchar to replace the D6 datetime and time fields.
$definition [ 'fields' ] [ $field_name ] [ 'type' ] = 'varchar' ;
$definition [ 'fields' ] [ $field_name ] [ 'length' ] = '100' ;
}
else {
// Try use the provided length, if it doesn't exist default to 100. It' s
// not great but good enough for our dumps at this point.
$definition [ 'fields' ] [ $field_name ] [ 'length' ] = isset( $matches [ 2] ) ? $matches [ 2] : 100;
}
if ( isset( $row [ 'Default' ] ) ) {
$definition [ 'fields' ] [ $field_name ] [ 'default' ] = $row [ 'Default' ] ;
}
if ( isset( $matches [ 4] ) ) {
$definition [ 'fields' ] [ $field_name ] [ 'unsigned' ] = TRUE;
}
}
$fields = Variable::export( array_keys( $definition [ 'fields' ] ) , ' ' ) ;
$definition = Variable::export( $definition , ' ' ) ;
// Do our substitutions.
$php = str_replace( '{{TABLE}}' , $table , $class_template ) ;
$php = str_replace( '{{CLASS_NAME}}' , $class , $php ) ;
$php = str_replace( '{{PHP_VALUES}}' , $values , $php ) ;
$php = str_replace( '{{PHP_FIELDS}}' , $fields , $php ) ;
$php = str_replace( '{{TABLE_DEFINITION}}' , $definition , $php ) ;
// Save the file.
$php = implode( "\n" , array_map( 'rtrim' , explode( "\n" , $php ) ) ) ;
file_put_contents( " $output_folder / $class .php " , $php ) ;
}
function _db_field_type_map( $sql_type ) {
$map = array(
'longtext' = > 'text' ,
'tinytext' = > 'text' ,
'mediumtext' = > 'text' ,
'tinyint' = > 'int' ,
'smallint' = > 'int' ,
'mediumint' = > 'int' ,
'bigint' = > 'int' ,
'int' = > 'int' ,
'double' = > 'numeric' ,
'float' = > 'numeric' ,
'decimal' = > 'numeric' ,
'longblob' = > 'blob' ,
) ;
return isset( $map [ $sql_type ] ) ? $map [ $sql_type ] : $sql_type ;
}
function _db_get_query( $table ) {
$queries = array(
'users' = > 'SELECT * FROM {users} WHERE uid NOT IN (0,1)' ,
) ;
return isset( $queries [ $table ] ) ? $queries [ $table ] : 'SELECT * FROM {' . $table .'}' ;
}
$options = $connection ->getConnectionOptions( ) ;
$user = $options [ 'username' ] ;
$pass = $options [ 'password' ] ;
$db = $options [ 'database' ] ;
@system( " mysqldump -u $user -p $pass $db | gzip -c > core/modules/migrate_drupal/src/Tests/d6.gz " ) ;