Tuukka Norri avatar Tuukka Norri committed e9ac283

Fixed a bug which could have caused problems with lock notifications after restoring the database from a dump
- Persistent table identifiers are now used instead.
- Oids are no longer stored in modification or lock tables.

Comments (0)

Files changed (7)

Resources/BaseTenModifications.sql.m4

 
 changequote(`{{', `}}')
 -- ' -- Fix for syntax coloring in SQL mode.
-define({{_bx_version_}}, {{0.932}})dnl
+define({{_bx_version_}}, {{0.933}})dnl
 define({{_bx_compat_version_}}, {{0.19}})dnl
 
 
 CREATE TABLE "baseten".modification (
 	"baseten_modification_id"				INTEGER PRIMARY KEY DEFAULT nextval ('"baseten"."modification_id_seq"'),
 	"baseten_modification_relid"			INTEGER NOT NULL REFERENCES "baseten".relation (id),
-	"baseten_modification_reloid"			OID NOT NULL,
 	"baseten_modification_timestamp"		TIMESTAMP (6) WITHOUT TIME ZONE NULL DEFAULT NULL,
 	"baseten_modification_insert_timestamp" TIMESTAMP (6) WITHOUT TIME ZONE NOT NULL DEFAULT clock_timestamp (),
 	"baseten_modification_type"				CHAR NOT NULL,
 CREATE TABLE "baseten".lock (
 	"baseten_lock_id"				INTEGER PRIMARY KEY DEFAULT nextval ('"baseten"."lock_id_seq"'),
 	"baseten_lock_relid"			INTEGER NOT NULL REFERENCES "baseten".relation (id),
-	"baseten_lock_reloid"			OID NOT NULL,
 	"baseten_lock_timestamp"		TIMESTAMP (6) WITHOUT TIME ZONE NOT NULL DEFAULT clock_timestamp (),
 	"baseten_lock_query_type"		CHAR (1) NOT NULL DEFAULT 'U',	 -- U == UPDATE, D == DELETE
 	"baseten_lock_cleared"			BOOLEAN NOT NULL DEFAULT FALSE,
 
 CREATE VIEW "baseten".pending_locks AS
 	SELECT 
-		baseten_lock_reloid AS reloid, 
+		baseten_lock_relid AS relid, 
 		max (baseten_lock_timestamp) AS last_date, 
 		"baseten"._lock_table (baseten_lock_relid) AS lock_table_name 
 	FROM "baseten".lock 
 	WHERE baseten_lock_cleared = true AND baseten_lock_backend_pid != pg_backend_pid ()
-	GROUP BY reloid, lock_table_name;
+	GROUP BY relid, lock_table_name;
 REVOKE ALL PRIVILEGES ON "baseten".pending_locks FROM PUBLIC;
 GRANT SELECT ON "baseten".pending_locks TO basetenread;
 
 	query := 
 		'CREATE TABLE "baseten".' || quote_ident (lock_table) || ' (' ||
 			'"baseten_lock_relid" INTEGER NOT NULL DEFAULT ' || relid_ || ', ' ||
-			'"baseten_lock_reloid" OID NOT NULL DEFAULT ' || reloid || ', ' ||
 			pkey_decl ||
 		') INHERITS ("baseten".lock)';
 	EXECUTE query;
 	query :=
 		'CREATE TABLE "baseten".' || quote_ident (mod_table) || ' (' ||
 			'"baseten_modification_relid" INTEGER NOT NULL DEFAULT ' || relid_ || ', ' ||
-			'"baseten_modification_reloid" OID NOT NULL DEFAULT ' || reloid || ', ' ||
 			pkey_decl ||
 		') INHERITS ("baseten".modification)';
 	EXECUTE query;

Sources/BXPGClearLocksHandler.m

 		goto error;
 	}
 	
-	NSArray* oids = [mInterface observedOids];
+	NSArray* relids = [mInterface observedRelids];
     
     //Which tables have pending locks?
     NSString* query = 
-	@"SELECT reloid, last_date, lock_table_name "
+	@"SELECT relid, last_date, lock_table_name "
 	@" FROM baseten.pending_locks "
 	@" WHERE last_date > COALESCE ($1, '-infinity')::timestamp "
-	@"  AND reloid = ANY ($2) ";
-    PGTSResultSet* res = [mConnection executeQuery: query parameters: mLastCheck, oids];
+	@"  AND relid = ANY ($2) ";
+    PGTSResultSet* res = [mConnection executeQuery: query parameters: mLastCheck, relids];
     if (NO == [res querySucceeded])
 	{
 		error = [res error];

Sources/BXPGInterface.h

 - (NSArray *) executeFetchForEntity: (BXEntityDescription *) entity withPredicate: (NSPredicate *) predicate 
 					returningFaults: (BOOL) returnFaults class: (Class) aClass forUpdate: (BOOL) forUpdate error: (NSError **) error;
 - (NSArray *) observedOids;
+- (NSArray *) observedRelids;
 - (NSString *) insertQuery: (BXEntityDescription *) entity fieldValues: (NSDictionary *) fieldValues error: (NSError **) error;
 
 - (NSString *) viewDefaultValue: (BXAttributeDescription *) attr error: (NSError **) error;

Sources/BXPGInterface.m

 	return [mTransactionHandler observedOids];
 }
 
+- (NSArray *) observedRelids
+{
+	return [mTransactionHandler observedRelids];
+}
+
 /**
  * \internal
  * \brief Create an insert query.

Sources/BXPGLockHandler.mm

 	__strong NSMutableArray* l_for_update;
 	__strong NSMutableArray* l_for_delete;
 };
-typedef std::tr1::unordered_map <Oid, lock_st, 
-	std::tr1::hash <Oid>, 
-	std::equal_to <Oid>, 
-	PGTS::scanned_memory_allocator <std::pair <const Oid, lock_st> > > 
+typedef std::tr1::unordered_map <long, lock_st, 
+	std::tr1::hash <long>, 
+	std::equal_to <long>, 
+	PGTS::scanned_memory_allocator <std::pair <const long, lock_st> > > 
 	LockMap;
 
 
 		{
 			NSDictionary* row = [res currentRowAsDictionary];
 			unichar lockType = [[row valueForKey: @"baseten_lock_query_type"] characterAtIndex: 0];
-			Oid reloid = [[row valueForKey: @"baseten_lock_reloid"] PGTSOidValue];
+			long relid = [[row valueForKey: @"baseten_lock_relid"] longValue];
 			
-			struct lock_st ls = (* locks) [reloid];
+			struct lock_st ls = (* locks) [relid];
 			
 			NSMutableArray* ids = nil;
 			switch (lockType) 

Sources/BXPGTransactionHandler.h

 	NSMutableDictionary* mObservers;
 	NSMutableDictionary* mChangeHandlers;
 	NSMutableDictionary* mLockHandlers;
+	NSMutableDictionary* mDatabaseIdentifiers;
 	
 	NSUInteger mSavepointIndex;
 	NSError** mSyncErrorPtr;
 - (void) checkSuperEntities: (BXEntityDescription *) entity;
 - (void) checkSuperEntities: (BXEntityDescription *) entity connection: (PGTSConnection *) connection;
 - (NSArray *) observedOids;
+- (NSArray *) observedRelids;
 
 - (BOOL) logsQueries;
 - (void) setLogsQueries: (BOOL) shouldLog;

Sources/BXPGTransactionHandler.m

 	[mObservers release];
 	[mChangeHandlers release];
 	[mLockHandlers release];
+	[mDatabaseIdentifiers release];
 	[super dealloc];
 }
 
 			mChangeHandlers = [[NSMutableDictionary alloc] init];
 		if (! mLockHandlers)
 			mLockHandlers = [[NSMutableDictionary alloc] init];
+		if (! mDatabaseIdentifiers)
+			mDatabaseIdentifiers = [[NSMutableDictionary alloc] init];
 		
 		BXPGDatabaseDescription* database = (id) [connection databaseDescription];
 		BXPGTableDescription* table = [mInterface tableForEntity: entity inDatabase: database];
 				{
 					[res advanceRow];
 					NSString* notificationName = [res valueForKey: @"n_name"];
+					NSNumber* dbIdentifier = [res valueForKey: @"relid"];
 					BXPGModificationHandler* handler = [[[BXPGModificationHandler alloc] init] autorelease];
 					
 					[handler setInterface: mInterface];
 					
 					[mObservers setObject: handler forKey: notificationName];
 					[mChangeHandlers setObject: handler forKey: entity];
+					[mDatabaseIdentifiers setObject: dbIdentifier forKey: entity];
 				}
 				
 				{
 }
 
 
+- (NSArray *) observedRelids
+{
+	NSArray* retval = [mDatabaseIdentifiers allValues];
+	return retval;
+}
+
+
 - (NSArray *) observedOids
 {
 	NSMutableArray* retval = [NSMutableArray arrayWithCapacity: [mObservedEntities count]];
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.