When creating and updating tables, domain prefix should also update the sequence table. Otherwise new contents on affiliate site will have ID clash.

Comments

agentrickard’s picture

When using database prefixing, each table that uses the {sequences} table gets its own entry in the form 'tablename_variable' -- so I do not see why this is an issue.

Are you having actual problems?

agentrickard’s picture

Category: feature » bug

I see -- here's the potential issue:

Sites: example.com and test.example.com

Tables for {views} created for both domains. We create some views in both, and get the following variables:

view_view_vid          4
domain_1_view_vid  2

Now this should not be an issue unless you select the "update" option. In that case, we copy the 4 views from example.com, but the sequence for test.example.com id is at 2, so if we create a new view on test.example.com, we would get an id error.

I suppose that during the 'update' sequence, we would have to go through the {sequences} table, find the items that are prefixed, and then copy their 'parent' elements over.

Note that this is not an issue in the D6 version, since {sequences} has been deprecated.

If anyone wants to try a patch, we would insert a function into this sequence, lines 555-566 of domain_prefix.module:

        else if ($value == DOMAIN_PREFIX_UPDATE) {
          if ($exists > 0) {
            db_query("TRUNCATE TABLE {%s}", $newtable);
            db_query("INSERT INTO {%s} SELECT * FROM {%s}", $newtable, $sourcetable);
            // New function to be written to update {sequences}
            domain_prefix_update_sequences($prefix);
            if ($msg) {
              drupal_set_message(t('!string table updated from source.', array('!string' => $newtable)));
            }
            $update = TRUE;
            // Set the stored value to "copy" for record keeping.
            $value = DOMAIN_PREFIX_COPY;
          }
        }
agentrickard’s picture

Hm. This is actually more complex than described above. We cannot simply update _all_ the matching sequences, since we don't always want to update every item associated with a domain.

But, there may not be an easy way to determine which variables are assigned to which tables without knowing the table name.

So:

            // New function to be written to update {sequences}
            domain_prefix_update_sequences($prefix, $newtable);
agentrickard’s picture

OK. We need to run this on both COPY and UPDATE. Working on the patch.

agentrickard’s picture

Assigned: Unassigned » agentrickard
Status: Active » Needs review
StatusFileSize
new4.31 KB

Patch addresses the COPY and UPDATE routines -- and on DELETE and UNINSTALL as well.

agentrickard’s picture

Status: Needs review » Needs work

This patch is not quite right. We must use the $sourcetable and not assume the default table.

agentrickard’s picture

Status: Needs work » Needs review
StatusFileSize
new4.88 KB

OK. This patch should work.

ariflukito’s picture

hi agentrickard unfortunately it doesn't work when you have global db_prefix set. For example if $db_prefix = 'drupal'. the record in sequences table will be something like drupal_menu_mid and drupal_node_nid.

agentrickard’s picture

Status: Needs review » Needs work

There is a way to account for that; I just overlooked it -- which is what patch testing is for. Thanks!

agentrickard’s picture

Status: Needs work » Needs review
StatusFileSize
new4.93 KB

OK. Here's a new patch that should fix this issue.

ariflukito’s picture

ok couple problems
- domain_prefix_drop and domain_prefix uninstall still does not honor global prefix
- prefixing node table also add node_revision entry to sequence table (just an example if 2 tables share the same name)
- you forgot to modify 1 call to domain_prefix_update_sequences in DOMAIN_PREFIX_UPDATE
- variable $source in domain_prefix_update_sequences is unused

maybe is best to modify query to use {} rather than calling domain_prefix_get_prefix(), ie:

db_query("SELECT name, id FROM {sequences} WHERE name LIKE '%s%'", $sourcetable);
to
db_query("SELECT name, id FROM {sequences} WHERE name LIKE '{%s%}'", $sourcetable);

what do you think

agentrickard’s picture

I'd like to see a patch that addresses these issues.

Issue #1 needs more detail.

Prefixing the node tables is a very bad idea -- it would, in effect, break DA, since you split the node tables across multiple domains, then the node access rules would work unpredictably.

agentrickard’s picture

Status: Needs review » Needs work
agentrickard’s picture

To ensure that we only prefix the proper table -- via string matching such as node_* catching node_revisions_* by accident -- we will have to parse the string using explode().

agentrickard’s picture

Status: Needs work » Needs review
StatusFileSize
new5.35 KB

Using {%s} seems to be a good choice.

New patch for testing.

ariflukito’s picture

StatusFileSize
new4.83 KB

Doesn't work when the source table is not from primary domain.

Also if we have something like this drupal_node_node_id (the table name drupal_node), it will not work. However I've never seen something like that so probably we can safely ignore that.

The attached patch has different approach, it takes the shortest match. However it will fail if have something like this.
- we have node_revision in sequences table but no node record, so copying node table will add node_revision to sequences instead.
- we have sequence name like this drupal_node_verylooooooooooooonggggid

I ve just realized them but I attached the patch anyway, my patch also fixes the first issue I mention here.

agentrickard’s picture

Status: Needs review » Postponed (maintainer needs more info)

OK, when giving these reports, more detail would help. I think the issue to fix is the first one. Shortest match is not the proper solution.

"Doesn't work when the source table is not from primary domain."

But _what happens_ when you do that?

agentrickard’s picture

Status: Postponed (maintainer needs more info) » Needs review
StatusFileSize
new5.34 KB

Here's another patch. Using a regex to strip out parts of the variable name that we don't want.

ariflukito’s picture

StatusFileSize
new4.85 KB

Ok the latest one works fine but I made some changes

- move $dbprefix = domain_prefix_get_prefix() one line up so we don't have to call it twice
- change the $prefix argument to $newtable
- it doesn't use regex, it uses substr instead so $newvariable is constructed like this
$newvariable = $newtable . substr($variable['name'], strlen($dbprefix . $sourcetable));

agentrickard’s picture

Nice. I may not ge a chance to test for a bit, though, since I am on the road.

Originally, I had the regex in order to be sure to strip all possible global $db_prefix strings and combinations of 'domain_#'.

We need a little more testing, I think.

agentrickard’s picture

Status: Needs review » Fixed

Seems to work on both prefixed and non-prefixed databases. Committed.

Excellent work on this patch!

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.