datamapper4rail 0.1.0
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/History.txt +6 -0
- data/Manifest.txt +22 -0
- data/README.txt +101 -0
- data/Rakefile +32 -0
- data/generators/dm_install/dm_install_generator.rb +12 -0
- data/generators/dm_install/templates/datamapper.rake +42 -0
- data/generators/dm_migration/dm_migration_generator.rb +10 -0
- data/generators/dm_migration/templates/migration.rb +16 -0
- data/generators/dm_model/dm_model_generator.rb +27 -0
- data/generators/dm_model/templates/model.rb +14 -0
- data/generators/dm_model/templates/unit_test.rb +8 -0
- data/generators/rspec_default_values.rb +20 -0
- data/generators/rspec_dm_model/rspec_dm_model_generator.rb +33 -0
- data/generators/rspec_dm_model/templates/model.rb +16 -0
- data/generators/rspec_dm_model/templates/model_spec.rb +41 -0
- data/lib/datamapper4rails.rb +53 -0
- data/lib/datamapper4rails/adapters/base_adapter.rb +198 -0
- data/lib/datamapper4rails/adapters/restful_adapter.rb +252 -0
- data/lib/datamapper4rails/database_config.rb +49 -0
- data/lib/datamapper4rails/datamapper_store.rb +67 -0
- data/lib/datamapper4rails/restful_transactions.rb +42 -0
- data/lib/datamapper4rails/version.rb +3 -0
- metadata +97 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
generators/dm_install/dm_install_generator.rb
|
6
|
+
generators/dm_install/templates/datamapper.rake
|
7
|
+
generators/dm_migration/dm_migration_generator.rb
|
8
|
+
generators/dm_migration/templates/migration.rb
|
9
|
+
generators/dm_model/dm_model_generator.rb
|
10
|
+
generators/dm_model/templates/model.rb
|
11
|
+
generators/dm_model/templates/unit_test.rb
|
12
|
+
generators/rspec_default_values.rb
|
13
|
+
generators/rspec_dm_model/rspec_dm_model_generator.rb
|
14
|
+
generators/rspec_dm_model/templates/model.rb
|
15
|
+
generators/rspec_dm_model/templates/model_spec.rb
|
16
|
+
lib/datamapper4rails.rb
|
17
|
+
lib/datamapper4rails/adapters/base_adapter.rb
|
18
|
+
lib/datamapper4rails/adapters/restful_adapter.rb
|
19
|
+
lib/datamapper4rails/database_config.rb
|
20
|
+
lib/datamapper4rails/datamapper_store.rb
|
21
|
+
lib/datamapper4rails/restful_transactions.rb
|
22
|
+
lib/datamapper4rails/version.rb
|
data/README.txt
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
= datamapper4rails
|
2
|
+
|
3
|
+
* http://datamapper4rail.rubyforge.org
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
collection of datamapper related extensions. mostly needed to run within rails. the restful transactions is around filter for rails. the restful adapter can be outside of rails. datamapper store is a session store for rails which uses datamapper as persistent layer. the generators produces datamapper models for your rails application. quite a few things are "stolen" from dm-more/rails_datamapper. a lot of things do not work there and patches are still in process to be applied so until dm-more/rails_datamapper catches up, ut I hope these two project merge someday again.
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
* restful adapter does handle associations partially and does not handle collections
|
12
|
+
|
13
|
+
== SYNOPSIS:
|
14
|
+
|
15
|
+
=== restful transaction
|
16
|
+
|
17
|
+
wraps all modifying requests (POST, PUT, DELETE) into a transaction. any error/exception as well render of a page will rollback the transaction. typically if a POST, PUT or DELETE succeeds then a redirect gets send back to browser.
|
18
|
+
|
19
|
+
credits of the main idea goes to http://www.redhillonrails.org
|
20
|
+
|
21
|
+
is implemented as around filter in rails and gets prepend to the filters of the action_controller of rails
|
22
|
+
|
23
|
+
require 'datamapper4rails/restful_transations
|
24
|
+
|
25
|
+
=== datamapper session store
|
26
|
+
|
27
|
+
this is just the datamapper compaign to the activerecord_store.
|
28
|
+
|
29
|
+
in config/environment.rb add
|
30
|
+
|
31
|
+
config.action_controller.session_store = :datamapper_store
|
32
|
+
|
33
|
+
in case you need a memory cache for your sessions add this
|
34
|
+
|
35
|
+
config.action_controller.session = { :cache => true }
|
36
|
+
|
37
|
+
=== generators for datamapper models
|
38
|
+
|
39
|
+
this is taken from dm-more/rails_datamapper and extended it - to my liking. patches are submitted upstream until they get applied this will remain here.
|
40
|
+
|
41
|
+
* dm-install: rake task for datamapper: automigrate, autoupgrade
|
42
|
+
* dm_model
|
43
|
+
* rspec_dm_model
|
44
|
+
|
45
|
+
=== database config
|
46
|
+
|
47
|
+
this is also taken from dm-more/rails_datamapper and just uses the
|
48
|
+
'config/database.yml' to configure a database connection. it also allows to configure multiple repositories for a single environment just nest the config in such a way:
|
49
|
+
|
50
|
+
development:
|
51
|
+
repositories:
|
52
|
+
default:
|
53
|
+
adapter: sqlite3
|
54
|
+
database: db/development.sqlite3
|
55
|
+
pool: 5
|
56
|
+
timeout: 5000
|
57
|
+
users:
|
58
|
+
adapter: ldap
|
59
|
+
host: localhost
|
60
|
+
port: 389
|
61
|
+
base: dc=example,dc=com
|
62
|
+
bind_name: cn=admin,dc=example,dc=com
|
63
|
+
password: secret
|
64
|
+
|
65
|
+
|
66
|
+
=== restful adapter
|
67
|
+
|
68
|
+
this comes partly from dm-ldap-adapter and partly from dm-more/adapter/rest_adapter. the restful adapter allows to Create, Retrieve, Update and Delete resources via a restful service.
|
69
|
+
|
70
|
+
== REQUIREMENTS:
|
71
|
+
|
72
|
+
* datamapper
|
73
|
+
|
74
|
+
== INSTALL:
|
75
|
+
|
76
|
+
* sudo gem install datamapper4rails
|
77
|
+
|
78
|
+
== LICENSE:
|
79
|
+
|
80
|
+
(The MIT License)
|
81
|
+
|
82
|
+
Copyright (c) 2009 Kristian Meier
|
83
|
+
|
84
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
85
|
+
a copy of this software and associated documentation files (the
|
86
|
+
'Software'), to deal in the Software without restriction, including
|
87
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
88
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
89
|
+
permit persons to whom the Software is furnished to do so, subject to
|
90
|
+
the following conditions:
|
91
|
+
|
92
|
+
The above copyright notice and this permission notice shall be
|
93
|
+
included in all copies or substantial portions of the Software.
|
94
|
+
|
95
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
96
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
97
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
98
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
99
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
100
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
101
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
require './lib/datamapper4rails/version.rb'
|
6
|
+
|
7
|
+
Hoe.new('datamapper4rail', Datamapper4rails::VERSION) do |p|
|
8
|
+
p.rubyforge_name = 'datamapper4rail'
|
9
|
+
p.developer('mkristian', 'm.kristian@web.de')
|
10
|
+
p.extra_deps = ['slf4r']
|
11
|
+
p.remote_rdoc_dir = '' # Release to root
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'Install the package as a gem.'
|
15
|
+
task :install => [:clean, :package] do
|
16
|
+
gem = Dir['pkg/*.gem'].first
|
17
|
+
sh "gem install --local #{gem} --no-ri --no-rdoc"
|
18
|
+
end
|
19
|
+
|
20
|
+
# desc 'Run specifications'
|
21
|
+
# Spec::Rake::SpecTask.new(:spec) do |t|
|
22
|
+
# if File.exists?('spec/spec.opts')
|
23
|
+
# t.spec_opts << '--options' << 'spec/spec.opts'
|
24
|
+
# end
|
25
|
+
# t.spec_files = Pathname.glob('./spec/**/*_spec.rb')
|
26
|
+
# end
|
27
|
+
|
28
|
+
# require 'yard'
|
29
|
+
|
30
|
+
# YARD::Rake::YardocTask.new
|
31
|
+
|
32
|
+
# vim: syntax=Ruby
|
@@ -0,0 +1,42 @@
|
|
1
|
+
namespace :db do
|
2
|
+
|
3
|
+
desc "Perform automigration"
|
4
|
+
task :automigrate => :environment do
|
5
|
+
FileList["app/models/**/*.rb"].each do |model|
|
6
|
+
load model
|
7
|
+
end
|
8
|
+
::DataMapper.auto_migrate!
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Perform non destructive automigration"
|
12
|
+
task :autoupgrade => :environment do
|
13
|
+
FileList["app/models/**/*.rb"].each do |model|
|
14
|
+
load model
|
15
|
+
end
|
16
|
+
::DataMapper.auto_upgrade!
|
17
|
+
end
|
18
|
+
|
19
|
+
namespace :migrate do
|
20
|
+
task :load => :environment do
|
21
|
+
gem 'dm-migrations'
|
22
|
+
FileList["db/migrations/*.rb"].each do |migration|
|
23
|
+
load migration
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Migrate up using migrations"
|
28
|
+
task :up, :version, :needs => :load do |t, args|
|
29
|
+
version = args[:version]
|
30
|
+
migrate_up!(version)
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Migrate down using migrations"
|
34
|
+
task :down, :version, :needs => :load do |t, args|
|
35
|
+
version = args[:version]
|
36
|
+
migrate_down!(version)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "Migrate the database to the latest version"
|
41
|
+
task :migrate => 'db:migrate:up'
|
42
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class <%= migration_name %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :<%= table_name %> do |t|
|
4
|
+
<% for attribute in attributes -%>
|
5
|
+
t.<%= attribute.type %> :<%= attribute.name %>
|
6
|
+
<% end -%>
|
7
|
+
<% unless options[:skip_timestamps] %>
|
8
|
+
t.timestamps
|
9
|
+
<% end -%>
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
drop_table :<%= table_name %>
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rails_generator/generators/components/model/model_generator'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
class DmModelGenerator <ModelGenerator
|
5
|
+
|
6
|
+
def manifest
|
7
|
+
record do |m|
|
8
|
+
# Check for class naming collisions.
|
9
|
+
m.class_collisions class_path, class_name, "#{class_name}Test"
|
10
|
+
|
11
|
+
# Model, test, and fixture directories.
|
12
|
+
m.directory File.join('app/models', class_path)
|
13
|
+
m.directory File.join('test/unit', class_path)
|
14
|
+
|
15
|
+
# Model class, unit test, and fixtures.
|
16
|
+
m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
|
17
|
+
m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
|
18
|
+
|
19
|
+
unless options[:skip_migration]
|
20
|
+
m.migration_template 'model:migration.rb', 'db/migrate', :assigns => {
|
21
|
+
:migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
|
22
|
+
}, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class <%= class_name %>
|
2
|
+
include DataMapper::Resource
|
3
|
+
property :id, Serial
|
4
|
+
|
5
|
+
<% for attribute in attributes -%>
|
6
|
+
property :<%= attribute.name %>, <%= attribute.type.to_s.capitalize %>, :nullable => false
|
7
|
+
|
8
|
+
<% end -%>
|
9
|
+
<% unless options[:skip_timestamps] %>
|
10
|
+
property :created_at, DateTime, :nullable => false
|
11
|
+
property :updated_at, DateTime, :nullable => false
|
12
|
+
|
13
|
+
<% end -%>
|
14
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Rails
|
2
|
+
module Generator
|
3
|
+
class GeneratedAttribute
|
4
|
+
def default_value
|
5
|
+
@default_value ||= case type
|
6
|
+
when :int, :integer then "1"
|
7
|
+
when :float then "1.5"
|
8
|
+
when :decimal, :big_decimal then "9.99"
|
9
|
+
when :date_time, :datetime,
|
10
|
+
:timestamp, :time then "Time.now"
|
11
|
+
when :date then "Date.today"
|
12
|
+
when :string, :text then "\"value for #{@name}\""
|
13
|
+
when :boolean then "false"
|
14
|
+
else
|
15
|
+
""
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rails_generator/generators/components/model/model_generator'
|
2
|
+
require 'active_record'
|
3
|
+
require File.dirname(__FILE__) + '/../rspec_default_values'
|
4
|
+
|
5
|
+
class RspecDmModelExtendedGenerator <ModelGenerator
|
6
|
+
|
7
|
+
def manifest
|
8
|
+
record do |m|
|
9
|
+
|
10
|
+
# Check for class naming collisions.
|
11
|
+
m.class_collisions class_path, class_name
|
12
|
+
|
13
|
+
# Model, spec, and fixture directories.
|
14
|
+
m.directory File.join('app/models', class_path)
|
15
|
+
m.directory File.join('spec/models', class_path)
|
16
|
+
|
17
|
+
# Model class, spec and fixtures.
|
18
|
+
m.template 'model.rb', File.join('app/models',
|
19
|
+
class_path,
|
20
|
+
"#{file_name}.rb")
|
21
|
+
m.template 'model_spec.rb', File.join('spec/models',
|
22
|
+
class_path,
|
23
|
+
"#{file_name}_spec.rb")
|
24
|
+
end
|
25
|
+
|
26
|
+
# unless options[:skip_migration]
|
27
|
+
# m.migration_template 'model:migration.rb', 'db/migrate', :assigns => {
|
28
|
+
# :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
|
29
|
+
# }, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
|
30
|
+
# end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class <%= class_name %>
|
2
|
+
include DataMapper::Resource
|
3
|
+
property :id, Serial
|
4
|
+
|
5
|
+
<% for attribute in attributes -%>
|
6
|
+
property :<%= attribute.name %>, <%= attribute.type.to_s.camelize %>, :nullable => false <% if attribute.type == :string or attribute.type == :text -%>, :format => /^[^<'&">]*$/<% if attribute.type == :string %>, :length => 50<% end -%>
|
7
|
+
<% else -%>
|
8
|
+
|
9
|
+
<% end -%>
|
10
|
+
<% end -%>
|
11
|
+
<% unless options[:skip_timestamps] %>
|
12
|
+
property :created_at, DateTime, :nullable => false
|
13
|
+
property :updated_at, DateTime, :nullable => false
|
14
|
+
|
15
|
+
<% end -%>
|
16
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper')
|
2
|
+
|
3
|
+
describe <%= class_name %> do
|
4
|
+
before(:each) do
|
5
|
+
@valid_attributes = {
|
6
|
+
<% attributes.each_with_index do |attribute, attribute_index| -%>
|
7
|
+
:<%= attribute.name %> => <%= attribute.default_value %><%= attribute_index == attributes.length - 1 ? '' : ','%>
|
8
|
+
<% end -%>
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
<% attributes.each do |attribute| -%>
|
13
|
+
it "should require <%= attribute.name %>" do
|
14
|
+
<%= singular_name %> = <%= class_name %>.create(@valid_attributes.merge(:<%= attribute.name %> => nil))
|
15
|
+
<%= singular_name %>.errors.on(:<%= attribute.name %>).should_not == nil
|
16
|
+
end
|
17
|
+
|
18
|
+
<% if attribute.type == :string or attribute.type == :text -%>
|
19
|
+
it 'should not match <%= attribute.name %>' do
|
20
|
+
<%= singular_name %> = <%= class_name %>.create(@valid_attributes.merge(:<%= attribute.name %> => "<script" ))
|
21
|
+
<%= singular_name %>.errors.on(:<%= attribute.name %>).should_not == nil
|
22
|
+
<%= singular_name %> = <%= class_name %>.create(@valid_attributes.merge(:<%= attribute.name %> => "sc'ript" ))
|
23
|
+
<%= singular_name %>.errors.on(:<%= attribute.name %>).should_not == nil
|
24
|
+
<%= singular_name %> = <%= class_name %>.create(@valid_attributes.merge(:<%= attribute.name %> => "scr&ipt" ))
|
25
|
+
<%= singular_name %>.errors.on(:<%= attribute.name %>).should_not == nil
|
26
|
+
<%= singular_name %> = <%= class_name %>.create(@valid_attributes.merge(:<%= attribute.name %> => 'scr"ipt' ))
|
27
|
+
<%= singular_name %>.errors.on(:<%= attribute.name %>).should_not == nil
|
28
|
+
<%= singular_name %> = <%= class_name %>.create(@valid_attributes.merge(:<%= attribute.name %> => "script>" ))
|
29
|
+
<%= singular_name %>.errors.on(:<%= attribute.name %>).should_not == nil
|
30
|
+
end
|
31
|
+
|
32
|
+
<% elsif [:integer, :big_decimal, :float].member? attribute.type %>
|
33
|
+
it "should be numerical <%= attribute.name %>" do
|
34
|
+
<%= singular_name %> = <%= class_name %>.create(@valid_attributes.merge(:<%= attribute.name %> => "none-numberic" ))
|
35
|
+
<%= singular_name %>.<%= attribute.name %>.to_i.should == 0
|
36
|
+
<%= singular_name %>.errors.size.should == 0
|
37
|
+
end
|
38
|
+
|
39
|
+
<% end -%>
|
40
|
+
<% end -%>
|
41
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
def config_file()
|
3
|
+
RAILS_ROOT + "/config/database.yml"
|
4
|
+
end
|
5
|
+
|
6
|
+
def create_connection()
|
7
|
+
conf = config.dup
|
8
|
+
if repositories = conf.delete(:repositories)
|
9
|
+
repositories.each do |repo, conf|
|
10
|
+
::DataMapper.setup(repo, conf) unless conf.empty?
|
11
|
+
end
|
12
|
+
else
|
13
|
+
::DataMapper.setup(:default, conf) unless conf.empty?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_config_for_environment
|
18
|
+
if hash = full_config[RAILS_ENV]
|
19
|
+
symbolize_keys(hash)
|
20
|
+
elsif hash = full_config[RAILS_ENV.to_sym]
|
21
|
+
hash
|
22
|
+
else
|
23
|
+
raise ArgumentError, "missing environment '#{RAILS_ENV}' in config file #{config_file}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def full_config
|
28
|
+
@full_config ||= YAML::load(ERB.new(IO.read(config_file)).result)
|
29
|
+
end
|
30
|
+
|
31
|
+
def config
|
32
|
+
@config ||= get_config_for_environment
|
33
|
+
end
|
34
|
+
|
35
|
+
def symbolize_keys(h)
|
36
|
+
config = {}
|
37
|
+
|
38
|
+
h.each do |k, v|
|
39
|
+
if k == 'port'
|
40
|
+
config[k.to_sym] = v.to_i
|
41
|
+
elsif k == 'adapter' && v == 'postgresql'
|
42
|
+
config[k.to_sym] = 'postgres'
|
43
|
+
elsif v.is_a?(Hash)
|
44
|
+
config[k.to_sym] = symbolize_keys(v)
|
45
|
+
else
|
46
|
+
config[k.to_sym] = v
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
config
|
51
|
+
end
|
52
|
+
|
53
|
+
create_connection()
|
@@ -0,0 +1,198 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
require 'slf4r'
|
3
|
+
|
4
|
+
module DataMapper
|
5
|
+
module Adapters
|
6
|
+
class NoopTransaction
|
7
|
+
|
8
|
+
def close ; end
|
9
|
+
def begin ; end
|
10
|
+
def prepare ; end
|
11
|
+
def commit ; end
|
12
|
+
def rollback ; end
|
13
|
+
def rollback_prepared ; end
|
14
|
+
|
15
|
+
end
|
16
|
+
class BaseAdapter < AbstractAdapter
|
17
|
+
|
18
|
+
include Slf4r::Logger
|
19
|
+
|
20
|
+
# @see AbstractAdapter
|
21
|
+
def transaction_primitive
|
22
|
+
NoopTransaction.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(name, uri_or_options)
|
26
|
+
super(name, uri_or_options)
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
# checks whether a given resource fullfils the conditions
|
32
|
+
# @param [DataMapper::Resource] resource
|
33
|
+
# @param [Array<Condition>] conditions
|
34
|
+
# @return [Boolean]
|
35
|
+
# true if the resource are within the conditions otherwise false
|
36
|
+
def filter_resource(resource, conditions)
|
37
|
+
#puts "condi"
|
38
|
+
#p conditions
|
39
|
+
# no conditation => no filter
|
40
|
+
if conditions.size == 0
|
41
|
+
true
|
42
|
+
else
|
43
|
+
conditions.all? do |tuple|
|
44
|
+
operator, property, bind_value = *tuple
|
45
|
+
|
46
|
+
value = property.get!(resource)
|
47
|
+
case operator
|
48
|
+
when :eql, :in then equality_comparison(bind_value, value)
|
49
|
+
when :not then !equality_comparison(bind_value, value)
|
50
|
+
when :like then Regexp.new(bind_value.gsub(/%/, ".*")) =~ value
|
51
|
+
when :gt then !value.nil? && value > bind_value
|
52
|
+
when :gte then !value.nil? && value >= bind_value
|
53
|
+
when :lt then !value.nil? && value < bind_value
|
54
|
+
when :lte then !value.nil? && value <= bind_value
|
55
|
+
else raise "Invalid query operator: #{operator.inspect}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# helper method to dispatch the equality test for different
|
62
|
+
# classes
|
63
|
+
def equality_comparison(bind_value, value)
|
64
|
+
case bind_value
|
65
|
+
when Array, Range then bind_value.include?(value)
|
66
|
+
when NilClass then value.nil?
|
67
|
+
else bind_value == value
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
public
|
72
|
+
|
73
|
+
# @see AbstractAdapter
|
74
|
+
# @param [Array<DataMapper::Resources>] resources
|
75
|
+
# aaaa
|
76
|
+
# @return [Fixnum]
|
77
|
+
# number of the newly created resources
|
78
|
+
def create(resources)
|
79
|
+
resources.select do |resource|
|
80
|
+
|
81
|
+
create_resource(resource)
|
82
|
+
|
83
|
+
end.size # just return the number of create resources
|
84
|
+
end
|
85
|
+
|
86
|
+
# @see AbstractAdapter
|
87
|
+
# @param [Hash] attributes
|
88
|
+
# collection of attribute, i.e. the name/value pairs which
|
89
|
+
# needs to be updated
|
90
|
+
# @param [Query]
|
91
|
+
# on all resources which are selected by that query the
|
92
|
+
# update will be applied
|
93
|
+
# @return [Fixnum]
|
94
|
+
# number of the updated resources
|
95
|
+
def update(attributes, query)
|
96
|
+
read_many(query).select do |resource|
|
97
|
+
|
98
|
+
update_resource(resource, attributes)
|
99
|
+
|
100
|
+
end.size
|
101
|
+
end
|
102
|
+
|
103
|
+
# @see AbstractAdapter
|
104
|
+
# @param [DataMapper::Query] query
|
105
|
+
# which selects the resource
|
106
|
+
# @return [DataMapper::Resource]
|
107
|
+
# the found Resource or nil
|
108
|
+
def read_one(query)
|
109
|
+
result = read_resource(query)
|
110
|
+
if result.is_a? Resource
|
111
|
+
result
|
112
|
+
elsif result # assume result to be Array with the values
|
113
|
+
#puts "------------------"
|
114
|
+
#p result
|
115
|
+
query.model.load(result, query)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# @see AbstractAdapter
|
120
|
+
# @param [DataMapper::Query] query
|
121
|
+
# which selects the resources
|
122
|
+
# @return [DataMapper::Collection]
|
123
|
+
# collection of Resources
|
124
|
+
def read_many(query)
|
125
|
+
Collection.new(query) do |set|
|
126
|
+
result = read_resources(query)
|
127
|
+
#puts "read_many"
|
128
|
+
#p result
|
129
|
+
if result.size > 0 and result.first.is_a? Resource
|
130
|
+
set.replace(result)
|
131
|
+
else
|
132
|
+
result.each do |values|
|
133
|
+
set.load(values)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# @see AbstractAdapter
|
140
|
+
# @param [Query] query
|
141
|
+
# which selects the resources to be deleted
|
142
|
+
# @return [Fixnum]
|
143
|
+
# number of the deleted resources
|
144
|
+
def delete(query)
|
145
|
+
read_many(query).each do |resource|
|
146
|
+
|
147
|
+
delete_resource(resource)
|
148
|
+
|
149
|
+
end.size
|
150
|
+
end
|
151
|
+
|
152
|
+
private
|
153
|
+
|
154
|
+
# @param [DataMapper::Resource] resource
|
155
|
+
# which will be created
|
156
|
+
# @return [DataMapper::Resource]
|
157
|
+
# either the resource itself if the creation was successful or nil
|
158
|
+
def create_resource(resource)
|
159
|
+
raise NotImplementedError.new
|
160
|
+
end
|
161
|
+
|
162
|
+
# @param [DataMapper::Query] query
|
163
|
+
# which selects the resource
|
164
|
+
# @return [DataMapper::Resource,Array<String>]
|
165
|
+
# the resource or a set of values ordered in the same manner as query.fields attributes
|
166
|
+
def read_resource(query)
|
167
|
+
raise NotImplementedError.new
|
168
|
+
end
|
169
|
+
|
170
|
+
# @param [DataMapper::Query] query
|
171
|
+
# which selects the resources
|
172
|
+
# @return [Array<DataMapper::Resource>,Array<String>]
|
173
|
+
# resources or ordered values
|
174
|
+
# @see #read_resource
|
175
|
+
def read_resources(query)
|
176
|
+
raise NotImplementedError.new
|
177
|
+
end
|
178
|
+
|
179
|
+
# @param [DataMapper::Resource] resource
|
180
|
+
# which will be updated with the given attributes.
|
181
|
+
# @param [Hash] attributes
|
182
|
+
# the keys are the property names and the values are the new values of that property.
|
183
|
+
# @return [DataMapper::Resource]
|
184
|
+
# resource on success otherwise nil
|
185
|
+
def update_resource(resource, attributes)
|
186
|
+
raise NotImplementedError.new
|
187
|
+
end
|
188
|
+
|
189
|
+
# @param [DataMapper::Resource] resource
|
190
|
+
# which will be deleted
|
191
|
+
# @return [DataMapper::Resource]
|
192
|
+
# either the resource if the deletion was successful or nil
|
193
|
+
def delete_resource(resource)
|
194
|
+
raise NotImplementedError.new
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,252 @@
|
|
1
|
+
require 'adapters/restful_adapter'
|
2
|
+
require 'net/http'
|
3
|
+
require 'extlib/inflection'
|
4
|
+
require 'extlib/module'
|
5
|
+
|
6
|
+
module DataMapper
|
7
|
+
module Adapters
|
8
|
+
class RestfulAdapter < BaseAdapter
|
9
|
+
|
10
|
+
include ::Slf4r::Logger
|
11
|
+
|
12
|
+
def resource_name_from_model(model)
|
13
|
+
::Extlib::Inflection.underscore(model.name)
|
14
|
+
end
|
15
|
+
|
16
|
+
def resource_name_from_query(query)
|
17
|
+
resource_name_from_model(query.model)
|
18
|
+
end
|
19
|
+
|
20
|
+
def keys_from_query(query)
|
21
|
+
keys = query.model.key
|
22
|
+
# work around strange missing of properties in model
|
23
|
+
# but the query has still the fields :P
|
24
|
+
if keys.size == 0
|
25
|
+
query.fields.select do |f|
|
26
|
+
f.key?
|
27
|
+
end
|
28
|
+
else
|
29
|
+
keys
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def key_value_from_query(query)
|
34
|
+
keys = keys_from_query(query)
|
35
|
+
logger.debug { "keys=#{keys.inspect}" }
|
36
|
+
if keys.size == 1
|
37
|
+
key = keys[0]
|
38
|
+
# return the third element of the condition array
|
39
|
+
# which belongs to the key
|
40
|
+
query.conditions.detect do |c|
|
41
|
+
c[1] == key
|
42
|
+
end[2]
|
43
|
+
else
|
44
|
+
raise "compound keys are not supported"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def http_get(uri)
|
49
|
+
send_request do |http|
|
50
|
+
request = Net::HTTP::Get.new(uri)
|
51
|
+
request.basic_auth(@uri[:login],
|
52
|
+
@uri[:password]) unless @uri[:login].blank?
|
53
|
+
http.request(request)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def http_post(uri, data = nil)
|
58
|
+
send_request do |http|
|
59
|
+
request = Net::HTTP::Post.new(uri, {
|
60
|
+
'content-type' => 'application/xml',
|
61
|
+
'content-length' => data.length.to_s
|
62
|
+
})
|
63
|
+
request.basic_auth(@uri[:login],
|
64
|
+
@uri[:password]) unless @uri[:login].blank?
|
65
|
+
http.request(request, data)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def http_put(uri, data = {})
|
70
|
+
send_request do |http|
|
71
|
+
request = Net::HTTP::Put.new(uri)
|
72
|
+
request.basic_auth(@uri[:login],
|
73
|
+
@uri[:password]) unless @uri[:login].blank?
|
74
|
+
request.set_form_data(data)
|
75
|
+
http.request(request)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def http_delete(uri)
|
80
|
+
send_request do |http|
|
81
|
+
request = Net::HTTP::Delete.new(uri)
|
82
|
+
request.basic_auth(@uri[:login],
|
83
|
+
@uri[:password]) unless @uri[:login].blank?
|
84
|
+
http.request(request)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def send_request(&block)
|
89
|
+
res = nil
|
90
|
+
Net::HTTP.start(@uri[:host], @uri[:port].to_i) do |http|
|
91
|
+
res = yield(http)
|
92
|
+
end
|
93
|
+
logger.debug { "response=" + res.code }
|
94
|
+
res
|
95
|
+
end
|
96
|
+
|
97
|
+
def parse_resource(xml, model, query = nil)
|
98
|
+
elements = {}
|
99
|
+
associations = {}
|
100
|
+
many_to_many = {}
|
101
|
+
xml.elements.collect do |element|
|
102
|
+
if element.text.nil?
|
103
|
+
if element.attributes['type'] == 'array'
|
104
|
+
many_to_many[element.name.gsub('-','_').to_sym] = element
|
105
|
+
else
|
106
|
+
associations[element.name.gsub('-','_').to_sym] = element
|
107
|
+
end
|
108
|
+
else
|
109
|
+
elements[element.name.gsub('-','_').to_sym] = element.text
|
110
|
+
end
|
111
|
+
end
|
112
|
+
#puts
|
113
|
+
#puts "elements"
|
114
|
+
#p elements
|
115
|
+
resource = model.load(model.properties.collect do |f|
|
116
|
+
elements[f.name]
|
117
|
+
end, query)
|
118
|
+
resource.send("#{keys_from_query(query)[0].name}=".to_sym, elements[keys_from_query(query)[0].name] )
|
119
|
+
#p resource
|
120
|
+
associations.each do |name, association|
|
121
|
+
model =
|
122
|
+
if rel = model.relationships[name]
|
123
|
+
if rel.child_model == model
|
124
|
+
rel.parent_model
|
125
|
+
else
|
126
|
+
rel.child_model
|
127
|
+
end
|
128
|
+
# else
|
129
|
+
#::Extlib::Inflection.constantize(::Extlib::Inflection.classify(name))
|
130
|
+
# model.find_const(::Extlib::Inflection.classify(name))
|
131
|
+
end
|
132
|
+
if resource.respond_to? "#{name}=".to_sym
|
133
|
+
resource.send("#{name}=".to_sym,
|
134
|
+
parse_resource(association, model,
|
135
|
+
::DataMapper::Query.new(query.repository, model )))
|
136
|
+
else
|
137
|
+
resource.send(("#{name.to_s.pluralize}<" + "<").to_sym,
|
138
|
+
parse_resource(association, model,
|
139
|
+
::DataMapper::Query.new(query.repository, model )))
|
140
|
+
end
|
141
|
+
end
|
142
|
+
resource.instance_variable_set(:@new_record, false)
|
143
|
+
resource
|
144
|
+
end
|
145
|
+
|
146
|
+
# @see BaseAdapter
|
147
|
+
def create_resource(resource)
|
148
|
+
name = resource.model.name
|
149
|
+
uri = "/#{name.pluralize}.xml"
|
150
|
+
logger.debug { "post #{uri}" }
|
151
|
+
response = http_post(uri, resource.to_xml )
|
152
|
+
resource_new = parse_resource(REXML::Document::new(response.body).root,
|
153
|
+
resource.model,
|
154
|
+
::DataMapper::Query.new(resource.repository,
|
155
|
+
resource.model ))
|
156
|
+
|
157
|
+
# copy all attributes/associations from the downloaded resource
|
158
|
+
# to the given resource
|
159
|
+
# TODO better pass the given resource into parse_resource
|
160
|
+
resource_new.attributes.each do |key, value|
|
161
|
+
resource.send(:properties)[key].set!(resource, value)
|
162
|
+
end
|
163
|
+
resource_new.send(:relationships).each do |key, value|
|
164
|
+
resource.send("#{key}=".to_sym, resource_new.send(key))
|
165
|
+
end
|
166
|
+
resource
|
167
|
+
end
|
168
|
+
|
169
|
+
# @see BaseAdapter
|
170
|
+
def read_resource(query)
|
171
|
+
if(query.conditions.empty?)
|
172
|
+
raise "not implemented"
|
173
|
+
else
|
174
|
+
key = key_value_from_query(query)
|
175
|
+
uri = "/#{resource_name_from_query(query).pluralize}/#{key}.xml"
|
176
|
+
logger.debug { "get #{uri}" }
|
177
|
+
response = http_get(uri)
|
178
|
+
if response.kind_of?(Net::HTTPSuccess)
|
179
|
+
parse_resource(REXML::Document::new(response.body).root,
|
180
|
+
query.model,
|
181
|
+
query)
|
182
|
+
else
|
183
|
+
#TODO may act on different response codes differently
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# @see BaseAdapter
|
189
|
+
def read_resources(query)
|
190
|
+
# raise "not implemented"
|
191
|
+
[read_resource(query)]
|
192
|
+
end
|
193
|
+
|
194
|
+
# @overwrite BaseAdapter
|
195
|
+
def update(attributes, query)
|
196
|
+
name = resource_name_from_query(query)
|
197
|
+
params = {}
|
198
|
+
attributes.each do |attr, val|
|
199
|
+
params["#{name}[#{attr.name}]"]=val
|
200
|
+
end
|
201
|
+
key = key_value_from_query(query)
|
202
|
+
uri = "/#{name.pluralize}/#{key}.xml"
|
203
|
+
logger.debug { "put #{uri}" }
|
204
|
+
response = http_put(uri, params)
|
205
|
+
response.kind_of?(Net::HTTPSuccess)
|
206
|
+
end
|
207
|
+
|
208
|
+
# @see BaseAdapter
|
209
|
+
def update_resource(resource, attributes)
|
210
|
+
query = resource.to_query
|
211
|
+
if(query.conditions.empty?)
|
212
|
+
raise "not implemented"
|
213
|
+
else
|
214
|
+
name = resource.name
|
215
|
+
params = {}
|
216
|
+
attributes.each do |attr, val|
|
217
|
+
params["#{name}[#{attr.name}]"]=val
|
218
|
+
end
|
219
|
+
key = key_value_from_query(query)
|
220
|
+
logger.debug {resource.to_xml}
|
221
|
+
response = http_put("/#{resource_name_from_query(query).pluralize}/#{key}.xml", params)
|
222
|
+
response.kind_of?(Net::HTTPSuccess)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# @overwrite BaseAdapter
|
227
|
+
def delete(query)
|
228
|
+
# TODO limit == 1 is NOT sufficient ONLY necessary
|
229
|
+
if query.limit == 1
|
230
|
+
name = resource_name_from_query(query)
|
231
|
+
key = key_value_from_query(query)
|
232
|
+
uri = "/#{name.pluralize}/#{key}.xml"
|
233
|
+
logger.debug { "delete #{uri}" }
|
234
|
+
response = http_delete(uri)
|
235
|
+
response.kind_of?(Net::HTTPSuccess)
|
236
|
+
else
|
237
|
+
super
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
# @see BaseAdapter
|
242
|
+
def delete_resource(resource)
|
243
|
+
name = resource.name
|
244
|
+
key = key_value_from_query(resource.to_queryquery)
|
245
|
+
uri = "/#{name.pluralize}/#{key}.xml"
|
246
|
+
logger.debug { "delete #{uri}" }
|
247
|
+
response = http_delete(uri)
|
248
|
+
response.kind_of?(Net::HTTPSuccess)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
|
3
|
+
def config_file()
|
4
|
+
RAILS_ROOT + "/config/database.yml"
|
5
|
+
end
|
6
|
+
|
7
|
+
def create_connection()
|
8
|
+
conf = config.dup
|
9
|
+
repositories = conf.delete(:repositories)
|
10
|
+
::DataMapper.setup(:default, conf) unless conf.empty?
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_config_for_environment
|
14
|
+
if hash = full_config[RAILS_ENV]
|
15
|
+
symbolize_keys(hash)
|
16
|
+
elsif hash = full_config[RAILS_ENV.to_sym]
|
17
|
+
hash
|
18
|
+
else
|
19
|
+
raise ArgumentError, "missing environment '#{RAILS_ENV}' in config file #{config_file}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def full_config
|
24
|
+
@full_config ||= YAML::load(ERB.new(IO.read(config_file)).result)
|
25
|
+
end
|
26
|
+
|
27
|
+
def config
|
28
|
+
@config ||= get_config_for_environment
|
29
|
+
end
|
30
|
+
|
31
|
+
def symbolize_keys(h)
|
32
|
+
config = {}
|
33
|
+
|
34
|
+
h.each do |k, v|
|
35
|
+
if k == 'port'
|
36
|
+
config[k.to_sym] = v.to_i
|
37
|
+
elsif k == 'adapter' && v == 'postgresql'
|
38
|
+
config[k.to_sym] = 'postgres'
|
39
|
+
elsif v.is_a?(Hash)
|
40
|
+
config[k.to_sym] = symbolize_keys(v)
|
41
|
+
else
|
42
|
+
config[k.to_sym] = v
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
config
|
47
|
+
end
|
48
|
+
|
49
|
+
create_connection()
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
module Session
|
5
|
+
class DatamapperStore < AbstractStore
|
6
|
+
|
7
|
+
def initialize(app, options = {})
|
8
|
+
super
|
9
|
+
if options.delete(:cache)
|
10
|
+
@@cache = {}
|
11
|
+
end
|
12
|
+
@@session_class = ::DatamapperStore::Session
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def get_session(env, sid)
|
17
|
+
sid ||= generate_sid
|
18
|
+
session =
|
19
|
+
if @@cache
|
20
|
+
@@cache[sid] || @@session_class.get(sid)
|
21
|
+
else
|
22
|
+
@@session_class.get(sid)
|
23
|
+
end
|
24
|
+
[sid, session.nil? ? {} : session.data]
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_session(env, sid, session_data)
|
28
|
+
session =
|
29
|
+
if @@cache
|
30
|
+
@@cache[sid] || @@session_class.get(sid)
|
31
|
+
else
|
32
|
+
@@session_class.get(sid)
|
33
|
+
end || @@session_class.new(:session_id => sid)
|
34
|
+
session.data = session_data || {}
|
35
|
+
if session.new_record?
|
36
|
+
session.updated_at = Time.now
|
37
|
+
@@cache[sid] = session if @@cache
|
38
|
+
end
|
39
|
+
session.save
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module DatamapperStore
|
46
|
+
class Session
|
47
|
+
|
48
|
+
include ::DataMapper::Resource
|
49
|
+
|
50
|
+
def self.name
|
51
|
+
"session"
|
52
|
+
end
|
53
|
+
|
54
|
+
property :session_id, String, :key => true
|
55
|
+
|
56
|
+
property :data, Text, :nullable => false, :default => ::Base64.encode64(Marshal.dump({}))
|
57
|
+
|
58
|
+
property :updated_at, DateTime, :nullable => true, :index => true
|
59
|
+
|
60
|
+
def data=(data)
|
61
|
+
attribute_set(:data, ::Base64.encode64(Marshal.dump(data)))
|
62
|
+
end
|
63
|
+
def data
|
64
|
+
Marshal.load(::Base64.decode64(attribute_get(:data)))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Datamapper4rails
|
2
|
+
module RestfulTransactions
|
3
|
+
|
4
|
+
class Rollback < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
module Base
|
8
|
+
def self.included(base)
|
9
|
+
base.prepend_around_filter(TransactionFilter)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class TransactionFilter
|
14
|
+
def self.filter(controller)
|
15
|
+
case controller.request.method
|
16
|
+
when :post, :put, :delete then
|
17
|
+
begin
|
18
|
+
DataMapper::Transaction.new(DataMapper.repository(:default)) do |*block_args|
|
19
|
+
if block_given?
|
20
|
+
yield (*block_args)
|
21
|
+
# added rollback for all actions which just render
|
22
|
+
# a page with validation errors and do not redirect to new idem potent
|
23
|
+
# page (http-method get is idem potent within the
|
24
|
+
# restful paradigma
|
25
|
+
unless controller.response.redirected_to
|
26
|
+
raise Datamapper4rails::RestfulTransactions::Rollback
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
rescue Datamapper4rails::RestfulTransactions::Rollback
|
31
|
+
# ignore,
|
32
|
+
# this is just needed to trigger the rollback on the transaction
|
33
|
+
end
|
34
|
+
else
|
35
|
+
yield if block_given?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
::ActionController::Base.send(:include, Datamapper4rails::RestfulTransactions::Base)
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: datamapper4rail
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- mkristian
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-03-21 00:00:00 +05:30
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: slf4r
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: hoe
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.8.3
|
34
|
+
version:
|
35
|
+
description: collection of datamapper related extensions. mostly needed to run within rails. the restful transactions is around filter for rails. the restful adapter can be outside of rails. datamapper store is a session store for rails which uses datamapper as persistent layer. the generators produces datamapper models for your rails application. quite a few things are "stolen" from dm-more/rails_datamapper. a lot of things do not work there and patches are still in process to be applied so until dm-more/rails_datamapper catches up, ut I hope these two project merge someday again.
|
36
|
+
email:
|
37
|
+
- m.kristian@web.de
|
38
|
+
executables: []
|
39
|
+
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files:
|
43
|
+
- History.txt
|
44
|
+
- Manifest.txt
|
45
|
+
- README.txt
|
46
|
+
files:
|
47
|
+
- History.txt
|
48
|
+
- Manifest.txt
|
49
|
+
- README.txt
|
50
|
+
- Rakefile
|
51
|
+
- generators/dm_install/dm_install_generator.rb
|
52
|
+
- generators/dm_install/templates/datamapper.rake
|
53
|
+
- generators/dm_migration/dm_migration_generator.rb
|
54
|
+
- generators/dm_migration/templates/migration.rb
|
55
|
+
- generators/dm_model/dm_model_generator.rb
|
56
|
+
- generators/dm_model/templates/model.rb
|
57
|
+
- generators/dm_model/templates/unit_test.rb
|
58
|
+
- generators/rspec_default_values.rb
|
59
|
+
- generators/rspec_dm_model/rspec_dm_model_generator.rb
|
60
|
+
- generators/rspec_dm_model/templates/model.rb
|
61
|
+
- generators/rspec_dm_model/templates/model_spec.rb
|
62
|
+
- lib/datamapper4rails.rb
|
63
|
+
- lib/datamapper4rails/adapters/base_adapter.rb
|
64
|
+
- lib/datamapper4rails/adapters/restful_adapter.rb
|
65
|
+
- lib/datamapper4rails/database_config.rb
|
66
|
+
- lib/datamapper4rails/datamapper_store.rb
|
67
|
+
- lib/datamapper4rails/restful_transactions.rb
|
68
|
+
- lib/datamapper4rails/version.rb
|
69
|
+
has_rdoc: true
|
70
|
+
homepage: http://datamapper4rail.rubyforge.org
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options:
|
73
|
+
- --main
|
74
|
+
- README.txt
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: "0"
|
82
|
+
version:
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: "0"
|
88
|
+
version:
|
89
|
+
requirements: []
|
90
|
+
|
91
|
+
rubyforge_project: datamapper4rail
|
92
|
+
rubygems_version: 1.3.1
|
93
|
+
signing_key:
|
94
|
+
specification_version: 2
|
95
|
+
summary: collection of datamapper related extensions
|
96
|
+
test_files: []
|
97
|
+
|