sniff 0.0.4 → 0.0.5

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.
Files changed (3) hide show
  1. data/lib/sniff/database.rb +43 -18
  2. metadata +7 -8
  3. data/lib/sniff/timeframe.rb +0 -251
@@ -7,45 +7,60 @@ module Sniff
7
7
  class Database
8
8
  class << self
9
9
  def init(local_root, options = {})
10
+ db_init options
11
+ earth_init(options[:earth])
12
+
10
13
  environments = []
11
- environments << really_init(local_root, options)
14
+ environments << init_environment(local_root, options)
12
15
 
13
16
  unless local_root == Sniff.root
14
- environments << really_init(Sniff.root)
17
+ environments << init_environment(Sniff.root)
15
18
  end
19
+
20
+ load_all_schemas
16
21
 
17
- db_init options
18
22
  environments.each { |e| e.populate_fixtures }
19
23
  end
20
24
 
21
- def really_init(root, options = {})
25
+ def define_schema(&blk)
26
+ schemas << blk
27
+ end
28
+
29
+ def schemas
30
+ @schemas = [] unless defined?(@schemas)
31
+ @schemas
32
+ end
33
+
34
+ private
35
+ def init_environment(root, options = {})
22
36
  db = new root, options
23
37
  db.init
24
38
  db
25
39
  end
26
40
 
27
41
  def db_init(options)
28
- ActiveRecord::Base.logger = Logger.new nil
29
- connect
30
- db_create
31
- earth_init(options[:earth])
42
+ ActiveRecord::Base.logger = Logger.new options[:sqllogdev]
43
+ ActiveRecord::Base.establish_connection :adapter => 'sqlite3',
44
+ :database => ':memory:'
32
45
  end
33
46
 
34
47
  def earth_init(domain)
48
+ domain ||= :none
35
49
  Earth.init domain, :apply_schemas => true
36
50
  end
37
51
 
38
- def connect
39
- ActiveRecord::Base.establish_connection :adapter => 'sqlite3',
40
- :database => ':memory:'
41
- end
42
-
43
- def db_drop(db_file_path)
44
- FileUtils.rm db_file_path if File.exists?(db_file_path)
45
- end
52
+ def load_all_schemas
53
+ orig_std_out = STDOUT.clone
54
+ STDOUT.reopen File.open(File.join('/tmp', 'schema_output'), 'w')
46
55
 
47
- def db_create
48
- ActiveRecord::Base.connection
56
+ ActiveRecord::Schema.define(:version => 1) do
57
+ ar_schema = self
58
+ Sniff::Database.schemas.each do |s|
59
+ ar_schema.instance_eval &s
60
+ end
61
+ end
62
+ ensure
63
+ STDOUT.reopen(orig_std_out)
49
64
  end
50
65
  end
51
66
 
@@ -69,6 +84,10 @@ module Sniff
69
84
  @load_data
70
85
  end
71
86
 
87
+ def schema_path
88
+ @schema_path ||= File.join(lib_path, 'db', 'schema.rb')
89
+ end
90
+
72
91
  def fixtures_path
73
92
  @fixtures_path ||= File.join(lib_path, 'db', 'fixtures')
74
93
  end
@@ -79,9 +98,15 @@ module Sniff
79
98
 
80
99
  def init
81
100
  load_supporting_libs
101
+ read_schema
82
102
  read_fixtures if load_data?
83
103
  end
84
104
 
105
+ def read_schema
106
+ log "Reading schema #{schema_path}"
107
+ load(schema_path) if File.exist?(schema_path)
108
+ end
109
+
85
110
  def read_fixtures
86
111
  require 'active_record/fixtures'
87
112
  log "Reading fixtures from #{fixtures_path}/**/*.{yml,csv}"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sniff
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 4
10
- version: 0.0.4
9
+ - 5
10
+ version: 0.0.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Derek Kastner
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-07-19 00:00:00 -04:00
18
+ date: 2010-07-20 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -189,12 +189,12 @@ dependencies:
189
189
  requirements:
190
190
  - - "="
191
191
  - !ruby/object:Gem::Version
192
- hash: 19
192
+ hash: 17
193
193
  segments:
194
194
  - 0
195
195
  - 0
196
- - 6
197
- version: 0.0.6
196
+ - 7
197
+ version: 0.0.7
198
198
  requirement: *id011
199
199
  - !ruby/object:Gem::Dependency
200
200
  type: :development
@@ -375,7 +375,6 @@ files:
375
375
  - lib/sniff/database.rb
376
376
  - lib/sniff/emitter.rb
377
377
  - lib/sniff/tasks.rb
378
- - lib/sniff/timeframe.rb
379
378
  - lib/test_support/db/fixtures/census_divisions.csv
380
379
  - lib/test_support/db/fixtures/census_regions.csv
381
380
  - lib/test_support/db/fixtures/climate_divisions.csv
@@ -1,251 +0,0 @@
1
- # Encapsulates a timeframe between two dates. The dates provided to the class are always until the last date. That means
2
- # that the last date is excluded.
3
- #
4
- # # from 2007-10-01 00:00:00.000 to 2007-10-31 23:59:59.999
5
- # Timeframe.new(Date(2007,10,1), Date(2007,11,1))
6
- # # and holds 31 days
7
- # Timeframe.new(Date(2007,10,1), Date(2007,11,1)).days #=> 31
8
-
9
- module Sniff
10
- class Timeframe
11
- attr_accessor :from, :to
12
-
13
- # Creates a new instance of Timeframe. You can either pass a start and end Date or a Hash with named arguments,
14
- # with the following options:
15
- #
16
- # <tt>:month</tt>: Start date becomes the first day of this month, and the end date becomes the first day of
17
- # the next month. If no <tt>:year</tt> is specified, the current year is used.
18
- # <tt>:year</tt>: Start date becomes the first day of this year, and the end date becomes the first day of the
19
- # next year.
20
- #
21
- # Examples:
22
- #
23
- # Timeframe.new Date.new(2007, 2, 1), Date.new(2007, 4, 1) # February and March
24
- # Timeframe.new :year => 2004 # The year 2004
25
- # Timeframe.new :month => 4 # April
26
- # Timeframe.new :year => 2004, :month => 2 # Feburary 2004
27
- def initialize(*args)
28
- options = args.extract_options!
29
-
30
- if month = options[:month]
31
- month = Date.parse(month).month if month.is_a? String
32
- year = options[:year] || Time.zone.today.year
33
- from = Date.new(year, month, 1)
34
- to = from.next_month
35
- elsif year = options[:year]
36
- from = Date.new(year, 1, 1)
37
- to = Date.new(year+1, 1, 1)
38
- end
39
-
40
- from ||= args.shift.andand.to_date
41
- to ||= args.shift.andand.to_date
42
-
43
- raise ArgumentError, "Please supply a start and end date, `#{args.map(&:inspect).to_sentence}' is not enough" if from.nil? or to.nil?
44
- raise ArgumentError, "Start date #{from} should be earlier than end date #{to}" if from > to
45
- raise ArgumentError, 'Timeframes that cross year boundaries are dangerous' unless options[:skip_year_boundary_crossing_check] or from.year == to.yesterday.year or from == to
46
-
47
- @from, @to = from, to
48
- end
49
-
50
- def inspect
51
- "<Timeframe(#{object_id}) #{days} days starting #{from} ending #{to}>"
52
- end
53
-
54
- # The number of days in the timeframe
55
- #
56
- # Timeframe.new(Date.new(2007, 11, 1), Date.new(2007, 12, 1)).days #=> 30
57
- # Timeframe.new(:month => 1).days #=> 31
58
- # Timeframe.new(:year => 2004).days #=> 366
59
- def days
60
- (to - from).to_i
61
- end
62
-
63
- # Returns a string representation of the timeframe
64
- def to_s
65
- if [from.day, from.month, to.day, to.month].uniq == [1]
66
- from.year.to_s
67
- elsif from.day == 1 and to.day == 1 and to.month - from.month == 1
68
- "#{Date::MONTHNAMES[from.month]} #{from.year}"
69
- else
70
- "the period from #{from.strftime('%d %B')} to #{to.yesterday.strftime('%d %B %Y')}"
71
- end
72
- end
73
-
74
- # Returns true when the date is included in this Timeframe
75
- def include?(obj)
76
- # puts "checking to see if #{date} is between #{from} and #{to}" if Emitter::DEBUG
77
- case obj
78
- when Date
79
- (from...to).include?(obj)
80
- when Time
81
- # (from...to).include?(obj.to_date)
82
- raise "this wasn't previously supported, but it could be"
83
- when Timeframe
84
- from <= obj.from and to >= obj.to
85
- end
86
- end
87
-
88
- def proper_include?(other_timeframe)
89
- raise ArgumentError, 'Proper inclusion only makes sense when testing other Timeframes' unless other_timeframe.is_a? Timeframe
90
- (from < other_timeframe.from) and (to > other_timeframe.to)
91
- end
92
-
93
- # Returns true when this timeframe is equal to the other timeframe
94
- def ==(other)
95
- # puts "checking to see if #{self} is equal to #{other}" if Emitter::DEBUG
96
- return false unless other.is_a?(Timeframe)
97
- from == other.from and to == other.to
98
- end
99
- alias :eql? :==
100
-
101
- # Calculates a hash value for the Timeframe, used for equality checking and Hash lookups.
102
- # This needs to be an integer or else it won't use #eql?
103
- def hash
104
- from.hash + to.hash
105
- end
106
- alias :to_param :hash
107
-
108
- # Returns an array of month-long subtimeframes
109
- # TODO: rename to month_subtimeframes
110
- def months
111
- raise ArgumentError, "Please only provide whole-month timeframes to Timeframe#months" unless from.day == 1 and to.day == 1
112
- raise ArgumentError, 'Timeframes that cross year boundaries are dangerous during Timeframe#months' unless from.year == to.yesterday.year
113
- year = from.year # therefore this only works in the from year
114
- (from.month..to.yesterday.month).map { |m| Timeframe.new :month => m, :year => year }
115
- end
116
-
117
- # Returns the relevant year as a Timeframe
118
- def year
119
- raise ArgumentError, 'Timeframes that cross year boundaries are dangerous during Timeframe#year' unless from.year == to.yesterday.year
120
- Timeframe.new :year => from.year
121
- end
122
-
123
- # multiyear safe
124
- def month_subtimeframes
125
- (from.year..to.yesterday.year).map do |year|
126
- (1..12).map do |month|
127
- Timeframe.new(:year => year, :month => month) & self
128
- end
129
- end.flatten.compact
130
- end
131
-
132
- # multiyear safe
133
- def full_month_subtimeframes
134
- month_subtimeframes.map { |st| Timeframe.new(:year => st.from.year, :month => st.from.month) }
135
- end
136
-
137
- # multiyear safe
138
- def year_subtimeframes
139
- (from.year..to.yesterday.year).map do |year|
140
- Timeframe.new(:year => year) & self
141
- end
142
- end
143
-
144
- # multiyear safe
145
- def full_year_subtimeframes
146
- (from.year..to.yesterday.year).map do |year|
147
- Timeframe.new :year => year
148
- end
149
- end
150
-
151
- # multiyear safe
152
- def ending_no_later_than(date)
153
- if to < date
154
- self
155
- elsif from >= date
156
- nil
157
- else
158
- Timeframe.multiyear from, date
159
- end
160
- end
161
-
162
- # Returns a timeframe representing the intersection of the timeframes
163
- def &(other_timeframe)
164
- this_timeframe = self
165
- if other_timeframe == this_timeframe
166
- this_timeframe
167
- elsif this_timeframe.from > other_timeframe.from and this_timeframe.to < other_timeframe.to
168
- this_timeframe
169
- elsif other_timeframe.from > this_timeframe.from and other_timeframe.to < this_timeframe.to
170
- other_timeframe
171
- elsif this_timeframe.from >= other_timeframe.to or this_timeframe.to <= other_timeframe.from
172
- nil
173
- else
174
- Timeframe.new [this_timeframe.from, other_timeframe.from].max, [this_timeframe.to, other_timeframe.to].min, :skip_year_boundary_crossing_check => true
175
- end
176
- end
177
-
178
- # Returns a fraction of another Timeframe
179
- def /(other_timeframe)
180
- raise ArgumentError, 'You can only divide a Timeframe by another Timeframe' unless other_timeframe.is_a? Timeframe
181
- self.days.to_f / other_timeframe.days.to_f
182
- end
183
-
184
- def crop(container)
185
- raise ArgumentError, 'You can only crop a timeframe by another timeframe' unless container.is_a? Timeframe
186
- self.class.new [from, container.from].max, [to, container.to].min
187
- end
188
-
189
- def gaps_left_by(*timeframes)
190
- # remove extraneous timeframes
191
- timeframes.reject! { |t| t.to <= from }
192
- timeframes.reject! { |t| t.from >= to }
193
-
194
- # crop timeframes
195
- timeframes.map! { |t| t.crop self }
196
-
197
- # remove proper subtimeframes
198
- timeframes.reject! { |t| timeframes.detect { |u| u.proper_include? t } }
199
-
200
- # escape
201
- return [self] if timeframes.empty?
202
-
203
- timeframes.sort! { |x, y| x.from <=> y.from }
204
-
205
- timeframes.collect(&:to).unshift(from).ykk(timeframes.collect(&:from).push(to)) do |gap|
206
- Timeframe.new(*gap) if gap[1] > gap[0]
207
- end.compact
208
- end
209
-
210
- def covered_by?(*timeframes)
211
- gaps_left_by(*timeframes).empty?
212
- end
213
-
214
- def last_year
215
- self.class.new((from - 1.year), (to - 1.year))
216
- end
217
-
218
- class << self
219
- def this_year
220
- new :year => Time.now.year
221
- end
222
-
223
- def constrained_new(from, to, constraint)
224
- raise ArgumentError, 'Need Date, Date, Timeframe as args' unless from.is_a? Date and to.is_a? Date and constraint.is_a? Timeframe
225
- raise ArgumentError, "Start date #{from} should be earlier than end date #{to}" if from > to
226
- if to <= constraint.from or from >= constraint.to
227
- new constraint.from, constraint.from
228
- elsif from.year == to.yesterday.year
229
- new(from, to) & constraint
230
- elsif from.year < constraint.from.year and constraint.from.year < to.yesterday.year
231
- constraint
232
- else
233
- new [constraint.from, from].max, [constraint.to, to].min
234
- end
235
- end
236
-
237
- def multiyear(from, to)
238
- from = Date.parse(from) if from.is_a?(String)
239
- to = Date.parse(to) if to.is_a?(String)
240
- new from, to, :skip_year_boundary_crossing_check => true
241
- end
242
-
243
- # create a multiyear timeframe +/- number of years around today
244
- def mid(number)
245
- from = Time.zone.today - number.years
246
- to = Time.zone.today + number.years
247
- multiyear from, to
248
- end
249
- end
250
- end
251
- end