public
Last active

Example of my versioning problem from earlier, or: things that were easier before ORMs

  • Download Gist
01_versioned.sql
SQL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
CREATE TABLE items (
uuid VARCHAR(255) NOT NULL PRIMARY KEY,
name VARCHAR(255) NOT NULL DEFAULT '');
 
CREATE TABLE item_versions (
uuid VARCHAR(255) NOT NULL PRIMARY KEY,
version INT(64) NOT NULL UNIQUE AUTO_INCREMENT,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
 
INSERT INTO items(uuid, name) VALUES("APP_GENERATED_ID", "An item");
REPLACE INTO item_versions SET uuid = "APP_GENERATED_ID";
 
SELECT items.*, item_versions.version FROM items, item_versions WHERE items.uuid = item_versions.uuid ORDER BY version DESC;
 
INSERT INTO items(uuid, name) VALUES("e2ee6f5c-c096-11e1-81de-966c5e8fb5dd", "Another item");
REPLACE INTO item_versions SET uuid = "e2ee6f5c-c096-11e1-81de-966c5e8fb5dd";
 
UPDATE items SET name = "Updated name" WHERE uuid = 'APP_GENERATED_ID';
REPLACE INTO item_versions SET uuid = "APP_GENERATED_ID";
 
SELECT items.*, item_versions.version FROM items, item_versions WHERE items.uuid = item_versions.uuid ORDER BY version DESC;
02_item.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
class Item
self.primary_key = :uuid
before_create :set_uuid
after_save :update_version
 
private
 
def set_uuid
self.uuid ||= SecureRandom.uuid
end
 
def update_version
# AFAIK this works in MySQL, would need to be adapted for any other RDBMS
# FIXME: Not that this is a security hole but surely there's a less
# SQL-injecty way to do this
connection.execute("REPLACE INTO item_versions SET uuid = '#{self.uuid}'")
end
 
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.