launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #06019
[Merge] lp:~stevenk/launchpad/db-merge-stable-redux into lp:launchpad
Steve Kowalik has proposed merging lp:~stevenk/launchpad/db-merge-stable-redux into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~stevenk/launchpad/db-merge-stable-redux/+merge/87298
Merge stable at r14617.
--
https://code.launchpad.net/~stevenk/launchpad/db-merge-stable-redux/+merge/87298
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~stevenk/launchpad/db-merge-stable-redux into lp:launchpad.
=== modified file 'database/sampledata/current-dev.sql'
--- database/sampledata/current-dev.sql 2011-12-13 15:21:25 +0000
+++ database/sampledata/current-dev.sql 2012-01-02 22:37:27 +0000
@@ -1,6 +1,6 @@
-- Copyright 2010-2011 Canonical Ltd. This software is licensed under the
-- GNU Affero General Public License version 3 (see the file LICENSE).
--- Created using pg_dump (PostgreSQL) 8.4.8
+-- Created using pg_dump (PostgreSQL) 8.4.9
SET check_function_bodies = false;
SET client_encoding = 'UTF8';
@@ -5752,6 +5752,13 @@
ALTER TABLE messagechunk ENABLE TRIGGER ALL;
+ALTER TABLE milestonetag DISABLE TRIGGER ALL;
+
+
+
+ALTER TABLE milestonetag ENABLE TRIGGER ALL;
+
+
ALTER TABLE mirror DISABLE TRIGGER ALL;
=== modified file 'database/sampledata/current.sql'
--- database/sampledata/current.sql 2011-12-13 15:21:25 +0000
+++ database/sampledata/current.sql 2012-01-02 22:37:27 +0000
@@ -1,6 +1,6 @@
-- Copyright 2010-2011 Canonical Ltd. This software is licensed under the
-- GNU Affero General Public License version 3 (see the file LICENSE).
--- Created using pg_dump (PostgreSQL) 8.4.8
+-- Created using pg_dump (PostgreSQL) 8.4.9
SET check_function_bodies = false;
SET client_encoding = 'UTF8';
@@ -5682,6 +5682,13 @@
ALTER TABLE messagechunk ENABLE TRIGGER ALL;
+ALTER TABLE milestonetag DISABLE TRIGGER ALL;
+
+
+
+ALTER TABLE milestonetag ENABLE TRIGGER ALL;
+
+
ALTER TABLE mirror DISABLE TRIGGER ALL;
=== modified file 'database/schema/comments.sql'
--- database/schema/comments.sql 2011-11-17 13:06:30 +0000
+++ database/schema/comments.sql 2012-01-02 22:37:27 +0000
@@ -2425,3 +2425,8 @@
'OpenId Identifiers that can be used to log into an Account.';
COMMENT ON COLUMN OpenIdIdentifier.identifier IS
'OpenId Identifier. This should be a URL, but is currently just a token that can be used to generate the Identity URL for the Canonical SSO OpenId Provider.';
+
+-- MilestoneTag
+COMMENT ON TABLE milestonetag IS 'Attaches simple text tags to a milestone.';
+COMMENT ON COLUMN milestonetag.milestone IS 'The milestone the tag is attached to.';
+COMMENT ON COLUMN milestonetag.tag IS 'The text representation of the tag.';
=== modified file 'database/schema/fti.py'
--- database/schema/fti.py 2011-12-31 00:07:44 +0000
+++ database/schema/fti.py 2012-01-02 22:37:27 +0000
@@ -11,6 +11,8 @@
"""
__metaclass__ = type
+import _pythonpath
+
from distutils.version import LooseVersion
from optparse import OptionParser
import os.path
@@ -20,24 +22,23 @@
from textwrap import dedent
import time
-import _pythonpath
import psycopg2.extensions
-import replication.helpers
-from canonical.config import config
-from canonical.database.postgresql import ConnectionString
-from canonical.database.sqlbase import (
+from lp.services.config import config
+from lp.services.database.postgresql import ConnectionString
+from lp.services.database.sqlbase import (
connect,
ISOLATION_LEVEL_AUTOCOMMIT,
ISOLATION_LEVEL_READ_COMMITTED,
quote,
quote_identifier,
)
-from canonical.launchpad.scripts import (
+from lp.services.scripts import (
db_options,
logger,
logger_options,
)
+import replication.helpers
# Defines parser and locale to use.
DEFAULT_CONFIG = 'default'
=== added file 'database/schema/patch-2209-00-3.sql'
--- database/schema/patch-2209-00-3.sql 1970-01-01 00:00:00 +0000
+++ database/schema/patch-2209-00-3.sql 2012-01-02 22:37:27 +0000
@@ -0,0 +1,22 @@
+-- Copyright 2011 Canonical Ltd. This software is licensed under the
+-- GNU Affero General Public License version 3 (see the file LICENSE).
+
+SET client_min_messages=ERROR;
+
+CREATE TABLE milestonetag (
+ id SERIAL PRIMARY KEY,
+ milestone integer NOT NULL REFERENCES milestone ON DELETE CASCADE,
+ tag text NOT NULL,
+ date_created timestamp without time zone DEFAULT
+ timezone('UTC'::text, now()) NOT NULL,
+ created_by integer NOT NULL REFERENCES person,
+ CONSTRAINT valid_tag CHECK (valid_name(tag))
+);
+
+ALTER TABLE ONLY milestonetag
+ ADD CONSTRAINT milestonetag__tag__milestone__key UNIQUE (tag, milestone);
+
+CREATE INDEX milestonetag__milestones_idx
+ ON milestonetag USING btree (milestone);
+
+INSERT INTO LaunchpadDatabaseRevision VALUES (2209, 0, 3);
=== added file 'database/schema/patch-2209-00-4.sql'
--- database/schema/patch-2209-00-4.sql 1970-01-01 00:00:00 +0000
+++ database/schema/patch-2209-00-4.sql 2012-01-02 22:37:27 +0000
@@ -0,0 +1,57 @@
+SET client_min_messages=ERROR;
+
+CREATE OR REPLACE FUNCTION check_email_address_person_account(
+ person integer, account integer)
+ RETURNS boolean
+ LANGUAGE plpythonu IMMUTABLE RETURNS NULL ON NULL INPUT AS
+$$
+ # It's possible for an EmailAddress to be created without an
+ # account. If that happens, and this function is called, we return
+ # True so as to avoid breakages.
+ if account is None:
+ return True
+ results = plpy.execute("""
+ SELECT account FROM Person WHERE id = %s""" % person)
+ # If there are no accounts with that Person in the DB, or the Person
+ # is new and hasn't yet been linked to an account, return success
+ # anyway. This helps avoid the PGRestore breaking (and referential
+ # integrity will prevent this from causing bugs later.
+ if results.nrows() == 0 or results[0]['account'] is None:
+ return True
+ return results[0]['account'] == account
+$$;
+
+COMMENT ON FUNCTION check_email_address_person_account(integer, integer) IS
+'Check that the person to which an email address is linked has the same account as that email address.';
+
+CREATE OR REPLACE FUNCTION check_person_email_address_account(
+ person integer, account integer)
+ RETURNS boolean
+ LANGUAGE plpythonu IMMUTABLE RETURNS NULL ON NULL INPUT AS
+$$
+ # It's possible for a Person to be created without an account. If
+ # that happens, return True so that things don't break.
+ if account is None:
+ return True
+ email_address_accounts = plpy.execute("""
+ SELECT account FROM EmailAddress WHERE
+ person = %s AND account IS NOT NULL""" % person)
+ # If there are no email address accounts to check, we're done.
+ if email_address_accounts.nrows() == 0:
+ return True
+ for email_account_row in email_address_accounts:
+ email_account = email_account_row['account']
+ if email_account is not None and email_account != account:
+ return False
+ return True
+$$;
+
+COMMENT ON FUNCTION check_person_email_address_account(integer, integer) IS
+'Check that the email addresses linked to a person have the same account ID as that person.';
+
+ALTER TABLE EmailAddress ADD CONSTRAINT valid_account_for_person
+ CHECK (check_email_address_person_account(person, account));
+ALTER TABLE Person ADD CONSTRAINT valid_account_for_emailaddresses
+ CHECK (check_person_email_address_account(id, account));
+
+INSERT INTO LaunchpadDatabaseRevision VALUES (2209, 00, 4);
=== modified file 'database/schema/security.cfg'
--- database/schema/security.cfg 2011-12-23 11:57:21 +0000
+++ database/schema/security.cfg 2012-01-02 22:37:27 +0000
@@ -18,6 +18,8 @@
public.bug_update_latest_patch_uploaded(integer) =
public.bugnotificationarchive =
public.calculate_bug_heat(integer) = EXECUTE
+public.check_email_address_person_account(integer, integer) = EXECUTE
+public.check_person_email_address_account(integer, integer) = EXECUTE
public.cursor_fetch(refcursor, integer) = EXECUTE
public.databasediskutilization =
public.debversion(character) = EXECUTE
@@ -221,6 +223,7 @@
public.messageapproval = SELECT, INSERT, UPDATE, DELETE
public.messagechunk = SELECT, INSERT
public.milestone = SELECT, INSERT, UPDATE, DELETE
+public.milestonetag = SELECT, INSERT, UPDATE, DELETE
public.mirrorcdimagedistroseries = SELECT, INSERT, DELETE
public.mirrordistroarchseries = SELECT, INSERT, DELETE, UPDATE
public.mirrordistroseriessource = SELECT, INSERT, UPDATE, DELETE
@@ -591,6 +594,7 @@
public.message = SELECT, INSERT
public.messagechunk = SELECT, INSERT
public.milestone = SELECT
+public.milestonetag = SELECT
public.person = SELECT, INSERT, UPDATE
public.personlanguage = SELECT
public.personsettings = SELECT, INSERT
@@ -649,6 +653,7 @@
public.karmaaction = SELECT
public.message = SELECT, INSERT
public.messagechunk = SELECT, INSERT
+public.milestonetag = SELECT
public.person = SELECT
public.revision = SELECT, INSERT, UPDATE
public.revisionauthor = SELECT, INSERT, UPDATE
@@ -862,6 +867,7 @@
public.message = SELECT, INSERT
public.messagechunk = SELECT, INSERT
public.milestone = SELECT
+public.milestonetag = SELECT
public.packagecopyjob = SELECT, INSERT, DELETE
public.packagecopyrequest = SELECT, INSERT, UPDATE
public.packagediff = SELECT, INSERT, UPDATE
@@ -1301,6 +1307,7 @@
public.message = SELECT, INSERT
public.messagechunk = SELECT, INSERT
public.milestone = SELECT
+public.milestonetag = SELECT
public.packagebuild = SELECT, INSERT, UPDATE
public.packagecopyjob = SELECT, INSERT
public.packagediff = SELECT, INSERT, UPDATE, DELETE
@@ -1404,6 +1411,7 @@
public.message = SELECT, INSERT
public.messagechunk = SELECT, INSERT
public.milestone = SELECT
+public.milestonetag = SELECT
public.packagebuild = SELECT, INSERT, UPDATE
public.packagecopyjob = SELECT, INSERT, UPDATE
public.packagediff = SELECT, UPDATE
@@ -1502,6 +1510,7 @@
public.message = SELECT, INSERT
public.messagechunk = SELECT, INSERT
public.milestone = SELECT
+public.milestonetag = SELECT
public.person = SELECT
public.personlanguage = SELECT
public.personsettings = SELECT
@@ -1706,6 +1715,7 @@
public.message = SELECT, INSERT
public.messagechunk = SELECT, INSERT
public.milestone = SELECT
+public.milestonetag = SELECT, INSERT, DELETE
public.packageset = SELECT
public.packagesetgroup = SELECT
public.packagesetinclusion = SELECT
@@ -1946,6 +1956,7 @@
public.job = SELECT, INSERT, UPDATE
public.message = SELECT, INSERT
public.messagechunk = SELECT, INSERT
+public.milestonetag = SELECT
public.person = SELECT, INSERT
public.personsettings = SELECT, INSERT
public.product = SELECT, INSERT, UPDATE
@@ -2044,6 +2055,7 @@
public.message = SELECT, UPDATE
public.messageapproval = SELECT, UPDATE
public.milestone = SELECT, UPDATE
+public.milestonetag = SELECT, INSERT, UPDATE, DELETE
public.mirror = SELECT, UPDATE
public.nameblacklist = SELECT, UPDATE
public.oauthaccesstoken = SELECT, UPDATE
@@ -2146,6 +2158,7 @@
public.job = SELECT, INSERT, DELETE
public.logintoken = SELECT, DELETE
public.mailinglistsubscription = SELECT, DELETE
+public.milestonetag = SELECT
public.oauthnonce = SELECT, DELETE
public.openidconsumerassociation = SELECT, DELETE
public.openidconsumernonce = SELECT, DELETE
=== removed symlink 'lib/canonical/config/__init__.py'
=== target was u'../../lp/services/config/__init__.py'
=== removed directory 'lib/canonical/database'
=== removed file 'lib/canonical/database/__init__.py'
=== removed file 'lib/canonical/database/postgresql.py'
--- lib/canonical/database/postgresql.py 2011-12-31 00:07:44 +0000
+++ lib/canonical/database/postgresql.py 1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
-# Copyright 2011 Canonical Ltd. This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-# Temporary shim for fti.py.
-
-__all__ = [
- 'ConnectionString',
- ]
-
-from lp.services.database.postgresql import ConnectionString
=== removed file 'lib/canonical/database/sqlbase.py'
--- lib/canonical/database/sqlbase.py 2011-12-31 00:07:44 +0000
+++ lib/canonical/database/sqlbase.py 1970-01-01 00:00:00 +0000
@@ -1,20 +0,0 @@
-# Copyright 2011 Canonical Ltd. This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-# Temporary shim for fti.py.
-
-__all__ = [
- 'connect',
- 'ISOLATION_LEVEL_AUTOCOMMIT',
- 'ISOLATION_LEVEL_READ_COMMITTED',
- 'quote',
- 'quote_identifier',
- ]
-
-from lp.services.database.sqlbase import (
- connect,
- ISOLATION_LEVEL_AUTOCOMMIT,
- ISOLATION_LEVEL_READ_COMMITTED,
- quote,
- quote_identifier,
- )
=== removed directory 'lib/canonical/launchpad/scripts'
=== removed file 'lib/canonical/launchpad/scripts/__init__.py'
--- lib/canonical/launchpad/scripts/__init__.py 2011-12-22 04:36:01 +0000
+++ lib/canonical/launchpad/scripts/__init__.py 1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-# This is a temporary shim to support database/schema/fti.py in devel.
-
-__all__ = [
- 'db_options',
- 'logger',
- 'logger_options',
- ]
-
-from lp.services.scripts import (
- db_options,
- logger,
- logger_options,
- )
=== modified file 'lib/lp/registry/tests/test_person.py'
--- lib/lp/registry/tests/test_person.py 2011-12-30 06:14:56 +0000
+++ lib/lp/registry/tests/test_person.py 2012-01-02 22:37:27 +0000
@@ -55,7 +55,10 @@
IMasterStore,
IStore,
)
-from lp.services.database.sqlbase import cursor
+from lp.services.database.sqlbase import (
+ cursor,
+ sqlvalues,
+ )
from lp.services.identity.interfaces.account import (
AccountCreationRationale,
AccountStatus,
@@ -847,8 +850,17 @@
with celebrity_logged_in('admin'):
email = from_person.preferredemail
email.status = EmailAddressStatus.NEW
- email.person = to_person
- email.account = to_person.account
+ store = IMasterStore(EmailAddress)
+ # EmailAddress.acount and .person need to be updated at the
+ # same time to prevent the constraints on the account field
+ # from kicking the change out.
+ store.execute("""
+ UPDATE EmailAddress SET
+ person = %s,
+ account = %s
+ WHERE id = %s
+ """ % sqlvalues(
+ to_person.id, to_person.accountID, email.id))
transaction.commit()
def _do_merge(self, from_person, to_person, reviewer=None):