activeuuid 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in activeuuid.gemspec
4
+ gemspec
@@ -0,0 +1,123 @@
1
+ # activeuuid
2
+
3
+ Add `binary(16)` UUIDs to ActiveRecord.
4
+
5
+ ## Example
6
+
7
+ ### Create a Migration
8
+
9
+ `activeuuid` adds the `uuid` type to your migrations. Example:
10
+
11
+ ```ruby
12
+ class CreateEmails < ActiveRecord::Migration
13
+ def self.up
14
+ create_table :emails, :id => false do |t|
15
+ t.uuid :id, :unique => true
16
+ t.uuid :sender_id # belongs_to :sender
17
+
18
+ t.string :subject
19
+ t.text :body
20
+
21
+ t.timestamp :sent_at
22
+ t.timestamps
23
+ end
24
+ add_index :emails, :id
25
+ end
26
+
27
+ def self.down
28
+ drop_table :emails
29
+ end
30
+ end
31
+ ```
32
+
33
+ ### include ActiveUUID::UUID in your model
34
+
35
+ ```ruby
36
+ class Email < ActiveRecord::Base
37
+ include ActiveUUID::UUID
38
+ belongs_to :sender
39
+ end
40
+ ```
41
+
42
+ ### use it:
43
+ Here are some example specs:
44
+
45
+ ```ruby
46
+ require 'spec_helper'
47
+
48
+ describe Email do
49
+
50
+ context "when using uuid's as keys" do
51
+ before(:each) do
52
+ Email.delete_all
53
+ @guid = "1dd74dd0-d116-11e0-99c7-5ac5d975667e"
54
+ @e = Email.new(:subject => "hello", :body => "world") {|e| e.id = UUIDTools::UUID.parse(@guid) }
55
+ @e.save
56
+ end
57
+
58
+ it "the id guid should be equal to the uuid" do
59
+ @e.id.to_s.should eql(@guid)
60
+ end
61
+
62
+ it "should be able to find an email by the uuid" do
63
+ f = Email.find(UUIDTools::UUID.parse(@guid))
64
+ f.id.to_s.should eql(@guid)
65
+ end
66
+
67
+ end
68
+ end
69
+ ```
70
+
71
+ ## Motivation
72
+
73
+ From [2]:
74
+
75
+ > [Here is a] UUID: 1e8ef774-581c-102c-bcfe-f1ab81872213
76
+ >
77
+ > A UUID like the one above is 36 characters long, including dashes. If you store this VARCHAR(36), you're going to decrease compare performance dramatically. This is your primary key, you don't want it to be slow.
78
+ >
79
+ > At its bit level, a UUID is 128 bits, which means it will fit into
80
+ > 16 bytes, note this is not very human readable, but it will keep
81
+ > storage low, and is only 4 times larger than a 32-bit int, or 2
82
+ > times larger than a 64-bit int.
83
+
84
+ Many of the existing examples of how to use UUIDs as primary keys
85
+ in Rails use strings rather than bytes (e.g. [3]).
86
+
87
+ However, this plugin stores the primary keys as bytes. To the
88
+ application the keys are represented by a UUIDTools::UUID object.
89
+
90
+ ## Benefits of UUIDs as primary key
91
+
92
+ * allows multi-master write
93
+ * no locking due to auto-increment
94
+ * with time-based UUIDs you can store a timestamp within your UUID
95
+ * you can create natural keys
96
+
97
+ ## Future work
98
+ * more transparent support for natural and composite keys
99
+ * support for MySQLs `INSERT ... ON DUPLICATE KEY UPDATE` syntax
100
+ * support a primary column name other than `id`
101
+ * tests
102
+
103
+ ## Inspiration
104
+ James Golick's `friendly` is a great gem for NoSQL on MySQL. It's
105
+ a great gateway drug to systems like Cassandra for teams that are
106
+ already familiar with the ins-and-outs of MySQL.
107
+
108
+ ## References
109
+ * [1] http://bret.appspot.com/entry/how-friendfeed-uses-mysql
110
+ * [2] http://kekoav.com/blog/36-computers/58-uuids-as-primary-keys-in-mysql.html
111
+ * [3] https://gist.github.com/937739
112
+ * [4] http://www.codinghorror.com/blog/2007/03/primary-keys-ids-versus-guids.html
113
+ * [5] http://krow.livejournal.com/497839.html
114
+ * [6] https://github.com/jamesgolick/friendly
115
+
116
+ ## Dependencies
117
+ Rails ~> 3.1.0 - It uses the custom column serialization Aaron
118
+ Patterson introduced in Rails 3.1.
119
+
120
+ I'm using JRuby 1.9 (1.6.3) but this should work under MRI (YMMV).
121
+
122
+ ## Author
123
+ Nate Murray <nate@xcombinator.com>
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "activeuuid/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "activeuuid"
7
+ s.version = Activeuuid::VERSION
8
+ s.authors = ["Nate Murray"]
9
+ s.email = ["nate@natemurray.com"]
10
+ s.homepage = "http://www.xcombinator.com"
11
+ s.summary = %q{Add binary UUIDs to ActiveRecord in MySQL}
12
+ s.description = %q{Add's binary (not string) UUIDs to ActiveRecord in MySQL}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ # s.add_development_dependency "rspec"
20
+ s.add_runtime_dependency "uuidtools"
21
+ end
@@ -0,0 +1,6 @@
1
+ require "activeuuid/version"
2
+
3
+ module ActiveUUID
4
+ require 'activeuuid/railtie' if defined?(Rails)
5
+ require 'activeuuid/uuid'
6
+ end
@@ -0,0 +1,21 @@
1
+ require 'activeuuid'
2
+ require 'rails'
3
+
4
+ module ActiveUUID
5
+ class Railtie < Rails::Railtie
6
+ railtie_name :activeuuid
7
+ initializer "activeuuid.configure_rails_initialization" do
8
+
9
+ module ActiveRecord::ConnectionAdapters
10
+ class TableDefinition
11
+ def uuid (*args)
12
+ options = args.extract_options!
13
+ column_names = args
14
+ column_names.each { |name| column(name, 'binary(16)', options) }
15
+ end
16
+ end
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,60 @@
1
+ module UUIDTools
2
+ class UUID
3
+ # monkey-patch Friendly::UUID to serialize UUIDs to MySQL
4
+ def quoted_id
5
+ s = raw.unpack("H*")[0]
6
+ "x'#{s}'"
7
+ end
8
+ end
9
+ end
10
+
11
+ module ActiveUUID
12
+ class UUIDSerializer
13
+ def load(binary)
14
+ case binary
15
+ when UUIDTools::UUID then binary
16
+ when nil then nil
17
+ else UUIDTools::UUID.parse_raw(binary)
18
+ end
19
+ end
20
+ def dump(uuid)
21
+ uuid ? uuid.raw : nil
22
+ end
23
+ end
24
+
25
+ module UUID
26
+ extend ActiveSupport::Concern
27
+
28
+ included do
29
+ before_create :generate_uuid_if_needed
30
+
31
+ set_primary_key "id"
32
+ serialize :id, ActiveUUID::UUIDSerializer.new
33
+
34
+
35
+ def generate_uuid_if_needed
36
+ generate_uuid unless self.id
37
+ end
38
+
39
+ def generate_uuid
40
+ self.id = UUIDTools::UUID.timestamp_create
41
+ end
42
+ end
43
+
44
+ module ClassMethods
45
+ #def uuids(*attributes)
46
+ # attributes.each do |attribute|
47
+ # class_eval <<-eos
48
+ # # def #{@association_name}
49
+ # # @_#{@association_name} ||= self.class.associations[:#{@association_name}].new_proxy(self)
50
+ # # end
51
+ # eos
52
+ # end
53
+ #end
54
+ end
55
+
56
+ module InstanceMethods
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,3 @@
1
+ module Activeuuid
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activeuuid
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nate Murray
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-29 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: uuidtools
16
+ requirement: &2156096440 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2156096440
25
+ description: Add's binary (not string) UUIDs to ActiveRecord in MySQL
26
+ email:
27
+ - nate@natemurray.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - Gemfile
34
+ - README.mkd
35
+ - Rakefile
36
+ - activeuuid.gemspec
37
+ - lib/activeuuid.rb
38
+ - lib/activeuuid/railtie.rb
39
+ - lib/activeuuid/uuid.rb
40
+ - lib/activeuuid/version.rb
41
+ homepage: http://www.xcombinator.com
42
+ licenses: []
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ requirements: []
60
+ rubyforge_project:
61
+ rubygems_version: 1.8.6
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Add binary UUIDs to ActiveRecord in MySQL
65
+ test_files: []