first commit

This commit is contained in:
ahoward 2012-08-10 09:06:48 -06:00
parent fc71f38dec
commit 6fb6677a1e
7 changed files with 349 additions and 51 deletions

View File

@ -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 %>
````

View File

@ -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
View 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
View 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

View File

@ -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
View 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

View 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