Permalink
Browse files

Merge pull request #13 from pyromaniac/master

Article.find('f81d861e-23fc-416e-91c0-bd3a4bd77af8') - Awesome work by @pyromaniac
  • Loading branch information...
2 parents c992cbe + 8289e2b commit 0beaff96b73a422b67dd90c2e628c9305d581097 @jashmenn committed Oct 5, 2012
View
@@ -2,3 +2,4 @@
.bundle
Gemfile.lock
pkg/*
+*.log
View
3 .rspec
@@ -0,0 +1,3 @@
+--colour
+--format documentation
+--backtrace
View
1 .rvmrc
@@ -0,0 +1 @@
+rvm use 1.9.3@activeuuid --create
View
@@ -12,7 +12,7 @@ Add `binary(16)` UUIDs to ActiveRecord.
class CreateEmails < ActiveRecord::Migration
def self.up
create_table :emails, :id => false do |t|
- t.uuid :id, :unique => true
+ t.uuid :id, :primary_key => true
t.uuid :sender_id # belongs_to :sender
t.string :subject
View
@@ -1 +1,6 @@
require "bundler/gem_tasks"
+
+require 'rspec/core'
+require 'rspec/core/rake_task'
+
+RSpec::Core::RakeTask.new(:spec)
View
@@ -18,6 +18,13 @@ Gem::Specification.new do |s|
s.add_development_dependency "rspec"
s.add_development_dependency "activesupport"
+ s.add_development_dependency "database_cleaner"
+ s.add_development_dependency "forgery"
+ s.add_development_dependency "fabrication"
+ s.add_development_dependency "sqlite3"
+ s.add_development_dependency "pg"
+ s.add_development_dependency "mysql2"
s.add_runtime_dependency "uuidtools"
+ s.add_runtime_dependency "activerecord"
end
View
@@ -1,6 +1,9 @@
require "activeuuid/version"
+require 'activeuuid/patches'
+require 'activeuuid/uuid'
+require 'activeuuid/railtie' if defined?(Rails::Railtie)
module ActiveUUID
- require 'activeuuid/railtie' if defined?(Rails::Railtie)
- require 'activeuuid/uuid'
end
+
+ActiveUUID::Patches.apply!
View
@@ -0,0 +1,60 @@
+module ActiveUUID
+ module Patches
+ module Migrations
+ def uuid(*args)
+ options = args.extract_options!
+ column_names = args
+ column_names.each do |name|
+ type = @base.adapter_name.downcase == 'postgresql' ? 'uuid' : 'binary(16)'
+ column(name, "#{type}#{' PRIMARY KEY' if options.delete(:primary_key)}", options)
+ end
+ end
+ end
+
+ module Quoting
+ extend ActiveSupport::Concern
+
+ included do
+ def quote_with_visiting(value, column = nil)
+ value = ActiveUUID::UUIDSerializer.new.load(value) if column && column.sql_type == 'binary(16)'
+ quote_without_visiting(value, column)
+ end
+
+ def type_cast_with_visiting(value, column = nil)
+ value = ActiveUUID::UUIDSerializer.new.load(value) if column && column.sql_type == 'binary(16)'
+ type_cast_without_visiting(value, column)
+ end
+
+ alias_method_chain :quote, :visiting
+ alias_method_chain :type_cast, :visiting
+ end
+ end
+
+ module PostgreSQLQuoting
+ extend ActiveSupport::Concern
+
+ included do
+ def quote_with_visiting(value, column = nil)
+ value = ActiveUUID::UUIDSerializer.new.load(value).to_s if column && column.sql_type == 'uuid'
+ quote_without_visiting(value, column)
+ end
+
+ def type_cast_with_visiting(value, column = nil)
+ value = ActiveUUID::UUIDSerializer.new.load(value).to_s if column && column.sql_type == 'uuid'
+ type_cast_without_visiting(value, column)
+ end
+
+ alias_method_chain :quote, :visiting
+ alias_method_chain :type_cast, :visiting
+ end
+ end
+
+ def self.apply!
+ ActiveRecord::ConnectionAdapters::Table.send :include, Migrations if defined? ActiveRecord::ConnectionAdapters::Table
+ ActiveRecord::ConnectionAdapters::TableDefinition.send :include, Migrations if defined? ActiveRecord::ConnectionAdapters::TableDefinition
+ ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter.send :include, Quoting if defined? ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter
+ ActiveRecord::ConnectionAdapters::SQLite3Adapter.send :include, Quoting if defined? ActiveRecord::ConnectionAdapters::SQLite3Adapter
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send :include, PostgreSQLQuoting if defined? ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
+ end
+ end
+end
View
@@ -4,17 +4,9 @@
module ActiveUUID
class Railtie < Rails::Railtie
railtie_name :activeuuid
- initializer "activeuuid.configure_rails_initialization" do
- module ActiveRecord::ConnectionAdapters
- class Table
- def uuid (*args)
- options = args.extract_options!
- column_names = args
- column_names.each { |name| column(name, 'binary(16)', options) }
- end
- end
- end
+ config.to_prepare do
+ ActiveUUID::Patches.apply!
end
end
end
View
@@ -3,6 +3,8 @@
module UUIDTools
class UUID
# monkey-patch Friendly::UUID to serialize UUIDs to MySQL
+ alias_method :id, :raw
+
def quoted_id
s = raw.unpack("H*")[0]
"x'#{s}'"
@@ -40,8 +42,7 @@ def visit_UUIDTools_UUID(o)
class PostgreSQL < Arel::Visitors::ToSql
def visit_UUIDTools_UUID(o)
- s = o.raw.unpack("H*")[0]
- "E'\\\\x#{s}'"
+ "'#{o.to_s}'"
end
end
end
@@ -55,10 +56,8 @@ def load(binary)
binary
when String
parse_string(binary)
- when nil
- nil
else
- raise TypeError, "the given type cannot be serialized"
+ nil
end
end
@@ -67,17 +66,16 @@ def dump(uuid)
when UUIDTools::UUID
uuid.raw
when String
- parse_string(uuid).raw
- when nil
- nil
+ parse_string(uuid).try(:raw)
else
- raise TypeError, "the given type cannot be serialized"
+ nil
end
end
private
def parse_string str
+ return nil if str.blank?
if str.length == 36
UUIDTools::UUID.parse str
elsif str.length == 32
@@ -92,6 +90,7 @@ module UUID
extend ActiveSupport::Concern
included do
+ class_attribute :uuid_attributes, :instance_writer => true
uuids :id
before_create :generate_uuids_if_needed
end
@@ -105,18 +104,18 @@ def natural_key(*attributes)
@_activeuuid_natural_key_attributes = attributes
end
- def uuid_attributes
- @_activeuuid_attributes
- end
-
def uuid_generator(generator_name=nil)
@_activeuuid_kind = generator_name if generator_name
@_activeuuid_kind || :random
- end
+ end
def uuids(*attributes)
- @_activeuuid_attributes = attributes.collect(&:intern).each do |attribute|
- serialize attribute.intern, ActiveUUID::UUIDSerializer.new
+ self.uuid_attributes = attributes.collect(&:intern).each do |attribute|
+ serialize attribute, ActiveUUID::UUIDSerializer.new
+ # serializing attributes on the fly
+ define_method "#{attribute}=" do |value|
+ write_attribute attribute, serialized_attributes[attribute.to_s].load(value)
+ end
end
#class_eval <<-eos
# # def #{@association_name}
@@ -142,10 +141,10 @@ def create_uuid
end
def generate_uuids_if_needed
- self.class.uuid_attributes.each do |attr|
+ (uuid_attributes & [self.class.primary_key.intern]).each do |attr|
self.send("#{attr}=", create_uuid) unless self.send(attr)
end
end
-
+
end
end
@@ -0,0 +1,4 @@
+Fabricator(:article) do
+ title { Forgery::LoremIpsum.word }
+ body { Forgery::LoremIpsum.sentence }
+end
@@ -0,0 +1,4 @@
+Fabricator(:uuid_article) do
+ title { Forgery::LoremIpsum.word }
+ body { Forgery::LoremIpsum.sentence }
+end
@@ -0,0 +1,63 @@
+require 'spec_helper'
+
+describe Article do
+ let!(:article) { Fabricate :article }
+ let(:id) { article.id }
+ let(:model) { Article }
+
+ context 'existance' do
+ specify { article.id.should be_a Integer }
+ it "should create record" do
+ model.all.should == [article]
+ model.first.should == article
+ end
+ end
+
+ context '.find' do
+ specify { model.find(id).should == article }
+ end
+
+ context '.where' do
+ specify { model.where(:id => id).first.should == article }
+ end
+
+ context '.destroy' do
+ specify { article.delete.should be_true }
+ specify { article.destroy.should be_true }
+ end
+end
+
+describe UuidArticle do
+ let!(:article) { Fabricate :uuid_article }
+ let(:id) { article.id }
+ let(:model) { UuidArticle }
+
+ specify { model.primary_key.should == 'id' }
+
+ context 'existance' do
+ specify { article.id.should be_a UUIDTools::UUID }
+ it "should create record" do
+ model.all.should == [article]
+ model.first.should == article
+ end
+ end
+
+ context '.find' do
+ specify { model.find(article).should == article }
+ specify { model.find(id).should == article }
+ specify { model.find(id.to_s).should == article }
+ specify { model.find(id.raw).should == article }
+ end
+
+ context '.where' do
+ specify { model.where(:id => article).first.should == article }
+ specify { model.where(:id => id).first.should == article }
+ specify { model.where(:id => id.to_s).first.should == article }
+ specify { model.where(:id => id.raw).first.should == article }
+ end
+
+ context '.destroy' do
+ specify { article.delete.should be_true }
+ specify { article.destroy.should be_true }
+ end
+end
@@ -1,4 +1,3 @@
-
require 'spec_helper'
describe ActiveUUID::UUIDSerializer do
@@ -34,12 +33,13 @@
@serializer.load(nil).should be_nil
end
- it 'throws an exception for other types' do
- lambda {
- @serializer.load(5)
- }.should raise_error(TypeError)
+ it 'returns nil for ""' do
+ @serializer.load('').should be_nil
+ end
+
+ it 'returns nil for other types' do
+ @serializer.load(5).should be_nil
end
-
end
describe '#dump' do
@@ -65,11 +65,12 @@
@serializer.dump(nil).should be_nil
end
- it 'throws an exception for other types' do
- lambda {
- @serializer.dump(5)
- }.should raise_error(TypeError)
+ it 'returns nil for ""' do
+ @serializer.dump('').should be_nil
end
+ it 'returns nil for other types' do
+ @serializer.dump(5).should be_nil
+ end
end
end
@@ -1,4 +1,3 @@
-
require 'spec_helper'
describe UUIDTools::UUID do
@@ -34,5 +33,5 @@
@uuid.to_param.should eql(@param_out)
end
end
-
+
end
View
@@ -1,10 +0,0 @@
-
-require 'rspec/mocks'
-RSpec::Mocks::setup(self)
-
-module Arel
- module Visitors
- class Visitor; end
- class ToSql; end
- end
-end
Oops, something went wrong.

0 comments on commit 0beaff9

Please sign in to comment.