sportdb-sync 0.1.0 → 1.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.
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