sportdb-models 1.19.0 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -20
  3. data/Manifest.txt +27 -38
  4. data/README.md +31 -31
  5. data/Rakefile +32 -32
  6. data/lib/sportdb/models.rb +212 -159
  7. data/lib/sportdb/{deleter.rb → models/deleter.rb} +3 -9
  8. data/lib/sportdb/models/formats.rb +23 -0
  9. data/lib/sportdb/models/models/assoc.rb +38 -0
  10. data/lib/sportdb/models/{badge.rb → models/badge.rb} +14 -14
  11. data/lib/sportdb/models/models/event.rb +55 -0
  12. data/lib/sportdb/models/{forward.rb → models/forward.rb} +55 -55
  13. data/lib/sportdb/models/{goal.rb → models/goal.rb} +15 -15
  14. data/lib/sportdb/models/models/ground.rb +16 -0
  15. data/lib/sportdb/models/{group.rb → models/group.rb} +10 -7
  16. data/lib/sportdb/models/models/league.rb +20 -0
  17. data/lib/sportdb/models/{roster.rb → models/lineup.rb} +17 -18
  18. data/lib/sportdb/models/{game.rb → models/match.rb} +18 -61
  19. data/lib/sportdb/models/{person.rb → models/person.rb} +21 -21
  20. data/lib/sportdb/models/{round.rb → models/round.rb} +1 -6
  21. data/lib/sportdb/models/{season.rb → models/season.rb} +15 -14
  22. data/lib/sportdb/models/{stage.rb → models/stage.rb} +9 -5
  23. data/lib/sportdb/models/{stats/alltime_standing_entry.rb → models/stats/alltime_standing.rb} +9 -1
  24. data/lib/sportdb/models/{stats/event_standing_entry.rb → models/stats/event_standing.rb} +31 -21
  25. data/lib/sportdb/models/{stats/group_standing_entry.rb → models/stats/group_standing.rb} +10 -1
  26. data/lib/sportdb/models/models/team.rb +56 -0
  27. data/lib/sportdb/models/{world → models/world}/city.rb +2 -2
  28. data/lib/sportdb/models/{world → models/world}/continent.rb +20 -20
  29. data/lib/sportdb/models/{world → models/world}/country.rb +0 -0
  30. data/lib/sportdb/models/{world → models/world}/state.rb +19 -19
  31. data/lib/sportdb/models/schema.rb +466 -0
  32. data/lib/sportdb/models/stats.rb +23 -0
  33. data/lib/sportdb/models/utils.rb +24 -24
  34. data/lib/sportdb/{version.rb → models/version.rb} +27 -22
  35. data/test/helper.rb +46 -42
  36. data/test/test_changes.rb +38 -38
  37. data/test/test_cursor.rb +15 -15
  38. data/test/test_winner.rb +75 -70
  39. metadata +39 -44
  40. data/lib/sportdb/calc.rb +0 -279
  41. data/lib/sportdb/models/assoc.rb +0 -106
  42. data/lib/sportdb/models/assoc_assoc.rb +0 -15
  43. data/lib/sportdb/models/event.rb +0 -66
  44. data/lib/sportdb/models/event_ground.rb +0 -15
  45. data/lib/sportdb/models/event_team.rb +0 -16
  46. data/lib/sportdb/models/ground.rb +0 -100
  47. data/lib/sportdb/models/group_team.rb +0 -14
  48. data/lib/sportdb/models/league.rb +0 -83
  49. data/lib/sportdb/models/stage_team.rb +0 -14
  50. data/lib/sportdb/models/stats/alltime_standing.rb +0 -44
  51. data/lib/sportdb/models/stats/event_standing.rb +0 -55
  52. data/lib/sportdb/models/stats/group_standing.rb +0 -50
  53. data/lib/sportdb/models/team.rb +0 -119
  54. data/lib/sportdb/models/team_compat.rb +0 -64
  55. data/lib/sportdb/patterns.rb +0 -37
  56. data/lib/sportdb/schema.rb +0 -397
  57. data/lib/sportdb/standings.rb +0 -178
  58. data/lib/sportdb/stats.rb +0 -27
@@ -1,21 +1,21 @@
1
-
2
- #### note ---
3
- ## uses PersonDb namespace!!!!!
4
- #
5
- # move to models/person/person.rb - why? why not??
6
-
7
-
8
- module PersonDb
9
- module Model
10
-
11
- ### extends "basic" person model in PersonDb
12
- class Person
13
-
14
- has_many :goals
15
-
16
- end # class Person
17
-
18
-
19
- end # module Model
20
- end # module PersonDb
21
-
1
+
2
+ #### note ---
3
+ ## uses PersonDb namespace!!!!!
4
+ #
5
+ # move to models/person/person.rb - why? why not??
6
+
7
+
8
+ module PersonDb
9
+ module Model
10
+
11
+ ### extends "basic" person model in PersonDb
12
+ class Person
13
+
14
+ has_many :goals
15
+
16
+ end # class Person
17
+
18
+
19
+ end # module Model
20
+ end # module PersonDb
21
+
@@ -5,11 +5,7 @@ module SportDb
5
5
 
6
6
  class Round < ActiveRecord::Base
7
7
 
8
- if ActiveRecord::VERSION::MAJOR == 3
9
- has_many :games, :order => 'pos'
10
- else
11
- has_many :games, -> { order('pos') }
12
- end
8
+ has_many :matches, -> { order('pos') }, class_name: 'Match'
13
9
 
14
10
  belongs_to :event
15
11
 
@@ -19,4 +15,3 @@ end # class Round
19
15
  end # module Model
20
16
  end # module SportDb
21
17
 
22
-
@@ -1,14 +1,15 @@
1
-
2
- module SportDb
3
- module Model
4
-
5
-
6
- class Season < ActiveRecord::Base
7
-
8
- has_many :events
9
-
10
- end # class Season
11
-
12
-
13
- end # module Model
14
- end # module SportDb
1
+
2
+ module SportDb
3
+ module Model
4
+
5
+
6
+ class Season < ActiveRecord::Base
7
+
8
+ has_many :events
9
+ has_many :leagues, :through => :events
10
+
11
+ end # class Season
12
+
13
+
14
+ end # module Model
15
+ end # module SportDb
@@ -5,11 +5,7 @@ module SportDb
5
5
 
6
6
  class Stage < ActiveRecord::Base
7
7
 
8
- if ActiveRecord::VERSION::MAJOR == 3
9
- has_many :games, order: 'pos'
10
- else
11
- has_many :games, -> { order('pos') }
12
- end
8
+ has_many :matches, -> { order('pos') }, class_name: 'Match'
13
9
 
14
10
  belongs_to :event
15
11
 
@@ -18,5 +14,13 @@ end
18
14
 
19
15
  end # class Stage
20
16
 
17
+
18
+ class StageTeam < ActiveRecord::Base
19
+ self.table_name = 'stages_teams'
20
+
21
+ belongs_to :stage
22
+ belongs_to :team
23
+ end # class StageTeam
24
+
21
25
  end # module Model
22
26
  end # module SportDb
@@ -4,6 +4,15 @@ module SportDb
4
4
  module Model
5
5
 
6
6
 
7
+ class AlltimeStanding < ActiveRecord::Base
8
+
9
+ self.table_name = 'alltime_standings'
10
+
11
+ has_many :entries, class_name: 'SportDb::Model::AlltimeStandingEntry', foreign_key: 'alltime_standing_id', :dependent => :delete_all
12
+
13
+ end # class AlltimeStanding
14
+
15
+
7
16
  class AlltimeStandingEntry < ActiveRecord::Base
8
17
 
9
18
  self.table_name = 'alltime_standing_entries'
@@ -15,7 +24,6 @@ class AlltimeStandingEntry < ActiveRecord::Base
15
24
  ## map standing_id to alltime_standing_id - convenience alias
16
25
  def standing_id=(value) write_attribute(:alltime_standing_id, value); end
17
26
 
18
-
19
27
  end # class AlltimeStandingEntry
20
28
 
21
29
 
@@ -1,21 +1,31 @@
1
- # encoding: utf-8
2
-
3
- module SportDb
4
- module Model
5
-
6
- class EventStandingEntry < ActiveRecord::Base
7
-
8
- self.table_name = 'event_standing_entries'
9
-
10
- belongs_to :standing, class_name: 'SportDb::Model::EventStanding', foreign_key: 'event_standing_id'
11
- belongs_to :team
12
-
13
- ## note:
14
- ## map standing_id to group_standing_id - convenience alias
15
- def standing_id=(value) write_attribute(:event_standing_id, value); end
16
-
17
- end # class EventStandingEntry
18
-
19
-
20
- end # module Model
21
- end # module SportDb
1
+ # encoding: utf-8
2
+
3
+ module SportDb
4
+ module Model
5
+
6
+
7
+ class EventStanding < ActiveRecord::Base
8
+
9
+ self.table_name = 'event_standings'
10
+
11
+ has_many :entries, class_name: 'SportDb::Model::EventStandingEntry', foreign_key: 'event_standing_id', :dependent => :delete_all
12
+ belongs_to :event
13
+
14
+ end # class EventStanding
15
+
16
+
17
+ class EventStandingEntry < ActiveRecord::Base
18
+
19
+ self.table_name = 'event_standing_entries'
20
+
21
+ belongs_to :standing, class_name: 'SportDb::Model::EventStanding', foreign_key: 'event_standing_id'
22
+ belongs_to :team
23
+
24
+ ## note:
25
+ ## map standing_id to group_standing_id - convenience alias
26
+ def standing_id=(value) write_attribute(:event_standing_id, value); end
27
+
28
+ end # class EventStandingEntry
29
+
30
+ end # module Model
31
+ end # module SportDb
@@ -4,6 +4,16 @@ module SportDb
4
4
  module Model
5
5
 
6
6
 
7
+ class GroupStanding < ActiveRecord::Base
8
+
9
+ self.table_name = 'group_standings'
10
+
11
+ has_many :entries, class_name: 'SportDb::Model::GroupStandingEntry', foreign_key: 'group_standing_id', :dependent => :delete_all
12
+ belongs_to :group
13
+
14
+ end # class GroupStanding
15
+
16
+
7
17
  class GroupStandingEntry < ActiveRecord::Base
8
18
 
9
19
  self.table_name = 'group_standing_entries'
@@ -17,6 +27,5 @@ class GroupStandingEntry < ActiveRecord::Base
17
27
 
18
28
  end # class GroupStandingEntry
19
29
 
20
-
21
30
  end # module Model
22
31
  end # module SportDb
@@ -0,0 +1,56 @@
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_matches, class_name: 'Match', foreign_key: 'team1_id'
17
+ has_many :away_matches, class_name: 'Match', foreign_key: 'team2_id'
18
+
19
+ validates :key, format: { with: TEAM_KEY_RE, message: TEAM_KEY_MESSAGE }
20
+ validates :code, format: { with: TEAM_CODE_RE, message: TEAM_CODE_MESSAGE }, allow_nil: true
21
+
22
+ has_many :event_teams, class_name: 'EventTeam' # join table (events+teams)
23
+ has_many :events, :through => :event_teams
24
+
25
+ # note: team belongs_to a single (optinal) assoc for now (national assoc may have many assocs)
26
+ belongs_to :assoc
27
+
28
+ ### fix!!! - how to do it with has_many macro? use finder_sql?
29
+ ## finder_sql is depreciated in Rails 4!!!
30
+ # use -> { where() } etc. -- try it if it works
31
+ ## keep as is! best solution ??
32
+ ## a discussion here -> https://github.com/rails/rails/issues/9726
33
+ ## 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
34
+
35
+ def matches
36
+ Match.where( 'team1_id = ? or team2_id = ?', id, id ).order( 'date' )
37
+ end
38
+
39
+ def upcoming_matches
40
+ Match.where( 'team1_id = ? or team2_id = ?', id, id ).where( 'date > ?', Date.today ).order( 'date' )
41
+ end
42
+
43
+ def past_matches
44
+ Match.where( 'team1_id = ? or team2_id = ?', id, id ).where( 'date < ?', Date.today ).order( 'date desc' )
45
+ end
46
+
47
+
48
+ has_many :badges # Winner, 2nd, Cupsieger, Aufsteiger, Absteiger, etc.
49
+
50
+ belongs_to :country, class_name: 'WorldDb::Model::Country', foreign_key: 'country_id'
51
+ belongs_to :city, class_name: 'WorldDb::Model::City', foreign_key: 'city_id'
52
+ end # class Team
53
+
54
+
55
+ end # module Model
56
+ end # module SportDb
@@ -6,14 +6,14 @@ module WorldDb
6
6
 
7
7
  class City
8
8
  has_many :teams, class_name: 'SportDb::Model::Team', foreign_key: 'city_id'
9
-
9
+
10
10
  # fix: require active record 4
11
11
  # has_many :clubs, -> { where club: true }, class_name: 'SportDb::Model::Team', foreign_key: 'city_id'
12
12
  # has_many :national_teams, -> { where club: false }, class_name: 'SportDb::Model::Team', foreign_key: 'city_id'
13
13
 
14
14
 
15
15
  has_many :grounds, class_name: 'SportDb::Model::Ground', foreign_key: 'city_id'
16
- has_many :games, :through => :grounds
16
+ has_many :matches, class_name: 'SportDb::Model::Match', :through => :grounds
17
17
  end
18
18
 
19
19
  end # module Model
@@ -1,20 +1,20 @@
1
- # encoding: utf-8
2
-
3
- module WorldDb
4
- module Model
5
-
6
- class Continent
7
- has_many :teams, :through => :countries
8
-
9
- # fix: require active record 4
10
- # has_many :clubs, :through => :countries
11
- # has_many :national_teams, :through => :countries
12
-
13
-
14
- has_many :leagues, :through => :countries
15
- has_many :grounds, :through => :countries
16
- end # class Continent
17
-
18
- end # module Model
19
- end # module WorldDb
20
-
1
+ # encoding: utf-8
2
+
3
+ module WorldDb
4
+ module Model
5
+
6
+ class Continent
7
+ has_many :teams, :through => :countries
8
+
9
+ # fix: require active record 4
10
+ # has_many :clubs, :through => :countries
11
+ # has_many :national_teams, :through => :countries
12
+
13
+
14
+ has_many :leagues, :through => :countries
15
+ has_many :grounds, :through => :countries
16
+ end # class Continent
17
+
18
+ end # module Model
19
+ end # module WorldDb
20
+
@@ -1,19 +1,19 @@
1
- # encoding: utf-8
2
-
3
-
4
- module WorldDb
5
- module Model
6
-
7
- class State
8
- has_many :teams, class_name: 'SportDb::Model::Team', :through => :cities
9
-
10
- # fix: require active record 4
11
- # has_many :clubs, class_name: 'SportDb::Model::Team', :through => :cities
12
- # has_many :national_teams, class_name: 'SportDb::Model::Team', :through => :cities
13
-
14
- has_many :grounds, class_name: 'SportDb::Model::Ground', :through => :cities
15
- end # class State
16
-
17
- end # module Model
18
- end # module WorldDb
19
-
1
+ # encoding: utf-8
2
+
3
+
4
+ module WorldDb
5
+ module Model
6
+
7
+ class State
8
+ has_many :teams, class_name: 'SportDb::Model::Team', :through => :cities
9
+
10
+ # fix: require active record 4
11
+ # has_many :clubs, class_name: 'SportDb::Model::Team', :through => :cities
12
+ # has_many :national_teams, class_name: 'SportDb::Model::Team', :through => :cities
13
+
14
+ has_many :grounds, class_name: 'SportDb::Model::Ground', :through => :cities
15
+ end # class State
16
+
17
+ end # module Model
18
+ end # module WorldDb
19
+
@@ -0,0 +1,466 @@
1
+
2
+ module SportDb
3
+
4
+ class CreateDb
5
+
6
+ def up
7
+ ActiveRecord::Schema.define do
8
+
9
+ create_table :teams do |t|
10
+ t.string :key, null: false # import/export key
11
+ t.string :name, null: false # "canonical" unique name
12
+
13
+ t.string :code # three letter code (short name)
14
+ t.string :alt_names # comma separated list of alt names / synonyms
15
+
16
+ t.references :country, null: false, index: false
17
+ t.references :city, index: false # note: city is optional (should be required for clubs e.g. non-national teams)
18
+ t.references :district, index: false # note: optional district (in city)
19
+
20
+ ## todo/check/fix: use team type or such e.g. club/national/etc. - why? why not?
21
+ ### or remove and add virtual attribute in model instead - why? why not?
22
+ t.boolean :club, null: false, default: false # is it a club (not a national team)?
23
+ t.boolean :national, null: false, default: false # is it a national selection team (not a club)?
24
+
25
+ ## todo/fix: add team reference for a and b team!!!!
26
+
27
+
28
+ t.integer :start_year # founding year -fix change to start_year / founded - why? why not?
29
+ t.integer :end_year
30
+ ## add more? - start_year2, end_year2 - why? why not?
31
+ # e.g. founded = 1946, 2013 (refounded)
32
+ # dissolved = 1997
33
+
34
+ t.string :address
35
+ t.string :web
36
+
37
+ ## todo/fix: change to gov / governing body or such!!!
38
+ t.references :assoc, index: false # optional: national football assoc(iation), for example - used for national teams
39
+
40
+ t.string :comments
41
+
42
+ t.timestamps
43
+ end
44
+
45
+ add_index :teams, :key, unique: true
46
+
47
+
48
+ ###########
49
+ # check: use table (rename to) venues / stadiums - why? why not?
50
+ create_table :grounds do |t|
51
+ t.string :key, null: false # import/export key
52
+ t.string :name, null: false
53
+ t.string :alt_names # comma separated list of alt_names / synonyms
54
+
55
+ t.references :country, null: false, index: false
56
+ t.references :city, index: false # todo: make city required ???
57
+ t.references :district, index: false # note: optional district (in city)
58
+
59
+ t.integer :start_year # founding year
60
+ t.integer :capacity # attentence capacity e.g. 10_000 or 50_000 etc.
61
+ t.string :address
62
+
63
+ ### fix/todo: add since/founded/opened/build attrib eg. 2011 or 1987
64
+ ## - add capacity e.g. 40_000
65
+ ## fix: add address !!!! etc
66
+
67
+ ## add region ??? or just use region from city ??
68
+
69
+ t.timestamps
70
+ end
71
+
72
+ add_index :grounds, :key, unique: true
73
+
74
+
75
+ # join table: person+match(team1+team2+event(season+league))
76
+ create_table :goals do |t|
77
+ t.references :person, null: false, index: false
78
+ t.references :match, null: false, index: false
79
+ t.references :team, null: false, index: false ## use integer instead w/ values 1 or 2 for team1 or team2 ?? why? why not?
80
+
81
+ t.integer :minute
82
+ t.integer :offset, null: false, default: 0 # e.g. 45' +3 or 90' +2
83
+
84
+ t.integer :score1
85
+ t.integer :score2
86
+
87
+ ## type of goal (penalty, owngoal)
88
+ t.boolean :penalty, null: false, default: false
89
+ t.boolean :owngoal, null: false, default: false # de: Eigentor -> # todo: find better name?
90
+
91
+ t.timestamps
92
+ end
93
+
94
+
95
+ # join table -> person+team+event(season+league)
96
+ create_table :lineups do |t| # use squads as an alternative name? why? why not??
97
+ t.references :person, null: false, index: false
98
+ t.references :team, null: false, index: false
99
+ t.references :event , index: false # make required?
100
+ t.integer :num, # optional - jersey (t-shirt) number
101
+
102
+ t.timestamps
103
+ end
104
+
105
+
106
+ create_table :events do |t|
107
+ t.string :key, null: false # import/export key
108
+ t.references :league, null: false, index: false
109
+ t.references :season, null: false, index: false
110
+ t.date :start_date, null: false # note: only use date (w/o time)
111
+ t.date :end_date # note: only use date (w/o time)
112
+
113
+ t.integer :num ## optional series counter e.g. World Cup No. 2, Bundesliga No. 43 etc. etc.
114
+
115
+ ## t.boolean :team3, null: false, default: true ## e.g. Champions League has no 3rd place (only 1st and 2nd/final)
116
+ ## todo: add league/cup flag/flags or to league itself?
117
+ ## or add add a tournament type field - why? why not?
118
+
119
+ ## auto-added flag (e.g. start_at n end_at dates got calculated)
120
+ ## if auto-added flag is false - do NOT auto-update start_at, end_at etc.
121
+ t.boolean :auto, null: false, default: true
122
+
123
+
124
+ #### track 1-n sources (from repos) - # todo move to its own table later
125
+ ## NB: relative to event.yml - use mapper to "resolve" to full path w/ repo; use league+season keys
126
+ # t.string :sources # e.g. cup or bl,bl_ii # NB: for now store all in on string separated by comma
127
+ # t.string :config # e.g. cup or bl # e.g assumes cup.yml, bl.yml etc. for now
128
+
129
+
130
+ t.timestamps
131
+ end
132
+
133
+ add_index :events, :key, unique: true
134
+
135
+
136
+ create_table :rounds do |t|
137
+ t.references :event, null: false, index: false ## Note: do NOT auto-add index
138
+ t.string :name, null: false
139
+ t.integer :pos, null: false ## use only for "internal" sort order (defaults to insertion order)
140
+
141
+ t.integer :num ## optional match day/week number
142
+ t.string :key ## optional match day/week number key (as string)
143
+
144
+ ## add new table stage/stages for grouping rounds in group rounds and playoff rounds, for example???
145
+ ## # "regular" season (group) matches or post-season (playoff) knockouts (k.o's)
146
+ t.boolean :knockout, null: false, default: false
147
+ ## todo: add leg (e.g. leg1, leg2, etc. why? why not?)
148
+ t.date :start_date # note: only use date (w/o time) - fix: change to start_date!!!
149
+ t.date :end_date # note: only use date (w/o time) - fix: change to end_date!!!
150
+ t.date :start_date2 # note: only use date (w/o time) - fix: change to start_date!!!
151
+ t.date :end_date2 # note: only use date (w/o time) - fix: change to end_date!!!
152
+
153
+ ## add last_date/first-date(auto) - for "real" last and first dates - auto-added - why? why not?
154
+
155
+ ## auto-added flag (e.g. start_at n end_at dates got calculated)
156
+ ## if auto-added flag is false - do NOT auto-update start_at, end_at etc.
157
+ t.boolean :auto, null: false, default: true
158
+
159
+ t.timestamps
160
+ end
161
+
162
+ add_index :rounds, :event_id # fk event_id index
163
+
164
+
165
+ create_table :groups do |t| # Teamgruppe (zB Gruppe A, Gruppe B, etc.)
166
+ t.references :event, null: false, index: false ## Note: do NOT auto-add index
167
+ t.string :name, null: false
168
+ t.integer :pos, null: false ## use only for "internal" sort order (defaults to insertion order)
169
+
170
+ t.string :key ## optional group key e.g. A, B, C or 1, 2, etc. - use why? why not?
171
+ t.timestamps
172
+ end
173
+
174
+ add_index :groups, :event_id # fk event_id index
175
+
176
+
177
+ create_table :stages do |t| # e.g. regular season, champions round, etc.
178
+ t.references :event, null: false, index: false ## Note: do NOT auto-add index
179
+ t.string :name, null: false
180
+ ## todo/check: add pos for use only for "internal" sort order (defaults to insertion order)??
181
+ t.timestamps
182
+ end
183
+
184
+ add_index :stages, :event_id # fk event_id index
185
+
186
+
187
+
188
+ create_table :matches do |t|
189
+ t.string :key # import/export key
190
+ t.references :event, null: false, index: false
191
+ t.integer :pos, null: false ## note: use only for "internal" sort order (defaults to insertion order)
192
+ t.integer :num ## optional - "event global" match number e.g. World Cup - Match 1, Match 2, etc.
193
+ t.references :team1, null: false, index: false ## Note: do NOT auto-add index
194
+ t.references :team2, null: false, index: false ## Note: do NOT auto-add index
195
+
196
+ t.references :round, index: false ## Note: do NOT auto-add index
197
+ t.references :group, index: false ## Note: do NOT auto-add index -- group is optional
198
+ t.references :stage, index: false # optional - regular seasion / champions round etc.
199
+
200
+ ## "inline" helper keys auto-populate for easier "no-join/single-table" queries
201
+ t.string :team1_key
202
+ t.string :team2_key
203
+ t.string :event_key
204
+ t.string :round_key
205
+ t.integer :round_num ## e.g. 1,2,3 for match day/match week
206
+ t.string :group_key
207
+ t.string :stage_key
208
+
209
+
210
+ t.date :date # optional play date - todo/fix: split into play_date AND play_time!!!
211
+ t.time :time
212
+
213
+ t.boolean :postponed, null: false, default: false
214
+ ## t.date :date2 # optional old date (when postponed)
215
+ ## t.date :date3 # optional old date (when postponed twice)
216
+
217
+ t.string :status ## optional match status - note: uses UPCASE string constants for now
218
+ ## e.g. CANCELLED / ABANDONED / REPLAY / AWARDED / POSTPONED / etc.
219
+
220
+
221
+ t.references :ground, index: false # optional - stadium (lets you get city,region,country,etc)
222
+ t.references :city, index: false # optional - convenience for ground.city_id ???
223
+
224
+ ## change home to neutral - why? why not?
225
+ t.boolean :home, null: false, default: true # is team1 play at home or neutral (that is, at its home stadium)
226
+ t.boolean :knockout, null: false, default: false
227
+
228
+ t.integer :score1
229
+ t.integer :score2
230
+ t.integer :score1et # extratime - team 1 (opt)
231
+ t.integer :score2et # extratime - team 2 (opt)
232
+ t.integer :score1p # penalty - team 1 (opt)
233
+ t.integer :score2p # penalty - team 2 (opt) elfmeter (opt)
234
+ t.integer :score1i # half time / first third (opt)
235
+ t.integer :score2i # half time - team 2
236
+ t.integer :score1ii # second third (opt)
237
+ t.integer :score2ii # second third - team2 (opt)
238
+ t.references :next_match, index: false ## Note: do NOT auto-add index -- for hinspiel bei rueckspiel in knockout match
239
+ t.references :prev_match, index: false ## Note: do NOT auto-add index
240
+
241
+ t.integer :winner # 1,2,0,nil calculate on save - "real" winner (after 90 or extra time or penalty, aggregated first+second leg?)
242
+ t.integer :winner90 # 1,2,0,nil calculate on save - winner after 90 mins (or regugular play time depending on sport - add alias or find a better name!)
243
+
244
+ t.string :comments
245
+
246
+ t.timestamps
247
+ end
248
+
249
+ add_index :matches, :key, unique: true
250
+ add_index :matches, :event_id # fk event_id index
251
+ add_index :matches, :round_id # fk round_id index
252
+ add_index :matches, :group_id # fk group_id index
253
+ add_index :matches, :next_match_id # fk next_match_id index
254
+ add_index :matches, :prev_match_id # fk next_match_id index
255
+ add_index :matches, :team1_id
256
+ add_index :matches, :team2_id
257
+
258
+
259
+ # todo: remove id from join table (without extra fields)? why?? why not??
260
+ create_table :events_teams do |t|
261
+ t.references :event, null: false, index: false ## Note: do NOT auto-add index
262
+ t.references :team, null: false, index: false ## Note: do NOT auto-add index
263
+ t.timestamps
264
+ end
265
+
266
+ add_index :events_teams, [:event_id, :team_id], unique: true
267
+ add_index :events_teams, :event_id
268
+
269
+
270
+ # todo: remove id from join table (without extra fields)? why?? why not??
271
+ create_table :stages_teams do |t|
272
+ t.references :stage, null: false, index: false ## Note: do NOT auto-add index
273
+ t.references :team, null: false, index: false ## Note: do NOT auto-add index
274
+ t.timestamps
275
+ end
276
+
277
+ add_index :stages_teams, [:stage_id, :team_id], unique: true
278
+ add_index :stages_teams, :stage_id
279
+
280
+
281
+
282
+ # todo: remove id from join table (without extra fields)? why?? why not??
283
+ create_table :events_grounds do |t|
284
+ t.references :event, null: false, index: false ## Note: do NOT auto-add index
285
+ t.references :ground, null: false, index: false ## Note: do NOT auto-add index
286
+ t.timestamps
287
+ end
288
+
289
+ add_index :events_grounds, [:event_id, :ground_id], unique: true
290
+ add_index :events_grounds, :event_id
291
+
292
+
293
+
294
+ create_table :groups_teams do |t|
295
+ t.references :group, null: false, index: false ## Note: do NOT auto-add index
296
+ t.references :team, null: false, index: false ## Note: do NOT auto-add index
297
+ t.timestamps
298
+ end
299
+
300
+ add_index :groups_teams, [:group_id, :team_id], unique: true
301
+ add_index :groups_teams, :group_id
302
+
303
+
304
+ ### todo: add models and some seed data
305
+
306
+ create_table :seasons do |t| ## also used for years - add a boolean year true/false flag too - why? why not?
307
+ t.string :key, null: false
308
+ t.string :name, null: false # e.g. 2011/12, 2012/13 ### what to do w/ 2012? for world cup etc?
309
+ t.timestamps
310
+ end
311
+
312
+
313
+ create_table :leagues do |t| ## also for cups/conferences/tournaments/world series/etc.
314
+ t.string :key, null: false
315
+ t.string :name, null: false # e.g. Premier League, Deutsche Bundesliga, World Cup, Champions League, etc.
316
+ t.string :alt_names # comma separated list of alt names / synonyms
317
+
318
+ t.references :country, index: false ## optional for now ### todo: create "virtual" country for international leagues e.g. use int? or world (ww?)/europe (eu)/etc. similar? already taken??
319
+
320
+ ## fix: rename to :clubs from :club - why? why not?
321
+ ## fix: rename to :intl from :international - why? why not? shorter? better?
322
+ ## todo/check: flip clup to league flag? why? why not?
323
+ t.boolean :clubs, null: false, default: false # club teams or national teams?
324
+ t.boolean :intl, null: false, default: false # national league or international?
325
+ t.boolean :cup, null: false, default: false ## or regular season league?? use a tournament type field with enums - why? why not?
326
+
327
+ t.integer :level ## use tier? e.g. level 1, level 2, etc.
328
+
329
+ t.integer :start_year
330
+ t.integer :end_year
331
+
332
+ ## todo: add t.boolean :national flag? for national teams?
333
+ t.timestamps
334
+ end
335
+
336
+
337
+ create_table :badges do |t|
338
+ t.references :team, null: false, index: false
339
+ ## todo/fix: use event insead of league+season ??
340
+ ## t.references :event, :null => false # event => league+season
341
+ t.references :league, null: false, index: false
342
+ t.references :season, null: false, index: false
343
+ t.string :name, null: false # Meister, Weltmeister, Europameister, Cupsieger, Vize-Meister, Aufsteiger, Absteiger, etc.
344
+ t.timestamps
345
+ end
346
+
347
+
348
+ create_table :assocs do |t|
349
+ t.string :key, null: false
350
+ t.string :name, null: false # e.g. Premier League, Deutsche Bundesliga, World Cup, Champions League, etc.
351
+
352
+ t.integer :start_year # founding year
353
+ t.string :web
354
+
355
+ ### if national assoc - has (optional) country ref
356
+ t.references :country, index: false # note: optional - only used/set (required) for national assocs (or subnational too?)
357
+ t.boolean :national, null: false, default: false
358
+
359
+ ## add :world flag for FIFA? - just check if parent is null? for root assoc(s)? why? why not?
360
+ ## add :regional flag for continental subdivision?
361
+ ## todo: shorten to contl and intercontl - why? why not?
362
+ t.boolean :continental, null: false, default: false
363
+ t.boolean :intercontinental, null: false, default: false # e.g. arab football league (africa+western asia/middle east)
364
+ t.timestamps
365
+ end
366
+
367
+ add_index :assocs, :key, unique: true
368
+
369
+
370
+
371
+ create_table :assocs_assocs do |t|
372
+ t.references :assoc1, null: false, index: false ## Note: do NOT auto-add index -- parent assoc
373
+ t.references :assoc2, null: false, index: false ## Note: do NOT auto-add index -- child assoc is_member_of parent assoc
374
+ t.timestamps
375
+ end
376
+
377
+ add_index :assocs_assocs, [:assoc1_id,:assoc2_id], unique: true
378
+ add_index :assocs_assocs, :assoc1_id
379
+ add_index :assocs_assocs, :assoc2_id
380
+
381
+
382
+
383
+ ############################################
384
+ # stats tables
385
+
386
+ # use tables for standings e.g group_tables? - why? why not?
387
+ #
388
+ # todo: add group_standings per round with pos diffs e.g +1,+2, -3 etc.
389
+
390
+ create_table :group_standings do |t|
391
+ t.references :group, null: false, index: false
392
+ t.timestamps
393
+ end
394
+
395
+ ### use items or lines instead of entries - why (shorter! simple plural e.g. just add s)
396
+ ## use group_table_lines/stats - why? why not?
397
+
398
+ create_table :group_standing_entries do |t|
399
+ t.references :group_standing, null: false, index: false
400
+ t.references :team, null: false, index: false
401
+ t.integer :pos # check/todo: use rank? -- keep/use pos only for "internal" insertation order only - why? why not?
402
+ t.integer :played ## p/pld
403
+ t.integer :won ## w
404
+ t.integer :lost ## l
405
+ t.integer :drawn ## d or t/tied ??
406
+ t.integer :goals_for # todo: find a short name - gf? why? why not?
407
+ t.integer :goals_against # todo: find a shorter name - ga? why? why not?
408
+ t.integer :pts
409
+ t.string :comments
410
+ t.timestamps
411
+ end
412
+
413
+
414
+ create_table :event_standings do |t|
415
+ t.references :event, null: false, index: false
416
+ t.timestamps
417
+ end
418
+
419
+ create_table :event_standing_entries do |t|
420
+ t.references :event_standing, null: false, index: false
421
+ t.references :team, null: false, index: false
422
+ t.integer :pos
423
+ t.integer :played
424
+ t.integer :won
425
+ t.integer :lost
426
+ t.integer :drawn
427
+ t.integer :goals_for # todo: find a short name - gf? or for? why? why not?
428
+ t.integer :goals_against # todo: find a shorter name - ga? or against? why? why not?
429
+ t.integer :pts
430
+ t.string :comments
431
+ t.timestamps
432
+ end
433
+
434
+
435
+ ## flex (free-style/form) standings table - lets you add as many events as you like (not bound to single event/season/etc.)
436
+ ## -use (find a better) a different name? why? why not?
437
+ create_table :alltime_standings do |t|
438
+ t.string :key, null: false
439
+ t.string :name, null: false
440
+ t.timestamps
441
+ end
442
+
443
+ create_table :alltime_standing_entries do |t|
444
+ t.references :alltime_standing, null: false, index: false
445
+ t.references :team, null: false, index: false
446
+ t.integer :pos
447
+ t.integer :played # todo: use a different name - why? why not?
448
+ t.integer :won
449
+ t.integer :lost
450
+ t.integer :drawn
451
+ t.integer :goals_for # todo: find a short name - gf? why? why not?
452
+ t.integer :goals_against # todo: find a shorter name - ga? why? why not?
453
+ t.integer :pts
454
+ t.integer :recs # note: specific to alltime - stats records counter (e.g. appearance counter) - find a better name - why? why not?
455
+ t.string :comments
456
+ t.timestamps
457
+ end
458
+
459
+
460
+ end # Schema.define
461
+ end # method up
462
+
463
+
464
+ end # class CreateDb
465
+
466
+ end # module SportDb