view src/nabble/model/DbSiteUpdater.java @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children
line wrap: on
line source


package nabble.model;

import fschmidt.db.DbDatabase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;


final class DbSiteUpdater {
	private static final Logger logger = LoggerFactory.getLogger(DbSiteUpdater.class);

	// don't forget to update site.schema
	static final int version = 167;

	private static class Result {
		private static final long wait = 2000L;  // 2 seconds
		private final long waitUntil = System.currentTimeMillis() + wait;
		private DbSiteUpdater updater;
		private SQLException sqlException = null;
		private RuntimeException runtimeException = null;
		private Error error = null;
		private final String user;

		private Result(DbDatabase db,String user) {
			updater = new DbSiteUpdater(db,this,user);
			this.user = user;
			updater.start();
		}

		private synchronized void check() throws SQLException {
			if( !isDone() ) {
				long now = System.currentTimeMillis();
				if( now < waitUntil ) {
					try {
						wait( waitUntil - now );
					} catch(InterruptedException e) {
						throw new RuntimeException(e);
					}
				}
				if( !isDone() )
					throw new UpdatingException(user);
			}
			if( sqlException != null )
				throw sqlException;
			if( runtimeException != null )
				throw runtimeException;
			if( error != null )
				throw error;
		}

		synchronized boolean isDone() {
			return updater==null;
		}

		synchronized void done(Throwable e) {
			updater = null;
			if( e != null ) {
				if( e instanceof SQLException ) {
					sqlException = (SQLException)e;
				} else if( e instanceof RuntimeException ) {
					runtimeException = (RuntimeException)e;
				} else if( e instanceof Error ) {
					error = (Error)e;
				} else {
					runtimeException = new RuntimeException("invalid exception type",e);
				}
			}
			notifyAll();
		}
	}

	private static final Map<String,Result> userResults = new HashMap<String,Result>();
	private static final Object lock = new Object();

	static void update(String user,DbDatabase db) throws SQLException {
		if( user.equals("global") )
			return;  // done from command line
		getResult(user,db).check();
	}

	private static Result getResult(String user,DbDatabase db) throws SQLException {
		synchronized(lock) {
			Result result = userResults.get(user);
			if( result == null ) {
				result = new Result(db,user);
				userResults.put(user,result);
			}
			return result;
		}
	}

	// for shell
	public static void clearResult(long siteId) {
		String user = SiteKey.getInstance(siteId).schema();
		synchronized(lock) {
			userResults.remove(user);
		}
	}




	private final Result result;
	private final DbUpdater up;

	private DbSiteUpdater(DbDatabase db,Result result,String schema) {
		this.up = new DbUpdater(db,schema);
		this.result = result;
	}

	private void start() {
		try {  // needed for site creation because version is only up to date in current transaction
			if( up.dbVersion() == version ) {
				result.done(null);
				return;
			}
		} catch(RuntimeException e) {
			result.done(e);
			return;
		} catch(Error e) {
			result.done(e);
			return;
		}
		Executors.executeNow(new Runnable(){public void run(){
			try {
				go();
				result.done(null);
			} catch(SQLException e) {
				result.done(e);
			} catch(RuntimeException e) {
				result.done(e);
			} catch(Error e) {
				result.done(e);
			} finally {
				if( !result.isDone() )
					logger.error("result isn't done");
			}
		}});
	}

	void go() throws SQLException {
		try {
			update();
			if( up.databaseVersion() != version )
				throw new RuntimeException();
		} finally {
			up.close();
		}
	}

	@Override public String toString() {
		return "DbSiteUpdater-" + up.schema;
	}

	private void execCatching(String sql,String exStr) throws SQLException {
		up.begin();
		try {
			up.exec(sql);
		} catch(SQLException e) {
			if( !e.getMessage().contains(exStr) )
				throw e;
			logger.info(e.toString());
			up.exec("rollback");
		}
		up.commit();
	}

	void update() throws SQLException {
		switch( up.dbVersion() ) {
		case 0:
			up.execStep( 
		"\r\n				create index embed_key_site_idx on embed_key(site_id)\r\n			"
 );
		case 1:
			up.execStep( 
		"\r\n				create index file_avatar_site_idx on file_avatar(site_id)\r\n			"
 );
		case 2:
			up.execStep( 
		"\r\n				create index file_node_site_idx on file_node(site_id)\r\n			"
 );
		case 3:
			up.execStep( 
		"\r\n				create index file_temp_site_idx on file_temp(site_id)\r\n			"
 );
		case 4:
			up.execStep( 
		"\r\n				create index mailing_list_site_idx on mailing_list(site_id)\r\n			"
 );
		case 5:
			up.execStep( 
		"\r\n				create index node_msg_site_idx on node_msg(site_id)\r\n			"
 );
		case 6:
			up.execStep( 
		"\r\n				create index node_property_site_idx on node_property(site_id)\r\n			"
 );
		case 7:
			up.execStep( 
		"\r\n				create index paid_site_idx on paid(site_id)\r\n			"
 );
		case 8:
			up.execStep( 
		"\r\n				create index registration_site_idx on registration(site_id)\r\n			"
 );
		case 9:
			up.execStep( 
		"\r\n				create index subscription_site_idx on subscription(site_id)\r\n			"
 );
		case 10:
			up.execStep( 
		"\r\n				create index user_property_site_idx on user_property(site_id)\r\n			"
 );
		case 11:
			up.execStep( 
		"\r\n				create index view_count_site_idx on view_count(site_id)\r\n			"
 );
		case 12:
			up.execStep( 
		"\r\n				create index visited_site_idx on visited(site_id)\r\n			"
 );

		case 13:
			up.execStep( 
		"\r\n				create index tag_node_idx on tag(node_id)\r\n			"
 );
		case 14:
			up.execStep( 
		"\r\n				create index tag_user_idx on tag(user_id)\r\n			"
 );
		case 15:
			up.execStep( 
		"\r\n				create index embed_key_node_idx on embed_key(node_id)\r\n			"
 );
		case 16:
			up.execStep( 
		"\r\n				create index visited_node_idx on visited(node_id)\r\n			"
 );
		case 17:
			up.execStep( 
		"\r\n				create index visited_last_node_idx on visited(last_node_id)\r\n			"
 );
		case 18:
			up.execStep( 
		"\r\n				alter table node add column poll_option_count integer default null\r\n			"
 );
		case 19:
			up.execStep( 
		"\r\n				alter table configuration drop column site_id\r\n			"
 );
		case 20:
			up.execStep( 
		"\r\n				alter table configuration ADD PRIMARY KEY (name)\r\n			"
 );
		case 21:
			up.execStep( 
		"\r\n				alter table embed_key drop column site_id\r\n			"
 );
		case 22:
			up.execStep( 
		"\r\n				alter table file_avatar drop column site_id\r\n			"
 );
		case 23:
			up.execStep( 
		"\r\n				alter table file_node drop column site_id\r\n			"
 );
		case 24:
			up.execStep( 
		"\r\n				alter table file_temp drop column site_id\r\n			"
 );
		case 25:
			up.execStep( 
		"\r\n				alter table mailing_list drop column site_id\r\n			"
 );
		case 26:
			up.execStep( 
		"\r\n				alter table node_msg drop column site_id\r\n			"
 );
		case 27:
			up.execStep( 
		"\r\n				alter table node_property drop column site_id\r\n			"
 );
		case 28:
			up.execStep( 
		"\r\n				alter table paid drop column site_id\r\n			"
 );
		case 29:
			up.execStep( 
		"\r\n				alter table registration drop column site_id\r\n			"
 );
		case 30:
			up.execStep( 
		"\r\n				alter table subscription drop column site_id\r\n			"
 );
		case 31:
			up.execStep( 
		"\r\n				alter table user_property drop column site_id\r\n			"
 );
		case 32:
			up.execStep( 
		"\r\n				alter table view_count drop column site_id\r\n			"
 );
		case 33:
			up.execStep( 
		"\r\n				alter table visited drop column site_id\r\n			"
 );
		case 34:
			up.execStep( 
		"\r\n				alter table file_site drop column site_id\r\n			"
 );
		case 35:
			up.execStep( 
		"\r\n				alter table file_site ADD PRIMARY KEY (name)\r\n			"
 );
		case 36:
			up.execStep( 
		"\r\n				alter table module drop column site_id\r\n			"
 );
		case 37:
			up.execStep( 
		"\r\n				alter table module ADD PRIMARY KEY (module_name)\r\n			"
 );
		case 38:
			up.execStep( 
		"\r\n				alter table site_property drop column site_id\r\n			"
 );
		case 39:
			up.execStep( 
		"\r\n				alter table site_property ADD PRIMARY KEY (key)\r\n			"
 );
		case 40:
			up.execStep( 
		"\r\n				alter table tweak drop column site_id\r\n			"
 );
		case 41:
			up.execStep( 
		"\r\n				alter table tweak ADD PRIMARY KEY (tweak_name)\r\n			"
 );
		case 42:
			up.execStep( 
		"\r\n				alter table tag drop column site_id\r\n			"
 );
		case 43:
			up.execStep( 
		"\r\n				CREATE UNIQUE INDEX tag_idx\r\n					ON tag (node_id, user_id, label);\r\n			"
 );
		case 44:
			up.execStep( 
		"\r\n				drop index tag_node_idx\r\n			"
 );
		case 45:
			up.execStep( 
		"\r\n				alter table user_ drop column site_id\r\n			"
 );
		case 46:
			up.execStep( 
		"\r\n				CREATE UNIQUE INDEX user_email_idx\r\n					ON user_ (lower(email));\r\n			"
 );
		case 47:
			up.execStep( 
		"\r\n				CREATE UNIQUE INDEX user_name_idx\r\n					ON user_ (lower(name));\r\n			"
 );
		case 48:
			up.execStep( 
		"\r\n				alter table node drop column site_id\r\n			"
 );
		case 49:
			up.execStep( 
		"\r\n				CREATE INDEX node_cookie_idx\r\n					ON node (cookie)\r\n					WHERE cookie IS NOT NULL;\r\n			"
 );
		case 50:
			up.execStep( 
		"\r\n				CREATE INDEX node_message_id_idx\r\n					ON node (lower(message_id))\r\n					WHERE message_id IS NOT NULL;\r\n			"
 );
		case 51:
			up.execStep( 
		"\r\n				drop table embed_key\r\n			"
 );
		case 52:
			up.execStep( 
		"\r\n				delete from site_property where key = '__embedding_warning'\r\n			"
 );
		case 53:
			up.execStep( 
		"\r\n				alter table site drop column site_id\r\n			"
 );
		case 54:
			up.execStep( 
		"\r\n				alter table site add column one integer default 1 not null\r\n			"
 );
		case 55:
			up.execStep( 
		"\r\n				alter table site ADD PRIMARY KEY (one)\r\n			"
 );
		case 56:
			up.execStep( 
		"\r\n				alter table site add column content_type character varying;\r\n			"
 );
		case 57:
			up.execStep( 
		"\r\n				update configuration set naml=E'<override_macro name=\"site_style\">\\n\\t<n.overridden/>\\n\\t#search-box { text-align:left; }\\n</override_macro>' where name='searchBoxAlignment';\r\n			"
 );
		case 58:
			up.execStep( 
		"\r\n				update site set ad_type=null where ad_type='ADBRITE' or ad_type='ADSENSE'\r\n			"
 );

		case 59:
			up.execStep( 
		"\r\n				alter table node\r\n					add column unsafe character varying default 'new',\r\n					add column safe_version integer\r\n			"
 );
		case 60:
			up.execStep( 
		"\r\n				alter table user_\r\n					add column unsafe character varying default 'new',\r\n					add column safe_version integer\r\n			"
 );

		case 61:
			up.execStep( 
		"\r\n				update site set ad_type='HOPELESS' where ad_type='COPYRIGHTED'\r\n			"
 );
		case 62:
			up.execStep( 
		"\r\n				update site set ad_type='HOPELESS' where ad_type='OURS'\r\n			"
 );
		case 63:
			up.execStep( 
		"\r\n				update site set ad_type=null, ad_free="
		+(Integer.MAX_VALUE)
		+" where ad_type='NONE'\r\n			"
 );

		case 64:
			up.execStep( 
		"\r\n				alter table node\r\n					add column is_safe boolean\r\n			"
 );
		case 65:
			up.execStep( 
		"\r\n				alter table user_\r\n					add column is_safe boolean\r\n			"
 );
		case 66:
			up.execStep( null );
		case 67:
			up.execStep( null );
		case 68:
			up.execStep( 
		"\r\n				delete from tag where label='hide_ads'\r\n			"
 );
		case 69:
			up.execStep( 
		"\r\n				update site set ad_type=null where ad_type='SOME_ADSENSE'\r\n			"
 );
		case 70:
			up.execStep( 
		"\r\n				update site set ad_type='ADULT' where ad_type='HACK'\r\n			"
 );
		case 71:
			up.execStep( 
		"\r\n				update site set content_type=null where content_type='FAMILY'\r\n			"
 );
		case 72:
			up.execStep( 
		"\r\n				drop index if exists node_is_safe_idx\r\n			"
 );
		case 73:
			up.execStep( 
		"\r\n				drop index if exists user_is_safe_idx\r\n			"
 );
		case 74:
			up.execStep( 
		"\r\n				create index node_unsafe_idx on node(unsafe) where unsafe is not null and unsafe!='new'\r\n			"
 );
		case 75:
			up.execStep( 
		"\r\n				create index user_unsafe_idx on user_(unsafe) where unsafe is not null and unsafe!='new'\r\n			"
 );
		case 76:
			up.execStep( 
		"\r\n				update site set content_type=ad_type where content_type is null and ad_type is not null and ad_type!='HOPELESS'\r\n			"
 );
		case 77:
			up.execStep( 
		"\r\n				update site set ad_type=content_type where content_type is not null and ad_type is null\r\n			"
 );
		case 78:
			up.execStep( 
		"\r\n				update site set ad_type='ADULT' where content_type='ADULT' and ad_type='PORN'\r\n			"
 );

		case 79:
			up.execStep( 
		"\r\n				alter table user_\r\n					drop column unsafe,\r\n					drop column safe_version,\r\n					drop column is_safe\r\n			"
 );
		case 80:
			up.execStep( null );
		case 81:
			up.execStep( null );
		case 82:
			up.begin();
			up.exec( 
		"\r\n				alter table node\r\n					drop column unsafe,\r\n					drop column safe_version,\r\n					drop column is_safe\r\n			"
 );
			up.exec( 
		"\r\n				alter table node\r\n					add column unsafe character varying,\r\n					add column safe_version integer,\r\n					add column is_safe boolean\r\n			"
 );
			up.commit();
		case 83:
			up.execStep( 
		"\r\n				create index node_unsafe_idx on node(unsafe) where safe_version is not null\r\n			"
 );
		case 84:
			up.execStep( 
		"\r\n				delete from module where module_name = 'topic_ads';\r\n			"
 );
		case 85:
			up.execStep( 
		"\r\n				alter table node\r\n					drop column unsafe,\r\n					drop column safe_version,\r\n					drop column is_safe\r\n			"
 );
		case 86:
			up.execStep( 
		"\r\n				alter table site\r\n					add column when_created timestamp with time zone NOT NULL DEFAULT now()\r\n			"
 );
		case 87:
			up.execStep( 
		"\r\n				update site\r\n					set when_created = node.when_created\r\n					from node\r\n					where node.node_id = site.root_node_id\r\n			"
 );

		case 88:
			up.execStep( 
		"\r\n				alter table site\r\n					add column is_safe boolean NOT NULL DEFAULT true\r\n			"
 );
		case 89:
			up.execStep( 
		"\r\n				update site set is_safe = false where ad_type is not null\r\n			"
 );
		case 90:
			up.execStep( 
		"\r\n				update site set when_created = now() where not is_safe\r\n			"
 );
		case 91:
			up.execStep( 
		"\r\n				alter table site rename column ad_type to old_ad_type\r\n			"
 );
		case 92:
			up.execStep( 
		"\r\n				alter table site rename column content_type to old_content_type\r\n			"
 );
		case 93:
			up.execStep( 
		"\r\n				alter table site\r\n					add column ad_credits_for_users boolean NOT NULL DEFAULT false\r\n			"
 );
		case 94:
			up.execStep( 
		"\r\n				alter table site\r\n					add column monthly_views integer NOT NULL DEFAULT 0\r\n			"
 );
		case 95:
			up.execStep( 
		"\r\n				delete from tag where label='group:Administrators' and node_id is null and user_id = (select user_id from user_ where email = 'pedro@nabble.com')\r\n			"
 );

		case 96:
			execCatching( 
		"\r\n				alter table tweak ADD PRIMARY KEY (tweak_name)\r\n			"
, "multiple primary keys for table" );
		case 97:
			execCatching( 
		"\r\n				alter table mailing_list ADD PRIMARY KEY (node_id)\r\n			"
, "multiple primary keys for table" );
		case 98:
/*
			execCatching( 
		"\r\n				alter table mailing_list ADD CONSTRAINT mailing_list_node_id_fkey FOREIGN KEY (node_id) REFERENCES node (node_id) ON DELETE CASCADE\r\n			"
, "already exists" );
*/
			up.execStep( null );
		case 99:
			execCatching( 
		"\r\n				CREATE INDEX forum_ml_idx ON mailing_list (lower(list_address))\r\n			"
, "already exists" );
		case 100:
			execCatching( 
		"\r\n				alter table node ADD PRIMARY KEY (node_id)\r\n			"
, "multiple primary keys for table" );
		case 101:
			execCatching( 
		"\r\n				alter table configuration ADD PRIMARY KEY (name)\r\n			"
, "multiple primary keys for table" );
		case 102:
			execCatching( 
		"\r\n				alter table file_avatar ADD PRIMARY KEY (user_id, name)\r\n			"
, "multiple primary keys for table" );
		case 103:
			execCatching( 
		"\r\n				alter table file_node ADD PRIMARY KEY (node_id, name)\r\n			"
, "multiple primary keys for table" );
		case 104:
			execCatching( 
		"\r\n				alter table file_site ADD PRIMARY KEY (name)\r\n			"
, "multiple primary keys for table" );
		case 105:
			execCatching( 
		"\r\n				alter table file_temp ADD PRIMARY KEY (user_id, name)\r\n			"
, "multiple primary keys for table" );
		case 106:
			execCatching( 
		"\r\n				CREATE INDEX file_temp_date_idx ON file_temp (date_)\r\n			"
, "already exists" );
		case 107:
			execCatching( 
		"\r\n				alter table module ADD PRIMARY KEY (module_name)\r\n			"
, "multiple primary keys for table" );
		case 108:
			execCatching( 
		"\r\n				CREATE INDEX node_cookie_idx ON node (cookie) WHERE cookie IS NOT NULL\r\n			"
, "already exists" );
		case 109:
			execCatching( 
		"\r\n				CREATE INDEX node_export ON node (export_permalink) WHERE export_permalink IS NOT NULL\r\n			"
, "already exists" );
		case 110:
			execCatching( 
		"\r\n				CREATE INDEX node_message_id_idx ON node (lower(message_id)) WHERE message_id IS NOT NULL\r\n			"
, "already exists" );
		case 111:
			execCatching( 
		"\r\n				CREATE INDEX node_ml2_idx ON node (lower(parent_message_id)) WHERE lower(parent_message_id) IS NOT NULL\r\n			"
, "already exists" );
		case 112:
			execCatching( 
		"\r\n				CREATE INDEX node_owner_idx ON node (owner_id, when_created)\r\n			"
, "already exists" );
		case 113:
			execCatching( 
		"\r\n				CREATE UNIQUE INDEX node_parent2_idx ON node (parent_id, when_created, node_id)\r\n			"
, "already exists" );
		case 114:
			execCatching( 
		"\r\n				CREATE UNIQUE INDEX node_parent_idx ON node (parent_id, last_node_date, node_id)\r\n			"
, "already exists" );
		case 115:
			execCatching( 
		"\r\n				CREATE INDEX node_sent_idx ON node (when_sent) WHERE when_sent IS NOT NULL\r\n			"
, "already exists" );
		case 116:
			execCatching( 
		"\r\n				CREATE UNIQUE INDEX pinned_node_idx ON node (parent_id, pin) WHERE pin IS NOT NULL\r\n			"
, "already exists" );
		case 117:
			execCatching( 
		"\r\n				CREATE INDEX post_date ON node (when_created)\r\n			"
, "already exists" );
		case 118:
			execCatching( 
		"\r\n				alter table node_msg ADD PRIMARY KEY (node_id)\r\n			"
, "multiple primary keys for table" );
		case 119:
			execCatching( 
		"\r\n				alter table node_property ADD PRIMARY KEY (node_id, key)\r\n			"
, "multiple primary keys for table" );
		case 120:
			execCatching( 
		"\r\n				alter table paid ADD PRIMARY KEY (user_id)\r\n			"
, "multiple primary keys for table" );
		case 121:
			execCatching( 
		"\r\n				alter table registration ADD PRIMARY KEY (key_)\r\n			"
, "multiple primary keys for table" );
		case 122:
			execCatching( 
		"\r\n				CREATE INDEX registration_date_idx ON registration (date_)\r\n			"
, "already exists" );
		case 123:
			execCatching( 
		"\r\n				alter table site ADD PRIMARY KEY (one)\r\n			"
, "multiple primary keys for table" );
		case 124:
			execCatching( 
		"\r\n				alter table site_property ADD PRIMARY KEY (key)\r\n			"
, "multiple primary keys for table" );
		case 125:
			execCatching( 
		"\r\n				alter table subscription ADD PRIMARY KEY (user_id, node_id)\r\n			"
, "multiple primary keys for table" );
		case 126:
			execCatching( 
		"\r\n				CREATE INDEX subscription_node_idx ON subscription (node_id)\r\n			"
, "already exists" );
		case 127:
			execCatching( 
		"\r\n				CREATE UNIQUE INDEX tag_idx ON tag (node_id, user_id, label)\r\n			"
, "already exists" );
		case 128:
			execCatching( 
		"\r\n				CREATE INDEX tag_user_idx ON tag (user_id)\r\n			"
, "already exists" );
		case 129:
			execCatching( 
		"\r\n				alter table user_ ADD PRIMARY KEY (user_id)\r\n			"
, "multiple primary keys for table" );
		case 130:
			execCatching( 
		"\r\n				CREATE UNIQUE INDEX user_email_idx ON user_ (lower(email))\r\n			"
, "already exists" );
		case 131:
			execCatching( 
		"\r\n				CREATE UNIQUE INDEX user_name_idx ON user_ (lower(name))\r\n			"
, "already exists" );
		case 132:
			execCatching( 
		"\r\n				alter table user_property ADD PRIMARY KEY (user_id, key)\r\n			"
, "multiple primary keys for table" );
		case 133:
			execCatching( 
		"\r\n				alter table view_count ADD PRIMARY KEY (node_id)\r\n			"
, "multiple primary keys for table" );
		case 134:
			execCatching( 
		"\r\n				alter table visited ADD PRIMARY KEY (user_id, node_id)\r\n			"
, "multiple primary keys for table" );
		case 135:
			execCatching( 
		"\r\n				CREATE INDEX visited_last_node_idx ON visited (last_node_id)\r\n			"
, "already exists" );
		case 136:
			execCatching( 
		"\r\n				CREATE INDEX visited_node_idx ON visited (node_id)\r\n			"
, "already exists" );

		case 137:
			execCatching( 
		"\r\n				ALTER TABLE ONLY file_avatar \r\n					ADD CONSTRAINT file_avatar_user_id_fkey FOREIGN KEY (user_id) REFERENCES user_(user_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 138:
			up.execStep( null );
		case 139:
			execCatching( 
		"\r\n				ALTER TABLE ONLY file_temp \r\n					ADD CONSTRAINT file_temp_user_id_fkey FOREIGN KEY (user_id) REFERENCES user_(user_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 140:
			execCatching( 
		"\r\n				ALTER TABLE ONLY mailing_list \r\n					ADD CONSTRAINT mailing_list_node_id_fkey FOREIGN KEY (node_id) REFERENCES node(node_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 141:
			up.execStep( null );
		case 142:
			execCatching( 
		"\r\n				ALTER TABLE ONLY node \r\n					ADD CONSTRAINT node_new_owner_id_fkey FOREIGN KEY (owner_id) REFERENCES user_(user_id)\r\n			"
, "already exists" );
		case 143:
			execCatching( 
		"\r\n				ALTER TABLE ONLY node \r\n					ADD CONSTRAINT node_node_id_fkey FOREIGN KEY (node_id) REFERENCES node_msg(node_id) DEFERRABLE INITIALLY DEFERRED\r\n			"
, "already exists" );
		case 144:
			up.execStep( null );
		case 145:
			up.execStep( null );
		case 146:
			execCatching( 
		"\r\n				ALTER TABLE ONLY paid \r\n					ADD CONSTRAINT paid_user_id_fkey FOREIGN KEY (user_id) REFERENCES user_(user_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 147:
			execCatching( 
		"\r\n				ALTER TABLE ONLY site \r\n					ADD CONSTRAINT site_root_node_id_fkey FOREIGN KEY (root_node_id) REFERENCES node(node_id) DEFERRABLE INITIALLY DEFERRED\r\n			"
, "already exists" );
		case 148:
			up.execStep( null );
		case 149:
			execCatching( 
		"\r\n				ALTER TABLE ONLY subscription \r\n					ADD CONSTRAINT subscription_user_id_fkey FOREIGN KEY (user_id) REFERENCES user_(user_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 150:
			up.execStep( null );
		case 151:
			execCatching( 
		"\r\n				ALTER TABLE ONLY tag \r\n					ADD CONSTRAINT tag_user_id_fkey FOREIGN KEY (user_id) REFERENCES user_(user_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 152:
			execCatching( 
		"\r\n				ALTER TABLE ONLY user_property \r\n					ADD CONSTRAINT user_property_user_id_fkey FOREIGN KEY (user_id) REFERENCES user_(user_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 153:
			up.execStep( null );
		case 154:
			up.execStep( null );
		case 155:
			up.execStep( null );
		case 156:
			execCatching( 
		"\r\n				ALTER TABLE ONLY visited \r\n					ADD CONSTRAINT visited_user_id_fkey FOREIGN KEY (user_id) REFERENCES user_(user_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 157:
			up.execStep( null );

		// problematic constraints
		case 158:
			execCatching( 
		"\r\n				ALTER TABLE ONLY file_node \r\n					ADD CONSTRAINT file_node_node_id_fkey FOREIGN KEY (node_id) REFERENCES node(node_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 159:
			execCatching( 
		"\r\n				ALTER TABLE ONLY node_msg \r\n					ADD CONSTRAINT node_msg_node_id_fkey FOREIGN KEY (node_id) REFERENCES node(node_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 160:
			execCatching( 
		"\r\n				ALTER TABLE ONLY node \r\n					ADD CONSTRAINT node_parent_id_fkey FOREIGN KEY (parent_id) REFERENCES node(node_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 161:
			execCatching( 
		"\r\n				ALTER TABLE ONLY node_property \r\n					ADD CONSTRAINT node_property_node_id_fkey FOREIGN KEY (node_id) REFERENCES node(node_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 162:
			execCatching( 
		"\r\n				ALTER TABLE ONLY subscription \r\n					ADD CONSTRAINT subscription_node_id_fkey FOREIGN KEY (node_id) REFERENCES node(node_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 163:
			execCatching( 
		"\r\n				ALTER TABLE ONLY tag \r\n					ADD CONSTRAINT tag_node_id_fkey FOREIGN KEY (node_id) REFERENCES node(node_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 164:
			execCatching( 
		"\r\n				ALTER TABLE ONLY view_count \r\n					ADD CONSTRAINT view_count_node_id_fkey FOREIGN KEY (node_id) REFERENCES node(node_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 165:
			execCatching( 
		"\r\n				ALTER TABLE ONLY visited \r\n					ADD CONSTRAINT visited_last_node_id_fkey FOREIGN KEY (last_node_id) REFERENCES node(node_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		case 166:
			execCatching( 
		"\r\n				ALTER TABLE ONLY visited \r\n					ADD CONSTRAINT visited_node_id_fkey FOREIGN KEY (node_id) REFERENCES node(node_id) ON DELETE CASCADE\r\n			"
, "already exists" );
		}
	}
}