first import
This commit is contained in:
464
sites/all/modules/migrate/migrate_example/beer.inc
Normal file
464
sites/all/modules/migrate/migrate_example/beer.inc
Normal file
@@ -0,0 +1,464 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* A basic example of using the Migrate module to import taxonomy, users, nodes,
|
||||
* and comments.
|
||||
*
|
||||
* The basic idea is
|
||||
* - The users in the source application are listed in the
|
||||
* migrate_example_beer_account table and are transformed into Drupal users.
|
||||
* - Drupal "beer" nodes describe beers; The information to create the nodes
|
||||
* comes from the migrate_example_beer_node table.
|
||||
* - Taxonomy terms for the beer nodes (ale, pilsner) come from the
|
||||
* migrate_example_beer_topic table and they are applied to nodes using the
|
||||
* source information in the migrate_example_beer_topic_node table.
|
||||
* - Comments to be attached to the beer nodes are described in the source
|
||||
* migrate_example_beer_comment table.
|
||||
*
|
||||
* We will use the Migrate API to import and transform this data and turn it into
|
||||
* a working Drupal system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* To define a migration process from a set of source data to a particular
|
||||
* kind of Drupal object (for example, a specific node type), you define
|
||||
* a class derived from Migration. You must define a constructor to initialize
|
||||
* your migration object. By default, your class name will be the "machine name"
|
||||
* of the migration, by which you refer to it. Note that the machine name is
|
||||
* case-sensitive.
|
||||
*
|
||||
* In any serious migration project, you will find there are some options
|
||||
* which are common to the individual migrations you're implementing. You can
|
||||
* define an abstract intermediate class derived from Migration, then derive your
|
||||
* individual migrations from that, to share settings, utility functions, etc.
|
||||
*/
|
||||
abstract class BasicExampleMigration extends Migration {
|
||||
public function __construct() {
|
||||
// Always call the parent constructor first for basic setup
|
||||
parent::__construct();
|
||||
|
||||
// With migrate_ui enabled, migration pages will indicate people involved in
|
||||
// the particular migration, with their role and contact info. We default the
|
||||
// list in the shared class; it can be overridden for specific migrations.
|
||||
$this->team = array(
|
||||
new MigrateTeamMember('Liz Taster', 'ltaster@example.com', t('Product Owner')),
|
||||
new MigrateTeamMember('Larry Brewer', 'lbrewer@example.com', t('Implementor')),
|
||||
);
|
||||
|
||||
// Individual mappings in a migration can be linked to a ticket or issue
|
||||
// in an external tracking system. Define the URL pattern here in the shared
|
||||
// class with ':id:' representing the position of the issue number, then add
|
||||
// ->issueNumber(1234) to a mapping.
|
||||
$this->issuePattern = 'http://drupal.org/node/:id:';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* There are four essential components to set up in your constructor:
|
||||
* $this->source - An instance of a class derived from MigrateSource, this
|
||||
* will feed data to the migration.
|
||||
* $this->destination - An instance of a class derived from MigrateDestination,
|
||||
* this will receive data that originated from the source and has been mapped
|
||||
* by the Migration class, and create Drupal objects.
|
||||
* $this->map - An instance of a class derived from MigrateMap, this will keep
|
||||
* track of which source items have been imported and what destination objects
|
||||
* they map to.
|
||||
* Mappings - Use $this->addFieldMapping to tell the Migration class what source
|
||||
* fields correspond to what destination fields, and additional information
|
||||
* associated with the mappings.
|
||||
*/
|
||||
class BeerTermMigration extends BasicExampleMigration {
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
// Human-friendly description of your migration process. Be as detailed as you
|
||||
// like.
|
||||
$this->description = t('Migrate styles from the source database to taxonomy terms');
|
||||
|
||||
// Create a map object for tracking the relationships between source rows
|
||||
// and their resulting Drupal objects. Usually, you'll use the MigrateSQLMap
|
||||
// class, which uses database tables for tracking. Pass the machine name
|
||||
// (BeerTerm) of this migration to use in generating map and message tables.
|
||||
// And, pass schema definitions for the primary keys of the source and
|
||||
// destination - we need to be explicit for our source, but the destination
|
||||
// class knows its schema already.
|
||||
$this->map = new MigrateSQLMap($this->machineName,
|
||||
array(
|
||||
'style' => array('type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Topic ID',
|
||||
)
|
||||
),
|
||||
MigrateDestinationTerm::getKeySchema()
|
||||
);
|
||||
|
||||
// In this example, we're using tables that have been added to the existing
|
||||
// Drupal database but which are not Drupal tables. You can examine the
|
||||
// various tables (starting here with migrate_example_beer_topic) using a
|
||||
// database browser like phpMyAdmin.
|
||||
// First, we set up a query for this data. Note that by ordering on
|
||||
// style_parent, we guarantee root terms are migrated first, so the
|
||||
// parent_name mapping below will find that the parent exists.
|
||||
$query = db_select('migrate_example_beer_topic', 'met')
|
||||
->fields('met', array('style', 'details', 'style_parent', 'region', 'hoppiness'))
|
||||
// This sort assures that parents are saved before children.
|
||||
->orderBy('style_parent', 'ASC');
|
||||
|
||||
// Create a MigrateSource object, which manages retrieving the input data.
|
||||
$this->source = new MigrateSourceSQL($query);
|
||||
|
||||
// Set up our destination - terms in the migrate_example_beer_styles vocabulary
|
||||
$this->destination = new MigrateDestinationTerm('migrate_example_beer_styles');
|
||||
|
||||
// Assign mappings TO destination fields FROM source fields. To discover
|
||||
// the names used in these calls, use the drush commands
|
||||
// drush migrate-fields-destination BeerTerm
|
||||
// drush migrate-fields-source BeerTerm
|
||||
$this->addFieldMapping('name', 'style');
|
||||
$this->addFieldMapping('description', 'details');
|
||||
|
||||
// Documenting your mappings makes it easier for the whole team to see
|
||||
// exactly what the status is when developing a migration process.
|
||||
$this->addFieldMapping('parent_name', 'style_parent')
|
||||
->description(t('The incoming style_parent field is the name of the term parent'));
|
||||
|
||||
// Mappings are assigned issue groups, by which they are grouped on the
|
||||
// migration info page when the migrate_ui module is enabled. The default
|
||||
// is 'Done', indicating active mappings which need no attention. A
|
||||
// suggested practice is to use groups of:
|
||||
// Do Not Migrate (or DNM) to indicate source fields which are not being used,
|
||||
// or destination fields not to be populated by migration.
|
||||
// Client Issues to indicate input from the client is needed to determine
|
||||
// how a given field is to be migrated.
|
||||
// Implementor Issues to indicate that the client has provided all the
|
||||
// necessary information, and now the implementor needs to complete the work.
|
||||
$this->addFieldMapping(NULL, 'hoppiness')
|
||||
->description(t('This info will not be maintained in Drupal'))
|
||||
->issueGroup(t('DNM'));
|
||||
|
||||
// Open mapping issues can be assigned priorities (the default is
|
||||
// MigrateFieldMapping::ISSUE_PRIORITY_OK). If you're using an issue
|
||||
// tracking system, and have defined issuePattern (see BasicExampleMigration
|
||||
// above), you can specify a ticket/issue number in the system on the
|
||||
// mapping and migrate_ui will link directory to it.
|
||||
$this->addFieldMapping(NULL, 'region')
|
||||
->description('Will a field be added to the vocabulary for this?')
|
||||
->issueGroup(t('Client Issues'))
|
||||
->issuePriority(MigrateFieldMapping::ISSUE_PRIORITY_MEDIUM)
|
||||
->issueNumber(770064);
|
||||
|
||||
// It is good practice to account for all source and destination fields
|
||||
// explicitly - this makes sure that everyone understands exactly what is
|
||||
// being migrated and what is not. Also, migrate_ui highlights unmapped
|
||||
// fields, or mappings involving fields not in the source and destination,
|
||||
// so if (for example) a new field is added to the destination field it's
|
||||
// immediately visible, and you can find out if anything needs to be
|
||||
// migrated into it.
|
||||
$this->addFieldMapping('format')
|
||||
->issueGroup(t('DNM'));
|
||||
$this->addFieldMapping('weight')
|
||||
->issueGroup(t('DNM'));
|
||||
$this->addFieldMapping('parent')
|
||||
->issueGroup(t('DNM'));
|
||||
|
||||
// We conditionally DNM these fields, so your field mappings will be clean
|
||||
// whether or not you have path and or pathauto enabled
|
||||
if (module_exists('path')) {
|
||||
$this->addFieldMapping('path')
|
||||
->issueGroup(t('DNM'));
|
||||
if (module_exists('pathauto')) {
|
||||
$this->addFieldMapping('pathauto')
|
||||
->issueGroup(t('DNM'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* And that's it for the BeerTerm migration! For a simple migration, all you
|
||||
* have to do is define the source, the destination, and mappings between the
|
||||
* two - to import the data you simply do:
|
||||
* drush migrate-import BeerTerm
|
||||
*
|
||||
* However, in real-world migrations not everything can be represented simply
|
||||
* through static mappings - you will frequently need to do some run-time
|
||||
* transformations of the data.
|
||||
*/
|
||||
class BeerUserMigration extends BasicExampleMigration {
|
||||
public function __construct() {
|
||||
// The basic setup is similar to BeerTermMigraiton
|
||||
parent::__construct();
|
||||
$this->description = t('Beer Drinkers of the world');
|
||||
$this->map = new MigrateSQLMap($this->machineName,
|
||||
array('aid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Account ID.'
|
||||
)
|
||||
),
|
||||
MigrateDestinationUser::getKeySchema()
|
||||
);
|
||||
$query = db_select('migrate_example_beer_account', 'mea')
|
||||
->fields('mea', array('aid', 'status', 'posted', 'name', 'nickname', 'password', 'mail', 'sex', 'beers'));
|
||||
$this->source = new MigrateSourceSQL($query);
|
||||
$this->destination = new MigrateDestinationUser();
|
||||
|
||||
// One good way to organize your mappings is in three groups - mapped fields,
|
||||
// unmapped source fields, and unmapped destination fields
|
||||
|
||||
// Mapped fields
|
||||
|
||||
// This is a shortcut you can use when the source and destination field
|
||||
// names are identical (i.e., the email address field is named 'mail' in
|
||||
// both the source table and in Drupal).
|
||||
$this->addSimpleMappings(array('status', 'mail'));
|
||||
|
||||
// Our source table has two entries for 'alice', but we must have a unique
|
||||
// username in the Drupal 'users' table. dedupe() creates new, unique
|
||||
// destination values when the source field of that value already exists.
|
||||
// For example, if we're importing a user with name 'test' and a user
|
||||
// 'test' already exists in the target, we'll create a new user named
|
||||
// 'test_1'.
|
||||
// dedupe() takes the Drupal table and column for determining uniqueness.
|
||||
$this->addFieldMapping('name', 'name')
|
||||
->dedupe('users', 'name');
|
||||
|
||||
// The migrate module automatically converts date/time strings to UNIX timestamps.
|
||||
$this->addFieldMapping('created', 'posted');
|
||||
|
||||
$this->addFieldMapping('pass', 'password');
|
||||
|
||||
// Instead of mapping a source field to a destination field, you can
|
||||
// hardcode a default value. You can also use both together - if a default
|
||||
// value is provided in addition to a source field, the default value will
|
||||
// be applied to any rows where the source field is empty or NULL.
|
||||
$this->addFieldMapping('roles')
|
||||
->defaultValue(DRUPAL_AUTHENTICATED_RID);
|
||||
|
||||
$this->addFieldMapping('field_migrate_example_gender', 'sex');
|
||||
|
||||
// The source field has beer names separated by a pipe character ('|'). By
|
||||
// adding ->separator('|'), the migration will automatically break them out,
|
||||
// look up the node with each title, and assign the node reference to this
|
||||
// user.
|
||||
if (module_exists('node_reference')) {
|
||||
$this->addFieldMapping('field_migrate_example_favbeers', 'beers')
|
||||
->separator('|');
|
||||
}
|
||||
|
||||
// Unmapped source fields
|
||||
$this->addFieldMapping(NULL, 'nickname')
|
||||
->issueGroup(t('DNM'));
|
||||
|
||||
// Unmapped destination fields
|
||||
|
||||
// This is a shortcut you can use to mark several destination fields as DNM
|
||||
// at once
|
||||
$this->addUnmigratedDestinations(array('theme', 'signature', 'access', 'login',
|
||||
'timezone', 'language', 'picture', 'is_new', 'signature_format', 'role_names'));
|
||||
|
||||
// Oops, we made a typo - this should have been 'init'! If you have
|
||||
// migrate_ui enabled, look at the BeerUser info page - you'll see that it
|
||||
// displays a warning "int used as destination field in mapping but not in
|
||||
// list of destination fields", and also lists "1 unmapped" under Destination,
|
||||
// where it highlights "init" as unmapped.
|
||||
$this->addFieldMapping('int')
|
||||
->issueGroup(t('DNM'));
|
||||
|
||||
if (module_exists('path')) {
|
||||
$this->addFieldMapping('path')
|
||||
->issueGroup(t('DNM'));
|
||||
if (module_exists('pathauto')) {
|
||||
$this->addFieldMapping('pathauto')
|
||||
->issueGroup(t('DNM'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The BeerNodeMigration uses the migrate_example_beer_node table as source
|
||||
* and creates Drupal nodes of type 'Beer' as destination.
|
||||
*/
|
||||
class BeerNodeMigration extends BasicExampleMigration {
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->description = t('Beers of the world');
|
||||
|
||||
// You may optionally declare dependencies for your migration - other migrations
|
||||
// which should run first. In this case, terms assigned to our nodes and
|
||||
// the authors of the nodes should be migrated before the nodes themselves.
|
||||
$this->dependencies = array('BeerTerm', 'BeerUser');
|
||||
|
||||
$this->map = new MigrateSQLMap($this->machineName,
|
||||
array(
|
||||
'bid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Beer ID.',
|
||||
'alias' => 'b',
|
||||
)
|
||||
),
|
||||
MigrateDestinationNode::getKeySchema()
|
||||
);
|
||||
|
||||
// We have a more complicated query. The Migration class fundamentally
|
||||
// depends on taking a single source row and turning it into a single
|
||||
// Drupal object, so how do we deal with zero or more terms attached to
|
||||
// each node? One way (demonstrated for MySQL) is to pull them into a single
|
||||
// comma-separated list.
|
||||
$query = db_select('migrate_example_beer_node', 'b')
|
||||
->fields('b', array('bid', 'name', 'body', 'excerpt', 'aid', 'countries',
|
||||
'image', 'image_alt', 'image_title', 'image_description'));
|
||||
$query->leftJoin('migrate_example_beer_topic_node', 'tb', 'b.bid = tb.bid');
|
||||
// Gives a single comma-separated list of related terms
|
||||
$query->groupBy('tb.bid');
|
||||
$query->addExpression('GROUP_CONCAT(tb.style)', 'terms');
|
||||
|
||||
// By default, MigrateSourceSQL derives a count query from the main query -
|
||||
// but we can override it if we know a simpler way
|
||||
$count_query = db_select('migrate_example_beer_node', 'b');
|
||||
$count_query->addExpression('COUNT(bid)', 'cnt');
|
||||
|
||||
// Passing the cache_counts option means the source count (shown in
|
||||
// drush migrate-status) will be cached - this can be very handy when
|
||||
// dealing with a slow source database.
|
||||
$this->source = new MigrateSourceSQL($query, array(), $count_query,
|
||||
array('cache_counts' => TRUE));
|
||||
|
||||
// Set up our destination - nodes of type migrate_example_beer
|
||||
$this->destination = new MigrateDestinationNode('migrate_example_beer');
|
||||
|
||||
// Mapped fields
|
||||
$this->addFieldMapping('title', 'name')
|
||||
->description(t('Mapping beer name in source to node title'));
|
||||
$this->addFieldMapping('sticky')
|
||||
->description(t('Should we default this to 0 or 1?'))
|
||||
->issueGroup(t('Client questions'))
|
||||
->issueNumber(765736)
|
||||
->issuePriority(MigrateFieldMapping::ISSUE_PRIORITY_LOW);
|
||||
|
||||
// To maintain node identities between the old and new systems (i.e., have
|
||||
// the same unique IDs), map the ID column from the old system to nid and
|
||||
// set is_new to TRUE. This works only if we're importing into a system that
|
||||
// has no existing nodes with the nids being imported.
|
||||
$this->addFieldMapping('nid', 'bid')
|
||||
->description(t('Preserve old beer ID as nid in Drupal'));
|
||||
$this->addFieldMapping('is_new')
|
||||
->defaultValue(TRUE);
|
||||
|
||||
// References to related objects (such as the author of the content) are
|
||||
// most likely going to be identifiers from the source data, not Drupal
|
||||
// identifiers (such as uids). You can use the mapping from the relevant
|
||||
// migration to translate from the old ID to the Drupal identifier.
|
||||
// Note that we also provide a default value of 1 - if the lookup fails to
|
||||
// find a corresponding uid for the aid, the owner will be the administrative
|
||||
// account.
|
||||
$this->addFieldMapping('uid', 'aid')
|
||||
->sourceMigration('BeerUser')
|
||||
->defaultValue(1);
|
||||
|
||||
// This is a multi-value text field
|
||||
$this->addFieldMapping('field_migrate_example_country', 'countries')
|
||||
->separator('|');
|
||||
// These are related terms, which by default will be looked up by name
|
||||
$this->addFieldMapping('migrate_example_beer_styles', 'terms')
|
||||
->separator(',');
|
||||
|
||||
// Some fields may have subfields such as text formats or summaries
|
||||
// (equivalent to teasers in previous Drupal versions).
|
||||
// These can be individually mapped as we see here.
|
||||
$this->addFieldMapping('body', 'body');
|
||||
$this->addFieldMapping('body:summary', 'excerpt');
|
||||
|
||||
// Copy an image file, write DB record to files table, and save in Field storage.
|
||||
// We map the filename (relative to the source_dir below) to the field itself.
|
||||
$this->addFieldMapping('field_migrate_example_image', 'image');
|
||||
// Here we specify the directory containing the source files.
|
||||
$this->addFieldMapping('field_migrate_example_image:source_dir')
|
||||
->defaultValue(drupal_get_path('module', 'migrate_example'));
|
||||
// And we map the alt and title values in the database to those on the image.
|
||||
$this->addFieldMapping('field_migrate_example_image:alt', 'image_alt');
|
||||
$this->addFieldMapping('field_migrate_example_image:title', 'image_title');
|
||||
|
||||
// No description for images, only alt and title
|
||||
$this->addUnmigratedSources(array('image_description'));
|
||||
|
||||
// Unmapped destination fields
|
||||
$this->addUnmigratedDestinations(array('created', 'changed', 'status',
|
||||
'promote', 'revision', 'language', 'revision_uid', 'log', 'tnid',
|
||||
'body:format', 'body:language', 'migrate_example_beer_styles:source_type',
|
||||
'migrate_example_beer_styles:create_term', 'field_migrate_example_image:destination_dir',
|
||||
'field_migrate_example_image:language', 'field_migrate_example_image:file_replace',
|
||||
'field_migrate_example_image:preserve_files', 'field_migrate_example_country:format',
|
||||
'field_migrate_example_country:language', 'comment',
|
||||
'field_migrate_example_image:file_class', 'field_migrate_example_image:destination_file'));
|
||||
|
||||
if (module_exists('path')) {
|
||||
$this->addFieldMapping('path')
|
||||
->issueGroup(t('DNM'));
|
||||
if (module_exists('pathauto')) {
|
||||
$this->addFieldMapping('pathauto')
|
||||
->issueGroup(t('DNM'));
|
||||
}
|
||||
}
|
||||
if (module_exists('statistics')) {
|
||||
$this->addUnmigratedDestinations(array('totalcount', 'daycount', 'timestamp'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Import items from the migrate_example_beer_comment table and make them into
|
||||
* Drupal comment objects.
|
||||
*/
|
||||
class BeerCommentMigration extends BasicExampleMigration {
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->description = 'Comments about beers';
|
||||
$this->dependencies = array('BeerUser', 'BeerNode');
|
||||
$this->map = new MigrateSQLMap($this->machineName,
|
||||
array('cid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
)
|
||||
),
|
||||
MigrateDestinationComment::getKeySchema()
|
||||
);
|
||||
$query = db_select('migrate_example_beer_comment', 'mec')
|
||||
->fields('mec', array('cid', 'cid_parent', 'name', 'mail', 'aid', 'body', 'bid', 'subject'))
|
||||
->orderBy('cid_parent', 'ASC');
|
||||
$this->source = new MigrateSourceSQL($query);
|
||||
$this->destination = new MigrateDestinationComment('comment_node_migrate_example_beer');
|
||||
|
||||
// Mapped fields
|
||||
$this->addSimpleMappings(array('name', 'subject', 'mail'));
|
||||
$this->addFieldMapping('status')
|
||||
->defaultValue(COMMENT_PUBLISHED);
|
||||
|
||||
// We preserved bid => nid ids during BeerNode import so simple mapping suffices.
|
||||
$this->addFieldMapping('nid', 'bid');
|
||||
|
||||
$this->addFieldMapping('uid', 'aid')
|
||||
->sourceMigration('BeerUser')
|
||||
->defaultValue(0);
|
||||
|
||||
$this->addFieldMapping('pid', 'cid_parent')
|
||||
->sourceMigration('BeerComment')
|
||||
->description('Parent comment.');
|
||||
|
||||
$this->addFieldMapping('comment_body', 'body');
|
||||
|
||||
// No unmapped source fields
|
||||
|
||||
// Unmapped destination fields
|
||||
$this->addUnmigratedDestinations(array('hostname', 'created', 'changed',
|
||||
'thread', 'homepage', 'language', 'comment_body:format', 'comment_body:language'));
|
||||
|
||||
if (module_exists('path')) {
|
||||
$this->addFieldMapping('path')
|
||||
->issueGroup(t('DNM'));
|
||||
}
|
||||
}
|
||||
}
|
678
sites/all/modules/migrate/migrate_example/beer.install.inc
Normal file
678
sites/all/modules/migrate/migrate_example/beer.install.inc
Normal file
@@ -0,0 +1,678 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Set up for the beer (basic) example.
|
||||
*/
|
||||
function migrate_example_beer_schema() {
|
||||
$schema['migrate_example_beer_account'] = migrate_example_beer_schema_account();
|
||||
$schema['migrate_example_beer_node'] = migrate_example_beer_schema_node();
|
||||
$schema['migrate_example_beer_comment'] = migrate_example_beer_schema_comment();
|
||||
$schema['migrate_example_beer_topic'] = migrate_example_beer_schema_topic();
|
||||
$schema['migrate_example_beer_topic_node'] = migrate_example_beer_schema_topic_node();
|
||||
|
||||
// These two tables are primarily for testing the table_copy plugin.
|
||||
// They do provide some guidance for uri redirection per uri_map_redirect.php
|
||||
$schema['migrate_example_beer_legacy_urls'] = migrate_example_beer_schema_legacy_urls();
|
||||
$schema['migrate_example_beer_copy_urls'] = migrate_example_beer_schema_legacy_urls();
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
function migrate_example_beer_install() {
|
||||
migrate_example_beer_content_type();
|
||||
migrate_example_beer_tags();
|
||||
migrate_example_beer_image();
|
||||
migrate_example_beer_country();
|
||||
migrate_example_beer_gender();
|
||||
if (module_exists('node_reference')) {
|
||||
migrate_example_beer_favs();
|
||||
}
|
||||
|
||||
// Populate our tables.
|
||||
migrate_example_beer_data_account();
|
||||
migrate_example_beer_data_node();
|
||||
migrate_example_beer_data_comment();
|
||||
migrate_example_beer_data_topic();
|
||||
migrate_example_beer_data_topic_node();
|
||||
migrate_example_beer_data_urls();
|
||||
}
|
||||
|
||||
function migrate_example_beer_uninstall() {
|
||||
if ($vids = taxonomy_vocabulary_load_multiple(array(), array('machine_name' => 'migrate_example_beer_styles'))) {
|
||||
// Grab key of the first returned vocabulary.
|
||||
taxonomy_vocabulary_delete(key($vids));
|
||||
}
|
||||
migrate_example_beer_content_type_delete();
|
||||
}
|
||||
|
||||
function migrate_example_beer_disable() {
|
||||
Migration::deregisterMigration('BeerTerm');
|
||||
Migration::deregisterMigration('BeerUser');
|
||||
Migration::deregisterMigration('BeerNode');
|
||||
Migration::deregisterMigration('BeerComment');
|
||||
}
|
||||
|
||||
function migrate_example_beer_schema_node() {
|
||||
return array(
|
||||
'description' => 'Beers of the world.',
|
||||
'fields' => array(
|
||||
'bid' => array(
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Beer ID.',
|
||||
),
|
||||
'name' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'body' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Full description of the beer.',
|
||||
),
|
||||
'excerpt' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Abstract for this beer.',
|
||||
),
|
||||
'countries' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Countries of origin. Multiple values, delimited by pipe',
|
||||
),
|
||||
'aid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account Id of the author.',
|
||||
),
|
||||
'image' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image path',
|
||||
),
|
||||
'image_alt' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image ALT',
|
||||
),
|
||||
'image_title' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image title',
|
||||
),
|
||||
'image_description' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image description',
|
||||
),
|
||||
),
|
||||
'primary key' => array('bid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_beer_schema_topic() {
|
||||
return array(
|
||||
'description' => 'Categories',
|
||||
'fields' => array(
|
||||
'style' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'details' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'style_parent' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Parent topic, if any',
|
||||
),
|
||||
'region' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Region first associated with this style',
|
||||
),
|
||||
'hoppiness' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Relative hoppiness of the beer',
|
||||
),
|
||||
),
|
||||
'primary key' => array('style'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_beer_schema_topic_node() {
|
||||
return array(
|
||||
'description' => 'Beers topic pairs.',
|
||||
'fields' => array(
|
||||
'bid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Beer ID.',
|
||||
),
|
||||
'style' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Topic name',
|
||||
),
|
||||
),
|
||||
'primary key' => array('style', 'bid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_beer_schema_comment() {
|
||||
return array(
|
||||
'description' => 'Beers comments.',
|
||||
'fields' => array(
|
||||
'cid' => array(
|
||||
'type' => 'serial',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Comment ID.',
|
||||
),
|
||||
'bid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Beer ID that is being commented upon',
|
||||
),
|
||||
'cid_parent' => array(
|
||||
'type' => 'int',
|
||||
'not null' => FALSE,
|
||||
'description' => 'Parent comment ID in case of comment replies.',
|
||||
),
|
||||
'subject' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Comment subject',
|
||||
),
|
||||
'body' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Comment body',
|
||||
),
|
||||
'name' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Comment name (if anon)',
|
||||
),
|
||||
'mail' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Comment email (if anon)',
|
||||
),
|
||||
'aid' => array(
|
||||
'type' => 'int',
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account ID (if any).',
|
||||
),
|
||||
),
|
||||
'primary key' => array('cid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_beer_schema_account() {
|
||||
return array(
|
||||
'description' => 'Beers accounts.',
|
||||
'fields' => array(
|
||||
'aid' => array(
|
||||
'type' => 'serial',
|
||||
//'not null' => TRUE,
|
||||
'description' => 'Account ID',
|
||||
),
|
||||
'status' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Blocked_Allowed',
|
||||
),
|
||||
'posted' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Registration date',
|
||||
),
|
||||
'name' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account name (for login)',
|
||||
),
|
||||
'nickname' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account name (for display)',
|
||||
),
|
||||
'password' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account password (raw)',
|
||||
),
|
||||
'mail' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Account email',
|
||||
),
|
||||
'sex' => array(
|
||||
'type' => 'int',
|
||||
'not null' => FALSE,
|
||||
'description' => 'Gender',
|
||||
),
|
||||
'beers' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Favorite Beers',
|
||||
),
|
||||
),
|
||||
'primary key' => array('aid'),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_beer_schema_legacy_urls() {
|
||||
return array(
|
||||
'description' => 'Stores legacy paths and destination ids for redirection.',
|
||||
'fields' => array(
|
||||
'id' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'description' => 'Primary Key: ID.',
|
||||
),
|
||||
'migration_name' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 50,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'source_id' => array(
|
||||
'type' => 'int',
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'source_uri' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 500,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'modificationdatetime' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
),
|
||||
'primary key' => array('ID'),
|
||||
'indexes' => array(
|
||||
'source_uri' => array(array('source_uri', 255)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function migrate_example_beer_content_type() {
|
||||
// This code based on from standard.profile.
|
||||
// Insert default user-defined node types into the database.
|
||||
$types = array(
|
||||
array(
|
||||
'type' => 'migrate_example_beer',
|
||||
'name' => st('Beer'),
|
||||
'base' => 'node_content',
|
||||
'description' => st("Beer is what we drink."),
|
||||
'custom' => 1,
|
||||
'modified' => 1,
|
||||
'locked' => 1,
|
||||
),
|
||||
);
|
||||
|
||||
foreach ($types as $type) {
|
||||
$type = node_type_set_defaults($type);
|
||||
node_type_save($type);
|
||||
node_add_body_field($type);
|
||||
}
|
||||
}
|
||||
|
||||
function migrate_example_beer_tags() {
|
||||
// Create a vocabulary named "Migrate Example Beer Styles", enabled for the 'migrate_example_beer' content type.
|
||||
$description = st('Use tags to group beers on similar topics into categories.');
|
||||
$help = st('Enter a comma-separated list of words to describe your content.');
|
||||
$vocabulary = (object) array(
|
||||
'name' => 'Migrate Example Beer Styles',
|
||||
'description' => $description,
|
||||
'machine_name' => 'migrate_example_beer_styles',
|
||||
'help' => $help,
|
||||
|
||||
);
|
||||
taxonomy_vocabulary_save($vocabulary);
|
||||
|
||||
if (!field_info_field('migrate_example_beer_styles')) {
|
||||
$field = array(
|
||||
'field_name' => $vocabulary->machine_name,
|
||||
'type' => 'taxonomy_term_reference',
|
||||
// Set cardinality to unlimited for tagging.
|
||||
'cardinality' => FIELD_CARDINALITY_UNLIMITED,
|
||||
'settings' => array(
|
||||
'allowed_values' => array(
|
||||
array(
|
||||
'vocabulary' => $vocabulary->machine_name,
|
||||
'vid' => $vocabulary->vid,
|
||||
'parent' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
field_create_field($field);
|
||||
}
|
||||
|
||||
if (!field_info_instance('node', 'migrate_example_beer_styles', 'migrate_example_beer')) {
|
||||
$instance = array(
|
||||
'field_name' => $vocabulary->machine_name,
|
||||
'entity_type' => 'node',
|
||||
'label' => $vocabulary->name,
|
||||
'bundle' => 'migrate_example_beer',
|
||||
'description' => $vocabulary->help,
|
||||
'widget' => array(
|
||||
'type' => 'taxonomy_autocomplete',
|
||||
),
|
||||
);
|
||||
field_create_instance($instance);
|
||||
}
|
||||
}
|
||||
|
||||
// Create an image field named "Migrate Example Image", enabled for the 'Beer' content type.
|
||||
function migrate_example_beer_image() {
|
||||
if (!field_info_field('field_migrate_example_image')) {
|
||||
$field = array(
|
||||
'field_name' => 'field_migrate_example_image',
|
||||
'type' => 'image',
|
||||
'cardinality' => 1,
|
||||
'translatable' => TRUE,
|
||||
'indexes' => array('fid' => array('fid')),
|
||||
'settings' => array(
|
||||
'uri_scheme' => 'public',
|
||||
'default_image' => FALSE,
|
||||
),
|
||||
);
|
||||
field_create_field($field);
|
||||
}
|
||||
|
||||
if (!field_info_instance('node', 'field_migrate_example_image', 'migrate_example_beer')) {
|
||||
$instance = array(
|
||||
'field_name' => 'field_migrate_example_image',
|
||||
'entity_type' => 'node',
|
||||
'label' => 'Image',
|
||||
'bundle' => 'migrate_example_beer',
|
||||
'description' => 'Upload an image to go with this beer.',
|
||||
'settings' => array(
|
||||
'file_directory' => 'field/migrate_example/image',
|
||||
'file_extensions' => 'png gif jpg jpeg',
|
||||
'max_filesize' => '',
|
||||
'max_resolution' => '',
|
||||
'min_resolution' => '',
|
||||
'alt_field' => TRUE,
|
||||
'title_field' => '',
|
||||
),
|
||||
|
||||
'widget' => array(
|
||||
'type' => 'image_image',
|
||||
'settings' => array(
|
||||
'progress_indicator' => 'throbber',
|
||||
'preview_image_style' => 'thumbnail',
|
||||
),
|
||||
'weight' => -1,
|
||||
),
|
||||
|
||||
'display' => array(
|
||||
'full' => array(
|
||||
'label' => 'hidden',
|
||||
'type' => 'image__large',
|
||||
'settings' => array(),
|
||||
'weight' => -1,
|
||||
),
|
||||
'teaser' => array(
|
||||
'label' => 'hidden',
|
||||
'type' => 'image_link_content__medium',
|
||||
'settings' => array(),
|
||||
'weight' => -1,
|
||||
),
|
||||
'rss' => array(
|
||||
'label' => 'hidden',
|
||||
'type' => 'image__large',
|
||||
'settings' => array(),
|
||||
'weight' => -1,
|
||||
),
|
||||
'search_index' => array(
|
||||
'label' => 'hidden',
|
||||
'type' => 'image__large',
|
||||
'settings' => array(),
|
||||
'weight' => -1,
|
||||
),
|
||||
'search_results' => array(
|
||||
'label' => 'hidden',
|
||||
'type' => 'image__large',
|
||||
'settings' => array(),
|
||||
'weight' => -1,
|
||||
),
|
||||
),
|
||||
);
|
||||
field_create_instance($instance);
|
||||
}
|
||||
}
|
||||
|
||||
function migrate_example_beer_favs() {
|
||||
if (!field_info_field('field_migrate_example_favbeers')) {
|
||||
$field = array(
|
||||
'field_name' => 'field_migrate_example_favbeers',
|
||||
'type' => 'node_reference',
|
||||
'cardinality' => -1,
|
||||
'settings' => array(
|
||||
'referenceable_types' => array('migrate_example_beer'),
|
||||
),
|
||||
);
|
||||
field_create_field($field);
|
||||
}
|
||||
|
||||
if (!field_info_instance('user', 'field_migrate_example_favbeers', 'user')) {
|
||||
$instance = array(
|
||||
'field_name' => 'field_migrate_example_favbeers',
|
||||
'entity_type' => 'user',
|
||||
'label' => 'Favorite Beers',
|
||||
'bundle' => 'user',
|
||||
'widget' => array(
|
||||
'type' => 'node_reference_autocomplete',
|
||||
),
|
||||
);
|
||||
field_create_instance($instance);
|
||||
}
|
||||
}
|
||||
|
||||
// Create Gender list field on User entity.
|
||||
function migrate_example_beer_gender() {
|
||||
if (!field_info_field('field_migrate_example_gender')) {
|
||||
$field = array(
|
||||
'field_name' => 'field_migrate_example_gender',
|
||||
'type' => 'list_integer',
|
||||
'settings' => array(
|
||||
'allowed_values' =>
|
||||
"0|Male\n" .
|
||||
"1|Female\n",
|
||||
),
|
||||
);
|
||||
field_create_field($field);
|
||||
}
|
||||
|
||||
if (!field_info_instance('user', 'field_migrate_example_gender', 'user')) {
|
||||
$instance = array(
|
||||
'field_name' => 'field_migrate_example_gender',
|
||||
'entity_type' => 'user',
|
||||
'label' => 'Gender',
|
||||
'bundle' => 'user',
|
||||
'widget' => array(
|
||||
'type' => 'options_select',
|
||||
),
|
||||
);
|
||||
field_create_instance($instance);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a text field named "Countries", enabled for the 'Beer' content type.
|
||||
function migrate_example_beer_country() {
|
||||
if (!field_info_field('field_migrate_example_country')) {
|
||||
$field = array(
|
||||
'field_name' => 'field_migrate_example_country',
|
||||
'type' => 'text',
|
||||
'cardinality' => -1,
|
||||
);
|
||||
field_create_field($field);
|
||||
}
|
||||
|
||||
if (!field_info_instance('node', 'field_migrate_example_country', 'migrate_example_beer')) {
|
||||
$instance = array(
|
||||
'field_name' => 'field_migrate_example_country',
|
||||
'entity_type' => 'node',
|
||||
'label' => 'Countries',
|
||||
'bundle' => 'migrate_example_beer',
|
||||
'description' => 'Beer country.',
|
||||
|
||||
'widget' => array(
|
||||
'type' => 'text_textfield',
|
||||
),
|
||||
);
|
||||
field_create_instance($instance);
|
||||
}
|
||||
}
|
||||
|
||||
function migrate_example_beer_content_type_delete() {
|
||||
$bundle = 'migrate_example_beer';
|
||||
$field_names = array('migrate_example_beer_styles', 'field_migrate_example_image', 'field_migrate_example_country');
|
||||
foreach ($field_names as $field_name) {
|
||||
$instance = field_info_instance('node', $field_name, $bundle);
|
||||
field_delete_instance($instance);
|
||||
field_delete_field($field_name);
|
||||
}
|
||||
node_type_delete($bundle);
|
||||
|
||||
$bundle = 'user';
|
||||
$field_names = array('field_migrate_example_gender');
|
||||
if (module_exists('node_reference')) {
|
||||
$field_names[] = 'field_migrate_example_favbeers';
|
||||
}
|
||||
foreach ($field_names as $field_name) {
|
||||
$instance = field_info_instance('user', $field_name, $bundle);
|
||||
field_delete_instance($instance);
|
||||
field_delete_field($field_name);
|
||||
}
|
||||
}
|
||||
|
||||
function migrate_example_beer_data_node() {
|
||||
$fields = array('bid', 'name', 'body', 'excerpt', 'countries', 'aid', 'image',
|
||||
'image_alt', 'image_title', 'image_description');
|
||||
$query = db_insert('migrate_example_beer_node')
|
||||
->fields($fields);
|
||||
// Use high bid numbers to avoid overwriting an existing node id.
|
||||
$data = array(
|
||||
array(99999999, 'Heineken', 'Blab Blah Blah Green', 'Green', 'Netherlands|Belgium', 0, 'heineken.jpg', 'Heinekin alt', 'Heinekin title', 'Heinekin description'), // comes with migrate_example project.
|
||||
array(99999998, 'Miller Lite', 'We love Miller Brewing', 'Tasteless', 'USA|Canada', 1, NULL, NULL, NULL, NULL),
|
||||
array(99999997, 'Boddington', 'English occassionally get something right', 'A treat', 'United Kingdom', 1, NULL, NULL, NULL, NULL),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
// Note that alice has duplicate username. Exercies dedupe() method.
|
||||
// @TODO duplicate email also.
|
||||
function migrate_example_beer_data_account() {
|
||||
$fields = array('status', 'posted', 'name', 'nickname', 'password', 'mail', 'sex', 'beers');
|
||||
$query = db_insert('migrate_example_beer_account')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, '2010-03-30 10:31:05', 'alice', 'alice hot pants', 'alicepass', 'alice@example.com', '1', '99999999|99999998|99999997'),
|
||||
array(1, '2010-04-04 10:31:05', 'alice', 'alice dupe pants', 'alicepass', 'alice2@example.com', '1', '99999999|99999998|99999997'),
|
||||
array(0, '2007-03-15 10:31:05', 'bob', 'rebob', 'bobpass', 'bob@example.com', '1', '99999999|99999997'),
|
||||
array(1, '2004-02-29 10:31:05', 'charlie', 'charlie chocolate', 'mykids', 'charlie@example.com', '0', '99999999|99999998'),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_beer_data_comment() {
|
||||
$fields = array('bid', 'cid_parent', 'subject', 'body', 'name', 'mail', 'aid');
|
||||
$query = db_insert('migrate_example_beer_comment')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(99999998, NULL, 'im first', 'hot body', 'alice', 'alice@example.com', 0),
|
||||
array(99999998, NULL, 'im second', 'hot body', 'alice', 'alice@example.com', 0),
|
||||
array(99999999, NULL, 'im parent', 'hot body', 'alice', 'alice@example.com', 0),
|
||||
array(99999999, 1, 'im child', 'cold body', 'bob', NULL, 1),
|
||||
array(99999999, 2, 'im grandchild', 'bitter body', 'charlie@example.com', NULL, 1),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_beer_data_topic() {
|
||||
$fields = array('style', 'details', 'style_parent', 'region', 'hoppiness');
|
||||
$query = db_insert('migrate_example_beer_topic')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array('ale', 'traditional', NULL, 'Medieval British Isles', 'Medium'),
|
||||
array('red ale', 'colorful', 'ale', NULL, NULL),
|
||||
array('pilsner', 'refreshing', NULL, 'Pilsen, Bohemia (now Czech Republic)', 'Low'),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_beer_data_topic_node() {
|
||||
$fields = array('bid', 'style');
|
||||
$query = db_insert('migrate_example_beer_topic_node')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(99999999, 'pilsner'),
|
||||
array(99999999, 'red ale'),
|
||||
array(99999998, 'red ale'),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
||||
|
||||
function migrate_example_beer_data_urls() {
|
||||
$fields = array('id', 'migration_name', 'source_id', 'source_uri', 'modificationdatetime');
|
||||
$query = db_insert('migrate_example_beer_legacy_urls')
|
||||
->fields($fields);
|
||||
$data = array(
|
||||
array(1, 'BeerNode', 99999997, 'the_boddington/main', strtotime('2010-04-12 08:32:06')),
|
||||
array(2, 'BeerNode', 99999998, 'Miller Lite taste', strtotime('2010-04-12 08:32:05')),
|
||||
array(3, 'BeerNode', 99999999, 'green wonder', strtotime('2010-04-12 08:32:03')),
|
||||
);
|
||||
foreach ($data as $row) {
|
||||
$query->values(array_combine($fields, $row));
|
||||
}
|
||||
$query->execute();
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Make a copy of the role table. To use this you must create a table named
|
||||
* role_copy with the same structure as role.
|
||||
*/
|
||||
|
||||
class RoleTableMigration extends Migration {
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->dependencies = array();
|
||||
$this->description = 'Copy the role table as an example of table_copy plugin.';
|
||||
$destination_key = array(
|
||||
'rid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
);
|
||||
$query = db_select('role', 'r')->fields('r');
|
||||
$this->source = new MigrateSourceSQL($query);
|
||||
$this->destination = new MigrateDestinationTableCopy('role_copy', $destination_key);
|
||||
|
||||
$this->map = new MigrateSQLMap($this->machineName,
|
||||
array('rid' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'alias' => 'r',
|
||||
)
|
||||
),
|
||||
$destination_key
|
||||
);
|
||||
}
|
||||
}
|
BIN
sites/all/modules/migrate/migrate_example/heineken.jpg
Normal file
BIN
sites/all/modules/migrate/migrate_example/heineken.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 119 KiB |
@@ -0,0 +1,27 @@
|
||||
name = "Migrate Example"
|
||||
description = "Example migration data."
|
||||
package = "Development"
|
||||
core = 7.x
|
||||
dependencies[] = taxonomy
|
||||
dependencies[] = image
|
||||
dependencies[] = comment
|
||||
dependencies[] = migrate
|
||||
dependencies[] = list
|
||||
dependencies[] = number
|
||||
|
||||
;node_reference is useful but not required
|
||||
;dependencies[] = node_reference
|
||||
|
||||
files[] = migrate_example.module
|
||||
files[] = beer.inc
|
||||
files[] = wine.inc
|
||||
|
||||
; For testing table_copy plugin. Since is infrequently used, we comment it out.
|
||||
; files[] = example.table_copy.inc
|
||||
|
||||
; Information added by drupal.org packaging script on 2012-06-02
|
||||
version = "7.x-2.4"
|
||||
core = "7.x"
|
||||
project = "migrate"
|
||||
datestamp = "1338661580"
|
||||
|
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Set up the migration example module.
|
||||
*/
|
||||
|
||||
require_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'migrate_example') .
|
||||
'/beer.install.inc';
|
||||
require_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'migrate_example') .
|
||||
'/wine.install.inc';
|
||||
|
||||
function migrate_example_schema() {
|
||||
$schema = migrate_example_beer_schema();
|
||||
$schema += migrate_example_wine_schema();
|
||||
return $schema;
|
||||
}
|
||||
|
||||
function migrate_example_install() {
|
||||
migrate_example_beer_install();
|
||||
migrate_example_wine_install();
|
||||
// A simple format for testing migration of format
|
||||
$example_format = array(
|
||||
'format' => 'migrate_example',
|
||||
'name' => 'Migrate example format',
|
||||
'weight' => 20,
|
||||
'filters' => array(
|
||||
// Escape all HTML.
|
||||
'filter_html_escape' => array(
|
||||
'weight' => 0,
|
||||
'status' => 1,
|
||||
),
|
||||
),
|
||||
);
|
||||
$example_format = (object) $example_format;
|
||||
filter_format_save($example_format);
|
||||
}
|
||||
|
||||
function migrate_example_uninstall() {
|
||||
migrate_example_beer_uninstall();
|
||||
migrate_example_wine_uninstall();
|
||||
if ($format = filter_format_load('migrate_example')) {
|
||||
filter_format_disable($format);
|
||||
}
|
||||
}
|
||||
|
||||
function migrate_example_disable() {
|
||||
migrate_example_beer_disable();
|
||||
migrate_example_wine_disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert modificationdate datetime field to modificationdatetime int field.
|
||||
*/
|
||||
function migrate_example_update_7001() {
|
||||
$ret = array();
|
||||
db_add_field('migrate_example_beer_legacy_urls', 'modificationdatetime', array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
)
|
||||
);
|
||||
|
||||
$result = db_select('migrate_example_beer_legacy_urls', 'ms')
|
||||
->fields('ms', array('machine_name', 'modificationdate'))
|
||||
->execute();
|
||||
foreach ($result as $row) {
|
||||
$modificationdatetime = strtotime($row->modificationdate);
|
||||
db_update('migrate_example_beer_legacy_urls')
|
||||
->fields(array('modificationdatetime' => $modificationdatetime))
|
||||
->condition('machine_name', $row->machineName)
|
||||
->execute();
|
||||
}
|
||||
|
||||
db_drop_field('migrate_example_beer_legacy_urls', 'modificationdate');
|
||||
|
||||
$ret[] = t('Converted modificationdate datetime field to modificationdatetime int field');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add image alt/title/description columns.
|
||||
*/
|
||||
function migrate_example_update_7002() {
|
||||
$ret = array();
|
||||
db_add_field('migrate_example_beer_node', 'image_alt', array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image ALT',
|
||||
)
|
||||
);
|
||||
db_add_field('migrate_example_beer_node', 'image_title', array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image title',
|
||||
)
|
||||
);
|
||||
db_add_field('migrate_example_beer_node', 'image_description', array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image description',
|
||||
)
|
||||
);
|
||||
db_update('migrate_example_beer_node')
|
||||
->fields(array(
|
||||
'image_alt' => 'Heinekin alt',
|
||||
'image_title' => 'Heinekin title',
|
||||
'image_description' => 'Heinekin description',
|
||||
))
|
||||
->condition('bid', 99999999)
|
||||
->execute();
|
||||
$ret[] = t('Added image_alt, image_title, and image_description fields.');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add data for remote file examples.
|
||||
*/
|
||||
function migrate_example_update_7003() {
|
||||
$ret = array();
|
||||
db_create_table('migrate_example_wine_files', migrate_example_wine_schema_files());
|
||||
migrate_example_wine_data_files();
|
||||
db_add_field('migrate_example_wine_account', 'imageid', array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Image ID.',
|
||||
)
|
||||
);
|
||||
db_update('migrate_example_wine_account')
|
||||
->fields(array('imageid' => 1))
|
||||
->condition('accountid', 9)
|
||||
->execute();
|
||||
$ret[] = t('Added migrate_example_wine_files table.');
|
||||
$ret[] = t('Added imageid field to migrate_example_wine_account table.');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add sample data for file fields. And, make the image field multi-value.
|
||||
*/
|
||||
function migrate_example_update_7004() {
|
||||
$ret = array();
|
||||
db_update('migrate_example_wine')
|
||||
->fields(array('image' => 'http://cyrve.com/files/penguin.jpeg'))
|
||||
->condition('wineid', 1)
|
||||
->execute();
|
||||
db_update('migrate_example_wine')
|
||||
->fields(array('image' => 'http://cyrve.com/files/rioja.jpeg|http://cyrve.com/files/boutisse_0.jpeg'))
|
||||
->condition('wineid', 2)
|
||||
->execute();
|
||||
$field = field_info_field('field_migrate_example_image');
|
||||
if ($field) {
|
||||
$field['cardinality'] = -1; // Unlimited
|
||||
field_update_field($field);
|
||||
}
|
||||
else {
|
||||
migrate_example_beer_image();
|
||||
migrate_example_wine_fields();
|
||||
}
|
||||
$ret[] = t('Added sample data for file fields.');
|
||||
$ret[] = t('Made field_migrate_example_image multi-value');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand file field example data.
|
||||
*/
|
||||
function migrate_example_update_7005() {
|
||||
$ret = array();
|
||||
// Easiest to just start over from scratch
|
||||
if (db_table_exists('migrate_example_wine_files')) {
|
||||
db_drop_table('migrate_example_wine_files');
|
||||
}
|
||||
db_create_table('migrate_example_wine_files', migrate_example_wine_schema_files());
|
||||
migrate_example_wine_data_files();
|
||||
|
||||
// Moved this data to migrate_example_wine_files
|
||||
if (db_field_exists('migrate_example_wine', 'image')) {
|
||||
db_drop_field('migrate_example_wine', 'image');
|
||||
}
|
||||
|
||||
$ret[] = t('Reconfigured sample data for file fields.');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sample data for table destinations..
|
||||
*/
|
||||
function migrate_example_update_7006() {
|
||||
$ret = array();
|
||||
db_create_table('migrate_example_wine_table_source', migrate_example_wine_schema_table_source());
|
||||
db_create_table('migrate_example_wine_table_dest', migrate_example_wine_schema_table_dest());
|
||||
migrate_example_wine_data_table_source();
|
||||
|
||||
$ret[] = t('Added sample data for table destinations.');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add data for testing/demonstrating roles.
|
||||
*/
|
||||
function migrate_example_update_7007() {
|
||||
$ret = array();
|
||||
db_add_field('migrate_example_wine_account', 'positions', array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'description' => 'Positions held',
|
||||
)
|
||||
);
|
||||
$query = db_update('migrate_example_wine_account')
|
||||
->fields(array('positions' => '5'))
|
||||
->condition('accountid', 1)
|
||||
->execute();
|
||||
db_update('migrate_example_wine_account')
|
||||
->fields(array('positions' => '18'))
|
||||
->condition('accountid', 3)
|
||||
->execute();
|
||||
db_update('migrate_example_wine_account')
|
||||
->fields(array('positions' => '5,18'))
|
||||
->condition('accountid', 9)
|
||||
->execute();
|
||||
$ret[] = t('Added positions field to migrate_example_wine_account table.');
|
||||
return $ret;
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* You must implement hook_migrate_api(), setting the API level to 2, for
|
||||
* your migration classes to be recognized by the Migrate module.
|
||||
*/
|
||||
function migrate_example_migrate_api() {
|
||||
$api = array(
|
||||
'api' => 2,
|
||||
);
|
||||
return $api;
|
||||
}
|
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implementation of hook_field_default_fields().
|
||||
*/
|
||||
function migrate_example_oracle_field_default_fields() {
|
||||
$fields = array();
|
||||
|
||||
// Exported field: 'node-migrate_example_oracle-body'
|
||||
$fields['node-migrate_example_oracle-body'] = array(
|
||||
'field_config' => array(
|
||||
'active' => '1',
|
||||
'cardinality' => '1',
|
||||
'deleted' => '0',
|
||||
'entity_types' => array(
|
||||
'0' => 'node',
|
||||
),
|
||||
'field_name' => 'body',
|
||||
'foreign keys' => array(
|
||||
'format' => array(
|
||||
'columns' => array(
|
||||
'format' => 'format',
|
||||
),
|
||||
'table' => 'filter_format',
|
||||
),
|
||||
),
|
||||
'indexes' => array(
|
||||
'format' => array(
|
||||
'0' => 'format',
|
||||
),
|
||||
),
|
||||
'module' => 'text',
|
||||
'settings' => array(),
|
||||
'translatable' => '1',
|
||||
'type' => 'text_with_summary',
|
||||
),
|
||||
'field_instance' => array(
|
||||
'bundle' => 'migrate_example_oracle',
|
||||
'default_value' => NULL,
|
||||
'deleted' => '0',
|
||||
'description' => '',
|
||||
'display' => array(
|
||||
'default' => array(
|
||||
'label' => 'hidden',
|
||||
'module' => 'text',
|
||||
'settings' => array(),
|
||||
'type' => 'text_default',
|
||||
'weight' => 0,
|
||||
),
|
||||
'teaser' => array(
|
||||
'label' => 'hidden',
|
||||
'module' => 'text',
|
||||
'settings' => array(
|
||||
'trim_length' => 600,
|
||||
),
|
||||
'type' => 'text_summary_or_trimmed',
|
||||
'weight' => 0,
|
||||
),
|
||||
),
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'body',
|
||||
'label' => 'Body',
|
||||
'required' => FALSE,
|
||||
'settings' => array(
|
||||
'display_summary' => TRUE,
|
||||
'text_processing' => 1,
|
||||
'user_register_form' => FALSE,
|
||||
),
|
||||
'widget' => array(
|
||||
'module' => 'text',
|
||||
'settings' => array(
|
||||
'rows' => 20,
|
||||
'summary_rows' => 5,
|
||||
),
|
||||
'type' => 'text_textarea_with_summary',
|
||||
'weight' => '-4',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Exported field: 'node-migrate_example_oracle-field_mainimage'
|
||||
$fields['node-migrate_example_oracle-field_mainimage'] = array(
|
||||
'field_config' => array(
|
||||
'active' => '1',
|
||||
'cardinality' => '1',
|
||||
'deleted' => '0',
|
||||
'entity_types' => array(),
|
||||
'field_name' => 'field_mainimage',
|
||||
'foreign keys' => array(
|
||||
'fid' => array(
|
||||
'columns' => array(
|
||||
'fid' => 'fid',
|
||||
),
|
||||
'table' => 'file_managed',
|
||||
),
|
||||
),
|
||||
'indexes' => array(
|
||||
'fid' => array(
|
||||
'0' => 'fid',
|
||||
),
|
||||
),
|
||||
'module' => 'image',
|
||||
'settings' => array(
|
||||
'default_image' => 0,
|
||||
'uri_scheme' => 'public',
|
||||
),
|
||||
'translatable' => '1',
|
||||
'type' => 'image',
|
||||
),
|
||||
'field_instance' => array(
|
||||
'bundle' => 'migrate_example_oracle',
|
||||
'deleted' => '0',
|
||||
'description' => '',
|
||||
'display' => array(
|
||||
'default' => array(
|
||||
'label' => 'above',
|
||||
'module' => 'image',
|
||||
'settings' => array(
|
||||
'image_link' => '',
|
||||
'image_style' => '',
|
||||
),
|
||||
'type' => 'image',
|
||||
'weight' => 1,
|
||||
),
|
||||
'teaser' => array(
|
||||
'label' => 'above',
|
||||
'settings' => array(),
|
||||
'type' => 'hidden',
|
||||
'weight' => 0,
|
||||
),
|
||||
),
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_mainimage',
|
||||
'label' => 'Main image',
|
||||
'required' => FALSE,
|
||||
'settings' => array(
|
||||
'alt_field' => 0,
|
||||
'file_directory' => '',
|
||||
'file_extensions' => 'png gif jpg jpeg',
|
||||
'max_filesize' => '',
|
||||
'max_resolution' => '',
|
||||
'min_resolution' => '',
|
||||
'title_field' => 0,
|
||||
'user_register_form' => FALSE,
|
||||
),
|
||||
'widget' => array(
|
||||
'module' => 'image',
|
||||
'settings' => array(
|
||||
'preview_image_style' => 'thumbnail',
|
||||
'progress_indicator' => 'throbber',
|
||||
),
|
||||
'type' => 'image_image',
|
||||
'weight' => '-3',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Translatables
|
||||
// Included for use with string extractors like potx.
|
||||
t('Body');
|
||||
t('Main image');
|
||||
|
||||
return $fields;
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implementation of hook_node_info().
|
||||
*/
|
||||
function migrate_example_oracle_node_info() {
|
||||
$items = array(
|
||||
'migrate_example_oracle' => array(
|
||||
'name' => t('Migrate example - oracle'),
|
||||
'base' => 'node_content',
|
||||
'description' => t('Example and test fodder for migration directly from an Oracle database.'),
|
||||
'has_title' => '1',
|
||||
'title_label' => t('Title'),
|
||||
'help' => '',
|
||||
),
|
||||
);
|
||||
return $items;
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
core = "7.x"
|
||||
dependencies[] = "features"
|
||||
dependencies[] = "image"
|
||||
dependencies[] = "migrate"
|
||||
description = "Content type supporting example of Oracle migration"
|
||||
features[field][] = "node-migrate_example_oracle-body"
|
||||
features[field][] = "node-migrate_example_oracle-field_mainimage"
|
||||
features[node][] = "migrate_example_oracle"
|
||||
files[] = "migrate_example_oracle.migrate.inc"
|
||||
name = "Migrate example - Oracle"
|
||||
package = "Migrate Examples"
|
||||
project = "migrate_example_oracle"
|
||||
|
||||
; Information added by drupal.org packaging script on 2012-06-02
|
||||
version = "7.x-2.4"
|
||||
core = "7.x"
|
||||
project = "migrate"
|
||||
datestamp = "1338661580"
|
||||
|
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Set up the Oracle migration example module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function migrate_example_oracle_install() {
|
||||
global $conf;
|
||||
|
||||
// Should never fail - we can't get here unless hook_requirements passed, right?
|
||||
$connection = @oci_connect($conf['oracle_db']['username'], $conf['oracle_db']['password'],
|
||||
$conf['oracle_db']['connection_string'], 'UTF8');
|
||||
if (!$connection) {
|
||||
$e = oci_error();
|
||||
throw new Exception($e['message']);
|
||||
}
|
||||
|
||||
// Create a table to hold test data
|
||||
$query = "CREATE TABLE ORACLE_CONTENT
|
||||
(OID NUMBER NOT NULL,
|
||||
TITLE VARCHAR2(255) NOT NULL,
|
||||
BODY CLOB NOT NULL,
|
||||
MAINIMAGE BLOB NOT NULL,
|
||||
CREATED DATE NOT NULL,
|
||||
UPDATED DATE NOT NULL,
|
||||
CONSTRAINT ORACLE_CONTENT_PK PRIMARY KEY (OID)
|
||||
)";
|
||||
$result = oci_parse($connection, $query);
|
||||
if (!$result) {
|
||||
$e = oci_error($connection);
|
||||
throw new Exception($e['message'] . "\n" . $e['sqltext']);
|
||||
}
|
||||
$status = oci_execute($result);
|
||||
if (!$status) {
|
||||
$e = oci_error($result);
|
||||
throw new Exception($e['message'] . "\n" . $e['sqltext']);
|
||||
}
|
||||
|
||||
// Insert a test row or three
|
||||
$query = "INSERT INTO ORACLE_CONTENT
|
||||
(OID, TITLE, BODY, MAINIMAGE, CREATED, UPDATED)
|
||||
VALUES(:oid, :title, EMPTY_CLOB(), EMPTY_BLOB(),
|
||||
TO_DATE(:created, 'yyyy/mm/dd hh24:mi:ss'),
|
||||
TO_DATE(:updated, 'yyyy/mm/dd hh24:mi:ss'))
|
||||
RETURNING body, mainimage INTO :body, :mainimage";
|
||||
$result = oci_parse($connection, $query);
|
||||
if (!$result) {
|
||||
$e = oci_error($connection);
|
||||
throw new Exception($e['message'] . "\n" . $e['sqltext']);
|
||||
}
|
||||
|
||||
$data = migrate_example_oracle_sample_data();
|
||||
|
||||
oci_bind_by_name($result, ':oid', $oid, 1, SQLT_INT);
|
||||
oci_bind_by_name($result, ':title', $title, 255, SQLT_CHR);
|
||||
$body_clob = oci_new_descriptor($connection, OCI_D_LOB);
|
||||
$image_blob = oci_new_descriptor($connection, OCI_D_LOB);
|
||||
oci_bind_by_name($result, ':body', $body_clob, -1, SQLT_CLOB);
|
||||
oci_bind_by_name($result, ':mainimage', $image_blob, -1, SQLT_BLOB);
|
||||
oci_bind_by_name($result, ':created', $created, 9, SQLT_CHR);
|
||||
oci_bind_by_name($result, ':updated', $updated, 9, SQLT_CHR);
|
||||
foreach ($data as $row) {
|
||||
extract($row);
|
||||
$status = oci_execute($result, OCI_DEFAULT);
|
||||
if (!$status) {
|
||||
$e = oci_error($result);
|
||||
throw new Exception($e['message'] . "\n" . $e['sqltext']);
|
||||
}
|
||||
$body_clob->save($body);
|
||||
$image_blob->save($mainimage);
|
||||
}
|
||||
oci_commit($connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*/
|
||||
function migrate_example_oracle_uninstall() {
|
||||
global $conf;
|
||||
|
||||
$connection = @oci_connect($conf['oracle_db']['username'], $conf['oracle_db']['password'],
|
||||
$conf['oracle_db']['connection_string'], 'UTF8');
|
||||
if (!$connection) {
|
||||
$e = oci_error();
|
||||
throw new Exception($e['message']);
|
||||
}
|
||||
|
||||
// Get rid of the test data
|
||||
// This SQL from http://dbaforums.org/oracle/index.php?showtopic=4990.
|
||||
$query = "begin execute immediate 'drop table ORACLE_CONTENT'; exception when others then null; end;";
|
||||
$result = oci_parse($connection, $query);
|
||||
if (!$result) {
|
||||
$e = oci_error($connection);
|
||||
throw new Exception($e['message'] . "\n" . $e['sqltext']);
|
||||
}
|
||||
$status = oci_execute($result);
|
||||
if (!$status) {
|
||||
$e = oci_error($result);
|
||||
throw new Exception($e['message'] . "\n" . $e['sqltext']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_requirements().
|
||||
*/
|
||||
function migrate_example_oracle_requirements($phase) {
|
||||
$requirements = array();
|
||||
$t = get_t();
|
||||
switch ($phase) {
|
||||
case 'install':
|
||||
// Check that the OCI8 extension is loaded
|
||||
$requirements['oci8'] = array('title' => $t('Oracle extension'));
|
||||
if (!extension_loaded('oci8')) {
|
||||
$requirements['oci8']['description'] = $t('Migrating from an Oracle
|
||||
database requires that you have the !link extension loaded in PHP.',
|
||||
array('!link' => l('oci8', 'http://us.php.net/manual/en/book.oci8.php')));
|
||||
$requirements['oci8']['severity'] = REQUIREMENT_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
$sample_setting =
|
||||
'<pre>
|
||||
$conf[\'oracle_db\'] = array(
|
||||
\'username\' => \'Oracle_username\',
|
||||
\'password\' => \'Oracle_password\',
|
||||
\'connection_string\' => \'//Oracle_host/SID\',
|
||||
);
|
||||
</pre>';
|
||||
// Check that there is an Oracle database configured for use
|
||||
$requirements['oracle_db'] = array('title' => $t('Oracle configuration'));
|
||||
global $conf;
|
||||
if (empty($conf['oracle_db']) || empty($conf['oracle_db']['username']) ||
|
||||
empty($conf['oracle_db']['password']) || empty($conf['oracle_db']['connection_string'])) {
|
||||
$requirements['oracle_db']['description'] = $t('You must define $conf[\'oracle_db\']
|
||||
(in your site\'s settings.php file) to point to the Oracle database where
|
||||
you want test data to be stored: ' . $sample_setting);
|
||||
$requirements['oracle_db']['severity'] = REQUIREMENT_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check that we can connect to the Oracle db.
|
||||
$requirements['oracle_connect'] = array('title' => $t('Oracle connection available'));
|
||||
$connection = oci_connect($conf['oracle_db']['username'], $conf['oracle_db']['password'],
|
||||
$conf['oracle_db']['connection_string'], 'UTF8');
|
||||
if (!$connection) {
|
||||
$e = oci_error();
|
||||
$requirements['oracle_connect']['description'] = $t('Could not connect to configured
|
||||
Oracle database at !conn_string. Oracle error message: !message',
|
||||
array('!conn_string' => $conf['oracle_db']['connection_string'],
|
||||
'!message' => $e['message']));
|
||||
$requirements['oracle_connect']['severity'] = REQUIREMENT_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check for necessary privileges
|
||||
$requirements['oracle_privs'] = array('title' => $t('Necessary Oracle privileges are assigned'));
|
||||
$statement = oci_parse($connection, 'SELECT * FROM SESSION_PRIVS');
|
||||
if (!$statement) {
|
||||
$e = oci_error($connection);
|
||||
$requirements['oracle_connect']['description'] = $e['message'];
|
||||
$requirements['oracle_connect']['severity'] = REQUIREMENT_ERROR;
|
||||
break;
|
||||
}
|
||||
$result = oci_execute($statement);
|
||||
if (!$result) {
|
||||
$e = oci_error($statement);
|
||||
$requirements['oracle_connect']['description'] = $e['message'];
|
||||
$requirements['oracle_connect']['severity'] = REQUIREMENT_ERROR;
|
||||
break;
|
||||
}
|
||||
$ok = FALSE;
|
||||
while ($row = oci_fetch_object($statement)) {
|
||||
if ($row->PRIVILEGE == 'CREATE TABLE') {
|
||||
$ok = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$ok) {
|
||||
$requirements['oracle_privs']['description'] = $t('The specified
|
||||
username !username does not have the CREATE TABLE privilege. This privilege
|
||||
is necessary to create test tables in the Oracle database.',
|
||||
array('!username' => $conf['oracle_db']['username']));
|
||||
$requirements['oracle_privs']['severity'] = REQUIREMENT_ERROR;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'update':
|
||||
break;
|
||||
case 'runtime':
|
||||
break;
|
||||
}
|
||||
return $requirements;
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Examples and test fodder for migration from Oracle sources. To use this example
|
||||
* (and to run the corresponding tests) you must define a connection to an Oracle database
|
||||
* in your settings.php. E.g.,
|
||||
*
|
||||
* $conf['oracle_db'] = array(
|
||||
* 'username' => 'DRUPAL',
|
||||
* 'password' => 'DRUPAL',
|
||||
* 'connection_string' => '//oracledb/orcl',
|
||||
* );
|
||||
*
|
||||
* The username must have the CREATE TABLE privilege, so test data can be stored for the
|
||||
* example to import.
|
||||
*
|
||||
* See http://us.php.net/manual/en/function.oci-connect.php for more information on
|
||||
* connection_string.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Migration class to test importing from Oracle into nodes.
|
||||
*/
|
||||
class MigrateExampleOracleNode extends Migration {
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->description = t('Example migration from Oracle into nodes.');
|
||||
|
||||
// Note that Oracle by default upper-cases all identifiers, so use upper-case
|
||||
// for the key name and for source fields below.
|
||||
$this->map = new MigrateSQLMap($this->machineName,
|
||||
array(
|
||||
'OID' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'Content ID',
|
||||
)
|
||||
),
|
||||
MigrateDestinationNode::getKeySchema()
|
||||
);
|
||||
|
||||
// Source fields available from the Oracle table.
|
||||
$fields = array(
|
||||
'OID' => t('Source id'),
|
||||
'TITLE' => t('Title'),
|
||||
'BODY' => t('Description'),
|
||||
'MAINIMAGE' => t('Main image'),
|
||||
'CREATED' => t('Creation date'),
|
||||
'UPDATED' => t('Updated date'),
|
||||
);
|
||||
|
||||
// Oracle will usually (depending on server configuration) return only a
|
||||
// date (such as 01-MAY-11) for datetime fields - you need to use TO_CHAR()
|
||||
// to extract time information as well.
|
||||
$query = "SELECT OID, TITLE, BODY, MAINIMAGE, TO_CHAR(CREATED, 'yyyy/mm/dd hh24:mi:ss') CREATED,
|
||||
TO_CHAR(UPDATED, 'yyyy/mm/dd hh24:mi:ss') UPDATED
|
||||
FROM ORACLE_CONTENT";
|
||||
$count_query = "SELECT COUNT(*) FROM ORACLE_CONTENT";
|
||||
|
||||
// Per above, the connection info should be defined in settings.php.
|
||||
global $conf;
|
||||
$this->source = new MigrateSourceOracle($conf['oracle_db'], $query,
|
||||
$count_query, $fields);
|
||||
$this->destination = new MigrateDestinationNode('migrate_example_oracle');
|
||||
|
||||
// Basic fields
|
||||
$this->addFieldMapping('title', 'TITLE');
|
||||
$this->addFieldMapping('uid')
|
||||
->defaultValue(1);
|
||||
$this->addFieldMapping('body', 'BODY');
|
||||
$this->addFieldMapping('field_mainimage', 'MAINIMAGE')
|
||||
->description('An image blob in the DB')
|
||||
->arguments(array(
|
||||
'file_function' => 'file_blob',
|
||||
// Alternatively, specify a column here for dynamic file name.
|
||||
'source_path' => 'druplicon.png',
|
||||
|
||||
));
|
||||
$this->addFieldMapping('created', 'CREATED');
|
||||
$this->addFieldMapping('changed', 'UPDATED');
|
||||
|
||||
|
||||
// Unmapped destination fields
|
||||
$this->addUnmigratedDestinations(array('is_new', 'status', 'promote',
|
||||
'revision', 'language', 'sticky', 'revision_uid', 'path'));
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
include_once('migrate_example_oracle.features.inc');
|
||||
|
||||
/*
|
||||
* Implementation of hook_migrate_api().
|
||||
*/
|
||||
function migrate_example_oracle_migrate_api() {
|
||||
$api = array(
|
||||
'api' => 2,
|
||||
);
|
||||
return $api;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a text string of reproducible contents for a given length.
|
||||
*
|
||||
* @param int $length
|
||||
* Number of characters to generate.
|
||||
*
|
||||
* $return
|
||||
* String of the given length.
|
||||
*/
|
||||
function migrate_example_oracle_generate($length) {
|
||||
$base = 'word '; // Five characters long
|
||||
$multiplier = ($length / 5) + 1; // 80% chance of going a bit long, thus substr below
|
||||
$data = str_repeat($base, $multiplier);
|
||||
$data = substr($data, 0, $length);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of data rows for testing Oracle import. Note that 4000 is a magic
|
||||
* number for Oracle LOB datatypes, so we testing lengths above and below that limit.
|
||||
*/
|
||||
function migrate_example_oracle_sample_data() {
|
||||
$image = file_get_contents('misc/druplicon.png');
|
||||
return array(
|
||||
array('oid' => 3, 'title' => 'Sample title', 'body' => 'Sample body',
|
||||
'mainimage' => $image, 'created' => '2011/05/01 01:02:03',
|
||||
'updated' => '2011/06/30 04:05:06'),
|
||||
array('oid' => 5, 'title' => 'Another title', 'body' => migrate_example_oracle_generate(3900),
|
||||
'mainimage' => $image, 'created' => '2011/08/12 07:08:09',
|
||||
'updated' => '2011/12/25 10:11:12'),
|
||||
array('oid' => 7, 'title' => 'Yet another title', 'body' => migrate_example_oracle_generate(4500),
|
||||
'mainimage' => $image, 'created' => '2012/01/01 13:14:15',
|
||||
'updated' => '2012/03/14 16:17:18'),
|
||||
);
|
||||
}
|
1236
sites/all/modules/migrate/migrate_example/wine.inc
Normal file
1236
sites/all/modules/migrate/migrate_example/wine.inc
Normal file
File diff suppressed because it is too large
Load Diff
1253
sites/all/modules/migrate/migrate_example/wine.install.inc
Normal file
1253
sites/all/modules/migrate/migrate_example/wine.install.inc
Normal file
File diff suppressed because it is too large
Load Diff
7
sites/all/modules/migrate/migrate_example/xml/0001.xml
Normal file
7
sites/all/modules/migrate/migrate_example/xml/0001.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<producer>
|
||||
<name>Lolonis Winery</name>
|
||||
<description>Makers of Ladybug Red</description>
|
||||
<authorid>3</authorid>
|
||||
<region>Redwood Valley</region>
|
||||
</producer>
|
4
sites/all/modules/migrate/migrate_example/xml/index.xml
Normal file
4
sites/all/modules/migrate/migrate_example/xml/index.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<content>
|
||||
<sourceid>0001</sourceid>
|
||||
</content>
|
11
sites/all/modules/migrate/migrate_example/xml/positions.xml
Normal file
11
sites/all/modules/migrate/migrate_example/xml/positions.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<positions>
|
||||
<position>
|
||||
<sourceid>5</sourceid>
|
||||
<name>Taster</name>
|
||||
</position>
|
||||
<position>
|
||||
<sourceid>18</sourceid>
|
||||
<name>Vintner</name>
|
||||
</position>
|
||||
</positions>
|
17
sites/all/modules/migrate/migrate_example/xml/producers.xml
Normal file
17
sites/all/modules/migrate/migrate_example/xml/producers.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<producers>
|
||||
<producer>
|
||||
<sourceid>0002</sourceid>
|
||||
<name>Blue Sky Winery</name>
|
||||
<description>Makers of Warm Sun Blush</description>
|
||||
<authorid>1</authorid>
|
||||
<region>Redwood Valley</region>
|
||||
</producer>
|
||||
<producer>
|
||||
<sourceid>0003</sourceid>
|
||||
<name>Meriam Winery</name>
|
||||
<description>Makers of Extra Dry Chardonnay</description>
|
||||
<authorid>9</authorid>
|
||||
<region>Redwood Valley</region>
|
||||
</producer>
|
||||
</producers>
|
17
sites/all/modules/migrate/migrate_example/xml/producers2.xml
Normal file
17
sites/all/modules/migrate/migrate_example/xml/producers2.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<producers>
|
||||
<producer>
|
||||
<sourceid>0005</sourceid>
|
||||
<name>Boston Winery</name>
|
||||
<description>Boston's only winery</description>
|
||||
<authorid>1</authorid>
|
||||
<region>Elba</region>
|
||||
</producer>
|
||||
<producer>
|
||||
<sourceid>0008</sourceid>
|
||||
<name>Nashoba Valley Winery</name>
|
||||
<description>Methode champenoise</description>
|
||||
<authorid>9</authorid>
|
||||
<region>Chile</region>
|
||||
</producer>
|
||||
</producers>
|
Reference in New Issue
Block a user