dm-yaml-adapter 0.7 → 1.0.0.rc3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +36 -0
- data/Gemfile +82 -0
- data/LICENSE +20 -0
- data/Rakefile +28 -0
- data/VERSION +1 -0
- data/dm-yaml-adapter.gemspec +65 -0
- data/lib/dm-yaml-adapter.rb +2 -189
- data/lib/dm-yaml-adapter/adapter.rb +111 -0
- data/lib/dm-yaml-adapter/core_ext/class.rb +5 -0
- data/lib/dm-yaml-adapter/spec/setup.rb +20 -0
- data/spec/adapter_spec.rb +21 -0
- data/spec/rcov.opts +5 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +3 -21
- data/tasks/local_gemfile.rake +18 -0
- data/tasks/spec.rake +41 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +86 -24
- data/README +0 -54
- data/spec/dm-yaml-adapter_spec.rb +0 -53
data/.gitignore
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
## MAC OS
|
2
|
+
.DS_Store
|
3
|
+
|
4
|
+
## TEXTMATE
|
5
|
+
*.tmproj
|
6
|
+
tmtags
|
7
|
+
|
8
|
+
## EMACS
|
9
|
+
*~
|
10
|
+
\#*
|
11
|
+
.\#*
|
12
|
+
|
13
|
+
## VIM
|
14
|
+
*.swp
|
15
|
+
|
16
|
+
## Rubinius
|
17
|
+
*.rbc
|
18
|
+
|
19
|
+
## PROJECT::GENERAL
|
20
|
+
*.gem
|
21
|
+
coverage
|
22
|
+
rdoc
|
23
|
+
pkg
|
24
|
+
tmp
|
25
|
+
doc
|
26
|
+
log
|
27
|
+
.yardoc
|
28
|
+
measurements
|
29
|
+
|
30
|
+
## BUNDLER
|
31
|
+
.bundle
|
32
|
+
Gemfile.local
|
33
|
+
Gemfile.lock
|
34
|
+
|
35
|
+
## PROJECT::SPECIFIC
|
36
|
+
spec/db/
|
data/Gemfile
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# If you're working on more than one datamapper gem at a time, then it's
|
2
|
+
# recommended to create a local Gemfile and use this instead of the git
|
3
|
+
# sources. This will make sure that you are developing against your
|
4
|
+
# other local datamapper sources that you currently work on. Gemfile.local
|
5
|
+
# will behave identically to the standard Gemfile apart from the fact that
|
6
|
+
# it fetches the gems from local paths. This means that you can use the
|
7
|
+
# same environment variables, like ADAPTER when running bundle commands.
|
8
|
+
# Gemfile.local is added to .gitignore, so you don't need to worry about
|
9
|
+
# accidentally checking local development paths into git.
|
10
|
+
#
|
11
|
+
# bundle exec rake local_gemfile
|
12
|
+
#
|
13
|
+
# will give you a Gemfile.local file that points to your local clones of
|
14
|
+
# the various datamapper gems. It's assumed that all datamapper repo clones
|
15
|
+
# reside in the same directory. You can use the Gemfile.local like so for
|
16
|
+
# running any bundle command:
|
17
|
+
#
|
18
|
+
# BUNDLE_GEMFILE=Gemfile.local bundle foo
|
19
|
+
#
|
20
|
+
# To speed up running bundle tasks, it's recommended to run
|
21
|
+
#
|
22
|
+
# bundle lock
|
23
|
+
#
|
24
|
+
# after running 'bundle install' for the first time. This will make 'bundle exec' run
|
25
|
+
# a lot faster compared to the unlocked version. With an unlocked bundle you would
|
26
|
+
# typically just run 'bundle install' from time to time to fetch the latest sources from
|
27
|
+
# upstream. When you locked your bundle, you need to run
|
28
|
+
#
|
29
|
+
# bundle install --relock
|
30
|
+
#
|
31
|
+
# to make sure to fetch the latest updates and then lock the bundle again. Gemfile.lock
|
32
|
+
# is added to the .gitignore file, so you don't need to worry about accidentally checking
|
33
|
+
# it into version control.
|
34
|
+
|
35
|
+
source 'http://rubygems.org'
|
36
|
+
|
37
|
+
DATAMAPPER = 'git://github.com/datamapper'
|
38
|
+
DM_VERSION = '~> 1.0.0.rc3'
|
39
|
+
|
40
|
+
group :runtime do # Runtime dependencies (as in the gemspec)
|
41
|
+
|
42
|
+
gem 'dm-core', DM_VERSION, :git => "#{DATAMAPPER}/dm-core.git"
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
group(:development) do # Development dependencies (as in the gemspec)
|
47
|
+
|
48
|
+
gem 'dm-migrations', DM_VERSION, :git => "#{DATAMAPPER}/dm-migrations.git"
|
49
|
+
|
50
|
+
gem 'rake', '~> 0.8.7'
|
51
|
+
gem 'rspec', '~> 1.3'
|
52
|
+
gem 'jeweler', '~> 1.4'
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
group :datamapper do # We need this because we want to pin these dependencies to their git master sources
|
57
|
+
|
58
|
+
if ENV['EXTLIB']
|
59
|
+
gem 'extlib', '~> 0.9.15', :git => "#{DATAMAPPER}/extlib.git", :require => nil
|
60
|
+
else
|
61
|
+
gem 'activesupport', '~> 3.0.0.beta3', :git => 'git://github.com/rails/rails.git', :require => nil
|
62
|
+
end
|
63
|
+
|
64
|
+
plugins = ENV['PLUGINS'] || ENV['PLUGIN']
|
65
|
+
plugins = (plugins.to_s.gsub(',',' ').split(' ') + ['dm-migrations']).uniq
|
66
|
+
|
67
|
+
plugins.each do |plugin|
|
68
|
+
gem plugin, DM_VERSION, :git => "#{DATAMAPPER}/#{plugin}.git"
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
group :quality do # These gems contain rake tasks that check the quality of the source code
|
74
|
+
|
75
|
+
gem 'metric_fu', '~> 1.3'
|
76
|
+
gem 'rcov', '~> 0.9.7'
|
77
|
+
gem 'reek', '~> 1.2.7'
|
78
|
+
gem 'roodi', '~> 2.1'
|
79
|
+
gem 'yard', '~> 0.5'
|
80
|
+
gem 'yardstick', '~> 0.1'
|
81
|
+
|
82
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Dan Kubb
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
gem 'jeweler', '~> 1.4'
|
6
|
+
require 'jeweler'
|
7
|
+
|
8
|
+
Jeweler::Tasks.new do |gem|
|
9
|
+
gem.name = 'dm-yaml-adapter'
|
10
|
+
gem.summary = 'YAML Adapter for DataMapper'
|
11
|
+
gem.description = gem.summary
|
12
|
+
gem.email = 'dan.kubb@gmail.com'
|
13
|
+
gem.homepage = 'http://github.com/datamapper/%s' % gem.name
|
14
|
+
gem.authors = [ 'Dan Kubb' ]
|
15
|
+
|
16
|
+
gem.rubyforge_project = 'datamapper'
|
17
|
+
|
18
|
+
gem.add_dependency 'dm-core', '~> 1.0.0.rc3'
|
19
|
+
|
20
|
+
gem.add_development_dependency 'rspec', '~> 1.3'
|
21
|
+
end
|
22
|
+
|
23
|
+
Jeweler::GemcutterTasks.new
|
24
|
+
|
25
|
+
FileList['tasks/**/*.rake'].each { |task| import task }
|
26
|
+
rescue LoadError
|
27
|
+
puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler'
|
28
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0.rc3
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{dm-yaml-adapter}
|
8
|
+
s.version = "1.0.0.rc3"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Dan Kubb"]
|
12
|
+
s.date = %q{2010-05-27}
|
13
|
+
s.description = %q{YAML Adapter for DataMapper}
|
14
|
+
s.email = %q{dan.kubb@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"Gemfile",
|
21
|
+
"LICENSE",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"dm-yaml-adapter.gemspec",
|
25
|
+
"lib/dm-yaml-adapter.rb",
|
26
|
+
"lib/dm-yaml-adapter/adapter.rb",
|
27
|
+
"lib/dm-yaml-adapter/core_ext/class.rb",
|
28
|
+
"lib/dm-yaml-adapter/spec/setup.rb",
|
29
|
+
"spec/adapter_spec.rb",
|
30
|
+
"spec/rcov.opts",
|
31
|
+
"spec/spec.opts",
|
32
|
+
"spec/spec_helper.rb",
|
33
|
+
"tasks/local_gemfile.rake",
|
34
|
+
"tasks/spec.rake",
|
35
|
+
"tasks/yard.rake",
|
36
|
+
"tasks/yardstick.rake"
|
37
|
+
]
|
38
|
+
s.homepage = %q{http://github.com/datamapper/dm-yaml-adapter}
|
39
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
40
|
+
s.require_paths = ["lib"]
|
41
|
+
s.rubyforge_project = %q{datamapper}
|
42
|
+
s.rubygems_version = %q{1.3.7}
|
43
|
+
s.summary = %q{YAML Adapter for DataMapper}
|
44
|
+
s.test_files = [
|
45
|
+
"spec/adapter_spec.rb",
|
46
|
+
"spec/spec_helper.rb"
|
47
|
+
]
|
48
|
+
|
49
|
+
if s.respond_to? :specification_version then
|
50
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
51
|
+
s.specification_version = 3
|
52
|
+
|
53
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
54
|
+
s.add_runtime_dependency(%q<dm-core>, ["~> 1.0.0.rc3"])
|
55
|
+
s.add_development_dependency(%q<rspec>, ["~> 1.3"])
|
56
|
+
else
|
57
|
+
s.add_dependency(%q<dm-core>, ["~> 1.0.0.rc3"])
|
58
|
+
s.add_dependency(%q<rspec>, ["~> 1.3"])
|
59
|
+
end
|
60
|
+
else
|
61
|
+
s.add_dependency(%q<dm-core>, ["~> 1.0.0.rc3"])
|
62
|
+
s.add_dependency(%q<rspec>, ["~> 1.3"])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
data/lib/dm-yaml-adapter.rb
CHANGED
@@ -1,189 +1,2 @@
|
|
1
|
-
require '
|
2
|
-
require 'dm-
|
3
|
-
require 'yaml'
|
4
|
-
require 'dm-core/adapters/abstract_adapter'
|
5
|
-
|
6
|
-
module DataMapper::Adapters
|
7
|
-
|
8
|
-
class YamlAdapter < AbstractAdapter
|
9
|
-
|
10
|
-
def initialize(name, options)
|
11
|
-
super
|
12
|
-
|
13
|
-
@options = Hash.new
|
14
|
-
|
15
|
-
@options[:directory] = options[:directory]
|
16
|
-
|
17
|
-
@options[:directory] ||= './db'
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
def destroy_model_storage(repository, model)
|
22
|
-
FileUtils.rm_rf(classname_to_dir(model.to_s))
|
23
|
-
end
|
24
|
-
|
25
|
-
def create_model_storage(repository, model)
|
26
|
-
FileUtils.mkdir_p(classname_to_dir(model.to_s))
|
27
|
-
end
|
28
|
-
|
29
|
-
def create(resources)
|
30
|
-
resources.each do |resource|
|
31
|
-
model = resource.model
|
32
|
-
id = find_free_id_for(resource.class.to_s)
|
33
|
-
# find name of key attribute
|
34
|
-
key = model.key.first.name
|
35
|
-
resource.attributes[key] = id
|
36
|
-
resource.instance_variable_set("@" + key.to_s, id)
|
37
|
-
save(resource)
|
38
|
-
end
|
39
|
-
return resources.size
|
40
|
-
end
|
41
|
-
|
42
|
-
def delete(query)
|
43
|
-
resultset = yaml_query(query)
|
44
|
-
resultset.each do |result|
|
45
|
-
yaml_destroy(result)
|
46
|
-
end
|
47
|
-
return resultset.size
|
48
|
-
end
|
49
|
-
|
50
|
-
def read_one(query)
|
51
|
-
return(filter_result_set(get_all(query.model), query).first)
|
52
|
-
end
|
53
|
-
|
54
|
-
def update(attributes, query)
|
55
|
-
# ok, for each object found we have to update the attribs we found
|
56
|
-
# first thing is figure out what class we are dealing with
|
57
|
-
clazz = query.model
|
58
|
-
# next, get all the matching objects
|
59
|
-
objs = filter_result_set(clazz.all, query)
|
60
|
-
# iterate over every object in this set and set the given attributes
|
61
|
-
objs.each do |obj|
|
62
|
-
attributes.each do |attrib|
|
63
|
-
# attrib is an array
|
64
|
-
# first member is Property object
|
65
|
-
# second member is the value
|
66
|
-
obj.instance_variable_set("@" + attrib[0].name.to_s, attrib[1])
|
67
|
-
end
|
68
|
-
save(obj)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def read_many(query)
|
73
|
-
return filter_result_set(get_all(query.model), query)
|
74
|
-
end
|
75
|
-
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
def yaml_destroy(resource)
|
80
|
-
# take an objects class and ID and figure
|
81
|
-
# out what file it's in
|
82
|
-
# and then remove that file
|
83
|
-
class_name = resource.class.to_s
|
84
|
-
id = resource.key.first
|
85
|
-
file = class_name_to_file(class_name, id)
|
86
|
-
File.unlink(file)
|
87
|
-
end
|
88
|
-
|
89
|
-
def yaml_query(query)
|
90
|
-
# in this method, we want to take each condition and figure out
|
91
|
-
# what we should return
|
92
|
-
|
93
|
-
# first is figuring out our class
|
94
|
-
model = query.model
|
95
|
-
# if we just want all the objects...
|
96
|
-
if (query.conditions.empty?)
|
97
|
-
return get_all(model)
|
98
|
-
end
|
99
|
-
|
100
|
-
# otherwise we have to filter on some conditions...
|
101
|
-
all_objs = get_all(model)
|
102
|
-
# for each object, check all the conditions
|
103
|
-
filter_result_set(all_objs, query)
|
104
|
-
end
|
105
|
-
|
106
|
-
def filter_result_set(objects, query)
|
107
|
-
result_set = objects.clone
|
108
|
-
objects.each do |obj|
|
109
|
-
query.conditions.each do |operator, property, value|
|
110
|
-
case operator
|
111
|
-
# handle eql
|
112
|
-
when :eql, :like
|
113
|
-
if ! (obj.instance_variable_get("@" + property.field).to_s == value.to_s)
|
114
|
-
# remove from teh result set...
|
115
|
-
result_set.delete(obj)
|
116
|
-
end
|
117
|
-
# handle :not
|
118
|
-
when :not
|
119
|
-
if (obj.instance_variable_get("@" + property.field).to_s == value.to_s)
|
120
|
-
result_set.delete(obj)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
return result_set
|
126
|
-
end
|
127
|
-
|
128
|
-
def get_all(clazz)
|
129
|
-
objects = Array.new
|
130
|
-
directory = classname_to_dir(clazz.to_s)
|
131
|
-
if ! File.exists?(directory)
|
132
|
-
return objects
|
133
|
-
end
|
134
|
-
Dir.entries(directory).grep(/\.yaml$/).each do |entry|
|
135
|
-
objects << file_to_object(File.join(directory, entry))
|
136
|
-
end
|
137
|
-
return objects
|
138
|
-
end
|
139
|
-
|
140
|
-
def file_to_object(file)
|
141
|
-
new_obj = YAML.load_file(file)
|
142
|
-
new_obj.instance_variable_set("@new_record", false)
|
143
|
-
return new_obj
|
144
|
-
end
|
145
|
-
|
146
|
-
def find_free_id_for(class_name)
|
147
|
-
# if there are no entries in the directory, or the directory doesn't exist
|
148
|
-
# we need to create it...
|
149
|
-
|
150
|
-
if ! File.exists?(classname_to_dir(class_name))
|
151
|
-
# default ID
|
152
|
-
return 1
|
153
|
-
end
|
154
|
-
directory = Dir.new(classname_to_dir(class_name))
|
155
|
-
if directory.entries.size == 0
|
156
|
-
return 1
|
157
|
-
end
|
158
|
-
free_id = -1
|
159
|
-
id = -1
|
160
|
-
until free_id != -1 do
|
161
|
-
id += 1
|
162
|
-
if ! File.exists?(File.join(directory.path, id.to_s + ".yaml"))
|
163
|
-
return id
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
def save(resource)
|
169
|
-
file = File.join(class_name_to_file(resource.class.to_s, resource.id))
|
170
|
-
# see if the directory exists, if it doesn't, we need to create it
|
171
|
-
if ! File.exists?(classname_to_dir(resource.class.to_s))
|
172
|
-
FileUtils.mkdir_p(classname_to_dir(resource.class.to_s))
|
173
|
-
end
|
174
|
-
yamlfile = File.new(class_name_to_file(resource.class.to_s, resource.id), "w")
|
175
|
-
yamlfile.puts resource.to_yaml
|
176
|
-
yamlfile.close
|
177
|
-
end
|
178
|
-
|
179
|
-
def classname_to_dir(class_name)
|
180
|
-
return File.join(@options[:directory], class_name.gsub("/", "_"))
|
181
|
-
end
|
182
|
-
|
183
|
-
def class_name_to_file(class_name, id)
|
184
|
-
return File.join(classname_to_dir(class_name), id.to_s + ".yaml")
|
185
|
-
end
|
186
|
-
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
1
|
+
require 'dm-yaml-adapter/adapter'
|
2
|
+
require 'dm-yaml-adapter/core_ext/class'
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'dm-core'
|
3
|
+
|
4
|
+
module DataMapper
|
5
|
+
module Adapters
|
6
|
+
class YamlAdapter < AbstractAdapter
|
7
|
+
# @api semipublic
|
8
|
+
def create(resources)
|
9
|
+
update_records(resources.first.model) do |records|
|
10
|
+
resources.each do |resource|
|
11
|
+
initialize_serial(resource, records.size.succ)
|
12
|
+
records << attributes_as_fields(resource.attributes(nil))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# @api semipublic
|
18
|
+
def read(query)
|
19
|
+
query.filter_records(records_for(query.model).dup)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @api semipublic
|
23
|
+
def update(attributes, collection)
|
24
|
+
attributes = attributes_as_fields(attributes)
|
25
|
+
|
26
|
+
update_records(collection.model) do |records|
|
27
|
+
records_to_update = collection.query.filter_records(records.dup)
|
28
|
+
records_to_update.each { |record| record.update(attributes) }.size
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @api semipublic
|
33
|
+
def delete(collection)
|
34
|
+
update_records(collection.model) do |records|
|
35
|
+
records_to_delete = collection.query.filter_records(records.dup)
|
36
|
+
records.replace(records - records_to_delete)
|
37
|
+
records_to_delete.size
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# @api semipublic
|
44
|
+
def initialize(name, options = {})
|
45
|
+
super
|
46
|
+
(@path = Pathname(@options[:path]).freeze).mkpath
|
47
|
+
end
|
48
|
+
|
49
|
+
# Retrieves all records for a model and yields them to a block.
|
50
|
+
#
|
51
|
+
# The block should make any changes to the records in-place. After
|
52
|
+
# the block executes all the records are dumped back to the file.
|
53
|
+
#
|
54
|
+
# @param [Model, #to_s] model
|
55
|
+
# Used to determine which file to read/write to
|
56
|
+
#
|
57
|
+
# @yieldparam [Hash]
|
58
|
+
# A hash of record.key => record pairs retrieved from the file
|
59
|
+
#
|
60
|
+
# @api private
|
61
|
+
def update_records(model)
|
62
|
+
records = records_for(model)
|
63
|
+
result = yield records
|
64
|
+
write_records(model, records)
|
65
|
+
result
|
66
|
+
end
|
67
|
+
|
68
|
+
# Read all records from a file for a model
|
69
|
+
#
|
70
|
+
# @param [#storage_name] model
|
71
|
+
# The model/name to retieve records for
|
72
|
+
#
|
73
|
+
# @api private
|
74
|
+
def records_for(model)
|
75
|
+
file = yaml_file(model)
|
76
|
+
file.readable? && YAML.load_file(file) || []
|
77
|
+
end
|
78
|
+
|
79
|
+
# Writes all records to a file
|
80
|
+
#
|
81
|
+
# @param [#storage_name] model
|
82
|
+
# The model/name to write the records for
|
83
|
+
#
|
84
|
+
# @param [Hash] records
|
85
|
+
# A hash of record.key => record pairs to be written
|
86
|
+
#
|
87
|
+
# @api private
|
88
|
+
def write_records(model, records)
|
89
|
+
yaml_file(model).open('w') do |fh|
|
90
|
+
YAML.dump(records, fh)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Given a model, gives the filename to be used for record storage
|
95
|
+
#
|
96
|
+
# @example
|
97
|
+
# yaml_file(Article) #=> "/path/to/files/articles.yml"
|
98
|
+
#
|
99
|
+
# @param [#storage_name] model
|
100
|
+
# The model to be used to determine the file name.
|
101
|
+
#
|
102
|
+
# @api private
|
103
|
+
def yaml_file(model)
|
104
|
+
@path.join("#{model.storage_name(name)}.yml")
|
105
|
+
end
|
106
|
+
|
107
|
+
end # class YamlAdapter
|
108
|
+
|
109
|
+
const_added(:YamlAdapter)
|
110
|
+
end # module Adapters
|
111
|
+
end # module DataMapper
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'dm-yaml-adapter'
|
2
|
+
require 'dm-core/spec/setup'
|
3
|
+
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
module DataMapper
|
7
|
+
module Spec
|
8
|
+
module Adapters
|
9
|
+
|
10
|
+
class YamlAdapter < Adapter
|
11
|
+
def connection_uri
|
12
|
+
"yaml://#{Dir.tmpdir}/#{storage_name}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
use YamlAdapter
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'dm-core'
|
4
|
+
require 'dm-core/spec/shared/adapter_spec'
|
5
|
+
|
6
|
+
require 'dm-migrations'
|
7
|
+
require 'dm-yaml-adapter/spec/setup'
|
8
|
+
|
9
|
+
ENV['ADAPTER'] = 'yaml'
|
10
|
+
ENV['ADAPTER_SUPPORTS'] = 'all'
|
11
|
+
|
12
|
+
describe 'DataMapper::Adapters::YamlAdapter' do
|
13
|
+
|
14
|
+
before :all do
|
15
|
+
@adapter = DataMapper::Spec.adapter
|
16
|
+
@repository = DataMapper.repository(@adapter.name)
|
17
|
+
end
|
18
|
+
|
19
|
+
it_should_behave_like "An Adapter"
|
20
|
+
|
21
|
+
end
|
data/spec/rcov.opts
ADDED
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
CHANGED
@@ -1,23 +1,5 @@
|
|
1
|
-
require '
|
2
|
-
require 'dm-core'
|
3
|
-
require 'pathname'
|
4
|
-
require Pathname(__FILE__).dirname.parent.expand_path + 'lib/dm-yaml-adapter'
|
1
|
+
require 'dm-core/spec/lib/pending_helpers'
|
5
2
|
|
6
|
-
|
7
|
-
include
|
8
|
-
|
9
|
-
property :post_id, Serial
|
10
|
-
property :title, String
|
11
|
-
|
12
|
-
belongs_to :user
|
13
|
-
end
|
14
|
-
|
15
|
-
class User
|
16
|
-
include DataMapper::Resource
|
17
|
-
|
18
|
-
property :user_id, Serial
|
19
|
-
property :name, String
|
20
|
-
property :age, Integer
|
21
|
-
|
22
|
-
has n, :posts
|
3
|
+
Spec::Runner.configure do |config|
|
4
|
+
config.include(DataMapper::Spec::PendingHelpers)
|
23
5
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
desc "Support bundling from local source code (allows BUNDLE_GEMFILE=Gemfile.local bundle foo)"
|
2
|
+
task :local_gemfile do |t|
|
3
|
+
|
4
|
+
root = Pathname(__FILE__).dirname.parent
|
5
|
+
datamapper = root.parent
|
6
|
+
|
7
|
+
source_regex = /DATAMAPPER = 'git:\/\/github.com\/datamapper'/
|
8
|
+
gem_source_regex = /:git => \"#\{DATAMAPPER\}\/(.+?)(?:\.git)?\"/
|
9
|
+
|
10
|
+
root.join('Gemfile.local').open('w') do |f|
|
11
|
+
root.join('Gemfile').open.each do |line|
|
12
|
+
line.sub!(source_regex, "DATAMAPPER = '#{datamapper}'")
|
13
|
+
line.sub!(gem_source_regex, ':path => "#{DATAMAPPER}/\1"')
|
14
|
+
f.puts line
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
data/tasks/spec.rake
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
spec_defaults = lambda do |spec|
|
2
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
3
|
+
spec.libs << 'lib' << 'spec'
|
4
|
+
spec.spec_opts << '--options' << 'spec/spec.opts'
|
5
|
+
end
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'spec/rake/spectask'
|
9
|
+
|
10
|
+
Spec::Rake::SpecTask.new(:spec, &spec_defaults)
|
11
|
+
rescue LoadError
|
12
|
+
task :spec do
|
13
|
+
abort 'rspec is not available. In order to run spec, you must: gem install rspec'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
begin
|
18
|
+
require 'rcov'
|
19
|
+
require 'spec/rake/verify_rcov'
|
20
|
+
|
21
|
+
Spec::Rake::SpecTask.new(:rcov) do |rcov|
|
22
|
+
spec_defaults.call(rcov)
|
23
|
+
rcov.rcov = true
|
24
|
+
rcov.rcov_opts = File.read('spec/rcov.opts').split(/\s+/)
|
25
|
+
end
|
26
|
+
|
27
|
+
RCov::VerifyTask.new(:verify_rcov => :rcov) do |rcov|
|
28
|
+
rcov.threshold = 100
|
29
|
+
end
|
30
|
+
rescue LoadError
|
31
|
+
%w[ rcov verify_rcov ].each do |name|
|
32
|
+
task name do
|
33
|
+
abort "rcov is not available. In order to run #{name}, you must: gem install rcov"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
task :spec => :check_dependencies
|
39
|
+
task :rcov => :check_dependencies
|
40
|
+
|
41
|
+
task :default => :spec
|
data/tasks/yard.rake
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
begin
|
2
|
+
require 'pathname'
|
3
|
+
require 'yardstick/rake/measurement'
|
4
|
+
require 'yardstick/rake/verify'
|
5
|
+
|
6
|
+
# yardstick_measure task
|
7
|
+
Yardstick::Rake::Measurement.new
|
8
|
+
|
9
|
+
# verify_measurements task
|
10
|
+
Yardstick::Rake::Verify.new do |verify|
|
11
|
+
verify.threshold = 100
|
12
|
+
end
|
13
|
+
rescue LoadError
|
14
|
+
%w[ yardstick_measure verify_measurements ].each do |name|
|
15
|
+
task name.to_s do
|
16
|
+
abort "Yardstick is not available. In order to run #{name}, you must: gem install yardstick"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
metadata
CHANGED
@@ -1,57 +1,119 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-yaml-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 977940572
|
5
|
+
prerelease: true
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
- rc3
|
11
|
+
version: 1.0.0.rc3
|
5
12
|
platform: ruby
|
6
13
|
authors:
|
7
|
-
-
|
8
|
-
autorequire:
|
14
|
+
- Dan Kubb
|
15
|
+
autorequire:
|
9
16
|
bindir: bin
|
10
17
|
cert_chain: []
|
11
18
|
|
12
|
-
date:
|
19
|
+
date: 2010-05-27 00:00:00 -07:00
|
13
20
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
|
17
|
-
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: dm-core
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 977940572
|
31
|
+
segments:
|
32
|
+
- 1
|
33
|
+
- 0
|
34
|
+
- 0
|
35
|
+
- rc3
|
36
|
+
version: 1.0.0.rc3
|
37
|
+
type: :runtime
|
38
|
+
version_requirements: *id001
|
39
|
+
- !ruby/object:Gem::Dependency
|
40
|
+
name: rspec
|
41
|
+
prerelease: false
|
42
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
hash: 9
|
48
|
+
segments:
|
49
|
+
- 1
|
50
|
+
- 3
|
51
|
+
version: "1.3"
|
52
|
+
type: :development
|
53
|
+
version_requirements: *id002
|
54
|
+
description: YAML Adapter for DataMapper
|
55
|
+
email: dan.kubb@gmail.com
|
18
56
|
executables: []
|
19
57
|
|
20
58
|
extensions: []
|
21
59
|
|
22
60
|
extra_rdoc_files:
|
23
|
-
-
|
61
|
+
- LICENSE
|
24
62
|
files:
|
63
|
+
- .gitignore
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE
|
66
|
+
- Rakefile
|
67
|
+
- VERSION
|
68
|
+
- dm-yaml-adapter.gemspec
|
25
69
|
- lib/dm-yaml-adapter.rb
|
26
|
-
-
|
70
|
+
- lib/dm-yaml-adapter/adapter.rb
|
71
|
+
- lib/dm-yaml-adapter/core_ext/class.rb
|
72
|
+
- lib/dm-yaml-adapter/spec/setup.rb
|
73
|
+
- spec/adapter_spec.rb
|
74
|
+
- spec/rcov.opts
|
75
|
+
- spec/spec.opts
|
27
76
|
- spec/spec_helper.rb
|
28
|
-
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
77
|
+
- tasks/local_gemfile.rake
|
78
|
+
- tasks/spec.rake
|
79
|
+
- tasks/yard.rake
|
80
|
+
- tasks/yardstick.rake
|
81
|
+
has_rdoc: true
|
82
|
+
homepage: http://github.com/datamapper/dm-yaml-adapter
|
83
|
+
licenses: []
|
33
84
|
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options:
|
87
|
+
- --charset=UTF-8
|
34
88
|
require_paths:
|
35
89
|
- lib
|
36
90
|
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
37
92
|
requirements:
|
38
93
|
- - ">="
|
39
94
|
- !ruby/object:Gem::Version
|
95
|
+
hash: 3
|
96
|
+
segments:
|
97
|
+
- 0
|
40
98
|
version: "0"
|
41
|
-
version:
|
42
99
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
43
101
|
requirements:
|
44
|
-
- - "
|
102
|
+
- - ">"
|
45
103
|
- !ruby/object:Gem::Version
|
46
|
-
|
47
|
-
|
104
|
+
hash: 25
|
105
|
+
segments:
|
106
|
+
- 1
|
107
|
+
- 3
|
108
|
+
- 1
|
109
|
+
version: 1.3.1
|
48
110
|
requirements: []
|
49
111
|
|
50
|
-
rubyforge_project:
|
51
|
-
rubygems_version: 1.3.
|
112
|
+
rubyforge_project: datamapper
|
113
|
+
rubygems_version: 1.3.7
|
52
114
|
signing_key:
|
53
|
-
specification_version:
|
54
|
-
summary:
|
115
|
+
specification_version: 3
|
116
|
+
summary: YAML Adapter for DataMapper
|
55
117
|
test_files:
|
56
|
-
- spec/
|
118
|
+
- spec/adapter_spec.rb
|
57
119
|
- spec/spec_helper.rb
|
data/README
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
dm-yaml-adapter
|
2
|
-
|
3
|
-
This adapter is for DataMapper. This allows you to persist objects to YAML files and still have the query capabilities of DataMapper. I wouldn't scale this out to a zillion files, but if you have a lot of read action on a small database this could be the project for you. OR use it to better understand DataMapper.
|
4
|
-
|
5
|
-
|
6
|
-
Example usage:
|
7
|
-
|
8
|
-
We have to tell datamapper where we will be storing the YAML files.
|
9
|
-
directory tells the adapter where to store.
|
10
|
-
|
11
|
-
DataMapper.setup(:default, {:adapter => 'yaml', :directory => 'db'})
|
12
|
-
|
13
|
-
|
14
|
-
Trying it out:
|
15
|
-
|
16
|
-
If you want some examples of defining classes, check out the spec directory.
|
17
|
-
|
18
|
-
Anyway, assuming you have a decent environment set up, you can try out some examples.
|
19
|
-
|
20
|
-
If you want to use irb to try some of this interactively, try 'irb' and then
|
21
|
-
> load 'irbhelper.irb'
|
22
|
-
|
23
|
-
That sets up a basic environment with User and Post resources already defined.
|
24
|
-
|
25
|
-
irb(main):001:0> load 'irbhelper.irb'
|
26
|
-
=> true
|
27
|
-
irb(main):002:0> u = User.create(:name => 'Bob', :age => 55)
|
28
|
-
=> #<User user_id=1 name="Bob" age=55>
|
29
|
-
irb(main):003:0> u.save
|
30
|
-
=> true
|
31
|
-
irb(main):004:0> User.all
|
32
|
-
=> [#<User user_id=1 name="Bob" age=55>]
|
33
|
-
irb(main):005:0>
|
34
|
-
|
35
|
-
If you use another window to check out the db directory you should have a nice User directory with a 1.yaml file in there, with the data of Bob.
|
36
|
-
|
37
|
-
You can also add another object and start playing around with some queries.
|
38
|
-
|
39
|
-
irb(main):005:0> User.create(:name => 'Sue', :age => 32)
|
40
|
-
=> #<User user_id=2 name="Sue" age=32>
|
41
|
-
irb(main):006:0> User.all(:age => 32)
|
42
|
-
=> [#<User user_id=2 name="Sue" age=32>]
|
43
|
-
irb(main):007:0> User.all
|
44
|
-
=> [#<User user_id=1 name="Bob" age=55>, #<User user_id=2 name="Sue" age=32>]
|
45
|
-
irb(main):008:0> u.destroy
|
46
|
-
=> true
|
47
|
-
irb(main):009:0> User.all
|
48
|
-
=> [#<User user_id=2 name="Sue" age=32>]
|
49
|
-
irb(main):010:0>
|
50
|
-
|
51
|
-
Changes:
|
52
|
-
|
53
|
-
0.7: Ruby 1.9 Compatibility
|
54
|
-
Changed ID identity functions to to_s.
|
@@ -1,53 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'dm-core'
|
3
|
-
require 'dm-yaml-adapter'
|
4
|
-
require 'pathname'
|
5
|
-
require Pathname(__FILE__).dirname.expand_path + 'spec_helper'
|
6
|
-
|
7
|
-
describe DataMapper::Adapters::YamlAdapter do
|
8
|
-
before(:all) do
|
9
|
-
@adapter = DataMapper.setup(:default, {:adapter => 'yaml', :directory => 'db'})
|
10
|
-
User.auto_migrate!
|
11
|
-
@user1 = User.create(:name => 'tom')
|
12
|
-
@user2 = User.create(:name => 'jim')
|
13
|
-
end
|
14
|
-
|
15
|
-
describe "CRUD" do
|
16
|
-
|
17
|
-
describe "create" do
|
18
|
-
it "should create" do
|
19
|
-
@user1.user_id.should_not == nil
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe "read" do
|
24
|
-
it "should read all" do
|
25
|
-
begin
|
26
|
-
users = User.all
|
27
|
-
rescue Exception => e
|
28
|
-
puts e
|
29
|
-
puts e.backtrace
|
30
|
-
end
|
31
|
-
users.size.should_not == 0
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
describe "delete" do
|
36
|
-
it "should delete someone" do
|
37
|
-
user = User.create
|
38
|
-
user.destroy.should == true
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe "find not" do
|
43
|
-
it "should find someone with a not clause" do
|
44
|
-
users = User.all(:user_id.not => @user1.id)
|
45
|
-
users.first.user_id.should_not == @user1.id
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
|
52
|
-
end
|
53
|
-
|