beerdb 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
File without changes
data/Manifest.txt CHANGED
@@ -1,14 +1,18 @@
1
- History.markdown
1
+ History.md
2
2
  Manifest.txt
3
- README.markdown
3
+ README.md
4
4
  Rakefile
5
5
  bin/beerdb
6
6
  lib/beerdb.rb
7
+ lib/beerdb/cli/main.rb
7
8
  lib/beerdb/cli/opts.rb
8
- lib/beerdb/cli/runner.rb
9
+ lib/beerdb/deleter.rb
9
10
  lib/beerdb/models/beer.rb
10
11
  lib/beerdb/models/brewery.rb
12
+ lib/beerdb/models/city.rb
11
13
  lib/beerdb/models/country.rb
12
- lib/beerdb/models/prop.rb
14
+ lib/beerdb/models/forward.rb
15
+ lib/beerdb/reader.rb
13
16
  lib/beerdb/schema.rb
17
+ lib/beerdb/stats.rb
14
18
  lib/beerdb/version.rb
@@ -2,7 +2,7 @@
2
2
 
3
3
  beer.db Command Line Tool in Ruby
4
4
 
5
- * [geraldb.github.com/beer.db](http://geraldb.github.com/beer.db)
5
+ * [geraldb.github.com/beer.db.ruby](http://geraldb.github.com/beer.db.ruby)
6
6
 
7
7
 
8
8
  ## Usage
@@ -20,4 +20,4 @@ Just install the gem:
20
20
  ## License
21
21
 
22
22
  The `beerdb` scripts are dedicated to the public domain.
23
- Use it as you please with no restrictions whatsoever.
23
+ Use it as you please with no restrictions whatsoever.
data/Rakefile CHANGED
@@ -3,23 +3,105 @@ require './lib/beerdb/version.rb'
3
3
 
4
4
  Hoe.spec 'beerdb' do
5
5
 
6
- self.version = BeerDB::VERSION
6
+ self.version = BeerDb::VERSION
7
7
 
8
8
  self.summary = 'beerdb - beer.db command line tool'
9
9
  self.description = summary
10
10
 
11
- self.urls = ['http://geraldb.github.com/beer.db']
11
+ self.urls = ['https://github.com/geraldb/beer.db.ruby']
12
12
 
13
13
  self.author = 'Gerald Bauer'
14
14
  self.email = 'tobedone@googlegroups.com'
15
15
 
16
16
  # switch extension to .markdown for gihub formatting
17
- self.readme_file = 'README.markdown'
18
- self.history_file = 'History.markdown'
17
+ self.readme_file = 'README.md'
18
+ self.history_file = 'History.md'
19
19
 
20
20
  self.extra_deps = [
21
- ['activerecord', '~> 3.2'] # NB: will include activesupport,etc.
21
+ ['activerecord', '~> 3.2'], # NB: will include activesupport,etc.
22
22
  ### ['sqlite3', '~> 1.3'] # NB: install on your own; remove dependency
23
+
24
+ ['worlddb', '~> 1.6'], # NB: worlddb already includes
25
+ # - commander
26
+ # - logutils
27
+ # - textutils
28
+
29
+ ## 3rd party
30
+ ['commander', '~> 4.1.3'] # remove? -- already included as dep in worlddb
23
31
  ]
24
32
 
25
- end
33
+ self.licenses = ['Public Domain']
34
+
35
+ self.spec_extras = {
36
+ :required_ruby_version => '>= 1.9.2'
37
+ }
38
+
39
+ end
40
+
41
+
42
+
43
+ ##############################
44
+ ## for testing
45
+ ##
46
+ ## NB: use rake -I ../world.db.ruby/lib -I ./lib beerdb:build
47
+
48
+ namespace :beerdb do
49
+
50
+ BUILD_DIR = "./build"
51
+
52
+ BEER_DB_PATH = "#{BUILD_DIR}/beer.db"
53
+
54
+ DB_CONFIG = {
55
+ :adapter => 'sqlite3',
56
+ :database => BEER_DB_PATH
57
+ }
58
+
59
+ directory BUILD_DIR
60
+
61
+ task :clean do
62
+ rm BEER_DB_PATH if File.exists?( BEER_DB_PATH )
63
+ end
64
+
65
+ task :env => BUILD_DIR do
66
+ require 'worlddb' ### NB: for local testing use rake -I ./lib dev:test e.g. do NOT forget to add -I ./lib
67
+ require 'beerdb'
68
+ require 'logutils/db'
69
+
70
+ LogUtils::Logger.root.level = :info
71
+
72
+ pp DB_CONFIG
73
+ ActiveRecord::Base.establish_connection( DB_CONFIG )
74
+ end
75
+
76
+ task :create => :env do
77
+ LogDb.create
78
+ WorldDb.create
79
+ BeerDb.create
80
+ end
81
+
82
+ task :importworld => :env do
83
+ WorldDb.read_setup( 'setups/sport.db.admin', '../world.db', skip_tags: true ) # populate world tables
84
+ WorldDb.tables
85
+ end
86
+
87
+ task :importbeer => :env do
88
+ BeerDb.read_setup( 'setups/all', '../beer.db' )
89
+ BeerDb.tables
90
+ end
91
+
92
+ task :deletebeer => :env do
93
+ BeerDb.delete!
94
+ end
95
+
96
+
97
+ desc 'beerdb - build from scratch'
98
+ task :build => [:clean, :create, :importworld, :importbeer] do
99
+ puts 'Done.'
100
+ end
101
+
102
+ desc 'beerdb - update'
103
+ task :update => [:deletebeer, :importbeer] do
104
+ puts 'Done.'
105
+ end
106
+
107
+ end # namespace :beerdb
data/bin/beerdb CHANGED
@@ -4,4 +4,4 @@ require 'beerdb'
4
4
 
5
5
  ## todo: set x flag for file
6
6
 
7
- BeerDB.main
7
+ BeerDb.main
@@ -0,0 +1,230 @@
1
+ # encoding: utf-8
2
+
3
+ require 'commander/import'
4
+
5
+ require 'logutils/db' # add support for logging to db
6
+ require 'beerdb/cli/opts'
7
+
8
+ LogUtils::Logger.root.level = :info # set logging level to info
9
+
10
+
11
+ program :name, 'beerdb'
12
+ program :version, BeerDb::VERSION
13
+ program :description, "beer.db command line tool, version #{BeerDb::VERSION}"
14
+
15
+
16
+ # default_command :help
17
+ default_command :load
18
+
19
+ program :help_formatter, Commander::HelpFormatter::TerminalCompact
20
+
21
+
22
+ ## todo: find a better name e.g. change to settings? config? safe_opts? why? why not?
23
+ myopts = BeerDb::Opts.new
24
+
25
+ ### global option (required)
26
+ ## todo: add check that path is valid?? possible?
27
+
28
+ global_option '-i', '--include PATH', String, "Data path (default is #{myopts.data_path})"
29
+ global_option '-d', '--dbpath PATH', String, "Database path (default is #{myopts.db_path})"
30
+ global_option '-n', '--dbname NAME', String, "Database name (datault is #{myopts.db_name})"
31
+
32
+ global_option '-q', '--quiet', "Only show warnings, errors and fatal messages"
33
+ ### todo/fix: just want --debug/--verbose flag (no single letter option wanted) - fix
34
+ global_option '-w', '--verbose', "Show debug messages"
35
+
36
+
37
+ def connect_to_db( options )
38
+ puts BeerDb.banner
39
+
40
+ puts "working directory: #{Dir.pwd}"
41
+
42
+ db_config = {
43
+ :adapter => 'sqlite3',
44
+ :database => "#{options.db_path}/#{options.db_name}"
45
+ }
46
+
47
+ puts "Connecting to db using settings: "
48
+ pp db_config
49
+
50
+ ActiveRecord::Base.establish_connection( db_config )
51
+
52
+ LogDb.setup # turn on logging to db
53
+ end
54
+
55
+
56
+ command :create do |c|
57
+ c.syntax = 'beerdb create [options]'
58
+ c.description = 'Create DB schema'
59
+ c.action do |args, options|
60
+
61
+ LogUtils::Logger.root.level = :warn if options.quiet.present?
62
+ LogUtils::Logger.root.level = :debug if options.verbose.present?
63
+
64
+ myopts.merge_commander_options!( options.__hash__ )
65
+ connect_to_db( myopts )
66
+
67
+ LogDb.create
68
+ WorldDb.create
69
+ BeerDb.create
70
+ puts 'Done.'
71
+ end # action
72
+ end # command create
73
+
74
+ command :setup do |c|
75
+ c.syntax = 'beerdb setup [options]'
76
+ c.description = "Create DB schema 'n' load all data"
77
+
78
+ c.option '--world', 'Populate world tables'
79
+ ## todo: use --world-include - how? find better name?
80
+ c.option '--worldinclude PATH', String, 'World data path'
81
+
82
+ c.option '--beer', 'Populate beer tables'
83
+ c.option '--delete', 'Delete all records'
84
+
85
+ c.action do |args, options|
86
+
87
+ LogUtils::Logger.root.level = :warn if options.quiet.present?
88
+ LogUtils::Logger.root.level = :debug if options.verbose.present?
89
+
90
+ myopts.merge_commander_options!( options.__hash__ )
91
+ connect_to_db( myopts )
92
+
93
+ ## todo: document optional setup profile arg (defaults to all)
94
+ setup = args[0] || 'all'
95
+
96
+ if options.world.present? || options.beer.present?
97
+
98
+ ## todo: check order for reference integrity
99
+ # not really possible to delete world data if sport data is present
100
+ # delete sport first
101
+
102
+ if options.delete.present?
103
+ BeerDb.delete! if options.beer.present?
104
+ WorldDb.delete! if options.world.present?
105
+ end
106
+
107
+ if options.world.present?
108
+ WorldDb.read_all( myopts.world_data_path )
109
+ end
110
+
111
+ if options.beer.present?
112
+ BeerDb.read_setup( "setups/#{setup}", myopts.data_path )
113
+ end
114
+
115
+ else # assume "plain" regular setup
116
+ LogDb.create
117
+ WorldDb.create
118
+ BeerDb.create
119
+
120
+ WorldDb.read_all( myopts.world_data_path )
121
+ BeerDb.read_setup( "setups/#{setup}", myopts.data_path )
122
+ end
123
+
124
+ puts 'Done.'
125
+ end # action
126
+ end # command setup
127
+
128
+ command :load do |c|
129
+ ## todo: how to specify many fixutes <>... ??? in syntax
130
+ c.syntax = 'beerdb load [options] <fixtures>'
131
+ c.description = 'Load fixtures'
132
+
133
+ c.option '--delete', 'Delete all records'
134
+
135
+ c.action do |args, options|
136
+
137
+ LogUtils::Logger.root.level = :warn if options.quiet.present?
138
+ LogUtils::Logger.root.level = :debug if options.verbose.present?
139
+
140
+ myopts.merge_commander_options!( options.__hash__ )
141
+ connect_to_db( myopts )
142
+
143
+ if options.delete.present?
144
+ LogDb.delete!
145
+ BeerDb.delete!
146
+ end
147
+
148
+ # read plain text country/region/city fixtures
149
+ reader = BeerDb::Reader.new( myopts.data_path )
150
+ args.each do |arg|
151
+ name = arg # File.basename( arg, '.*' )
152
+ reader.load( name )
153
+ end # each arg
154
+
155
+ puts 'Done.'
156
+ end
157
+ end # command load
158
+
159
+
160
+ command :stats do |c|
161
+ c.syntax = 'beerdb stats [options]'
162
+ c.description = 'Show stats'
163
+ c.action do |args, options|
164
+
165
+ LogUtils::Logger.root.level = :warn if options.quiet.present?
166
+ LogUtils::Logger.root.level = :debug if options.verbose.present?
167
+
168
+ myopts.merge_commander_options!( options.__hash__ )
169
+ connect_to_db( myopts )
170
+
171
+ BeerDb.tables
172
+
173
+ puts 'Done.'
174
+ end
175
+ end
176
+
177
+
178
+ command :props do |c|
179
+ c.syntax = 'beerdb props [options]'
180
+ c.description = 'Show props'
181
+ c.action do |args, options|
182
+
183
+ LogUtils::Logger.root.level = :warn if options.quiet.present?
184
+ LogUtils::Logger.root.level = :debug if options.verbose.present?
185
+
186
+ myopts.merge_commander_options!( options.__hash__ )
187
+ connect_to_db( myopts )
188
+
189
+ BeerDb.props
190
+
191
+ puts 'Done.'
192
+ end
193
+ end
194
+
195
+
196
+ command :logs do |c|
197
+ c.syntax = 'beerdb logs [options]'
198
+ c.description = 'Show logs'
199
+ c.action do |args, options|
200
+
201
+ LogUtils::Logger.root.level = :warn if options.quiet.present?
202
+ LogUtils::Logger.root.level = :debug if options.verbose.present?
203
+
204
+ myopts.merge_commander_options!( options.__hash__ )
205
+ connect_to_db( myopts )
206
+
207
+ LogDb::Models::Log.all.each do |log|
208
+ puts "[#{log.level}] -- #{log.msg}"
209
+ end
210
+
211
+ puts 'Done.'
212
+ end
213
+ end
214
+
215
+
216
+
217
+ command :test do |c|
218
+ c.syntax = 'beerdb test [options]'
219
+ c.description = 'Debug/test command suite'
220
+ c.action do |args, options|
221
+ puts "hello from test command"
222
+ puts "args (#{args.class.name}):"
223
+ pp args
224
+ puts "options:"
225
+ pp options
226
+ puts "options.__hash__:"
227
+ pp options.__hash__
228
+ puts 'Done.'
229
+ end
230
+ end
@@ -1,47 +1,28 @@
1
- module BeerDB
1
+ module BeerDb
2
2
 
3
3
  class Opts
4
4
 
5
- def create=(boolean)
6
- @create = boolean
7
- end
8
5
 
9
- def create?
10
- return false if @create.nil? # default create flag is false
11
- @create == true
12
- end
13
-
6
+ def merge_commander_options!( options = {} )
7
+ @db_path = options[:dbpath] if options[:dbpath].present?
8
+ @db_name = options[:dbname] if options[:dbname].present?
14
9
 
15
- def delete=(boolean)
16
- @delete = boolean
10
+ @data_path = options[:include] if options[:include].present?
11
+
12
+ @world_data_path = options[:worldinclude] if options[:worldinclude].present?
17
13
  end
18
14
 
19
- def delete?
20
- return false if @delete.nil? # default create flag is false
21
- @delete == true
22
- end
23
15
 
24
16
 
25
- # use loader? (that is, built-in seed data)
26
- def load=(boolean)
27
- @load = boolean
17
+ def db_path
18
+ @db_path || '.'
28
19
  end
29
20
 
30
- def load?
31
- return false if @load.nil? # default create flag is false
32
- @load == true
21
+ def db_name
22
+ @db_name || 'beer.db'
33
23
  end
34
24
 
35
25
 
36
- def output_path=(value)
37
- @output_path = value
38
- end
39
-
40
- def output_path
41
- @output_path || '.'
42
- end
43
-
44
-
45
26
  def data_path=(value)
46
27
  @data_path = value
47
28
  end
@@ -50,7 +31,10 @@ class Opts
50
31
  @data_path || '.'
51
32
  end
52
33
 
34
+ def world_data_path
35
+ @world_data_path # NB: option has no default; return nil
36
+ end
53
37
 
54
38
  end # class Opts
55
39
 
56
- end # module BeerDB
40
+ end # module BeerDb
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module BeerDb
4
+
5
+ class Deleter
6
+
7
+ include BeerDb::Models
8
+
9
+ def run
10
+ # for now delete all tables
11
+
12
+ Beer.delete_all
13
+ Brewery.delete_all
14
+ end
15
+
16
+ end # class Deleter
17
+
18
+ end # module BeerDb
@@ -1,12 +1,12 @@
1
- module BeerDB
2
- module Models
1
+ module BeerDb::Models
3
2
 
4
-
5
3
  class Beer < ActiveRecord::Base
6
4
 
5
+ belongs_to :country, :class_name => 'WorldDb::Models::Country', :foreign_key => 'country_id'
6
+ belongs_to :city, :class_name => 'WorldDb::Models::City', :foreign_key => 'city_id'
7
7
 
8
8
  end # class Beer
9
9
 
10
10
 
11
- end # module Models
12
- end # module BeerDB
11
+ end # module BeerDb::Models
12
+
@@ -1,13 +1,14 @@
1
- module BeerDB
2
- module Models
1
+ module BeerDb::Models
3
2
 
4
-
5
3
  class Brewery < ActiveRecord::Base
6
-
4
+
7
5
  self.table_name = 'breweries'
8
6
 
7
+ belongs_to :country, :class_name => 'WorldDb::Models::Country', :foreign_key => 'country_id'
8
+ belongs_to :city, :class_name => 'WorldDb::Models::City', :foreign_key => 'city_id'
9
+
9
10
  end # class Brewery
10
11
 
11
12
 
12
- end # module Models
13
- end # module BeerDB
13
+ end # module BeerDb::Models
14
+
@@ -0,0 +1,8 @@
1
+ module WorldDb::Models
2
+
3
+ class City
4
+ has_many :beers, :class_name => 'BeerDb::Models::Beer', :foreign_key => 'country_id'
5
+ has_many :breweries, :class_name => 'BeerDb::Models::Brewery', :foreign_key => 'country_id'
6
+ end # class Country
7
+
8
+ end # module WorldDb::Models
@@ -1,26 +1,9 @@
1
- module BeerDB
2
- module Models
3
1
 
4
-
5
- class Country < ActiveRecord::Base
6
- self.table_name = 'countries'
7
-
8
- def self.create_from_ary!( countries )
9
- countries.each do |values|
10
-
11
- ## key & title required
12
- attr = {
13
- :key => values[0],
14
- :title => values[1],
15
- :tag => values[2]
16
- }
17
-
18
- Country.create!( attr )
19
- end # each country
20
- end
2
+ module WorldDb::Models
21
3
 
4
+ class Country
5
+ has_many :beers, :class_name => 'BeerDb::Models::Beer', :foreign_key => 'country_id'
6
+ has_many :breweries, :class_name => 'BeerDb::Models::Brewery', :foreign_key => 'country_id'
22
7
  end # class Country
23
8
 
24
-
25
- end # module Models
26
- end # module BeerDB
9
+ end # module WorldDb::Models
@@ -0,0 +1,25 @@
1
+ ### forward references
2
+ ## require first to resolve circular references
3
+
4
+ module BeerDb::Models
5
+
6
+ ## todo: why? why not use include WorldDb::Models here???
7
+
8
+ Continent = WorldDb::Models::Continent
9
+ Country = WorldDb::Models::Country
10
+ Region = WorldDb::Models::Region
11
+ City = WorldDb::Models::City
12
+ Prop = WorldDb::Models::Prop
13
+
14
+ class Beer < ActiveRecord::Base ; end
15
+ class Brewery < ActiveRecord::Base ; end
16
+
17
+ end
18
+
19
+
20
+ module WorldDb::Models
21
+
22
+ Beer = BeerDb::Models::Beer
23
+ Brewery = BeerDb::Models::Brewery
24
+
25
+ end
@@ -0,0 +1,196 @@
1
+ # encoding: UTF-8
2
+
3
+ module BeerDb
4
+
5
+ class Reader
6
+
7
+ include LogUtils::Logging
8
+
9
+ include BeerDb::Models
10
+
11
+ attr_reader :include_path
12
+
13
+
14
+ def initialize( include_path, opts = {} )
15
+ @include_path = include_path
16
+ end
17
+
18
+
19
+ def load_setup( setup )
20
+ ary = load_fixture_setup( setup )
21
+
22
+ ary.each do |name|
23
+ load( name )
24
+ end
25
+ end # method load_setup
26
+
27
+
28
+ ## fix/todo: rename ??
29
+ def load_fixture_setup( name )
30
+
31
+ ## todo/fix: cleanup quick and dirty code
32
+
33
+ path = "#{include_path}/#{name}.yml"
34
+
35
+ logger.info "parsing data '#{name}' (#{path})..."
36
+
37
+ text = File.read_utf8( path )
38
+
39
+ hash = YAML.load( text )
40
+
41
+ ### build up array for fixtures from hash
42
+
43
+ ary = []
44
+
45
+ hash.each do |key_wild, value_wild|
46
+ key = key_wild.to_s.strip
47
+
48
+ logger.debug "yaml key:#{key_wild.class.name} >>#{key}<<, value:#{value_wild.class.name} >>#{value_wild}<<"
49
+
50
+ if value_wild.kind_of?( String ) # assume single fixture name
51
+ ary << value_wild
52
+ elsif value_wild.kind_of?( Array ) # assume array of fixture names as strings
53
+ ary = ary + value_wild
54
+ else
55
+ logger.error "unknow fixture type in setup (yaml key:#{key_wild.class.name} >>#{key}<<, value:#{value_wild.class.name} >>#{value_wild}<<); skipping"
56
+ end
57
+ end
58
+
59
+ logger.debug "fixture setup:"
60
+ logger.debug ary.to_json
61
+
62
+ ary
63
+ end # load_fixture_setup
64
+
65
+
66
+ def load( name )
67
+
68
+ if name =~ /\/([a-z]{2})\/beers/
69
+ ## auto-add required country code (from folder structure)
70
+ load_beers( $1, name )
71
+ else
72
+ logger.error "unknown beer.db fixture type >#{name}<"
73
+ # todo/fix: exit w/ error
74
+ end
75
+ end
76
+
77
+
78
+ def load_beers( country_key, name, more_values={} )
79
+ country = Country.find_by_key!( country_key )
80
+ logger.debug "Country #{country.key} >#{country.title} (#{country.code})<"
81
+
82
+ more_values[ :country_id ] = country.id
83
+
84
+ path = "#{include_path}/#{name}.txt"
85
+
86
+ logger.info "parsing data '#{name}' (#{path})..."
87
+
88
+ reader = ValuesReader.new( path, more_values )
89
+
90
+ load_beers_worker( reader )
91
+
92
+ Prop.create_from_fixture!( name, path )
93
+ end
94
+
95
+
96
+ private
97
+
98
+
99
+ def load_beers_worker( reader )
100
+
101
+ ## NB: assumes active activerecord db connection
102
+ ##
103
+
104
+ reader.each_line do |attribs, values|
105
+
106
+ value_tag_keys = []
107
+
108
+ ### check for "default" tags - that is, if present attribs[:tags] remove from hash
109
+
110
+ if attribs[:tags].present?
111
+ more_tag_keys = attribs[:tags].split('|')
112
+ attribs.delete(:tags)
113
+
114
+ ## unify; replace _w/ space; remove leading n trailing whitespace
115
+ more_tag_keys = more_tag_keys.map do |key|
116
+ key = key.gsub( '_', ' ' )
117
+ key = key.strip
118
+ key
119
+ end
120
+
121
+ value_tag_keys += more_tag_keys
122
+ end
123
+
124
+
125
+ ## check for optional values
126
+ values.each_with_index do |value,index|
127
+ if value =~ /^country:/ ## country:
128
+ value_country_key = value[8..-1] ## cut off country: prefix
129
+ value_country = Country.find_by_key!( value_country_key )
130
+ attribs[ :country_id ] = value_country.id
131
+ elsif value =~ /^city:/ ## city:
132
+ value_city_key = value[5..-1] ## cut off city: prefix
133
+ value_city = City.find_by_key!( value_city_key )
134
+ attribs[ :city_id ] = value_city.id
135
+ elsif (values.size==(index+1)) && value =~ /^[a-z0-9\|_ ]+$/ # tags must be last entry
136
+
137
+ logger.debug " found tags: >>#{value}<<"
138
+
139
+ tag_keys = value.split('|')
140
+
141
+ ## unify; replace _w/ space; remove leading n trailing whitespace
142
+ tag_keys = tag_keys.map do |key|
143
+ key = key.gsub( '_', ' ' )
144
+ key = key.strip
145
+ key
146
+ end
147
+
148
+ value_tag_keys += tag_keys
149
+ else
150
+ # issue warning: unknown type for value
151
+ logger.warn "unknown type for value >#{value}<"
152
+ end
153
+ end # each value
154
+
155
+ # rec = Beer.find_by_key_and_country_id( attribs[ :key ], attribs[ :country_id] )
156
+ rec = Beer.find_by_key( attribs[ :key ] )
157
+
158
+ if rec.present?
159
+ logger.debug "update Beer #{rec.id}-#{rec.key}:"
160
+ else
161
+ logger.debug "create Beer:"
162
+ rec = Beer.new
163
+ end
164
+
165
+ logger.debug attribs.to_json
166
+
167
+ rec.update_attributes!( attribs )
168
+
169
+ =begin
170
+ ##################
171
+ ## add taggings
172
+
173
+ if value_tag_keys.size > 0
174
+
175
+ value_tag_keys.uniq! # remove duplicates
176
+ logger.debug " adding #{value_tag_keys.size} taggings: >>#{value_tag_keys.join('|')}<<..."
177
+
178
+ ### fix/todo: check tag_ids and only update diff (add/remove ids)
179
+
180
+ value_tag_keys.each do |key|
181
+ tag = Tag.find_by_key( key )
182
+ if tag.nil? # create tag if it doesn't exit
183
+ logger.debug " creating tag >#{key}<"
184
+ tag = Tag.create!( key: key )
185
+ end
186
+ rec.tags << tag
187
+ end
188
+ end
189
+ =end
190
+
191
+ end # each_line
192
+
193
+ end # method load_beers_worker
194
+
195
+ end # class Reader
196
+ end # module BeerDb
data/lib/beerdb/schema.rb CHANGED
@@ -1,27 +1,10 @@
1
1
 
2
- module BeerDB
2
+ module BeerDb
3
3
 
4
- class CreateDB
4
+ class CreateDb < ActiveRecord::Migration
5
5
 
6
- include BeerDB::Models
7
6
 
8
-
9
- def self.up
10
-
11
- ActiveRecord::Schema.define do
12
-
13
- create_table :countries do |t|
14
- t.string :title, :null => false
15
- t.string :tag, :null => false # short three letter tag
16
- t.string :key, :null => false
17
- t.timestamps
18
- end
19
-
20
- create_table :props do |t|
21
- t.string :key, :null => false
22
- t.string :value, :null => false
23
- t.timestamps
24
- end
7
+ def up
25
8
 
26
9
  create_table :beers do |t|
27
10
  t.string :title, :null => false
@@ -32,23 +15,32 @@ create_table :beers do |t|
32
15
  ## todo: check seasonal is it proper english?
33
16
  t.boolean :seasonal, :null => false, :default => false # all year or just eg. Festbier/Oktoberfest Special
34
17
  ## todo: add microbrew/brewpub flag?
35
- #### t.boolean :brewpub, :null => false, :default => false
18
+ #### t.boolean :brewpub, :null => false, :default => false
19
+
20
+ t.references :country, :null => false
21
+ t.references :city # optional
22
+
36
23
  t.timestamps
37
24
  end
38
-
25
+
26
+
39
27
  create_table :breweries do |t|
40
28
  t.string :title
29
+ t.string :key, :null => false # import/export key
30
+ t.string :synonyms # comma separated list of synonyms
41
31
  t.references :country, :null => false
32
+ t.references :city # optional
33
+
42
34
  t.timestamps
43
35
  end
44
-
45
- end # block Schema.define
46
36
 
37
+ end # method up
47
38
 
48
- Prop.create!( key: 'db.schema.version', value: BeerDB::VERSION )
39
+ def down
40
+ raise ActiveRecord::IrreversibleMigration
41
+ end
49
42
 
50
- end # method up
51
43
 
52
- end # class CreateDB
44
+ end # class CreateDb
53
45
 
54
- end # module BeerDB
46
+ end # module BeerDb
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ module BeerDb
4
+
5
+ class Stats
6
+ include BeerDb::Models
7
+
8
+ def tables
9
+ puts "Stats:"
10
+ puts " #{'%5d' % Beer.count} beers"
11
+ puts " #{'%5d' % Brewery.count} breweries"
12
+ end
13
+
14
+ def props
15
+ puts "Props:"
16
+ Prop.order( 'created_at asc' ).all.each do |prop|
17
+ puts " #{prop.key} / #{prop.value} || #{prop.created_at}"
18
+ end
19
+ end
20
+ end # class Stats
21
+
22
+ end # module BeerDb
@@ -1,4 +1,4 @@
1
1
 
2
- module BeerDB
3
- VERSION = '0.0.1'
2
+ module BeerDb
3
+ VERSION = '0.1.0'
4
4
  end
data/lib/beerdb.rb CHANGED
@@ -12,23 +12,31 @@ require 'optparse'
12
12
  require 'fileutils'
13
13
  require 'erb'
14
14
 
15
- # rubygems
15
+ # 3rd party gems / libs
16
16
 
17
17
  require 'active_record' ## todo: add sqlite3? etc.
18
18
 
19
+ require 'logutils'
20
+ require 'textutils'
21
+ require 'worlddb'
22
+
19
23
 
20
24
  # our own code
21
25
 
26
+ require 'beerdb/version'
27
+
28
+ require 'beerdb/models/forward'
22
29
  require 'beerdb/models/country'
30
+ require 'beerdb/models/city'
23
31
  require 'beerdb/models/beer'
24
32
  require 'beerdb/models/brewery'
25
- require 'beerdb/models/prop'
26
- require 'beerdb/schema' # NB: requires beerdb/models (include BeerDB::Models)
27
- require 'beerdb/version'
28
- require 'beerdb/cli/opts'
29
- require 'beerdb/cli/runner'
33
+ require 'beerdb/schema'
34
+ require 'beerdb/reader'
35
+ require 'beerdb/deleter'
36
+ require 'beerdb/stats'
37
+
30
38
 
31
- module BeerDB
39
+ module BeerDb
32
40
 
33
41
  def self.banner
34
42
  "beerdb #{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
@@ -39,10 +47,53 @@ module BeerDB
39
47
  end
40
48
 
41
49
  def self.main
42
- Runner.new.run(ARGV)
50
+ require 'beerdb/cli/main'
51
+ # Runner.new.run(ARGV) old code
52
+ end
53
+
54
+ def self.create
55
+ CreateDb.new.up
56
+ BeerDb::Models::Prop.create!( key: 'db.schema.beer.version', value: VERSION )
57
+ end
58
+
59
+
60
+ def self.read( ary, include_path )
61
+ reader = Reader.new( include_path )
62
+ ary.each do |name|
63
+ reader.load( name )
64
+ end
43
65
  end
44
-
45
- end # module BeerDB
66
+
67
+ def self.read_setup( setup, include_path, opts={} )
68
+ reader = Reader.new( include_path, opts )
69
+ reader.load_setup( setup )
70
+ end
71
+
72
+ def self.read_all( include_path, opts={} ) # load all builtins (using plain text reader); helper for convenience
73
+ read_setup( 'setups/all', include_path, opts )
74
+ end # method read_all
75
+
76
+
77
+ # delete ALL records (use with care!)
78
+ def self.delete!
79
+ puts '*** deleting beer table records/data...'
80
+ Deleter.new.run
81
+ end # method delete!
82
+
83
+ def self.tables
84
+ Stats.new.tables
85
+ end
86
+
87
+ def self.props
88
+ Stats.new.props
89
+ end
90
+
91
+ end # module BeerDb
46
92
 
47
93
 
48
- BeerDB.main if __FILE__ == $0
94
+ if __FILE__ == $0
95
+ BeerDb.main
96
+ else
97
+ # say hello
98
+ puts BeerDb.banner
99
+ end
metadata CHANGED
@@ -1,123 +1,122 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: beerdb
3
- version: !ruby/object:Gem::Version
4
- hash: 29
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 1
10
- version: 0.0.1
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Gerald Bauer
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-10-17 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2013-03-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: activerecord
16
+ requirement: &73327670 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.2'
22
+ type: :runtime
22
23
  prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
+ version_requirements: *73327670
25
+ - !ruby/object:Gem::Dependency
26
+ name: worlddb
27
+ requirement: &73327440 !ruby/object:Gem::Requirement
24
28
  none: false
25
- requirements:
29
+ requirements:
26
30
  - - ~>
27
- - !ruby/object:Gem::Version
28
- hash: 3
29
- segments:
30
- - 3
31
- - 2
32
- version: "3.2"
31
+ - !ruby/object:Gem::Version
32
+ version: '1.6'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *73327440
36
+ - !ruby/object:Gem::Dependency
37
+ name: commander
38
+ requirement: &73327210 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 4.1.3
33
44
  type: :runtime
34
- version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: rdoc
37
45
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
46
+ version_requirements: *73327210
47
+ - !ruby/object:Gem::Dependency
48
+ name: rdoc
49
+ requirement: &72898760 !ruby/object:Gem::Requirement
39
50
  none: false
40
- requirements:
51
+ requirements:
41
52
  - - ~>
42
- - !ruby/object:Gem::Version
43
- hash: 19
44
- segments:
45
- - 3
46
- - 10
47
- version: "3.10"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.10'
48
55
  type: :development
49
- version_requirements: *id002
50
- - !ruby/object:Gem::Dependency
51
- name: hoe
52
56
  prerelease: false
53
- requirement: &id003 !ruby/object:Gem::Requirement
57
+ version_requirements: *72898760
58
+ - !ruby/object:Gem::Dependency
59
+ name: hoe
60
+ requirement: &72898510 !ruby/object:Gem::Requirement
54
61
  none: false
55
- requirements:
62
+ requirements:
56
63
  - - ~>
57
- - !ruby/object:Gem::Version
58
- hash: 7
59
- segments:
60
- - 3
61
- - 0
62
- version: "3.0"
64
+ - !ruby/object:Gem::Version
65
+ version: '3.3'
63
66
  type: :development
64
- version_requirements: *id003
67
+ prerelease: false
68
+ version_requirements: *72898510
65
69
  description: beerdb - beer.db command line tool
66
70
  email: tobedone@googlegroups.com
67
- executables:
71
+ executables:
68
72
  - beerdb
69
73
  extensions: []
70
-
71
- extra_rdoc_files:
74
+ extra_rdoc_files:
72
75
  - Manifest.txt
73
- files:
74
- - History.markdown
76
+ files:
77
+ - History.md
75
78
  - Manifest.txt
76
- - README.markdown
79
+ - README.md
77
80
  - Rakefile
78
81
  - bin/beerdb
79
82
  - lib/beerdb.rb
83
+ - lib/beerdb/cli/main.rb
80
84
  - lib/beerdb/cli/opts.rb
81
- - lib/beerdb/cli/runner.rb
85
+ - lib/beerdb/deleter.rb
82
86
  - lib/beerdb/models/beer.rb
83
87
  - lib/beerdb/models/brewery.rb
88
+ - lib/beerdb/models/city.rb
84
89
  - lib/beerdb/models/country.rb
85
- - lib/beerdb/models/prop.rb
90
+ - lib/beerdb/models/forward.rb
91
+ - lib/beerdb/reader.rb
86
92
  - lib/beerdb/schema.rb
93
+ - lib/beerdb/stats.rb
87
94
  - lib/beerdb/version.rb
88
- homepage: http://geraldb.github.com/beer.db
89
- licenses: []
90
-
95
+ homepage: https://github.com/geraldb/beer.db.ruby
96
+ licenses:
97
+ - Public Domain
91
98
  post_install_message:
92
- rdoc_options:
99
+ rdoc_options:
93
100
  - --main
94
- - README.markdown
95
- require_paths:
101
+ - README.md
102
+ require_paths:
96
103
  - lib
97
- required_ruby_version: !ruby/object:Gem::Requirement
104
+ required_ruby_version: !ruby/object:Gem::Requirement
98
105
  none: false
99
- requirements:
100
- - - ">="
101
- - !ruby/object:Gem::Version
102
- hash: 3
103
- segments:
104
- - 0
105
- version: "0"
106
- required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: 1.9.2
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
111
  none: false
108
- requirements:
109
- - - ">="
110
- - !ruby/object:Gem::Version
111
- hash: 3
112
- segments:
113
- - 0
114
- version: "0"
112
+ requirements:
113
+ - - ! '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
115
116
  requirements: []
116
-
117
117
  rubyforge_project: beerdb
118
- rubygems_version: 1.8.24
118
+ rubygems_version: 1.8.17
119
119
  signing_key:
120
120
  specification_version: 3
121
121
  summary: beerdb - beer.db command line tool
122
122
  test_files: []
123
-
@@ -1,124 +0,0 @@
1
-
2
- module BeerDB
3
-
4
- class Runner
5
-
6
-
7
- include BeerDB::Models
8
-
9
- def initialize
10
- @logger = Logger.new(STDOUT)
11
- @logger.level = Logger::INFO
12
-
13
- @opts = Opts.new
14
- end
15
-
16
- attr_reader :logger, :opts
17
-
18
-
19
- def run( args )
20
- opt=OptionParser.new do |cmd|
21
-
22
- cmd.banner = "Usage: beerdb [options]"
23
-
24
- ## todo: change to different flag?? use -c/--config ???
25
- cmd.on( '-c', '--create', 'Create DB Schema' ) { opts.create = true }
26
-
27
- cmd.on( '--delete', 'Delete all records' ) { opts.delete = true }
28
-
29
- cmd.on( '--load', 'Use Loader for Builtin Beer Data' ) { opts.load = true }
30
-
31
- ### todo: in future allow multiple search path??
32
- cmd.on( '-i', '--include PATH', "Data Path (default is #{opts.data_path})" ) { |path| opts.data_path = path }
33
-
34
- cmd.on( '-v', '--version', "Show version" ) do
35
- puts BeerDB.banner
36
- exit
37
- end
38
-
39
- cmd.on( "--verbose", "Show debug trace" ) do
40
- logger.datetime_format = "%H:%H:%S"
41
- logger.level = Logger::DEBUG
42
-
43
- ActiveRecord::Base.logger = Logger.new(STDOUT)
44
- end
45
-
46
- cmd.on_tail( "-h", "--help", "Show this message" ) do
47
- puts <<EOS
48
-
49
- beerdb - beer.db command line tool, version #{VERSION}
50
-
51
- #{cmd.help}
52
-
53
- Examples:
54
- beerdb at # import austrian beers
55
- beerdb -c # create database schema
56
-
57
- More Examples:
58
- beerdb # show stats (table counts, table props)
59
-
60
- Further information:
61
- http://geraldb.github.com/beer.db
62
-
63
- EOS
64
- exit
65
- end
66
- end
67
-
68
- opt.parse!( args )
69
-
70
- puts BeerDB.banner
71
-
72
- puts "working directory: #{Dir.pwd}"
73
-
74
- db_config = {
75
- :adapter => 'sqlite3',
76
- :database => "#{opts.output_path}/beer.db"
77
- }
78
-
79
- puts "Connecting to db using settings: "
80
- pp db_config
81
-
82
- ActiveRecord::Base.establish_connection( db_config )
83
-
84
- if opts.create?
85
- CreateDB.up
86
- end
87
-
88
- if opts.delete?
89
- # tbd
90
- end
91
-
92
-
93
- args.each do |arg|
94
- name = arg # File.basename( arg, '.*' )
95
-
96
- # tbd
97
- end
98
-
99
- dump_stats
100
- dump_props
101
-
102
- puts 'Done.'
103
-
104
- end # method run
105
-
106
-
107
- def dump_stats
108
- # todo: use %5d or similar to format string
109
- puts "Stats:"
110
- puts " #{Beer.count} beers"
111
- puts " #{Brewery.count} breweries"
112
- puts " #{Country.count} countries"
113
- end
114
-
115
- def dump_props
116
- # todo: use %5 or similar to format string
117
- puts "Props:"
118
- Prop.order( 'created_at asc' ).all.each do |prop|
119
- puts " #{prop.key} / #{prop.value} || #{prop.created_at}"
120
- end
121
- end
122
-
123
- end # class Runner
124
- end # module BeerDB
@@ -1,12 +0,0 @@
1
- module BeerDB
2
- module Models
3
-
4
-
5
- class Prop < ActiveRecord::Base
6
-
7
- end # class Prop
8
-
9
-
10
-
11
- end # module Models
12
- end # module BeerDB