* Add a foreign key constraint to make person_emails and purpose_emails sync

the person_id.
* Misc fixes with the bugzilla_sync_email trigger.
This commit is contained in:
Toshio Kuratomi 2008-03-11 15:04:44 -07:00
parent ecf68e2c1f
commit 4d8973658f

View file

@ -78,6 +78,7 @@ CREATE TABLE person_emails (
description text, description text,
verified boolean NOT NULL DEFAULT false, verified boolean NOT NULL DEFAULT false,
creation TIMESTAMP WITH TIME ZONE DEFAULT NOW(), creation TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
unique (id, person_id),
unique (email, verified) --You can't "claim" an email before you verify it first unique (email, verified) --You can't "claim" an email before you verify it first
); );
@ -89,6 +90,8 @@ CREATE TABLE email_purposes (
person_id INTEGER NOT NULL references people(id), person_id INTEGER NOT NULL references people(id),
purpose text NOT NULL, purpose text NOT NULL,
primary key (person_id, purpose), primary key (person_id, purpose),
foreign key (email_id, person_id) references person_emails(id,
person_id) on update cascade,
check (purpose ~ ('(bugzilla|primary|cla|pending|other[0-9]+)')) check (purpose ~ ('(bugzilla|primary|cla|pending|other[0-9]+)'))
); );
@ -308,12 +311,12 @@ create or replace function bugzilla_sync() returns trigger as $bz_sync$
return None return None
# Retrieve the bugzilla email address # Retrieve the bugzilla email address
plan = plpy.prepare("select email, purpose from person_emails as pee," plan = plpy.prepare("select email, purpose from person_emails as pem,"
" email_purposes as epu" " email_purposes as epu"
" where epu.id = epu.email_id and pee.person_id = $1" " where pem.id = epu.email_id and pem.person_id = $1"
" and purpose in ('bugzilla', 'primary')", " and epu.purpose in ('bugzilla', 'primary')",
('integer',)) ('int4',))
result = plpy.execute(plan, row['person_id']) result = plpy.execute(plan, (row['person_id'],))
email = None email = None
for record in result: for record in result:
email = record['email'] email = record['email']
@ -333,7 +336,7 @@ create or replace function bugzilla_sync() returns trigger as $bz_sync$
else: else:
plan = plpy.prepare("insert into bugzilla_queue (email, group_id" plan = plpy.prepare("insert into bugzilla_queue (email, group_id"
", person_id, action) values ($1, $2, $3, $4)", ", person_id, action) values ($1, $2, $3, $4)",
('text', 'integer', 'integer', 'char')) ('text', 'int4', 'int4', 'char'))
plpy.execute(plan, (email, row['group_id'], row['person_id'], newaction)) plpy.execute(plan, (email, row['group_id'], row['person_id'], newaction))
return None return None
$bz_sync$ language plpythonu; $bz_sync$ language plpythonu;
@ -352,7 +355,7 @@ create or replace function bugzilla_sync_email() returns trigger AS $bz_sync_e$
plan = plpy.prepare("select * from people as p, person_roles as r" plan = plpy.prepare("select * from people as p, person_roles as r"
" where p.id = r.person_id and r.group_id = $1" " where p.id = r.person_id and r.group_id = $1"
" and r.role_status = 'approved' and p.id = $2", " and r.role_status = 'approved' and p.id = $2",
('integer', 'integer',)) ('int4', 'int4',))
result = plpy.execute(plan, (group_id, person_id), 1) result = plpy.execute(plan, (group_id, person_id), 1)
if result: if result:
return True return True
@ -366,7 +369,7 @@ create or replace function bugzilla_sync_email() returns trigger AS $bz_sync_e$
emailAffectsBz = False emailAffectsBz = False
possible = False possible = False
plan = plpy.prepare("select purpose from email_purposes where" plan = plpy.prepare("select purpose from email_purposes where"
" email_id = $1", ('integer',)) " email_id = $1", ('int4',))
result = plpy.execute(plan, (email_id,)) result = plpy.execute(plan, (email_id,))
for record in result: for record in result:
if record['purpose'] == 'bugzilla': if record['purpose'] == 'bugzilla':
@ -379,7 +382,7 @@ create or replace function bugzilla_sync_email() returns trigger AS $bz_sync_e$
# If it's primary, we have to check that the user doesn't have a # If it's primary, we have to check that the user doesn't have a
# different email setup for bugzilla # different email setup for bugzilla
plan = plpy.prepare("select purpose from email_purposes where" plan = plpy.prepare("select purpose from email_purposes where"
" person_id = $1 and purpose = 'bugzilla'", ('integer',)) " person_id = $1 and purpose = 'bugzilla'", ('int4',))
result = plpy.execute(plan, (person_id,), 1) result = plpy.execute(plan, (person_id,), 1)
if not result: if not result:
# A separate bugzilla email address does not exist # A separate bugzilla email address does not exist
@ -426,6 +429,7 @@ create or replace function bugzilla_sync_email() returns trigger AS $bz_sync_e$
if oldHasBugs and oldAffectsBz: if oldHasBugs and oldAffectsBz:
# Remove the old email # Remove the old email
changes[TD['old']['email']] = (TD['old']['email'], fedorabugsId, TD['old']['person_id'], 'r') changes[TD['old']['email']] = (TD['old']['email'], fedorabugsId, TD['old']['person_id'], 'r')
if TD['new']['person_id'] != TD['old']['person_id']: if TD['new']['person_id'] != TD['old']['person_id']:
# Email changed owners. If one owner has fedorabugs and the other # Email changed owners. If one owner has fedorabugs and the other
# does not we have to adjust. # does not we have to adjust.
@ -437,25 +441,54 @@ create or replace function bugzilla_sync_email() returns trigger AS $bz_sync_e$
# Remove the email address # Remove the email address
changes[TD['old']['email']] = (TD['old']['email'], fedorabugsId, TD['old']['person_id'], 'r') changes[TD['old']['email']] = (TD['old']['email'], fedorabugsId, TD['old']['person_id'], 'r')
# If both have fedorabugs, we need to decide which of the addresses to
# use with bugzilla.
if oldHasBugs and newHasBugs and newAffectsBz:
# Retrieve the bugzilla email address
plan = plpy.prepare("select email, purpose from person_emails as pem,"
" email_purposes as epu"
" where pem.id = epu.email_id and pem.person_id = $1"
" and epu.purpose in ('bugzilla', 'primary')", ('int4',))
result = plpy.execute(plan, (TD['new']['person_id'],))
email = None
bzEmail = False
for record in result:
email = record['email']
if record['purpose'] == 'bugzilla':
bzEmail = True
break
# Note: we depend on the unique constraint having already run and
# stopped us from getting to this point with two email addresses
# for the same purpose.
# Since only one can be the bzEmail address and only one the
# primary, we can do what we need only knowing the purpose for one
# of the email addresses.
if bzEmail:
# Remove the new email address as the old one is the bz email
changes[TD['new']['email']] = (TD['new']['email'], fedorabugsId, TD['new']['person_id'], 'r')
else:
# Remove the current email address
changes[email] = (email, fedorabugsId, TD['new']['person_id'], 'r')
if TD['new']['verified'] != TD['old']['verified']: if TD['new']['verified'] != TD['old']['verified']:
if TD['new']['verified'] and newHasBugs and newAffectsBz: if TD['new']['verified'] and newHasBugs and newAffectsBz:
# Add the email address # Add the email address
if not TD['new']['email'] in changes: if not TD['new']['email'] in changes:
changes[TD['new']['email']] = (TD['new']['email'], fedorabugsId, TD['new']['person_id'], 'a') changes[TD['new']['email']] = (TD['new']['email'], fedorabugsId, TD['new']['person_id'], 'a')
elif not TD['new']['verified'] and oldHasBugs and oldAffectsBz: elif not TD['new']['verified'] and oldHasBugs and oldAffectsBz:
# Remove the email address # Remove the email address
changes[TD['old']['email']] = (TD['old']['email'], fedorabugsId, TD['old']['person_id'], 'r') changes[TD['old']['email']] = (TD['old']['email'], fedorabugsId, TD['old']['person_id'], 'r')
# Now actually add the changes to the queue. # Now actually add the changes to the queue.
for email in changes: for email in changes:
plan = plpy.prepare("select email from bugzilla_queue where email = $1", plan = plpy.prepare("select email from bugzilla_queue where email = $1", ('text',))
('text',))
result = plpy.execute(plan, (email,), 1) result = plpy.execute(plan, (email,), 1)
if result: if result:
# Update another record with the new information # Update another record with the new information
plan = plpy.prepare("update bugzilla_queue set email = $1," plan = plpy.prepare("update bugzilla_queue set email = $1,"
" group_id = $2, person_id = $3, action = $4" " group_id = $2, person_id = $3, action = $4"
" where email = $5", ('text', 'integer', 'integer', 'char', 'text')) " where email = $5", ('text', 'int4', 'int4', 'char', 'text'))
params = list(changes[email]) params = list(changes[email])
params.append(email) params.append(email)
plpy.execute(plan, params) plpy.execute(plan, params)
@ -463,7 +496,7 @@ create or replace function bugzilla_sync_email() returns trigger AS $bz_sync_e$
# Add a brand new record # Add a brand new record
plan = plpy.prepare("insert into bugzilla_queue" plan = plpy.prepare("insert into bugzilla_queue"
" (email, group_id, person_id, action) values" " (email, group_id, person_id, action) values"
" ($1, $2, $3, $3)", ('text', 'integer', 'integer', 'char')) " ($1, $2, $3, $4)", ('text', 'int4', 'int4', 'char'))
plpy.execute(plan, changes[email]) plpy.execute(plan, changes[email])
return None return None
$bz_sync_e$ language plpythonu; $bz_sync_e$ language plpythonu;