sportdb-sync 0.1.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9189544ea7204fc5b6f2f11ee1c73dfc6c052a26
4
- data.tar.gz: 22c9e9825e8af300213bdaa222bcf1ee457477fe
3
+ metadata.gz: 397b58e2e8ed6c6c747f9ac04885cf7040152e83
4
+ data.tar.gz: 99f0d69e4f45a7c000325268e4d63bec53af8941
5
5
  SHA512:
6
- metadata.gz: fdb749934627aeca879237a42ba50f7284a8c25eef611208b8aea00f9209655e705dbab01c5ae2a0a7bc51509db2c3ed465a26dfc0c60a12e8e73b6dac26caf6
7
- data.tar.gz: 5a4005e89e00f18b339198f545b2fa3402531fcc6e4798399defcbc0d2d42f1c7a79f6757e10e85a2667c77d421883d4f80f976240bfeb5e2d2f02f2d5b85740
6
+ metadata.gz: cb1cb72c8ee98549af0ed85879ba8e5490afae58747a2ddd25356f3886e5d72672a0f1badda739baed05646e5b2ceceefe2f0b7a4bfb932ff6425a4a7dedccc6
7
+ data.tar.gz: 93cee1c25615d5fcce27b414f2bd964f411ddf3f110ca15863631c44ae38b14b11585e206dbd966a68f68391a1ae116cb5b584105f341a4f2ba38aa9565587df
@@ -3,7 +3,14 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  lib/sportdb/sync.rb
6
+ lib/sportdb/sync/club.rb
7
+ lib/sportdb/sync/country.rb
8
+ lib/sportdb/sync/event.rb
9
+ lib/sportdb/sync/league.rb
10
+ lib/sportdb/sync/season.rb
6
11
  lib/sportdb/sync/sync.rb
7
12
  lib/sportdb/sync/version.rb
8
13
  test/helper.rb
9
- test/test_sync.rb
14
+ test/test_country.rb
15
+ test/test_league.rb
16
+ test/test_misc.rb
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require './lib/sportdb/sync/version.rb'
3
3
 
4
4
  Hoe.spec 'sportdb-sync' do
5
5
 
6
- self.version = SportDb::Sync::VERSION
6
+ self.version = SportDb::Module::Sync::VERSION
7
7
 
8
8
  self.summary = "sportdb-sync - sport.db sync helpers for leagues, seasons, clubs, match schedules and results, and more"
9
9
  self.description = summary
@@ -20,9 +20,8 @@ Hoe.spec 'sportdb-sync' do
20
20
  self.licenses = ['Public Domain']
21
21
 
22
22
  self.extra_deps = [
23
- ['sportdb-clubs', '>= 0.2.3'],
24
- ['sportdb-leagues', '>= 0.2.1'],
25
- ['sportdb-models', '>= 1.18.2'],
23
+ ['sportdb-config', '>= 1.1.0'],
24
+ ['sportdb-models', '>= 2.0.1'],
26
25
  ]
27
26
 
28
27
  self.spec_extras = {
@@ -1,10 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
-
4
- require 'sportdb/clubs'
5
- require 'sportdb/leagues'
6
-
7
-
3
+ require 'sportdb/config'
8
4
  require 'sportdb/models' ## add sql database support
9
5
 
10
6
 
@@ -12,7 +8,12 @@ require 'sportdb/models' ## add sql database support
12
8
  ###
13
9
  # our own code
14
10
  require 'sportdb/sync/version' # let version always go first
11
+ require 'sportdb/sync/country'
12
+ require 'sportdb/sync/league'
13
+ require 'sportdb/sync/season'
14
+ require 'sportdb/sync/event'
15
+ require 'sportdb/sync/club'
15
16
  require 'sportdb/sync/sync'
16
17
 
17
18
 
18
- puts SportDb::Sync.banner # say hello
19
+ puts SportDb::Module::Sync.banner # say hello
@@ -0,0 +1,87 @@
1
+ module SportDb
2
+ module Sync
3
+ class Club
4
+
5
+ ## auto-cache all clubs by find_or_create for later mapping / lookup
6
+ def self.cache() @cache ||= {}; end
7
+
8
+
9
+ def self.club( q, league: nil) ## "internal" search helper using catalog
10
+ ## note: league.country might return nil (e.g. for intl leagues)
11
+ country = league ? league.country : nil
12
+ club = Import.catalog.clubs.find_by( name: q, country: country )
13
+
14
+ if club.nil?
15
+ ## todo/check: exit if no match - why? why not?
16
+ puts "!!! *** ERROR *** no matching club found for >#{q}< - add to clubs setup"
17
+ exit 1
18
+ end
19
+ club
20
+ end
21
+
22
+ #############################
23
+ # searchers
24
+
25
+ ## todo/fix - move array support for now to attic!!!
26
+
27
+ def self.search_or_create_by!( name:, league: nil, season: nil )
28
+ ## note: season is for now optional (and unused) - add/use in the future!!!
29
+
30
+ ## note: allow search by single name/q
31
+ ## or allow search by list/array of names/qs tooo!!!
32
+ if name.is_a?( Array )
33
+ ## assume batch search return array of mappings
34
+ club_recs = []
35
+ name.each do |q|
36
+ club = club( q, league: league )
37
+ clubs_recs << find_or_create( club )
38
+ end
39
+ club_recs
40
+ else
41
+ ## assume single search
42
+ q = name
43
+ club = club( q, league: league )
44
+ find_or_create( club )
45
+ end
46
+ end
47
+
48
+
49
+ ##################################
50
+ # finders
51
+
52
+ def self.find_or_create( club )
53
+ ## note: assume "canonical uniquie" names for now for clubs
54
+ rec = Model::Team.find_by( name: club.name )
55
+ if rec.nil?
56
+
57
+ ## todo/fix: move auto-key gen to structs for re(use)!!!!!!
58
+ ## check if key is present otherwise generate e.g. remove all non-ascii a-z chars
59
+ key = club.key || club.name.downcase.gsub( /[^a-z]/, '' )
60
+ puts "add club: #{key}, #{club.name}, #{club.country.name} (#{club.country.key})"
61
+
62
+ attribs = {
63
+ key: key,
64
+ name: club.name,
65
+ country_id: Sync::Country.find_or_create( club.country ).id,
66
+ club: true,
67
+ national: false ## check -is default anyway - use - why? why not?
68
+ ## todo/fix: add city if present - why? why not?
69
+ }
70
+
71
+ attribs[:code] = club.code if club.code ## add code (abbreviation) if present
72
+
73
+ if club.alt_names.empty? == false
74
+ attribs[:alt_names] = club.alt_names.join('|')
75
+ end
76
+
77
+ rec = Model::Team.create!( attribs )
78
+ end
79
+ ## auto-add to cache
80
+ cache[club.name] = rec
81
+
82
+ rec
83
+ end
84
+
85
+ end # class Club
86
+ end # module Sync
87
+ end # module SportDb
@@ -0,0 +1,72 @@
1
+ module SportDb
2
+ module Sync
3
+ class Country
4
+
5
+ ### todo/fix:
6
+ ## add ALTERNATE / ALTERNATIVE COUNTRY KEYS!!!!
7
+ ## e.g. d => de, a => at, en => eng, etc.
8
+ ## plus add all fifa codes too aut => at, etc. - why? why not?
9
+
10
+ def self.country( q )
11
+ ## note: use built-in countries for mapping country keys/codes
12
+ country = Import.catalog.countries.find( q )
13
+ if country
14
+ ## todo/check: keep key mapping warning - useful? why? why not?
15
+ if country.key != q.to_s
16
+ puts "** note: mapping (normalizing) country key >#{q}< to >#{country.key}<"
17
+ end
18
+ else
19
+ puts "** !!! ERROR !!! unknown / invalid country for key >#{q}<; sorry - add to COUNTRIES table"
20
+ exit 1
21
+ end
22
+ country
23
+ end
24
+
25
+ ########################
26
+ # searchers
27
+
28
+ def self.search!( q )
29
+ country = country( q )
30
+ find!( country )
31
+ end
32
+
33
+ def self.search_or_create!( q )
34
+ country = country( q )
35
+ find_or_create( country )
36
+ end
37
+
38
+ #############################
39
+ # finders
40
+
41
+ def self.find( country )
42
+ WorldDb::Model::Country.find_by( key: country.key )
43
+ end
44
+
45
+ def self.find!( country )
46
+ rec = find( country )
47
+ if rec.nil?
48
+ puts "** !!! ERROR !!! - country for key >#{country.key}< not found; sorry - add to COUNTRIES table"
49
+ exit 1
50
+ end
51
+ rec
52
+ end
53
+
54
+ def self.find_or_create( country )
55
+ rec = find( country )
56
+ if rec.nil?
57
+ attribs = {
58
+ key: country.key,
59
+ name: country.name,
60
+ code: country.code, ## fix: uses fifa code now (should be iso-alpha3 if available)
61
+ ## fifa: country.fifa,
62
+ area: 1,
63
+ pop: 1
64
+ }
65
+ rec = WorldDb::Model::Country.create!( attribs )
66
+ end
67
+ rec
68
+ end
69
+ end # class Country
70
+
71
+ end # module Sync
72
+ end # module SportDb
@@ -0,0 +1,97 @@
1
+ module SportDb
2
+ module Sync
3
+
4
+ class Event
5
+ def self.league( q ) League.league( q ); end
6
+ def self.season( q ) Season.season( q ); end
7
+
8
+ ############################################
9
+ # searchers
10
+
11
+ def self.search_by!( league:, season: )
12
+ raise ArgumentError.new( "league query string expected; got #{league.class.name}" ) unless league.is_a?( String )
13
+ raise ArgumentError.new( "season query string expected; got #{season.class.name}" ) unless season.is_a?( String )
14
+
15
+ league = league( league )
16
+ season = season( season )
17
+
18
+ find_by( league: league, season: season )
19
+ end
20
+
21
+ def self.search_or_create_by!( league:, season: )
22
+ raise ArgumentError.new( "league query string expected; got #{league.class.name}" ) unless league.is_a?( String )
23
+ raise ArgumentError.new( "season query string expected; got #{season.class.name}" ) unless season.is_a?( String )
24
+
25
+ league = league( league )
26
+ season = season( season )
27
+
28
+ find_or_create_by( league: league, season: season )
29
+ end
30
+
31
+ ##################################################
32
+ # finders
33
+
34
+ def self.find_by( league:, season: )
35
+ ## note: allow passing in of activerecord db records too - why? why not?
36
+ raise ArgumentError.new( "league struct record expected; got #{league.class.name}" ) unless league.is_a?( Import::League )
37
+ raise ArgumentError.new( "season struct record expected; got #{season.class.name}" ) unless season.is_a?( Import::Season )
38
+
39
+ ## auto-create league and season (db) records if missing? - why? why not?
40
+ season_rec = Season.find( season )
41
+ league_rec = League.find( league )
42
+
43
+ rec = nil
44
+ rec = Model::Event.find_by( league_id: league_rec.id,
45
+ season_id: season_rec.id ) if season_rec && league_rec
46
+ rec
47
+ end
48
+
49
+ def self.find_by!( league:, season: )
50
+ rec = find_by( league: league, season: season )
51
+ if rec.nil?
52
+ puts "** !!!ERROR!!! db sync - no event match found for:"
53
+ pp league
54
+ pp season
55
+ exit 1
56
+ end
57
+ rec
58
+ end
59
+
60
+ def self.find_or_create_by( league:, season: )
61
+ ## note: allow passing in of activerecord db records too - why? why not?
62
+ raise ArgumentError.new( "league struct record expected; got #{league.class.name}" ) unless league.is_a?( Import::League )
63
+ raise ArgumentError.new( "season struct record expected; got #{season.class.name}" ) unless season.is_a?( Import::Season )
64
+
65
+ ## note: auto-creates league and season (db) records if missing - why? why not?
66
+ season_rec = Season.find_or_create( season )
67
+ league_rec = League.find_or_create( league )
68
+
69
+ rec = Model::Event.find_by( league_id: league_rec.id,
70
+ season_id: season_rec.id )
71
+ if rec.nil?
72
+ attribs = {
73
+ league_id: league_rec.id,
74
+ season_id: season_rec.id,
75
+ }
76
+
77
+ ## quick hack/change later !!
78
+ ## todo/fix: check season - if is length 4 (single year) use 2017, 1, 1
79
+ ## otherwise use 2017, 7, 1
80
+ ## start_at use year and 7,1 e.g. Date.new( 2017, 7, 1 )
81
+ ## hack: fix/todo1!!
82
+ ## add "fake" start_date for now
83
+ attribs[:start_date] = if season.year? ## e.g. assume 2018 etc.
84
+ Date.new( season.start_year, 1, 1 )
85
+ else ## assume 2014/15 etc.
86
+ Date.new( season.start_year, 7, 1 )
87
+ end
88
+
89
+ rec = Model::Event.create!( attribs )
90
+ end
91
+ rec
92
+ end
93
+ end # class Event
94
+
95
+ end # module Sync
96
+ end # module SportDb
97
+
@@ -0,0 +1,58 @@
1
+ module SportDb
2
+ module Sync
3
+ class League
4
+
5
+ def self.league( q ) ## todo/check: find a better or "generic" alias name e.g. convert/builtin/etc. - why? why not?
6
+ Import.catalog.leagues.find!( q ) ## todo/fix: change find to search!!!
7
+ end
8
+
9
+
10
+ ################################
11
+ # searchers
12
+
13
+ def self.search!( q ) ## note: use search for passing in string queries (and find for records/structs only)
14
+ league = league( q )
15
+ find( league )
16
+ end
17
+
18
+ def self.search_or_create!( q )
19
+ league = league( q )
20
+ find_or_create( league )
21
+ end
22
+
23
+ ###################################
24
+ # finders
25
+
26
+ def self.find( league )
27
+ Model::League.find_by( key: league.key )
28
+ end
29
+
30
+ def self.find!( league )
31
+ rec = find( league )
32
+ if rec.nil?
33
+ puts "** !!!ERROR!!! db sync - no league match found for:"
34
+ pp league
35
+ exit 1
36
+ end
37
+ rec
38
+ end
39
+
40
+ def self.find_or_create( league )
41
+ rec = find( league )
42
+ if rec.nil?
43
+ attribs = { key: league.key,
44
+ name: league.name }
45
+
46
+ if league.country
47
+ attribs[ :country_id ] = Sync::Country.find_or_create( league.country ).id
48
+ end
49
+
50
+ rec = Model::League.create!( attribs )
51
+ end
52
+ rec
53
+ end
54
+
55
+ end # class League
56
+ end # module Sync
57
+ end # module SportDb
58
+
@@ -0,0 +1,54 @@
1
+ module SportDb
2
+ module Sync
3
+ class Season
4
+ def self.season( q ) ## helper for season key (rename to norm_key ???)
5
+ Import::Season.new( q )
6
+ end
7
+
8
+
9
+ ###########
10
+ # searchers
11
+
12
+ def self.search( q ) ## e.g. '2017/18'
13
+ season = season( q )
14
+ find( season )
15
+ end
16
+
17
+ ## todo/fix: remove builtin marker? - there are no "builtin" seasons like numbers all excepted for now
18
+ def self.search_or_create( q ) ## e.g. '2017-18'
19
+ season = season( q )
20
+ find_or_create( season )
21
+ end
22
+
23
+ ################
24
+ # finders
25
+
26
+ def self.find( season )
27
+ season = season( season ) if season.is_a?( String ) ## auto-convert for now (for old compat) - why? why not?
28
+ Model::Season.find_by( key: season.key )
29
+ end
30
+
31
+ def self.find!( season )
32
+ season = season( season ) if season.is_a?( String ) ## auto-convert for now (for old compat) - why? why not?
33
+ rec = find( season )
34
+ if rec.nil?
35
+ puts "** !!!ERROR!!! db sync - no season match found for >#{season.key}<:"
36
+ exit 1
37
+ end
38
+ rec
39
+ end
40
+
41
+ def self.find_or_create( season )
42
+ season = season( season ) if season.is_a?( String ) ## auto-convert for now (for old compat) - why? why not?
43
+ rec = find( season )
44
+ if rec.nil?
45
+ attribs = { key: season.key,
46
+ name: season.name }
47
+ rec = Model::Season.create!( attribs )
48
+ end
49
+ rec
50
+ end
51
+ end # class Season
52
+ end # module Sync
53
+ end # module SportDb
54
+
@@ -1,191 +1,115 @@
1
1
  # encoding: utf-8
2
2
 
3
-
4
3
  module SportDb
5
-
6
- module Sync
7
- class Country
8
- def self.find_or_create( country )
9
- rec = WorldDb::Model::Country.find_by( key: country.key )
10
- if rec.nil?
11
- attribs = {
12
- key: country.key,
13
- name: country.name,
14
- code: country.fifa, ## fix: uses fifa code now (should be iso-alpha3 if available)
15
- fifa: country.fifa,
16
- area: 1,
17
- pop: 1
18
- }
19
- rec = WorldDb::Model::Country.create!( attribs )
20
- end
21
- rec
22
- end
23
- end # class Country
4
+ module Sync
24
5
 
25
6
 
26
- class League
27
- def self.find( league )
28
- SportDb::Model::League.find_by( key: league.key )
29
- end
30
- def self.find!( league )
31
- rec = find( league )
7
+ class NationalTeam
8
+ def self.find_or_create( team )
9
+ rec = Model::Team.find_by( name: team.name )
32
10
  if rec.nil?
33
- puts "** !!!ERROR!!! db sync - no league match found for:"
34
- pp league
35
- exit 1
36
- end
37
- rec
38
- end
11
+ puts "add national team: #{team.key}, #{team.name}, #{team.country.name} (#{team.country.key})"
39
12
 
40
- def self.find_or_create( league )
41
- rec = find( league )
42
- if rec.nil?
43
- ## use title and not name - why? why not?
44
- ## quick fix: change name to title
45
- attribs = { key: league.key,
46
- title: league.name }
47
- if league.country
48
- attribs[ :country_id ] = Country.find_or_create( league.country ).id
49
- end
50
-
51
- rec = SportDb::Model::League.create!( attribs )
52
- end
53
- rec
54
- end
55
- end # class League
56
-
57
-
58
- class Season
59
- def self.normalize_key( key ) ## helper for season key (rename to norm_key ???)
60
- ## note: "normalize" season key
61
- ## always use 2017/18 (and not 2017-18 or 2017-2018 or 2017/2018)
62
- ## 1) change 2017-18 to 2017/18
63
- key = key.tr( '-', '/' )
64
- ## 2) check for 2017/2018 - change to 2017/18
65
- if key.length == 9
66
- key = "#{key[0..3]}/#{key[7..8]}"
67
- end
68
- key
69
- end
13
+ ### note: key expected three or more lowercase letters a-z /\A[a-z]{3,}\z/
14
+ attribs = {
15
+ key: team.key, ## note: always use downcase fifa code for now!!!
16
+ name: team.name,
17
+ code: team.code,
18
+ country_id: Sync::Country.find_or_create( team.country ).id,
19
+ club: false,
20
+ national: true ## check -is default anyway - use - why? why not?
21
+ }
70
22
 
71
- def self.find( key )
72
- key = normalize_key( key )
73
- SportDb::Model::Season.find_by( key: key )
74
- end
75
- def self.find!( key )
76
- rec = find( key )
77
- if rec.nil?
78
- puts "** !!!ERROR!!! db sync - no season match found for >#{normalize_key(key)}<:"
79
- pp key
80
- exit 1
81
- end
82
- rec
83
- end
23
+ if team.alt_names.empty? == false
24
+ attribs[:alt_names] = team.alt_names.join('|')
25
+ end
84
26
 
85
- def self.find_or_create( key ) ## e.g. key = '2017/18'
86
- rec = find( key )
87
- if rec.nil?
88
- key = normalize_key( key ) ## note: do NOT forget to normalize key e.g. always use slash (2019/20) etc.
89
- attribs = { key: key,
90
- title: key }
91
- rec = SportDb::Model::Season.create!( attribs )
27
+ rec = Model::Team.create!( attribs )
92
28
  end
93
29
  rec
94
30
  end
95
- end # class Season
96
-
97
- class Club
98
- def self.find_or_create( club )
99
- rec = SportDb::Model::Team.find_by( title: club.name )
100
- if rec.nil?
101
- ## check if key is present otherwise generate e.g. remove all non-ascii a-z chars
102
- key = club.key || club.name.downcase.gsub( /[^a-z]/, '' )
103
- puts "add club: #{key}, #{club.name}, #{club.country.name} (#{club.country.key})"
104
-
105
- attribs = {
106
- key: key,
107
- title: club.name,
108
- country_id: Country.find_or_create( club.country ).id,
109
- club: true,
110
- national: false ## check -is default anyway - use - why? why not?
111
- ## todo/fix: add city if present - why? why not?
112
- }
31
+ end # class NationalTeam
113
32
 
114
- attribs[:code] = club.code if club.code ## add code (abbreviation) if present
115
33
 
34
+ class Team
35
+ ## auto-cache all clubs by find_or_create for later mapping / lookup
36
+ def self.cache() @cache ||= {}; end
116
37
 
117
- if club.alt_names.empty? == false
118
- attribs[:synonyms] = club.alt_names.join('|')
38
+ def self.find_or_create( team_or_teams )
39
+ if team_or_teams.is_a?( Array )
40
+ recs = []
41
+ teams = team_or_teams
42
+ teams.each do |team|
43
+ recs << __find_or_create( team )
119
44
  end
120
-
121
- rec = SportDb::Model::Team.create!( attribs )
45
+ recs
46
+ else # assome single rec
47
+ team = team_or_teams
48
+ __find_or_create( team )
122
49
  end
123
- rec
124
50
  end
125
- end # class Club
126
51
 
127
- class Event
128
- def self.find( league:, season: )
129
- SportDb::Model::Event.find_by( league_id: league.id, season_id: season.id )
130
- end
131
- def self.find!( league:, season: )
132
- rec = find( league: league, season: season )
133
- if rec.nil?
134
- puts "** !!!ERROR!!! db sync - no event match found for:"
135
- pp league
136
- pp season
137
- exit 1
138
- end
139
- rec
52
+ def self.__find_or_create( team ) ## todo/check: use find_or_create_worker instead of _find - why? why not?
53
+ rec = if team.is_a?( Import::NationalTeam )
54
+ NationalTeam.find_or_create( team )
55
+ else ## assume Club
56
+ Club.find_or_create( team )
57
+ end
58
+ cache[ team.name ] = rec ## note: assume "canonical" unique team name
59
+ rec
140
60
  end
61
+ end # class Team
141
62
 
142
- def self.find_or_create( league:, season: )
143
- rec = find( league: league, season: season )
144
- if rec.nil?
145
- ## quick hack/change later !!
146
- ## todo/fix: check season - if is length 4 (single year) use 2017, 1, 1
147
- ## otherwise use 2017, 7, 1
148
- ## start_at use year and 7,1 e.g. Date.new( 2017, 7, 1 )
149
- ## hack: fix/todo1!!
150
- ## add "fake" start_at date for now
151
- if season.key.size == '4' ## e.g. assume 2018 etc.
152
- year = season.key.to_i
153
- start_at = Date.new( year, 1, 1 )
154
- else ## assume 2014/15 etc.
155
- year = season.key[0..3].to_i
156
- start_at = Date.new( year, 7, 1 )
157
- end
158
-
159
- attribs = {
160
- league_id: league.id,
161
- season_id: season.id,
162
- start_at: start_at }
163
63
 
164
- rec = SportDb::Model::Event.create!( attribs )
165
- end
166
- rec
167
- end
168
- end # class Event
169
64
 
170
65
  class Round
171
66
  def self.find_or_create( round, event: )
172
- rec = SportDb::Model::Round.find_by( title: round.title, event_id: event.id )
67
+ rec = Model::Round.find_by( name: round.name, event_id: event.id )
173
68
  if rec.nil?
69
+ ## find last pos - check if it can be nil?
70
+ max_pos = Model::Round.where( event_id: event.id ).maximum( 'pos' )
71
+ max_pos = max_pos ? max_pos+1 : 1
72
+
174
73
  attribs = { event_id: event.id,
175
- title: round.title,
176
- pos: round.pos,
177
- start_at: event.start_at.to_date
74
+ name: round.name,
75
+ pos: max_pos
178
76
  }
179
- rec = SportDb::Model::Round.create!( attribs )
77
+
78
+ ## todo/fix: check if round has (optional) start or end date and add!!!
79
+ ## attribs[ :start_date] = round.start_date.to_date
80
+
81
+ rec = Model::Round.create!( attribs )
180
82
  end
181
83
  rec
182
84
  end
183
85
  end # class Round
184
86
 
185
87
 
88
+ class Group
89
+ def self.find_or_create( group, event: )
90
+ rec = Model::Group.find_by( name: group.name, event_id: event.id )
91
+ if rec.nil?
92
+ ## find last pos - check if it can be nil?
93
+ max_pos = Model::Group.where( event_id: event.id ).maximum( 'pos' )
94
+ max_pos = max_pos ? max_pos+1 : 1
95
+
96
+ attribs = { event_id: event.id,
97
+ name: group.name,
98
+ pos: max_pos
99
+ }
100
+
101
+ ## todo/fix: check/add optional group key (was: pos before)!!!!
102
+ rec = Model::Group.create!( attribs )
103
+ end
104
+ ## todo/fix: add/update teams in group too!!!!!
105
+ rec
106
+ end
107
+ end # class Group
108
+
109
+
186
110
  class Stage
187
111
  def self.find( name, event: )
188
- SportDb::Model::Stage.find_by( title: name, event_id: event.id )
112
+ Model::Stage.find_by( name: name, event_id: event.id )
189
113
  end
190
114
  def self.find!( name, event: )
191
115
  rec = find( name, event: event )
@@ -201,12 +125,10 @@ module Sync
201
125
  def self.find_or_create( name, event: )
202
126
  rec = find( name, event: event )
203
127
  if rec.nil?
204
- ## use title and not name - why? why not?
205
- ## quick fix: change name to title
206
128
  attribs = { event_id: event.id,
207
- title: name,
129
+ name: name,
208
130
  }
209
- rec = SportDb::Model::Stage.create!( attribs )
131
+ rec = Model::Stage.create!( attribs )
210
132
  end
211
133
  rec
212
134
  end
@@ -214,26 +136,68 @@ module Sync
214
136
 
215
137
 
216
138
 
217
- class Match ## todo/check: add alias for Game class - why? why not?
139
+ class Match
218
140
  def self.create_or_update( match, event: )
219
141
  ## note: MUST find round, thus, use bang (!)
220
- round_rec = SportDb::Model::Round.find_by!( event_id: event.id,
221
- title: match.round.title )
222
142
 
223
- rec = SportDb::Model::Game.find_by( round_id: round_rec.id,
224
- team1_id: match.team1.id,
225
- team2_id: match.team2.id )
143
+ ## todo/check: allow strings too - why? why not?
144
+
145
+ ## query for round - allow string or round rec
146
+ round_name = match.round.is_a?( String ) ? match.round : match.round.name
147
+ round_rec = Model::Round.find_by!( event_id: event.id,
148
+ name: round_name )
149
+
150
+ ## todo/check: allow fallback with db lookup if NOT found in cache - why? why not?
151
+ ## or better use Sync::Team.find_or_create( team ) !!!!!!! to auto-create on first hit!
152
+ ## || Team.find_or_create( team1 ) -- note: does NOT work for string (only recs) - what to do?
153
+ ## || Model::Team.find_by!( name: team1_name )
154
+ team1_name = match.team1.is_a?( String ) ? match.team1 : match.team1.name
155
+ team1_rec = Team.cache[ team1_name ]
156
+ team2_name = match.team2.is_a?( String ) ? match.team2 : match.team2.name
157
+ team2_rec = Team.cache[ team2_name ]
158
+
159
+ ## check optional group (e.g. Group A, etc.)
160
+ group_rec = if match.group
161
+ group_name = match.group.is_a?( String ) ? match.group : match.group.name
162
+ Model::Group.find_by!( event_id: event.id,
163
+ name: group_name )
164
+ else
165
+ nil
166
+ end
167
+
168
+ ## check optional stage (e.g. Regular, Play Off, Relegation, etc. )
169
+ stage_rec = if match.stage
170
+ stage_name = match.stage.is_a?( String ) ? match.stage : match.stage.name
171
+ Model::Stage.find_by!( event_id: event.id,
172
+ name: stage_name )
173
+ else
174
+ nil
175
+ end
176
+
177
+ ### todo/check: what happens if there's more than once match? exception raised??
178
+ rec = Model::Match.find_by( round_id: round_rec.id,
179
+ team1_id: team1_rec.id,
180
+ team2_id: team2_rec.id )
226
181
  if rec.nil?
227
- attribs = { round_id: round_rec.id,
228
- team1_id: match.team1.id,
229
- team2_id: match.team2.id,
230
- pos: 999, ## make optional why? why not? - change to num?
231
- play_at: match.date.to_date,
182
+ ## find last pos - check if it can be nil? yes, is nil if no records found
183
+ max_pos = Model::Match.where( event_id: event.id ).maximum( 'pos' )
184
+ max_pos = max_pos ? max_pos+1 : 1
185
+
186
+ attribs = { event_id: event.id, ## todo/fix: change to data struct too?
187
+ round_id: round_rec.id,
188
+ team1_id: team1_rec.id,
189
+ team2_id: team2_rec.id,
190
+ pos: max_pos,
191
+ date: match.date.to_date, ## todo/fix: split and add date & time!!!!
232
192
  score1: match.score1,
233
193
  score2: match.score2,
234
194
  score1i: match.score1i,
235
195
  score2i: match.score2i }
236
- rec = SportDb::Model::Game.create!( attribs )
196
+
197
+ attribs[ :group_id ] = group_rec.id if group_rec
198
+ attribs[ :stage_id ] = stage_rec.id if stage_rec
199
+
200
+ rec = Model::Match.create!( attribs )
237
201
  else
238
202
  # update - todo
239
203
  end
@@ -2,9 +2,10 @@
2
2
 
3
3
 
4
4
  module SportDb
5
+ module Module
5
6
  module Sync
6
7
 
7
- MAJOR = 0 ## todo: namespace inside version or something - why? why not??
8
+ MAJOR = 1 ## todo: namespace inside version or something - why? why not??
8
9
  MINOR = 1
9
10
  PATCH = 0
10
11
  VERSION = [MAJOR,MINOR,PATCH].join('.')
@@ -22,4 +23,5 @@ module Sync
22
23
  end
23
24
 
24
25
  end # module Sync
26
+ end # module Module
25
27
  end # module SportDb
@@ -1,4 +1,8 @@
1
- ## $:.unshift(File.dirname(__FILE__))
1
+ ## note: use the local version of sportdb gems
2
+ $LOAD_PATH.unshift( File.expand_path( '../sportdb-formats/lib' ))
3
+ $LOAD_PATH.unshift( File.expand_path( '../sportdb-config/lib' ))
4
+ $LOAD_PATH.unshift( File.expand_path( '../sportdb-models/lib' ))
5
+
2
6
 
3
7
  ## minitest setup
4
8
  require 'minitest/autorun'
@@ -6,3 +10,23 @@ require 'minitest/autorun'
6
10
 
7
11
  ## our own code
8
12
  require 'sportdb/sync'
13
+
14
+
15
+ ## use (switch to) "external" datasets
16
+ SportDb::Import.config.leagues_dir = "../../../openfootball/leagues"
17
+ SportDb::Import.config.clubs_dir = "../../../openfootball/clubs"
18
+
19
+
20
+ COUNTRIES = SportDb::Import.catalog.countries
21
+ LEAGUES = SportDb::Import.catalog.leagues
22
+ CLUBS = SportDb::Import.catalog.clubs
23
+
24
+
25
+ SportDb.connect( adapter: 'sqlite3', database: ':memory:' )
26
+ SportDb.create_all ## build schema
27
+
28
+ ## turn on logging to console
29
+ ## ActiveRecord::Base.logger = Logger.new(STDOUT)
30
+
31
+
32
+
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+
3
+ ###
4
+ # to run use
5
+ # ruby -I ./lib -I ./test test/test_country.rb
6
+
7
+
8
+ require 'helper'
9
+
10
+
11
+ class TestCountry < MiniTest::Test
12
+
13
+ Country = SportDb::Sync::Country
14
+
15
+ def test_find # note: find uses "data" structs
16
+ at = SportDb::Import::Country.new( key: 'at', name: 'Austria', code: 'AUT' )
17
+ eng = SportDb::Import::Country.new( key: 'eng', name: 'England', code: 'ENG' )
18
+
19
+ rec = Country.find_or_create( at )
20
+ rec2 = Country.find_or_create( at )
21
+
22
+ rec = Country.find_or_create( eng )
23
+ rec2 = Country.find_or_create( eng )
24
+ end # method test_find
25
+
26
+
27
+ def test_search # note: search uses query strings
28
+ rec = Country.search_or_create!( 'at' ) ## try (iso-alpha2) key
29
+ assert_equal 'Austria', rec.name
30
+ assert_equal 'at', rec.key
31
+ assert_equal 'AUT', rec.code
32
+
33
+ rec = Country.search_or_create!( 'aut' ) ## try fifa code
34
+ assert_equal 'Austria', rec.name
35
+ assert_equal 'at', rec.key
36
+ assert_equal 'AUT', rec.code
37
+
38
+
39
+ rec = Country.search_or_create!( 'eng' )
40
+ assert_equal 'England', rec.name
41
+ assert_equal 'eng', rec.key
42
+ assert_equal 'ENG', rec.code
43
+
44
+ rec = Country.search_or_create!( 'eng' )
45
+ assert_equal 'England', rec.name
46
+ assert_equal 'eng', rec.key
47
+ assert_equal 'ENG', rec.code
48
+ end
49
+
50
+ end # class TestCountry
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ ###
4
+ # to run use
5
+ # ruby -I ./lib -I ./test test/test_league.rb
6
+
7
+
8
+ require 'helper'
9
+
10
+ class TestLeague < MiniTest::Test
11
+
12
+ League = SportDb::Sync::League
13
+
14
+
15
+ def test_search
16
+ rec = League.search_or_create!( 'eng' )
17
+ assert_equal 'Premier League', rec.name
18
+ assert_equal 'eng.1', rec.key
19
+ assert_equal 'eng', rec.country.key
20
+ assert_equal 'England', rec.country.name
21
+ # assert_equal true, rec.clubs
22
+
23
+ rec = League.search!( 'eng' )
24
+ assert_equal 'Premier League', rec.name
25
+ assert_equal 'eng.1', rec.key
26
+ assert_equal 'eng', rec.country.key
27
+ assert_equal 'England', rec.country.name
28
+ ## assert_equal true, rec.clubs
29
+
30
+ ## try 2nd call (just lookup)
31
+ rec = League.search_or_create!( 'eng' )
32
+ assert_equal 'Premier League', rec.name
33
+ assert_equal 'eng.1', rec.key
34
+ assert_equal 'eng', rec.country.key
35
+ assert_equal 'England', rec.country.name
36
+ ## assert_equal true, rec.clubs
37
+ end
38
+ end # class TestLeague
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ ###
4
+ # to run use
5
+ # ruby -I ./lib -I ./test test/test_misc.rb
6
+
7
+
8
+ require 'helper'
9
+
10
+ class TestMisc < MiniTest::Test
11
+
12
+ Season = SportDb::Sync::Season
13
+
14
+
15
+ def test_season
16
+ rec = Season.search_or_create( '2017-18' )
17
+ assert_equal '2017/18', rec.name
18
+ assert_equal '2017/18', rec.key
19
+
20
+ rec = Season.search_or_create( '2017/2018' )
21
+ assert_equal '2017/18', rec.name
22
+ assert_equal '2017/18', rec.key
23
+
24
+ rec = Season.search_or_create( '2017/8' )
25
+ assert_equal '2017/18', rec.name
26
+ assert_equal '2017/18', rec.key
27
+ end
28
+
29
+ end # class TestMisc
metadata CHANGED
@@ -1,57 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sportdb-sync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-28 00:00:00.000000000 Z
11
+ date: 2020-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: sportdb-clubs
14
+ name: sportdb-config
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.3
19
+ version: 1.1.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.3
27
- - !ruby/object:Gem::Dependency
28
- name: sportdb-leagues
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 0.2.1
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: 0.2.1
26
+ version: 1.1.0
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: sportdb-models
43
29
  requirement: !ruby/object:Gem::Requirement
44
30
  requirements:
45
31
  - - ">="
46
32
  - !ruby/object:Gem::Version
47
- version: 1.18.2
33
+ version: 2.0.1
48
34
  type: :runtime
49
35
  prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
52
38
  - - ">="
53
39
  - !ruby/object:Gem::Version
54
- version: 1.18.2
40
+ version: 2.0.1
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: rdoc
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -95,10 +81,17 @@ files:
95
81
  - README.md
96
82
  - Rakefile
97
83
  - lib/sportdb/sync.rb
84
+ - lib/sportdb/sync/club.rb
85
+ - lib/sportdb/sync/country.rb
86
+ - lib/sportdb/sync/event.rb
87
+ - lib/sportdb/sync/league.rb
88
+ - lib/sportdb/sync/season.rb
98
89
  - lib/sportdb/sync/sync.rb
99
90
  - lib/sportdb/sync/version.rb
100
91
  - test/helper.rb
101
- - test/test_sync.rb
92
+ - test/test_country.rb
93
+ - test/test_league.rb
94
+ - test/test_misc.rb
102
95
  homepage: https://github.com/sportdb/sport.db
103
96
  licenses:
104
97
  - Public Domain
@@ -1,29 +0,0 @@
1
- # encoding: utf-8
2
-
3
- ###
4
- # to run use
5
- # ruby -I ./lib -I ./test test/test_sync.rb
6
-
7
-
8
- require 'helper'
9
-
10
-
11
- class TestSync < MiniTest::Test
12
-
13
- def test_sync
14
- SportDb.connect( adapter: 'sqlite3', database: ':memory:' )
15
- SportDb.create_all ## build schema
16
-
17
- ## turn on logging to console
18
- ActiveRecord::Base.logger = Logger.new(STDOUT)
19
-
20
- at_rec = SportDb::Import::Country.new( 'at', 'Austria', fifa: 'AUT' )
21
- eng_rec = SportDb::Import::Country.new( 'eng', 'England', fifa: 'ENG' )
22
-
23
- at = SportDb::Sync::Country.find_or_create( at_rec )
24
- at2 = SportDb::Sync::Country.find_or_create( at_rec )
25
-
26
- eng = SportDb::Sync::Country.find_or_create( eng_rec )
27
- eng2 = SportDb::Sync::Country.find_or_create( eng_rec )
28
- end # method test_sync
29
- end # class TestSync