dm-rails 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,12 @@
1
+ module Rails
2
+ module DataMapper
3
+
4
+ module I18nSupport
5
+ # Set the i18n scope to overwrite ActiveModel.
6
+ def i18n_scope #:nodoc:
7
+ :data_mapper
8
+ end
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,31 @@
1
+ module DataMapper
2
+ module Railties
3
+
4
+ class LogSubscriber < Rails::LogSubscriber
5
+
6
+ def sql(event)
7
+ name = '%s (%.1fms)' % [event.payload[:name], event.duration]
8
+ sql = event.payload[:sql].squeeze(' ')
9
+
10
+ if odd?
11
+ name = color(name, :cyan, true)
12
+ sql = color(sql, nil, true)
13
+ else
14
+ name = color(name, :magenta, true)
15
+ end
16
+
17
+ debug " #{name} #{sql}"
18
+ end
19
+
20
+ def odd?
21
+ @odd_or_even = !@odd_or_even
22
+ end
23
+
24
+ def logger
25
+ ::DataMapper.logger
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,61 @@
1
+ require 'dm-core'
2
+
3
+ # Implements DataMapper-specific session store.
4
+
5
+ module Rails
6
+ module DataMapper
7
+
8
+ class SessionStore < ActionDispatch::Session::AbstractStore
9
+
10
+ class Session
11
+
12
+ include ::DataMapper::Resource
13
+
14
+ property :id, Serial
15
+ property :session_id, String, :required => true, :unique => true, :unique_index => true
16
+ property :data, Object, :required => true, :default => ActiveSupport::Base64.encode64(Marshal.dump({}))
17
+ property :updated_at, DateTime, :required => false, :index => true
18
+
19
+ def self.name
20
+ 'session'
21
+ end
22
+
23
+ end
24
+
25
+ SESSION_RECORD_KEY = 'rack.session.record'.freeze
26
+
27
+ cattr_accessor :session_class
28
+ self.session_class = Session
29
+
30
+ private
31
+
32
+ def get_session(env, sid)
33
+ sid ||= generate_sid
34
+ session = find_session(sid)
35
+ env[SESSION_RECORD_KEY] = session
36
+ [ sid, session.data ]
37
+ end
38
+
39
+ def set_session(env, sid, session_data)
40
+ session = get_session_resource(env, sid)
41
+ session.data = session_data
42
+ session.updated_at = Time.now if session.dirty?
43
+ session.save ? sid : false
44
+ end
45
+
46
+ def get_session_resource(env, sid)
47
+ if env[ENV_SESSION_OPTIONS_KEY][:id].nil?
48
+ env[SESSION_RECORD_KEY] = find_session(sid)
49
+ else
50
+ env[SESSION_RECORD_KEY] ||= find_session(sid)
51
+ end
52
+ end
53
+
54
+ def find_session(sid)
55
+ self.class.session_class.first_or_new(:session_id => sid)
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,41 @@
1
+ require 'active_support/core_ext/hash/except'
2
+
3
+ require 'dm-rails/configuration'
4
+ require 'dm-rails/railties/benchmarking_mixin'
5
+
6
+ module Rails
7
+ module DataMapper
8
+
9
+ def self.setup(environment)
10
+ puts "[datamapper] Setting up the #{environment.inspect} environment:"
11
+ configuration.repositories[environment].each do |name, config|
12
+ setup_with_instrumentation(name.to_sym, config)
13
+ end
14
+ initialize_foreign_keys
15
+ end
16
+
17
+ def self.setup_logger(logger)
18
+ ::DataMapper.logger = logger
19
+ end
20
+
21
+ def self.setup_with_instrumentation(name, options)
22
+ puts "[datamapper] Setting up #{name.inspect} repository: '#{options['database']}' on #{options['adapter']}"
23
+ adapter = ::DataMapper.setup(name, options)
24
+ adapter.extend ::DataMapper::Adapters::Benchmarking
25
+ end
26
+
27
+ def self.initialize_foreign_keys
28
+ ::DataMapper::Model.descendants.each do |model|
29
+ model.relationships.each_value { |r| r.child_key }
30
+ end
31
+ end
32
+
33
+ def self.preload_models(app)
34
+ app.config.paths.app.models.each do |path|
35
+ Dir.glob("#{path}/**/*.rb").sort.each { |file| require_dependency file }
36
+ end
37
+ initialize_foreign_keys
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,165 @@
1
+ module Rails
2
+ module DataMapper
3
+
4
+ def self.storage
5
+ Storage
6
+ end
7
+
8
+ class Storage
9
+ attr_reader :name, :config
10
+
11
+ def self.create_all
12
+ with_local_repositories { |config| create_environment(config) }
13
+ end
14
+
15
+ def self.drop_all
16
+ with_local_repositories { |config| drop_environment(config) }
17
+ end
18
+
19
+ def self.create_environment(config)
20
+ config.each { |repo_name, repo_config| new(repo_name, repo_config).create }
21
+ end
22
+
23
+ def self.drop_environment(config)
24
+ config.each { |repo_name, repo_config| new(repo_name, repo_config).drop }
25
+ end
26
+
27
+ def self.new(name, config)
28
+ klass = lookup_class(config['adapter'])
29
+ if klass.equal?(self)
30
+ super(name, config)
31
+ else
32
+ klass.new(name, config)
33
+ end
34
+ end
35
+
36
+ class << self
37
+ private
38
+
39
+ def with_local_repositories
40
+ Rails::DataMapper.configuration.repositories.each_value do |config|
41
+ if config['host'].blank? || %w[ 127.0.0.1 localhost ].include?(config['host'])
42
+ yield(config)
43
+ else
44
+ puts "This task only modifies local databases. #{config['database']} is on a remote host."
45
+ end
46
+ end
47
+ end
48
+
49
+ def lookup_class(adapter)
50
+ klass_name = adapter.camelize.to_sym
51
+
52
+ unless Storage.const_defined?(klass_name)
53
+ raise "Adapter #{adapter} not supported (#{klass_name.inspect})"
54
+ end
55
+
56
+ const_get(klass_name)
57
+ end
58
+
59
+ end
60
+
61
+ def initialize(name, config)
62
+ @name, @config = name.to_sym, config
63
+ end
64
+
65
+ def create
66
+ _create
67
+ puts "[datamapper] Created database '#{database}'"
68
+ end
69
+
70
+ def drop
71
+ _drop
72
+ puts "[datamapper] Dropped database '#{database}'"
73
+ end
74
+
75
+ def database
76
+ @database ||= config['database'] || config['path']
77
+ end
78
+
79
+ def username
80
+ @username ||= config['username'] || ''
81
+ end
82
+
83
+ def password
84
+ @password ||= config['password'] || ''
85
+ end
86
+
87
+ def charset
88
+ @charset ||= config['charset'] || ENV['CHARSET'] || 'utf8'
89
+ end
90
+
91
+ class Sqlite3 < Storage
92
+ def _create
93
+ return if in_memory?
94
+ ::DataMapper.setup(name, config.merge('database' => path))
95
+ end
96
+
97
+ def _drop
98
+ return if in_memory?
99
+ path.unlink if path.file?
100
+ end
101
+
102
+ private
103
+
104
+ def in_memory?
105
+ database == ':memory:'
106
+ end
107
+
108
+ def path
109
+ @path ||= Pathname(File.expand_path(database, Rails.root))
110
+ end
111
+
112
+ end
113
+
114
+ class Mysql < Storage
115
+ def _create
116
+ execute("CREATE DATABASE `#{database}` DEFAULT CHARACTER SET #{charset} DEFAULT COLLATE #{collation}")
117
+ end
118
+
119
+ def _drop
120
+ execute("DROP DATABASE IF EXISTS `#{database}`")
121
+ end
122
+
123
+ private
124
+
125
+ def execute(statement)
126
+ system(
127
+ 'mysql',
128
+ (username.blank? ? '' : "--user=#{username}"),
129
+ (password.blank? ? '' : "--password=#{password}"),
130
+ '-e',
131
+ statement
132
+ )
133
+ end
134
+
135
+ def collation
136
+ @collation ||= config['collation'] || ENV['COLLATION'] || 'utf8_unicode_ci'
137
+ end
138
+
139
+ end
140
+
141
+ class Postgres < Storage
142
+ def _create
143
+ system(
144
+ 'createdb',
145
+ '-E',
146
+ charset,
147
+ '-U',
148
+ username,
149
+ database
150
+ )
151
+ end
152
+
153
+ def _drop
154
+ system(
155
+ 'dropdb',
156
+ '-U',
157
+ username,
158
+ database
159
+ )
160
+ end
161
+
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,82 @@
1
+ require 'rails/generators/named_base'
2
+ require 'rails/generators/migration'
3
+ require 'rails/generators/active_model'
4
+
5
+ module DataMapper
6
+ module Generators
7
+
8
+ class Base < ::Rails::Generators::NamedBase #:nodoc:
9
+
10
+ include ::Rails::Generators::Migration
11
+
12
+ def self.source_root
13
+ @_datamapper_source_root ||=
14
+ File.expand_path("../#{base_name}/#{generator_name}/templates", __FILE__)
15
+ end
16
+
17
+ protected
18
+
19
+ # Datamapper does not care if migrations have the same name as long as
20
+ # they have different ids.
21
+ #
22
+ def migration_exists?(dirname, file_name) #:nodoc:
23
+ false
24
+ end
25
+
26
+ # Implement the required interface for Rails::Generators::Migration.
27
+ #
28
+ def self.next_migration_number(dirname) #:nodoc:
29
+ "%.3d" % (current_migration_number(dirname) + 1)
30
+ end
31
+
32
+ end
33
+
34
+ class ActiveModel < ::Rails::Generators::ActiveModel #:nodoc:
35
+ def self.all(klass)
36
+ "#{klass}.all"
37
+ end
38
+
39
+ def self.find(klass, params=nil)
40
+ "#{klass}.get(#{params})"
41
+ end
42
+
43
+ def self.build(klass, params=nil)
44
+ if params
45
+ "#{klass}.new(#{params})"
46
+ else
47
+ "#{klass}.new"
48
+ end
49
+ end
50
+
51
+ def save
52
+ "#{name}.save"
53
+ end
54
+
55
+ def update_attributes(params=nil)
56
+ "#{name}.update(#{params})"
57
+ end
58
+
59
+ def errors
60
+ "#{name}.errors"
61
+ end
62
+
63
+ def destroy
64
+ "#{name}.destroy"
65
+ end
66
+ end
67
+
68
+ end
69
+ end
70
+
71
+ module Rails
72
+
73
+ module Generators
74
+ class GeneratedAttribute #:nodoc:
75
+ def type_class
76
+ return 'DateTime' if type.to_s == 'datetime'
77
+ return type.to_s.camelcase
78
+ end
79
+ end
80
+ end
81
+
82
+ end
@@ -0,0 +1,30 @@
1
+ require 'generators/data_mapper'
2
+
3
+ module DataMapper
4
+ module Generators
5
+
6
+ class MigrationGenerator < Base
7
+
8
+ argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
9
+ class_option :id, :type => :numeric, :desc => "The id to be used in this migration"
10
+
11
+ def create_migration_file
12
+ set_local_assigns!
13
+ migration_template "migration.rb", "db/migrate/#{file_name}.rb"
14
+ end
15
+
16
+ protected
17
+
18
+ attr_reader :migration_action
19
+
20
+ def set_local_assigns!
21
+ if file_name =~ /^(add|remove|drop)_.*_(?:to|from)_(.*)/
22
+ @migration_action = $1 == 'add' ? 'add' : 'drop'
23
+ @table_name = $2.pluralize
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ migration <%= migration_number.to_i %>, :<%= migration_file_name %> do
2
+
3
+ up do
4
+ <% unless attributes.empty? -%>
5
+ modify_table :<%= table_name %> do
6
+ <% attributes.each do |attribute| -%>
7
+ <%= migration_action %>_column :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type_class %><% end -%>
8
+ <% end -%>
9
+ end
10
+ <% end -%>
11
+ end
12
+
13
+ down do
14
+ <% unless attributes.empty? -%>
15
+ modify_table :<%= table_name %> do
16
+ <% attributes.reverse.each do |attribute| -%>
17
+ <%= migration_action == 'add' ? 'drop' : 'add' %>_column :<%= attribute.name %><% if migration_action == 'drop' %>, :<%= attribute.type_class %><% end -%>
18
+ <% end -%>
19
+ end
20
+ <% end -%>
21
+ end
22
+
23
+ end