beerdb 0.0.1 → 0.1.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.
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