first import

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-08 11:40:19 +02:00
commit 1bc61b12ad
8435 changed files with 1582817 additions and 0 deletions

View 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'));
}
}
}

View 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();
}

View File

@@ -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
);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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'));
}
}

View File

@@ -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'),
);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<content>
<sourceid>0001</sourceid>
</content>

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

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

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