sinatra-dm 0.1.2 → 0.1.3

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/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