static-data 0.1.1 → 0.2.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.
@@ -0,0 +1,11 @@
1
+ # 0.2.0
2
+
3
+ * Add support for incrementally updating tables rather than merely deleting all
4
+ data and rewriting. This should play nicer with foreign key constraints on
5
+ static data tables, which, after all, is one of the main reasons to use a static
6
+ data table in the first place. Use the new rake task `static-data:update`.
7
+
8
+ # 0.1.1
9
+
10
+ * Add rdocs for StaticData::Base
11
+ * Update homepage to github location in gemspec
data/README.md CHANGED
@@ -6,10 +6,14 @@ useful for pre-populating lookup tables and the like. It consists of
6
6
  a simple framework for describing your static data and a Rake task
7
7
  for ensuring that your static data is installed in your database.
8
8
 
9
+ While you can use migrations to do this, you can't referencing models
10
+ in migrations can get you into trouble, and it can be awkward to
11
+ update static data in migrations later.
12
+
9
13
  It doesn't do much, but it's awfully handy to have a simple way of
10
- adding lookup table data to your database. Anything that makes it
11
- easier to set up a brand new database from scratch is a win in my
12
- book.
14
+ adding lookup table data to your database. And with StaticData, you
15
+ can easily add new data and make it easy for to get everyone's
16
+ database in sync with the latest static data (even production).
13
17
 
14
18
  ## Installation
15
19
 
@@ -32,7 +36,9 @@ Create a db/static-data directory in your app:
32
36
  mkdir db/static-data
33
37
 
34
38
  Create a file for each model that you want to store static for. The
35
- file should be named after the model:
39
+ file should be named after the model. Implement two class methods, `columns`
40
+ and `rows`. The `columns` method should return the names of the columns in the
41
+ order their data appears in the `rows`
36
42
 
37
43
  # For a model named ImageType:
38
44
  cat > db/static-data/image_type.rb <<EOF
@@ -58,18 +64,8 @@ Enjoy!
58
64
 
59
65
  ## Limitations
60
66
 
61
- The current static-data:install task blows away any existing data
62
- already present in the model's table before installing, so any
63
- non-static data in the table will be nuked. It would be nice to
64
- offer another task that simply ensures that all static data is
65
- present without deleting other data. I consider that a TODO, but
66
- am happy to receive pull requests.
67
-
68
- If you have existing data in your tables and use foreign key
69
- constraints (which do go hand-in-hand with lookup tables), you
70
- probably don't want to run this rake task, because it will either
71
- fail or cause delete cascades, depending on how you've set up your
72
- constraints. Fixing the above item should hopefully fix this, too.
67
+ StaticData isn't designed for large volumes of data and performance may be poor
68
+ on large static data sets.
73
69
 
74
70
  ## Contributing
75
71
 
@@ -3,4 +3,30 @@ require "static-data/base"
3
3
  require "static-data/railtie" if defined?(Rails)
4
4
 
5
5
  module StaticData
6
+
7
+ def self.report_duration(step_name, report_format)
8
+ puts step_name
9
+ start = Time.now
10
+ yield
11
+ puts report_format % [Time.now - start]
12
+ end
13
+
14
+ def self.static_data_classes(root)
15
+ static_data_class_files(root).each do |file|
16
+ basename = File.basename(file).split('.', 2).first
17
+ expected_class_name = "Static" + basename.camelize
18
+
19
+ require File.join(root, 'db', 'static-data', basename)
20
+
21
+ klass = Object.const_get(expected_class_name)
22
+ yield klass
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def self.static_data_class_files(root)
29
+ Dir.glob(File.join(root, 'db', 'static-data', '*.rb')).sort
30
+ end
31
+
6
32
  end
@@ -41,9 +41,28 @@ module StaticData
41
41
  self.rows.each do |row|
42
42
  row_class.create!(Hash[cols.zip(row)], :without_protection => true)
43
43
  end
44
+ return {:created => self.rows.size}
44
45
  end
45
46
 
46
- # def self.update
47
- # end
47
+ # Creates new records for all of the data returned by the `rows` method
48
+ # of the StaticData subclass -- unless they exist already.
49
+ def self.update
50
+ created = 0
51
+ existing = 0
52
+ cols = self.columns
53
+ row_class = self.model_class
54
+ self.rows.each do |row|
55
+ attribs = Hash[cols.zip(row)]
56
+ row_class.transaction do
57
+ if row_class.exists?(attribs)
58
+ existing += 1
59
+ else
60
+ row_class.create!(attribs, :without_protection => true)
61
+ created += 1
62
+ end
63
+ end
64
+ end
65
+ return {:created => created, :existing => existing}
66
+ end
48
67
  end
49
68
  end
@@ -1,31 +1,42 @@
1
1
  namespace "static-data" do
2
+
2
3
  desc "Install all static data from db/static-data"
3
4
  task :install => :environment do
4
5
  require "static-data"
5
6
 
6
- Dir.glob('db/static-data/*') do |file|
7
- basename = File.basename(file).split('.', 2).first
8
- expected_class_name = "Static" + basename.
9
- camelize
10
-
11
- start = Time.now
12
- puts "== #{expected_class_name}: installing"
13
-
14
- require "#{Rails.root}/db/static-data/#{basename}"
15
- Object.const_get(expected_class_name).tap do |static_data_class|
16
- step_start = Time.now
17
- puts "-- reset"
18
- static_data_class.reset
19
- puts " -> %0.4fs" % [(Time.now - step_start)]
20
-
21
- step_start = Time.now
22
- puts "-- install"
23
- static_data_class.install
24
- puts " -> %0.4fs" % [(Time.now - step_start)]
7
+ StaticData.static_data_classes(Rails.root) do |static_data_class|
8
+ StaticData.report_duration("== #{static_data_class}: installing",
9
+ "== #{static_data_class}: installed (%0.4fs)") do
10
+
11
+ StaticData.report_duration("-- reset", " -> %0.4fs") do
12
+ static_data_class.reset
13
+ end
14
+
15
+ StaticData.report_duration("-- install", " -> %0.4fs") do
16
+ static_data_class.install
17
+ end
18
+ end
19
+
20
+ puts # add blank line separator
21
+ end
22
+ end
23
+
24
+ desc "Update any missing static data table rows from db/static-data"
25
+ task :update => :environment do
26
+ require "static-data"
27
+
28
+ StaticData.static_data_classes(Rails.root) do |static_data_class|
29
+ StaticData.report_duration("== #{static_data_class}: updating",
30
+ "== #{static_data_class}: updating (%0.4fs)") do
31
+
32
+ StaticData.report_duration("-- update", " -> %0.4fs") do
33
+ results = static_data_class.update
34
+ puts " -> existing: #{results[:existing]}; added: #{results[:created]}"
35
+ end
25
36
  end
26
37
 
27
- puts "== #{expected_class_name}: installed (%0.4fs)" % [(Time.now - start)]
28
- puts
38
+ puts # add blank line separator
29
39
  end
30
40
  end
41
+
31
42
  end
@@ -1,3 +1,3 @@
1
1
  module StaticData
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: static-data
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-13 00:00:00.000000000 Z
12
+ date: 2013-05-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -83,6 +83,7 @@ extensions: []
83
83
  extra_rdoc_files: []
84
84
  files:
85
85
  - .gitignore
86
+ - CHANGELOG.md
86
87
  - Gemfile
87
88
  - LICENSE.txt
88
89
  - README.md