first commit
This commit is contained in:
parent
fc71f38dec
commit
6fb6677a1e
51
README.md
51
README.md
@ -1,56 +1,35 @@
|
|||||||
NAME
|
NAME
|
||||||
----
|
----
|
||||||
mongoid-grid_fs
|
mongoid-sequence
|
||||||
|
|
||||||
INSTALL
|
INSTALL
|
||||||
-------
|
-------
|
||||||
gem install mongoid-grid_fs
|
gem install mongoid-sequence
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
|
|
||||||
````ruby
|
````ruby
|
||||||
|
|
||||||
require 'mongoid-grid_fs'
|
require 'mongoid'
|
||||||
|
require 'mongoid-sequence'
|
||||||
|
|
||||||
g = GridFs.put readable
|
|
||||||
|
|
||||||
GridFS.get id
|
class Page
|
||||||
|
include Mongoid::Document
|
||||||
|
include Mongoid::Sequence
|
||||||
|
|
||||||
GridFS.delete id
|
sequence :number
|
||||||
|
end
|
||||||
|
|
||||||
|
p Page.create.number #=> 1
|
||||||
|
p Page.create.number #=> 2
|
||||||
|
p Page.create.number #=> 3
|
||||||
|
|
||||||
|
|
||||||
````
|
````
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
mongoid_grid_fs is a pure mongoid 3 / moped implementation of the mongodb
|
mongoid_sequence is a pure mongoid sequence generator based on mongodb's
|
||||||
grid_fs specification
|
increment operator
|
||||||
|
|
||||||
ref: http://www.mongodb.org/display/DOCS/GridFS+Specification
|
|
||||||
|
|
||||||
it has the following features:
|
|
||||||
|
|
||||||
- implementation is on top of mongoid for portability. moped (the driver) is
|
|
||||||
barely used
|
|
||||||
|
|
||||||
- simple, REST-like api
|
|
||||||
|
|
||||||
- support for custom namespaces (fs.files vs. image.files)
|
|
||||||
|
|
||||||
- pathnames and io-like objects can be written to the grid
|
|
||||||
|
|
||||||
- auto-unique pathnames are generated (by default) to avoid collisions using #put
|
|
||||||
|
|
||||||
'path/info/a.rb' -> '$object_id/a.rb'
|
|
||||||
|
|
||||||
- [] and []= methods which allow the grid to be used like a giant file
|
|
||||||
hash in the sky
|
|
||||||
|
|
||||||
- supprt for data_uris
|
|
||||||
|
|
||||||
````erb
|
|
||||||
|
|
||||||
<%= image_tag :src => file.data_uri %>
|
|
||||||
|
|
||||||
````
|
|
||||||
|
4
Rakefile
4
Rakefile
@ -1,8 +1,8 @@
|
|||||||
This.name =
|
This.name =
|
||||||
"Mongoid::GridFs"
|
"Mongoid::Sequence"
|
||||||
|
|
||||||
This.synopsis =
|
This.synopsis =
|
||||||
"a mongoid 3/moped compatible implementation of the grid_fs specification"
|
"a mongoid 3/moped compatible sequence generator for your models"
|
||||||
|
|
||||||
This.rubyforge_project = 'codeforpeople'
|
This.rubyforge_project = 'codeforpeople'
|
||||||
This.author = "Ara T. Howard"
|
This.author = "Ara T. Howard"
|
||||||
|
125
lib/mongoid-sequence.rb
Normal file
125
lib/mongoid-sequence.rb
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
require 'mongoid'
|
||||||
|
|
||||||
|
module Mongoid
|
||||||
|
module Sequence
|
||||||
|
def Sequence.version
|
||||||
|
'1.0.0'
|
||||||
|
end
|
||||||
|
|
||||||
|
ClassMethods = proc do
|
||||||
|
def sequence(fieldname, *args, &block)
|
||||||
|
options = args.extract_options!.to_options!
|
||||||
|
|
||||||
|
sequence_name = (
|
||||||
|
options.delete(:sequence) || sequence_name_for(fieldname)
|
||||||
|
)
|
||||||
|
|
||||||
|
args.push(options)
|
||||||
|
|
||||||
|
before_create do |doc|
|
||||||
|
doc[fieldname] = SequenceGenerator.for(sequence_name).next
|
||||||
|
end
|
||||||
|
|
||||||
|
field(fieldname, *args, &block)
|
||||||
|
|
||||||
|
SequenceGenerator.for(sequence_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def sequence_for(fieldname)
|
||||||
|
SequenceGenerator.for(sequence_name_for(fieldname))
|
||||||
|
end
|
||||||
|
|
||||||
|
def sequence_name_for(fieldname)
|
||||||
|
SequenceGenerator.sequence_name_for(self, fieldname)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
InstanceMethods = proc do
|
||||||
|
def sequence_for(fieldname)
|
||||||
|
self.class.sequence_for(fieldname)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def Sequence.included(other)
|
||||||
|
other.send(:instance_eval, &ClassMethods)
|
||||||
|
other.send(:class_eval, &InstanceMethods)
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class SequenceGenerator
|
||||||
|
include Mongoid::Document
|
||||||
|
|
||||||
|
field(:name, :type => String)
|
||||||
|
|
||||||
|
field(:value, :default => 0, :type => Integer)
|
||||||
|
|
||||||
|
validates_presence_of(:name)
|
||||||
|
validates_uniqueness_of(:name)
|
||||||
|
|
||||||
|
validates_presence_of(:value)
|
||||||
|
|
||||||
|
index({:name => 1}, {:unique => true})
|
||||||
|
|
||||||
|
Cache = Hash.new
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def for(name)
|
||||||
|
name = name.to_s
|
||||||
|
|
||||||
|
Cache[name] ||= (
|
||||||
|
begin
|
||||||
|
create!(:name => name)
|
||||||
|
rescue
|
||||||
|
where(:name => name).first || create!(:name => name)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method('[]', 'for')
|
||||||
|
|
||||||
|
def sequence_name_for(klass, fieldname)
|
||||||
|
"#{ klass.name.underscore }-#{ fieldname }"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
after_destroy do |sequence|
|
||||||
|
Cache.delete(sequence.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def next
|
||||||
|
inc(:value, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_value
|
||||||
|
reload.value
|
||||||
|
end
|
||||||
|
|
||||||
|
def reset!
|
||||||
|
update_attributes!(:value => 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if $0 == __FILE__
|
||||||
|
|
||||||
|
Mongoid.configure do |config|
|
||||||
|
config.connect_to('mongoid-sequence')
|
||||||
|
end
|
||||||
|
|
||||||
|
class A
|
||||||
|
include Mongoid::Document
|
||||||
|
include Mongoid::Sequence
|
||||||
|
|
||||||
|
p sequence(:number)
|
||||||
|
end
|
||||||
|
|
||||||
|
A.sequence_for(:number).destroy
|
||||||
|
|
||||||
|
a = A.create!
|
||||||
|
p a
|
||||||
|
|
||||||
|
end
|
36
mongoid-sequence.gemspec
Normal file
36
mongoid-sequence.gemspec
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
## mongoid-sequence.gemspec
|
||||||
|
#
|
||||||
|
|
||||||
|
Gem::Specification::new do |spec|
|
||||||
|
spec.name = "mongoid-sequence"
|
||||||
|
spec.version = "1.0.0"
|
||||||
|
spec.platform = Gem::Platform::RUBY
|
||||||
|
spec.summary = "mongoid-sequence"
|
||||||
|
spec.description = "a mongoid 3/moped compatible sequence generator for your models"
|
||||||
|
|
||||||
|
spec.files =
|
||||||
|
["README.md",
|
||||||
|
"Rakefile",
|
||||||
|
"lib",
|
||||||
|
"lib/mongoid-sequence.rb",
|
||||||
|
"test",
|
||||||
|
"test/helper.rb",
|
||||||
|
"test/mongoid-sequence.rb",
|
||||||
|
"test/mongoid-sequence_test.rb",
|
||||||
|
"test/testing.rb"]
|
||||||
|
|
||||||
|
spec.executables = []
|
||||||
|
|
||||||
|
spec.require_path = "lib"
|
||||||
|
|
||||||
|
spec.test_files = "test/mongoid-sequence.rb"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
spec.extensions.push(*[])
|
||||||
|
|
||||||
|
spec.rubyforge_project = "codeforpeople"
|
||||||
|
spec.author = "Ara T. Howard"
|
||||||
|
spec.email = "ara.t.howard@gmail.com"
|
||||||
|
spec.homepage = "https://github.com/ahoward/mongoid-sequence"
|
||||||
|
end
|
@ -1,18 +1,8 @@
|
|||||||
# -*- encoding : utf-8 -*-
|
# -*- encoding : utf-8 -*-
|
||||||
|
require 'pp'
|
||||||
require_relative 'testing'
|
require_relative 'testing'
|
||||||
require_relative '../lib/mongoid-grid_fs.rb'
|
require_relative '../lib/mongoid-sequence.rb'
|
||||||
|
|
||||||
Mongoid.configure do |config|
|
Mongoid.configure do |config|
|
||||||
config.connect_to('mongoid-grid_fs_test')
|
config.connect_to('mongoid-sequence')
|
||||||
end
|
|
||||||
|
|
||||||
require 'stringio'
|
|
||||||
|
|
||||||
class SIO < StringIO
|
|
||||||
attr_accessor :filename
|
|
||||||
|
|
||||||
def initialize(filename, *args, &block)
|
|
||||||
@filename = filename
|
|
||||||
super(*args, &block)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
84
test/mongoid-sequence.rb
Normal file
84
test/mongoid-sequence.rb
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
require_relative 'helper'
|
||||||
|
|
||||||
|
Testing Mongoid::Sequence do
|
||||||
|
##
|
||||||
|
#
|
||||||
|
Sequence =
|
||||||
|
Mongoid::Sequence
|
||||||
|
|
||||||
|
SequenceGenerator =
|
||||||
|
Mongoid::SequenceGenerator
|
||||||
|
|
||||||
|
prepare do
|
||||||
|
SequenceGenerator.destroy_all
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
#
|
||||||
|
test 'can be included' do
|
||||||
|
assert do
|
||||||
|
model_class do
|
||||||
|
include Mongoid::Sequence
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'provided a "sequence" class method that builds a field' do
|
||||||
|
m =
|
||||||
|
assert do
|
||||||
|
model_class do
|
||||||
|
include Mongoid::Sequence
|
||||||
|
|
||||||
|
sequence 'number'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert{ m.fields['number'].name == 'number' }
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'autoincrements the field on create' do
|
||||||
|
m =
|
||||||
|
assert do
|
||||||
|
model_class do
|
||||||
|
include Mongoid::Sequence
|
||||||
|
|
||||||
|
sequence 'number'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
10.times do |i|
|
||||||
|
assert{ m.create.number == i.succ }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'allows the sequence to be reset' do
|
||||||
|
m =
|
||||||
|
assert do
|
||||||
|
model_class do
|
||||||
|
include Mongoid::Sequence
|
||||||
|
|
||||||
|
sequence 'number'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert{ m.sequence_for(:number).reset! }
|
||||||
|
assert{ m.sequence_for(:number).next == 1 }
|
||||||
|
assert{ m.sequence_for(:number).next != 1 }
|
||||||
|
assert{ m.sequence_for(:number).reset! }
|
||||||
|
assert{ m.sequence_for(:number).next == 1 }
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected
|
||||||
|
def model_class(&block)
|
||||||
|
m = Class.new
|
||||||
|
m.class_eval do
|
||||||
|
def m.name() 'm' end
|
||||||
|
include Mongoid::Document
|
||||||
|
end
|
||||||
|
m.destroy_all
|
||||||
|
m.class_eval(&block) if block
|
||||||
|
m
|
||||||
|
end
|
||||||
|
end
|
84
test/mongoid-sequence_test.rb
Normal file
84
test/mongoid-sequence_test.rb
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
require_relative 'helper'
|
||||||
|
|
||||||
|
Testing Mongoid::Sequence do
|
||||||
|
##
|
||||||
|
#
|
||||||
|
Sequence =
|
||||||
|
Mongoid::Sequence
|
||||||
|
|
||||||
|
SequenceGenerator =
|
||||||
|
Mongoid::SequenceGenerator
|
||||||
|
|
||||||
|
prepare do
|
||||||
|
SequenceGenerator.destroy_all
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
#
|
||||||
|
test 'can be included' do
|
||||||
|
assert do
|
||||||
|
model_class do
|
||||||
|
include Mongoid::Sequence
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'provided a "sequence" class method that builds a field' do
|
||||||
|
m =
|
||||||
|
assert do
|
||||||
|
model_class do
|
||||||
|
include Mongoid::Sequence
|
||||||
|
|
||||||
|
sequence 'number'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert{ m.fields['number'].name == 'number' }
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'autoincrements the field on create' do
|
||||||
|
m =
|
||||||
|
assert do
|
||||||
|
model_class do
|
||||||
|
include Mongoid::Sequence
|
||||||
|
|
||||||
|
sequence 'number'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
10.times do |i|
|
||||||
|
assert{ m.create.number == i.succ }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'allows the sequence to be reset' do
|
||||||
|
m =
|
||||||
|
assert do
|
||||||
|
model_class do
|
||||||
|
include Mongoid::Sequence
|
||||||
|
|
||||||
|
sequence 'number'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert{ m.sequence_for(:number).reset! }
|
||||||
|
assert{ m.sequence_for(:number).next == 1 }
|
||||||
|
assert{ m.sequence_for(:number).next != 1 }
|
||||||
|
assert{ m.sequence_for(:number).reset! }
|
||||||
|
assert{ m.sequence_for(:number).next == 1 }
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected
|
||||||
|
def model_class(&block)
|
||||||
|
m = Class.new
|
||||||
|
m.class_eval do
|
||||||
|
def m.name() 'm' end
|
||||||
|
include Mongoid::Document
|
||||||
|
end
|
||||||
|
m.destroy_all
|
||||||
|
m.class_eval(&block) if block
|
||||||
|
m
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user