sinatra-dm 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,6 +1,169 @@
1
- = sinatra-dm
1
+ = Sinatra::DM
2
+
3
+ A Sinatra Extension that makes working with DataMapper easier.
4
+
5
+
6
+ == Installation
7
+
8
+ # Add Gemcutter to your RubyGems sources
9
+ $ gem sources -a http://gemcutter.com
10
+
11
+ $ (sudo)? gem install sinatra-dm
12
+
13
+ == Dependencies
14
+
15
+ This Gem depends upon the following:
16
+
17
+ === Runtime:
18
+
19
+ * sinatra ( >= 0.10.1 )
20
+ * dm-core ( >= 0.10.1 )
21
+
22
+ And a constant named ::APP_ROOT defined in your App, pointing to the root of your app.
23
+
24
+ # set the root of the whole app
25
+ APP_ROOT = Dir.pwd
26
+
27
+ ==== Question:
28
+
29
+ Do you know how I can avoid this APP_ROOT constant inside the Extension, but still use full paths ?
30
+ If so, please let me know.
31
+
32
+
33
+ === Development & Tests:
34
+
35
+ * rspec (>= 1.2.7 )
36
+ * rack-test (>= 0.4.1)
37
+ * rspec_hpricot_matchers (>= 0.1.0)
38
+ * sinatra-tests (>= 0.1.5)
39
+
40
+ === Optional:
41
+
42
+ * kematzy-tasks (>= 0.1.5) # handy Rake tasks for working with SQLite3 DB's
43
+
44
+
45
+
46
+
47
+ == Getting Started
48
+
49
+
50
+ In your Sinatra app code base,
51
+
52
+ require 'sinatra/dm'
53
+
54
+
55
+ then in your App declaration,
56
+
57
+
58
+ class YourApp < Sinatra::Base
59
+ register(Sinatra::DataMapperExtension) # NOTE:: the extension name
60
+
61
+ # NOTE:: need to ensure this is set this for the logger to function
62
+ set :environment, ENV['RACK_ENV'].to_sym || :test
63
+
64
+ # NOTE:: The database configuration must be set so
65
+ # the DataMapper.auto_migrate! / .auto_upgrade! migrations work
66
+ set :database, dm_database_url
67
+
68
+ ## ROUTES
69
+ get '/posts' do
70
+ @posts = Post.all
71
+ end
72
+
73
+ end
74
+
75
+ Most of the above is obvious, but this line...
76
+
77
+ set :database, dm_database_url
78
+
79
+ ...is perhaps a bit confusing, so let's clarify it.
80
+
81
+ <tt>#dm_database_url</tt> is an Extension setting - (see below) - that contains the whole
82
+ SQLite3 DSN string.
83
+
84
+ "sqlite3:///path/2/your/app/root/db/db.test.db"
85
+
86
+
87
+ In real terms, you could just as well have written this:
88
+
89
+ set :database, "sqlite3:///path/2/your/app/root/db/db.test.db"
90
+
91
+ or
92
+
93
+ set :database, "mysql://username:password@dbhost/db_name"
94
+
95
+ # if you have MySQL set up **insecurely** on your local workstation
96
+ set :database, "mysql://root:@dbhost/db_name"
97
+
98
+
99
+
100
+ == Configuration Options
101
+
102
+ The following options are available for you to configure your DataMapper setup
103
+
104
+ * <tt>:db_dir</tt> -- sets the path to where your SQLite3 DBs should be.
105
+ (Default: [/full/path/2/your/app/db] )
106
+
107
+ * <tt>:dm_logger_level</tt> -- sets the level at which DataMapper.Logger should log.
108
+ (Default: [:debug] )
109
+
110
+ * <tt>:dm_logger_path</tt> -- sets the path to the log file where DataMapper.Logger should log.
111
+ (Default: [/full/path/2/your/app/log/dm.{environment}.log] )
112
+
113
+ * <tt>:dm_setup_context</tt> -- sets the DataMapper Setup context.
114
+ (Default: [:default] )
115
+
116
+ * <tt>:dm_database_url</tt> -- sets the DSN.
117
+ (Default: ENV['DATABASE_URL'] || "sqlite3://#{db_dir}/db.#{environment}.db" )
118
+
119
+
120
+ There are many ways in which you can use the above configurations in YourApp.
121
+
122
+ Here are a few examples:
123
+
124
+ class YourApp < Sinatra::Base
125
+ register(Sinatra::DataMapperExtension) # NOTE:: the extension name
126
+
127
+ <snip...>
128
+
129
+ # set the db path to outside of your app root
130
+ set :db_dir, "/home/USERNAME/SQLite3-dbs/"
131
+
132
+ # to only log :warn and above
133
+ set :dm_logger_level, :warn
134
+
135
+ # set the path to your log files outside of your app root
136
+ set :dm_logger_path, "/var/log/dm.your_app.log"
137
+
138
+ # use a different Setup context than :default
139
+ set :dm_setup_context, :custom
140
+
141
+ <snip...>
142
+
143
+ # NB! Don't forget to set the database configuration
144
+ set :database, dm_database_url
145
+
146
+ end
147
+
148
+
149
+ == RTFM
150
+
151
+ If the above is NOT clear enough, please check the Specs for a better understanding.
152
+
153
+
154
+ == TODOs
155
+
156
+ There are a number of things I'd love to have help with through a fork:
157
+
158
+ * Enabling DataMapper Migrations to work flawlessly.
159
+
160
+ * Decide if there should be a :dm_logger_status (On/Off) switch for turning off DM logger
161
+
162
+ * Test it with a PostgreSQL db (although I'm sure it would work fine there as is)
163
+
164
+ * Any other improvements you can think of.
165
+
2
166
 
3
- Description goes here.
4
167
 
5
168
  == Note on Patches/Pull Requests
6
169
 
@@ -15,4 +178,7 @@ Description goes here.
15
178
 
16
179
  == Copyright
17
180
 
18
- Copyright (c) 2009 kematzy. See LICENSE for details.
181
+ Copyright (c) 2009 kematzy. Released under the MIT License.
182
+
183
+ See LICENSE for details.
184
+
data/Rakefile CHANGED
@@ -12,6 +12,7 @@ begin
12
12
  gem.authors = ["kematzy"]
13
13
  gem.add_dependency('sinatra', '>= 0.10.1')
14
14
  gem.add_dependency('dm-core', '>= 0.10.1')
15
+ gem.add_dependency('kematzy-tasks', '>= 0.1.0')
15
16
  # gem.add_dependency('dependency', '>=x.x.x')
16
17
  gem.add_development_dependency("sinatra-tests", '>= 0.1.5')
17
18
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
@@ -36,6 +37,23 @@ end
36
37
 
37
38
  task :spec => :check_dependencies
38
39
 
40
+ namespace :spec do
41
+
42
+ desc "Run all specifications quietly"
43
+ Spec::Rake::SpecTask.new(:quiet) do |t|
44
+ t.libs << "lib"
45
+ t.spec_opts = ["--color", "--require", "spec/spec_helper.rb"]
46
+ end
47
+
48
+ desc "Run specific spec (SPEC=/path/2/file)"
49
+ Spec::Rake::SpecTask.new(:select) do |t|
50
+ t.libs << "lib"
51
+ t.spec_files = [ENV["SPEC"]]
52
+ t.spec_opts = ["--color", "--format", "specdoc", "--require", "spec/spec_helper.rb"]
53
+ end
54
+
55
+ end
56
+
39
57
  task :default => :spec
40
58
 
41
59
  require 'rake/rdoctask'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.1.3
data/lib/sinatra/dm.rb CHANGED
@@ -1,89 +1,273 @@
1
1
 
2
2
  require 'sinatra/base'
3
3
  require 'dm-core'
4
- # # require 'dm-migrations'
5
- # require 'dm-timestamps'
6
- # require 'dm-validations'
7
- # require 'dm-serializer'
8
- # require 'dm-types'
9
4
 
10
5
  module Sinatra
11
6
 
12
- # Sinatra DataMapperExtension module
7
+ # = Sinatra DataMapperExtension module
8
+ #
9
+ # A Sinatra Extension that makes working with DataMapper easier.
10
+ #
11
+ #
12
+ # == Installation
13
+ #
14
+ # # Add Gemcutter to your RubyGems sources
15
+ # $ gem sources -a http://gemcutter.com
16
+ #
17
+ # $ (sudo)? gem install sinatra-dm
18
+ #
19
+ # == Dependencies
20
+ #
21
+ # This Gem depends upon the following:
22
+ #
23
+ # === Runtime:
24
+ #
25
+ # * sinatra ( >= 0.10.1 )
26
+ # * dm-core ( >= 0.10.1 )
27
+ #
28
+ # And a constant named ::APP_ROOT defined in your App, pointing to the root of your app.
29
+ #
30
+ # # set the root of the whole app
31
+ # APP_ROOT = Dir.pwd
32
+ #
33
+ # === Development & Tests:
34
+ #
35
+ # * rspec (>= 1.2.7 )
36
+ # * rack-test (>= 0.4.1)
37
+ # * rspec_hpricot_matchers (>= 0.1.0)
38
+ # * sinatra-tests (>= 0.1.5)
39
+ #
40
+ # === Optional:
41
+ #
42
+ # * kematzy-tasks (>= 0.1.5) # handy Rake tasks for working with SQLite3 DB's
43
+ #
44
+ #
45
+ # == Getting Started
46
+ #
47
+ # In your Sinatra app code base,
48
+ #
49
+ # require 'sinatra/dm'
50
+ #
51
+ # then in your App declaration,
52
+ #
53
+ #
54
+ # class YourApp < Sinatra::Base
55
+ # register(Sinatra::DataMapperExtension) # NOTE:: the extension name
56
+ #
57
+ # # NOTE:: need to ensure this is set this for the logger to function
58
+ # set :environment, ENV['RACK_ENV'].to_sym || :test
59
+ #
60
+ # # NOTE:: The database configuration must be set so
61
+ # # the DataMapper.auto_migrate! / .auto_upgrade! migrations work
62
+ # set :database, dm_database_url
63
+ #
64
+ # ## ROUTES
65
+ # get '/posts' do
66
+ # @posts = Post.all
67
+ # end
68
+ #
69
+ # end
70
+ #
71
+ # Most of the above is obvious, but this line...
72
+ #
73
+ # set :database, dm_database_url
74
+ #
75
+ # ...is perhaps a bit confusing, so let's clarify it.
76
+ #
77
+ # <tt>#dm_database_url</tt> is an Extension setting - (see below) - that contains the whole
78
+ # SQLite3 DSN string.
79
+ #
80
+ # "sqlite3:///path/2/your/app/root/db/db.test.db"
81
+ #
82
+ #
83
+ # In real terms, you could just as well have written this:
84
+ #
85
+ # set :database, "sqlite3:///path/2/your/app/root/db/db.test.db"
86
+ #
87
+ # or
88
+ #
89
+ # set :database, "mysql://username:password@dbhost/db_name"
90
+ #
91
+ # # if you have MySQL set up **insecurely** on your local workstation
92
+ # set :database, "mysql://root:@dbhost/db_name"
93
+ #
94
+ #
95
+ #
96
+ # == Configuration Options
97
+ #
98
+ # The following options are available for you to configure your DataMapper setup
99
+ #
100
+ # * <tt>:db_dir</tt> -- sets the path to where your SQLite3 DBs should be.
101
+ # (Default: [/full/path/2/your/app/db] )
102
+ #
103
+ # * <tt>:dm_logger_level</tt> -- sets the level at which DataMapper.Logger should log.
104
+ # (Default: [:debug] )
105
+ #
106
+ # * <tt>:dm_logger_path</tt> -- sets the path to the log file where DataMapper.Logger should log.
107
+ # (Default: [/full/path/2/your/app/log/dm.{environment}.log] )
108
+ #
109
+ # * <tt>:dm_setup_context</tt> -- sets the DataMapper Setup context.
110
+ # (Default: [:default] )
111
+ #
112
+ # * <tt>:dm_database_url</tt> -- sets the DSN.
113
+ # (Default: ENV['DATABASE_URL'] || "sqlite3://#{db_dir}/db.#{environment}.db" )
114
+ #
115
+ #
116
+ # There are many ways in which you can use the above configurations in YourApp.
117
+ #
118
+ # Here are a few examples:
119
+ #
120
+ # class YourApp < Sinatra::Base
121
+ # register(Sinatra::DataMapperExtension) # NOTE:: the extension name
122
+ #
123
+ # <snip...>
124
+ #
125
+ # # set the db path to outside of your app root
126
+ # set :db_dir, "/home/USERNAME/SQLite3-dbs/"
127
+ #
128
+ # # to only log :warn and above
129
+ # set :dm_logger_level, :warn
130
+ #
131
+ # # set the path to your log files outside of your app root
132
+ # set :dm_logger_path, "/var/log/dm.your_app.log"
133
+ #
134
+ # # use a different Setup context than :default
135
+ # set :dm_setup_context, :custom
136
+ #
137
+ # <snip...>
138
+ #
139
+ # # NB! Don't forget to set the database configuration
140
+ # set :database, dm_database_url
141
+ #
142
+ # end
143
+ #
13
144
  #
14
- # TODO:: Need to write documentation here
15
145
  #
16
146
  module DataMapperExtension
17
147
 
18
- VERSION = '0.1.2' unless const_defined?(:VERSION)
148
+ VERSION = '0.1.3' unless const_defined?(:VERSION)
19
149
  def self.version; "Sinatra::DataMapperExtension v#{VERSION}"; end
20
150
 
21
151
  module Helpers
22
152
 
23
153
  ##
24
- # TODO: add some comments here
154
+ # Access to the database settings, should you need them
155
+ # within your app
25
156
  #
26
157
  # ==== Examples
27
158
  #
159
+ # if database.name == :default
160
+ # # do something...
161
+ #
162
+ #
28
163
  #
29
164
  # @api public
30
- def database
31
- options.database
165
+ def database
166
+ settings.database
167
+ end
168
+
169
+ ##
170
+ # Handy alias to the DataMapper logger
171
+ #
172
+ # ==== Examples
173
+ #
174
+ # db_logger.info("message")
175
+ #
176
+ #
177
+ # @api public/private
178
+ def db_logger
179
+ self.class.database_logger
32
180
  end
33
181
 
34
182
  end #/ Helpers
35
183
 
36
184
 
37
185
  ##
38
- # TODO: add some comments here
186
+ # Sets the Database DSN connection, and setup name.
39
187
  #
40
188
  # ==== Examples
189
+ #
190
+ # # Default usage is via the set :database setting
191
+ #
192
+ # set :database, "sqlite3:///path/2/your/app/db/test.db"
193
+ #
194
+ #
195
+ # But you can also set the db connection on your App directly via this as a class method
196
+ #
197
+ # YourApp.database = "sqlite3:///path/2/your/app/db/test.db", :custom_setup_name
41
198
  #
42
199
  #
43
200
  # @api public
44
- def database=(url, context = :default)
45
- # NOTE:: see note below in :database method
46
- # @database = nil
201
+ def database=(*args)
202
+ if args.first.is_a?(Array)
203
+ reset_db = true
204
+ url = args.first[0]
205
+ context = args.first[1] || dm_setup_context || :default
206
+ else
207
+ url = args.first
208
+ context = dm_setup_context || :default
209
+ end
47
210
  set :dm_setup_context, context
48
- set :database_url, url
49
- db_type = database_url.split('://').first
50
- db_url = database_url.sub(::APP_ROOT, '').sub("#{db_type}://",'')
211
+ set :dm_database_url, url
212
+ db_type = dm_database_url.split('://').first
213
+ db_url = dm_database_url.sub(::APP_ROOT, '').sub("#{db_type}://",'')
51
214
  puts "-- - activated DataMapper #{db_type.capitalize} Database at [ #{db_url} ]"
215
+ database_reset if reset_db
52
216
  database_logger
53
217
  database
54
218
  end
55
219
 
56
220
  ##
57
- # TODO: add some comments here
221
+ # Provides access to your database setup
58
222
  #
59
223
  # ==== Examples
60
224
  #
225
+ # YourApp.database => returns the whole DataMapper db setup
226
+ #
61
227
  #
62
228
  # @api public
63
- def database
229
+ def database
64
230
  # NOTE:: Having an instance variable here, causes problems
65
231
  # when having two Sinatra Apps, each with their own db setup.
66
232
  # the instance variable retains only the last setup, so the
67
233
  # first setup is overwritten.
68
- database ||= ::DataMapper.setup(dm_setup_context, database_url)
234
+ @database ||= ::DataMapper.setup(dm_setup_context, dm_database_url)
69
235
  end
70
236
 
237
+ ##
238
+ # Resets the current DB setup and connection
239
+ #
240
+ # ==== Examples
241
+ #
242
+ #
243
+ # @api private
244
+ def database_reset
245
+ @database = nil
246
+ end
71
247
 
72
248
  ##
73
- # TODO: add some comments here
249
+ # Sets up the DataMapper::Logger instance, caches it and returns it
74
250
  #
75
251
  # ==== Examples
252
+ #
253
+ # YourApp.database_logger.debug("Message") => log's message in the log
76
254
  #
77
255
  #
78
256
  # @api public
79
- def database_logger
257
+ def database_logger
258
+ # NOTE:: Having an instance variable here, causes problems
259
+ # when having two Sinatra Apps, each with their own db setup.
260
+ # the instance variable retains only the last setup, so the
261
+ # first setup is overwritten.
80
262
  @database_logger ||= ::DataMapper::Logger.new(dm_logger_path, dm_logger_level)
81
263
  end
82
264
 
265
+ # :nodoc:
266
+
83
267
  ## TODO: Should support real migrations,
84
268
 
85
269
  ##
86
- # TODO: add some comments here
270
+ # TODO: implement this functionality
87
271
  #
88
272
  # ==== Examples
89
273
  #
@@ -99,7 +283,7 @@ module Sinatra
99
283
  # end
100
284
 
101
285
  ##
102
- # TODO: add some comments here
286
+ # TODO: implement this functionality
103
287
  #
104
288
  # ==== Examples
105
289
  #
@@ -119,31 +303,16 @@ module Sinatra
119
303
  # define_method("#{adapter}?") { @database.options['adapter'] == adapter }
120
304
  # end
121
305
 
122
- protected
123
-
124
-
125
- # ##
126
- # # TODO: add some comments here
127
- # #
128
- # # ==== Examples
129
- # #
130
- # #
131
- # # @api public
132
- # def create_migrations_table
133
- # database.create_table? :migrations do
134
- # primary_key :id
135
- # text :name, :null => false, :index => true
136
- # timestamp :ran_at
137
- # end
138
- # end
306
+ # :doc:
139
307
 
308
+ protected
140
309
 
141
310
  def self.registered(app)
142
311
  app.set :db_dir, "#{::APP_ROOT}/db"
143
312
  app.set :dm_logger_level, :debug
144
313
  app.set :dm_logger_path, lambda { "#{::APP_ROOT}/log/dm.#{environment}.log" }
145
314
  app.set :dm_setup_context, :default
146
- app.set :database_url, lambda { ENV['DATABASE_URL'] || "sqlite3://#{::APP_ROOT}/db/#{environment}.db" }
315
+ app.set :dm_database_url, lambda { ENV['DATABASE_URL'] || "sqlite3://#{db_dir}/db.#{environment}.db" }
147
316
 
148
317
  # app.set :migrations_table_name, :migrations
149
318
  # app.set :migrations_log, lambda { STDOUT }
@@ -152,42 +321,16 @@ module Sinatra
152
321
 
153
322
  ## add the extension specific options to those inspectable by :options_inspect method
154
323
  if app.respond_to?(:sinatra_options_for_inspection)
155
- %w( db_dir dm_logger_path dm_logger_level database_url
324
+ %w( db_dir dm_logger_path dm_logger_level dm_database_url
156
325
  dm_setup_context database ).each do |m|
157
326
  app.sinatra_options_for_inspection << m
158
327
  end
159
328
  end
160
329
 
161
- # QUESTION:: Should this actually be here?
162
- # or should I just use the rake tasks
163
- #
164
- if app.development?
165
- app.get '/install/db/bootstrap' do
166
- out = ""
167
- Dir["#{::APP_ROOT}/db/bootstraps/*.sql"].each do |b|
168
- db = self.class.database_url.sub('sqlite3://','')
169
- `sqlite3 #{db} < #{b}`
170
- out << "\t\t<li> -- #{b.sub(::APP_ROOT,'..')} loaded</li>\n"
171
- end
172
-
173
- html = %Q[<div id="main-content">\n]
174
- html << %Q[\t<h2>Install :: Database Bootstrapping</h2>\n]
175
- html << %Q[\t<p>Loading bootstraps from [ #{::APP_ROOT}/db/bootstraps/ ]</p>\n]
176
- html << %Q[\t<ul>\n]
177
- html << out
178
- html << %Q[\t</ul>\n]
179
- html << %Q[\t<p>Bootstrapping finished.</p>\n]
180
- html << %Q[\t<p><a href="javascript:history.go(-1);">Go Back</a></p>\n]
181
- html << %Q[</div>\n]
182
-
183
- erb(html)
184
- end
185
- end
186
-
187
330
  end #/ self.registered
188
331
 
189
332
  end #/ DataMapperExtension
190
333
 
191
- register(Sinatra::DataMapperExtension)
334
+ # register(Sinatra::DataMapperExtension)
192
335
 
193
336
  end #/ Sinatra