sportdb-models 1.19.1 → 2.0.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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Manifest.txt +27 -38
  3. data/Rakefile +1 -1
  4. data/lib/sportdb/models.rb +55 -49
  5. data/lib/sportdb/{deleter.rb → models/deleter.rb} +3 -9
  6. data/lib/sportdb/models/formats.rb +23 -0
  7. data/lib/sportdb/models/models/assoc.rb +38 -0
  8. data/lib/sportdb/models/{badge.rb → models/badge.rb} +1 -1
  9. data/lib/sportdb/models/models/event.rb +55 -0
  10. data/lib/sportdb/models/{forward.rb → models/forward.rb} +3 -3
  11. data/lib/sportdb/models/{goal.rb → models/goal.rb} +1 -1
  12. data/lib/sportdb/models/models/ground.rb +16 -0
  13. data/lib/sportdb/models/{group.rb → models/group.rb} +10 -7
  14. data/lib/sportdb/models/models/league.rb +20 -0
  15. data/lib/sportdb/models/{roster.rb → models/lineup.rb} +3 -4
  16. data/lib/sportdb/models/{game.rb → models/match.rb} +16 -60
  17. data/lib/sportdb/models/{person.rb → models/person.rb} +0 -0
  18. data/lib/sportdb/models/{round.rb → models/round.rb} +1 -6
  19. data/lib/sportdb/models/{season.rb → models/season.rb} +0 -0
  20. data/lib/sportdb/models/{stage.rb → models/stage.rb} +9 -5
  21. data/lib/sportdb/models/{stats/alltime_standing_entry.rb → models/stats/alltime_standing.rb} +9 -1
  22. data/lib/sportdb/models/{stats/event_standing_entry.rb → models/stats/event_standing.rb} +11 -1
  23. data/lib/sportdb/models/{stats/group_standing_entry.rb → models/stats/group_standing.rb} +10 -1
  24. data/lib/sportdb/models/models/team.rb +56 -0
  25. data/lib/sportdb/models/{world → models/world}/city.rb +2 -2
  26. data/lib/sportdb/models/{world → models/world}/continent.rb +0 -0
  27. data/lib/sportdb/models/{world → models/world}/country.rb +0 -0
  28. data/lib/sportdb/models/{world → models/world}/state.rb +0 -0
  29. data/lib/sportdb/{schema.rb → models/schema.rb} +98 -74
  30. data/lib/sportdb/{stats.rb → models/stats.rb} +4 -4
  31. data/lib/sportdb/models/utils.rb +24 -24
  32. data/lib/sportdb/{version.rb → models/version.rb} +4 -4
  33. data/test/helper.rb +10 -6
  34. data/test/test_changes.rb +38 -38
  35. data/test/test_cursor.rb +15 -15
  36. data/test/test_winner.rb +75 -70
  37. metadata +29 -40
  38. data/lib/sportdb/calc.rb +0 -279
  39. data/lib/sportdb/models/assoc.rb +0 -106
  40. data/lib/sportdb/models/assoc_assoc.rb +0 -15
  41. data/lib/sportdb/models/event.rb +0 -66
  42. data/lib/sportdb/models/event_ground.rb +0 -15
  43. data/lib/sportdb/models/event_team.rb +0 -16
  44. data/lib/sportdb/models/ground.rb +0 -100
  45. data/lib/sportdb/models/group_team.rb +0 -14
  46. data/lib/sportdb/models/league.rb +0 -83
  47. data/lib/sportdb/models/stage_team.rb +0 -14
  48. data/lib/sportdb/models/stats/alltime_standing.rb +0 -44
  49. data/lib/sportdb/models/stats/event_standing.rb +0 -55
  50. data/lib/sportdb/models/stats/group_standing.rb +0 -50
  51. data/lib/sportdb/models/team.rb +0 -119
  52. data/lib/sportdb/models/team_compat.rb +0 -64
  53. data/lib/sportdb/patterns.rb +0 -37
  54. data/lib/sportdb/standings.rb +0 -178
@@ -1,119 +0,0 @@
1
-
2
- module SportDb
3
- module Model
4
-
5
- ##################
6
- # FIX: add ?
7
- #
8
- # use single table inheritance STI ????
9
- # - to mark two dervided classes e.g.
10
- # - Club ??? - why? why not?
11
- # - NationalTeam ??? - why? why not?
12
-
13
-
14
- class Team < ActiveRecord::Base
15
-
16
- has_many :home_games, class_name: 'Game', foreign_key: 'team1_id'
17
- has_many :away_games, class_name: 'Game', foreign_key: 'team2_id'
18
-
19
- ## todo/fix: must be 3 or more letters (plus allow digits e.g. salzburgii, muenchen1980, etc.) - why? why not??
20
- validates :key, format: { with: /#{TEAM_KEY_PATTERN}/, message: TEAM_KEY_PATTERN_MESSAGE }
21
- validates :code, format: { with: /#{TEAM_CODE_PATTERN}/, message: TEAM_CODE_PATTERN_MESSAGE }, allow_nil: true
22
-
23
- has_many :event_teams, class_name: 'EventTeam' # join table (events+teams)
24
- has_many :events, :through => :event_teams
25
-
26
- # note: team belongs_to a single (optinal) assoc for now (national assoc may have many assocs)
27
- belongs_to :assoc
28
-
29
- ### fix!!! - how to do it with has_many macro? use finder_sql?
30
- ## finder_sql is depreciated in Rails 4!!!
31
- # use -> { where() } etc. -- try it if it works
32
- ## keep as is! best solution ??
33
- ## a discussion here -> https://github.com/rails/rails/issues/9726
34
- ## a discussion here (not really helpful) -> http://stackoverflow.com/questions/2125440/activerecord-has-many-where-two-columns-in-table-a-are-primary-keys-in-table-b
35
-
36
- def games
37
- Game.where( 'team1_id = ? or team2_id = ?', id, id ).order( 'play_at' )
38
- end
39
-
40
- def upcoming_games
41
- Game.where( 'team1_id = ? or team2_id = ?', id, id ).where( 'play_at > ?', Time.now ).order( 'play_at' )
42
- end
43
-
44
- def past_games
45
- Game.where( 'team1_id = ? or team2_id = ?', id, id ).where( 'play_at < ?', Time.now ).order( 'play_at desc' )
46
- end
47
-
48
-
49
- has_many :badges # Winner, 2nd, Cupsieger, Aufsteiger, Absteiger, etc.
50
-
51
- belongs_to :country, class_name: 'WorldDb::Model::Country', foreign_key: 'country_id'
52
- belongs_to :city, class_name: 'WorldDb::Model::City', foreign_key: 'city_id'
53
-
54
-
55
- ## fix/todo: change title to name; title2 to name2 etc.
56
- def name() title; end
57
-
58
-
59
- def self.create_or_update_from_values( new_attributes, values )
60
-
61
- ## fix: add/configure logger for ActiveRecord!!!
62
- logger = LogUtils::Logger.root
63
-
64
-
65
- ## check optional values
66
- values.each_with_index do |value, index|
67
- if value =~ /^city:/ ## city:
68
- value_city_key = value[5..-1] ## cut off city: prefix
69
- value_city = City.find_by_key( value_city_key )
70
- if value_city.present?
71
- new_attributes[ :city_id ] = value_city.id
72
- else
73
- ## todo/fix: add strict mode flag - fail w/ exit 1 in strict mode
74
- logger.warn "city with key #{value_city_key} missing"
75
- ## todo: log errors to db log???
76
- end
77
- elsif value =~ /^(18|19|20)[0-9]{2}$/ ## assume founding year -- allow 18|19|20
78
- ## logger.info " founding/opening year #{value}"
79
- new_attributes[ :since ] = value.to_i
80
- elsif value =~ /\/{2}/ # assume it's an address line e.g. xx // xx
81
- ## logger.info " found address line #{value}"
82
- new_attributes[ :address ] = value
83
- elsif value =~ /^(?:[a-z]{2}\.)?wikipedia:/ # assume it's wikipedia e.g. [es.]wikipedia:
84
- logger.info " found wikipedia line #{value}; skipping for now"
85
- elsif value =~ /(^www\.)|(\.com$)/ # FIX: !!!! use a better matcher not just www. and .com
86
- new_attributes[ :web ] = value
87
- elsif value =~ /^[A-Z][A-Z0-9][A-Z0-9_]?$/ ## assume two or three-letter code e.g. FCB, RBS, etc.
88
- new_attributes[ :code ] = value
89
- elsif value =~ /^[a-z]{2,3}$/ ## assume two or three-letter country key e.g. at,de,mx, or eng,sco,wal,nir etc.
90
- ## fix: if country does NOT match / NOT found - just continue w/ next match!!!!
91
- # - just issue an error/warn do NOT crash
92
- value_country = Country.find_by_key!( value )
93
- new_attributes[ :country_id ] = value_country.id
94
- else
95
- ## todo: assume title2 ??
96
- # issue warning: unknown type for value
97
- logger.warn "unknown type for value >#{value}< - key #{new_attributes[:key]}"
98
- end
99
- end
100
-
101
- rec = Team.find_by_key( new_attributes[ :key ] )
102
- if rec.present?
103
- logger.debug "update Team #{rec.id}-#{rec.key}:"
104
- else
105
- logger.debug "create Team:"
106
- rec = Team.new
107
- end
108
-
109
- logger.debug new_attributes.to_json
110
-
111
- rec.update_attributes!( new_attributes )
112
-
113
- end # create_or_update_from_values
114
-
115
- end # class Team
116
-
117
-
118
- end # module Model
119
- end # module SportDb
@@ -1,64 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module SportDb
4
- module Model
5
-
6
- #############################################################
7
- # collect depreciated or methods for future removal here
8
- # - keep for now for compatibility (for old code)
9
-
10
- class Team
11
-
12
-
13
- def self.create_from_ary!( teams, more_values={} )
14
- teams.each do |values|
15
-
16
- ## key & title required
17
- attr = {
18
- key: values[0]
19
- }
20
-
21
- ## title (split of optional synonyms)
22
- # e.g. FC Bayern Muenchen|Bayern Muenchen|Bayern
23
- titles = values[1].split('|')
24
-
25
- attr[ :title ] = titles[0]
26
- ## add optional synonyms
27
- attr[ :synonyms ] = titles[1..-1].join('|') if titles.size > 1
28
-
29
-
30
- attr = attr.merge( more_values )
31
-
32
- ## check for optional values
33
- values[2..-1].each do |value|
34
- if value.is_a? Country
35
- attr[ :country_id ] = value.id
36
- elsif value.is_a? City
37
- attr[ :city_id ] = value.id
38
- elsif value =~ /#{TEAM_CODE_PATTERN}/ ## assume its three letter code (e.g. ITA or S04 etc.)
39
- attr[ :code ] = value
40
- elsif value =~ /^city:/ ## city:
41
- value_city_key = value[5..-1] ## cut off city: prefix
42
- value_city = City.find_by_key!( value_city_key )
43
- attr[ :city_id ] = value_city.id
44
- else
45
- attr[ :title2 ] = value
46
- end
47
- end
48
-
49
- ## check if exists
50
- team = Team.find_by_key( values[0] )
51
- if team.present?
52
- puts "*** warning team with key '#{values[0]}' exists; skipping create"
53
- else
54
- Team.create!( attr )
55
- end
56
- end # each team
57
- end
58
-
59
- end # class Team
60
-
61
-
62
-
63
- end # module Model
64
- end # module SportDb
@@ -1,37 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module SportDb
4
-
5
- # collection of regex patterns for reuse (SportDb specific)
6
-
7
- ### todo: add a patterns.md page to github ??
8
- ## - add regexper pics??
9
-
10
- ############
11
- # about ruby regexps
12
- #
13
- # try the rubular - Ruby regular expression editor and tester
14
- # -> http://rubular.com
15
- # code -> ?? by ??
16
- #
17
- #
18
- # Jeff Avallone's Regexper - Shows State-Automata Diagrams
19
- # try -> http://regexper.com
20
- # code -> https://github.com/javallone/regexper
21
- #
22
- #
23
- # Regular Expressions | The Bastards Book of Ruby by Dan Nguyen
24
- # http://ruby.bastardsbook.com/chapters/regexes/
25
- #
26
- # move to notes regex|patterns on geraldb.github.io ??
27
- #
28
-
29
- TEAM_KEY_PATTERN = '\A[a-z]{3,}\z'
30
- TEAM_KEY_PATTERN_MESSAGE = "expected three or more lowercase letters a-z /#{TEAM_KEY_PATTERN}/"
31
-
32
- # must start w/ letter A-Z (2nd,3rd,4th or 5th can be number or underscore _)
33
- TEAM_CODE_PATTERN = '\A[A-Z_][A-Z0-9_]{1,4}\z'
34
- TEAM_CODE_PATTERN_MESSAGE = "expected two or three or four or five uppercase letters A-Z (and 0-9_; must start with A-Z) /#{TEAM_CODE_PATTERN}/"
35
-
36
-
37
- end # module SportDb
@@ -1,178 +0,0 @@
1
- # encoding: utf-8
2
-
3
-
4
- ##############
5
- ##
6
- ## fix/todo:
7
- ## - reuse in footballcsv/build e.g. require sportdb and remove "old" code!!!!
8
-
9
- module SportDb
10
-
11
-
12
- class StandingsLine
13
- attr_accessor :rank, :team_name,
14
- :played, :won, :lost, :drawn, ## -- total
15
- :goals_for, :goals_against, :pts,
16
- :home_played, :home_won, :home_lost, :home_drawn, ## -- home
17
- :home_goals_for, :home_goals_against, :home_pts,
18
- :away_played, :away_won, :away_lost, :away_drawn, ## -- away
19
- :away_goals_for, :away_goals_against, :away_pts
20
-
21
- def initialize( team_name )
22
- @rank = nil # use 0? why? why not?
23
- @team_name = team_name
24
- @played = @home_played = @away_played = 0
25
- @won = @home_won = @away_won = 0
26
- @lost = @home_lost = @away_lost = 0
27
- @drawn = @home_drawn = @away_drawn = 0
28
- @goals_for = @home_goals_for = @away_goals_for = 0
29
- @goals_against = @home_goals_against = @away_goals_against = 0
30
- @pts = @home_pts = @away_pts = 0
31
-
32
- ### fix: add @recs too - to count number of records (e.g. appearances/seasons etc.)
33
- end
34
- end # class StandingsLine
35
-
36
-
37
- class Standings
38
-
39
- def initialize( opts={} )
40
- ## fix:
41
- # passing in e.g. pts for win (3? 2? etc.)
42
- # default to 3 for now
43
-
44
- ## lets you pass in 2 as an alterantive, for example
45
- @pts_won = opts[:pts_won] || 3
46
-
47
- @lines = {} # StandingsLines cached by team name/key
48
- end
49
-
50
-
51
- def update( match_or_matches )
52
- puts " [debug] update match_or_matches.class.name: #{match_or_matches.class.name}"
53
-
54
- ## convenience - update all matches at once
55
- if match_or_matches.is_a?( Array ) ||
56
- match_or_matches.is_a?( ActiveRecord::Associations::CollectionProxy )
57
- matches = match_or_matches
58
- matches.each_with_index do |match,i| # note: index(i) starts w/ zero (0)
59
- update_match( match )
60
- end
61
- else
62
- match = match_or_matches
63
- update_match( match )
64
- end
65
- self # note: return self to allow chaining
66
- end
67
-
68
- def to_a
69
- ## return lines; sort and add rank
70
- ## note: will update rank!!!! (side effect)
71
-
72
- #############################
73
- ### calc ranking position (rank)
74
- ## fix/allow same rank e.g. all 1 or more than one team 3rd etc.
75
-
76
- # build array from hash
77
- ary = []
78
- @lines.each do |k,v|
79
- ary << v
80
- end
81
-
82
- ary.sort! do |l,r|
83
- ## note: reverse order (thus, change l,r to r,l)
84
- value = r.pts <=> l.pts
85
- if value == 0 # same pts try goal diff
86
- value = (r.goals_for-r.goals_against) <=> (l.goals_for-l.goals_against)
87
- if value == 0 # same goal diff too; try assume more goals better for now
88
- value = r.goals_for <=> l.goals_for
89
- end
90
- end
91
- value
92
- end
93
-
94
- ## update rank using ordered array
95
- ary.each_with_index do |line,i|
96
- line.rank = i+1 ## add ranking (e.g. 1,2,3 etc.) - note: i starts w/ zero (0)
97
- end
98
-
99
- ary
100
- end # to_a
101
-
102
-
103
- private
104
- def update_match( m ) ## add a match
105
-
106
- ## puts " #{m.team1} - #{m.team2} #{m.score_str}"
107
- unless m.over?
108
- puts " !!!! skipping match - not yet over (play_at date in the future)"
109
- return
110
- end
111
-
112
- unless m.complete?
113
- puts "!!! [calc_standings] skipping match #{m.team1_name} - #{m.team2_name} - scores incomplete #{m.score_str}"
114
- return
115
- end
116
-
117
- ### fix/todo: use team1_name n team2_name ???
118
- ### fix/todo: - add extra time and penalty shootout !!!!
119
-
120
- line1 = @lines[ m.team1_name ] || StandingsLine.new( m.team1_name )
121
- line2 = @lines[ m.team2_name ] || StandingsLine.new( m.team2_name )
122
-
123
- line1.played += 1
124
- line1.home_played += 1
125
-
126
- line2.played += 1
127
- line2.away_played += 1
128
-
129
- if m.winner == 1
130
- line1.won += 1
131
- line1.home_won += 1
132
-
133
- line2.lost += 1
134
- line2.away_lost += 1
135
-
136
- line1.pts += @pts_won
137
- line1.home_pts += @pts_won
138
- elsif m.winner == 2
139
- line1.lost += 1
140
- line1.home_lost += 1
141
-
142
- line2.won += 1
143
- line2.away_won += 1
144
-
145
- line2.pts += @pts_won
146
- line2.away_pts += @pts_won
147
- else ## assume drawn/tie (that is, 0)
148
- line1.drawn += 1
149
- line1.home_drawn += 1
150
-
151
- line2.drawn += 1
152
- line2.away_drawn += 1
153
-
154
- line1.pts += 1
155
- line1.home_pts += 1
156
- line2.pts += 1
157
- line2.away_pts += 1
158
- end
159
-
160
- line1.goals_for += m.score1
161
- line1.home_goals_for += m.score1
162
- line1.goals_against += m.score2
163
- line1.home_goals_against += m.score2
164
-
165
- line2.goals_for += m.score2
166
- line2.away_goals_for += m.score2
167
- line2.goals_against += m.score1
168
- line2.away_goals_against += m.score1
169
-
170
- @lines[ m.team1_name ] = line1
171
- @lines[ m.team2_name ] = line2
172
- end # method update_match
173
-
174
- end # class Standings
175
-
176
-
177
-
178
- end # module SportDb