sportdb-catalogs 1.2.1 → 1.2.2

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
  SHA256:
3
- metadata.gz: 4615353b8720394e2c0edcd97de249822923718bf9d7703e4ce2f93f4411b372
4
- data.tar.gz: ac4536c29d15caf8bf5c3de62539785f17fbad3e6098c5e0d18282c1e5cccb2a
3
+ metadata.gz: '09d5c1b4a2fea093abfc294ccbf6149315a335a07a5e934d25fb652215e0ab23'
4
+ data.tar.gz: 991f6cd9ee018fa4f7d84be847c5868a024ac240ec5d29cb60636addbd1984c5
5
5
  SHA512:
6
- metadata.gz: 93dc76f6a2dd70d04a9ebb6700e66bbcd41a98cd517a9f1ed24b6a2ad667806963ffd2fda6991a02600c3aa4d61c45431201b4f350a37b4a080e53bf664866ec
7
- data.tar.gz: f0cc52b6590c598ec8ae40abdb7b8238a647617b10825b76d4c910bcd01ca7facde765cf977e0abb807312fa7fa55ffa83a239446962b209c8a747004e43e03a
6
+ metadata.gz: ffaca4423b4dc8adba0db61187dfcf2cc0b1fb5c47255953ed08e8e13bc1a0e2967673d7f1a60f5d6a7045b93ff3575fc27114ed86be15c27f72041287e59a91
7
+ data.tar.gz: ded797ffeae2ce160c1d6477416fa90d8b26433e78aca4bdc61c82bf0bdf8eef95f346c2f2fe95e070be962d8789d511d222379057245a9d649388b0a40d93c1
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 1.2.1
1
+ ### 1.2.2
2
2
  ### 0.0.1 / 2019-06-29
3
3
 
4
4
  * Everything is new. First release.
data/README.md CHANGED
@@ -9,23 +9,19 @@
9
9
 
10
10
 
11
11
 
12
- ## Usage
12
+ ## Usage
13
13
 
14
14
  Let's use the [/clubs datasets](https://github.com/openfootball/clubs)
15
- (1500+ football clubs from around the world)
15
+ (3000+ football clubs from around the world)
16
16
  to match name "variants" e.g. `Arsenal` to canonical global unique
17
17
  names e.g. `Arsenal FC, London, England`:
18
18
 
19
19
  ``` ruby
20
20
  require 'sportdb/catalogs'
21
21
 
22
- ## note: requires a local copy of the football.db clubs datasets
23
- ## see https://github.com/openfootball/clubs
24
- SportDb::Import.config.clubs_dir = './clubs'
22
+ Club = CatalogDb::Metal::Club
25
23
 
26
- CLUBS = SportDb::Import.catalog.clubs
27
-
28
- m = CLUBS.match( 'Arsenal' )
24
+ m = Club.match_by( name: 'Arsenal' )
29
25
  m.size # 3 club matches found
30
26
  #=> 3
31
27
  m[0].name; m[0].city; m[0].country
@@ -36,20 +32,20 @@ m[2].name; m[2].city; m[2].country
36
32
  #=> "Arsenal de Sarandí", "Sarandí", "Argentina"
37
33
 
38
34
 
39
- m = CLUBS.match_by( name: 'Arsenal', country: 'eng' )
35
+ m = Club.match_by( name: 'Arsenal', country: 'eng' )
40
36
  # -or- try alternative names (and auto-generated spelling variants)
41
- m = CLUBS.match_by( name: 'Arsenal FC', country: 'eng' )
42
- m = CLUBS.match_by( name: 'Arsenal F.C.', country: 'eng' )
43
- m = CLUBS.match_by( name: '...A.r.s.e.n.a.l... F.C...', country: 'eng' )
37
+ m = Club.match_by( name: 'Arsenal FC', country: 'eng' )
38
+ m = Club.match_by( name: 'Arsenal F.C.', country: 'eng' )
39
+ m = Club.match_by( name: '...A.r.s.e.n.a.l... F.C...', country: 'eng' )
44
40
  m.size # 1 club match found
45
41
  #=> 1
46
42
  m[0].name; m[0].city; m[0].country
47
43
  #=> "Arsenal FC", "London", "England"
48
44
 
49
- m = CLUBS.match_by( name: 'Arsenal', country: 'ar' )
45
+ m = Club.match_by( name: 'Arsenal', country: 'ar' )
50
46
  # -or- try alternative names (and auto-generated spelling variants)
51
- m = CLUBS.match_by( name: 'Arsenal Sarandí', country: 'ar' )
52
- m = CLUBS.match_by( name: 'Arsenal Sarandi', country: 'ar' )
47
+ m = Club.match_by( name: 'Arsenal Sarandí', country: 'ar' )
48
+ m = Club.match_by( name: 'Arsenal Sarandi', country: 'ar' )
53
49
  m.size # 1 club match found
54
50
  #=> 1
55
51
  m[0].name; m[0].city; m[0].country
@@ -57,15 +53,15 @@ m[0].name; m[0].city; m[0].country
57
53
 
58
54
 
59
55
  # try some more
60
- m = CLUBS.match( 'AZ' )
56
+ m = Club.match_by( name: 'AZ' )
61
57
  m[0].name; m[0].city; m[0].country
62
58
  #=> "AZ Alkmaar", "Alkmaar", "Netherlands"
63
59
 
64
- m = CLUBS.match( 'Bayern' )
60
+ m = Club.match_by( name: 'Bayern' )
65
61
  # -or- try alternative names (and auto-generated spelling variants)
66
- m = CLUBS.match( 'Bayern München' )
67
- m = CLUBS.match( 'Bayern Munchen' )
68
- m = CLUBS.match( 'Bayern Muenchen' )
62
+ m = Club.match_by( name: 'Bayern München' )
63
+ m = Club.match_by( name: 'Bayern Munchen' )
64
+ m = Club.match_by( name: 'Bayern Muenchen' )
69
65
  m[0].name; m[0].city; m[0].country
70
66
  #=> "Bayern München", "München", "Germany"
71
67
 
data/Rakefile CHANGED
@@ -20,7 +20,7 @@ Hoe.spec 'sportdb-catalogs' do
20
20
  self.licenses = ['Public Domain']
21
21
 
22
22
  self.extra_deps = [
23
- ['sportdb-formats', '>= 2.0.0'],
23
+ ['sportdb-structs', '>= 0.3.1'],
24
24
  ['sqlite3'], ## add sqlite for "metal" use (no activerecord etc.)
25
25
  ['footballdb-data'] ## add builtin default db
26
26
  ]
@@ -8,29 +8,29 @@ module Metal
8
8
 
9
9
 
10
10
  class BaseRecord ## or just use Base or such - why? why not?
11
-
12
- def self.execute( sql )
11
+
12
+ def self.execute( sql )
13
13
  ## puts "==> sql query [#{self.name}]"
14
14
  ## puts sql
15
- database.execute( sql )
15
+ database.execute( sql )
16
16
  end
17
-
17
+
18
18
  def self.tablename=(name) @tablename = name; end
19
19
  def self.tablename() @tablename; end
20
-
21
- def self.columns=(names)
20
+
21
+ def self.columns=(names)
22
22
  ## note: auto-add table name to qualify
23
- @columns = names.map {|name| "#{self.tablename}.#{name}" }
23
+ @columns = names.map {|name| "#{self.tablename}.#{name}" }
24
24
  @columns
25
25
  end
26
26
  def self.columns() @columns; end
27
-
27
+
28
28
  def self.count
29
29
  sql = "SELECT count(*) FROM #{self.tablename}"
30
30
  rows = execute( sql )
31
31
  rows[0][0] # e.g. returns [[241]]
32
32
  end
33
-
33
+
34
34
  ## helpers from country - use a helper module for includes (share with clubs etc.) - why? why not?
35
35
  # include NameHelper
36
36
  extend SportDb::NameHelper
@@ -48,7 +48,7 @@ class BaseRecord ## or just use Base or such - why? why not?
48
48
  ## use TypeError - why? why not? or if exits ValueError?
49
49
  raise ArgumentError, "0 or 1 expected for bool in sqlite; got #{value}"
50
50
  end
51
- end
51
+ end
52
52
 
53
53
 
54
54
  ##
@@ -58,7 +58,7 @@ class BaseRecord ## or just use Base or such - why? why not?
58
58
  if country.is_a?( String ) || country.is_a?( Symbol )
59
59
  # note: query/find country via catalog db
60
60
  rec = Country.find_by_code( country )
61
- rec = Country.find_by_name( country ) if rec.nil?
61
+ rec = Country.find_by_name( country ) if rec.nil?
62
62
  if rec.nil?
63
63
  puts "** !!! ERROR !!! - unknown country >#{country}< - no match found, sorry - add to world/countries.txt in config"
64
64
  exit 1
@@ -72,41 +72,50 @@ end # class BaseRecord
72
72
 
73
73
 
74
74
  class PlayerRecord < BaseRecord
75
+
76
+ ## lets you query if datbase setup
77
+ def self.database?() defined?( @@db ); end
78
+
75
79
  def self.database
76
80
  ### note: only one database for all derived records/tables!!!
77
81
  ## thus MUST use @@ and not @!!!!!
78
82
  ## todo - change later to built-in database
79
83
  ## or download on request???
80
- @@db ||= SQLite3::Database.new( './players.db' )
84
+ @@db ||= SQLite3::Database.new( './players.db', readonly: true )
81
85
  @@db
82
86
  end
83
-
87
+
84
88
  def self.database=(path)
85
89
  puts "==> setting (internal) players db to: >#{path}<"
86
- @@db = SQLite3::Database.new( path )
90
+ @@db = SQLite3::Database.new( path, readonly: true )
87
91
  pp @@db
88
92
  @@db
89
- end
93
+ end
90
94
  end # class PlayerRecord
91
95
 
92
96
 
93
97
 
94
98
  ##############
95
99
  ### todo (fix) / rename to CatalogRecord - why? why not?
96
- class Record < BaseRecord
100
+ class Record < BaseRecord
97
101
  ## add db alias why? why not?
102
+
103
+ ## lets you query if datbase setup
104
+ def self.database?() defined?( @@db ); end
105
+
98
106
  def self.database
99
107
  ### note: only one database for all derived records/tables!!!
100
108
  ## thus MUST use @@ and not @!!!!!
101
109
  ##
102
110
  ## default to built-in via footballdb-data gem for now!!!
103
- @@db ||= SQLite3::Database.new( './catalog.db' )
111
+ @@db ||= SQLite3::Database.new( "#{FootballDb::Data.data_dir}/catalog.db",
112
+ readonly: true )
104
113
  @@db
105
114
  end
106
115
 
107
116
  def self.database=(path)
108
117
  puts "==> setting (internal) catalog db to: >#{path}<"
109
- @@db = SQLite3::Database.new( path )
118
+ @@db = SQLite3::Database.new( path, readonly: true )
110
119
  pp @@db
111
120
  @@db
112
121
  end
@@ -118,14 +127,14 @@ def self._to_league( key )
118
127
  League._record( key )
119
128
  end
120
129
 
121
- def self._to_country( key )
130
+ def self._to_country( key )
122
131
  # note: use cached record or (faster) key lookup on fallback
123
- Country._record( key )
132
+ Country._record( key )
124
133
  end
125
134
 
126
135
  def self._to_city( key ) ### rename; use find_by_key / find_by( key: )
127
136
  # note: use cached record or (faster) key lookup on fallback
128
- City._record( key )
137
+ City._record( key )
129
138
  end
130
139
 
131
140
 
@@ -4,20 +4,19 @@ module Metal
4
4
  class EventInfo < Record
5
5
  self.tablename = 'event_infos'
6
6
 
7
- self.columns = ['league_key',
8
- 'season',
9
- 'teams',
7
+ self.columns = ['league_key',
8
+ 'season',
9
+ 'teams',
10
10
  'matches',
11
11
  'goals',
12
- 'start_date',
12
+ 'start_date',
13
13
  'end_date']
14
-
14
+
15
15
 
16
16
  def self._build_event_info( row )
17
17
  ## note: cache structs by key (do NOT rebuild duplicates; reuse)
18
18
  @cache ||= Hash.new
19
- ## note: move EventInfo from sports/format to structs - why? why not?
20
- @cache[ row[0] ] ||= SportDb::Import::EventInfo.new(
19
+ @cache[ row[0] ] ||= Sports::EventInfo.new(
21
20
  league: _to_league( row[0] ),
22
21
  season: Season.parse(row[1]),
23
22
  teams: row[2],
@@ -25,35 +24,35 @@ class EventInfo < Record
25
24
  goals: row[4],
26
25
  start_date: row[5] ? Date.strptime( row[5], '%Y-%m-%d' ) : nil,
27
26
  end_date: row[6] ? Date.strptime( row[6], '%Y-%m-%d' ) : nil,
28
- )
29
- end
30
-
27
+ )
28
+ end
29
+
31
30
 
32
31
  def self.seasons( league )
33
- league_key = league.is_a?( String ) ? League.find!( league ).key
32
+ league_key = league.is_a?( String ) ? League.find!( league ).key
34
33
  : league.key
35
34
 
36
35
  rows = execute( <<-SQL )
37
36
  SELECT #{self.columns.join(', ')}
38
- FROM event_infos
39
- WHERE event_infos.league_key = '#{league_key}'
37
+ FROM event_infos
38
+ WHERE event_infos.league_key = '#{league_key}'
40
39
  SQL
41
40
 
42
41
  rows.map {|row| _build_event_info( row ) }
43
42
  end
44
43
 
45
-
44
+
46
45
  def self.find_by( league:, season: )
47
- league_key = league.is_a?( String ) ? League.find!( league ).key
46
+ league_key = league.is_a?( String ) ? League.find!( league ).key
48
47
  : league.key
49
- season_key = season.is_a?( String ) ? Season.parse(season).key
48
+ season_key = season.is_a?( String ) ? Season.parse(season).key
50
49
  : season.key
51
50
 
52
51
  rows = execute( <<-SQL )
53
52
  SELECT #{self.columns.join(', ')}
54
- FROM event_infos
53
+ FROM event_infos
55
54
  WHERE event_infos.league_key = '#{league_key}' AND
56
- event_infos.season = '#{season_key}'
55
+ event_infos.season = '#{season_key}'
57
56
  SQL
58
57
 
59
58
  if rows.empty?
@@ -5,7 +5,7 @@ module Catalogs
5
5
 
6
6
  MAJOR = 1 ## todo: namespace inside version or something - why? why not??
7
7
  MINOR = 2
8
- PATCH = 1
8
+ PATCH = 2
9
9
  VERSION = [MAJOR,MINOR,PATCH].join('.')
10
10
 
11
11
  def self.version
@@ -1,7 +1,4 @@
1
- ### our own sportdb libs / gems
2
- ### try min. dependencies - change to structs only (NOT formats) - why? why not?
3
- ## require 'sportdb/structs'
4
- require 'sportdb/formats'
1
+ require 'sportdb/structs'
5
2
 
6
3
  require 'sqlite3'
7
4
 
@@ -15,77 +12,17 @@ require_relative 'catalogs/base' ## base record
15
12
  require_relative 'catalogs/country'
16
13
  require_relative 'catalogs/city'
17
14
 
18
- require_relative 'catalogs/club'
15
+ require_relative 'catalogs/club'
19
16
  require_relative 'catalogs/national_team'
20
17
  require_relative 'catalogs/league'
21
18
  require_relative 'catalogs/event_info'
22
- require_relative 'catalogs/ground'
19
+ require_relative 'catalogs/ground'
23
20
 
24
21
  ## more
25
22
  require_relative 'catalogs/player'
26
23
 
27
24
 
28
25
 
29
- module SportDb
30
- module Import
31
-
32
- class Configuration
33
- ## note: add more configs (open class), see sportdb-structs for original config!!!
34
-
35
- ###
36
- # find a better name for setting - why? why not?
37
- # how about catalogdb or ???
38
- attr_reader :catalog_path
39
- def catalog_path=(path)
40
- @catalog_path = path
41
- ########
42
- # reset database here to new path
43
- CatalogDb::Metal::Record.database = path
44
-
45
- ## plus automagically set world search too (to use CatalogDb)
46
- self.world = WorldSearch.new(
47
- countries: CatalogDb::Metal::Country,
48
- cities: CatalogDb::Metal::City,
49
- )
50
-
51
- @catalog_path
52
- end
53
-
54
- def catalog
55
- @catalog ||= SportSearch.new(
56
- leagues: CatalogDb::Metal::League,
57
- national_teams: CatalogDb::Metal::NationalTeam,
58
- clubs: CatalogDb::Metal::Club,
59
- grounds: CatalogDb::Metal::Ground,
60
- events: CatalogDb::Metal::EventInfo,
61
- players: CatalogDb::Metal::Player, # note - via players.db !!!
62
- )
63
- end
64
-
65
- ###
66
- # find a better name for setting - why? why not?
67
- # how about playersdb or ???
68
- attr_reader :players_path
69
- def players_path=(path)
70
- @players_path = path
71
- ########
72
- # reset database here to new path
73
- CatalogDb::Metal::PlayerRecord.database = path
74
-
75
- @players_path
76
- end
77
- end # class Configuration
78
-
79
-
80
- ## e.g. use config.catalog -- keep Import.catalog as a shortcut (for "read-only" access)
81
- def self.catalog() config.catalog; end
82
- end # module Import
83
- end # module SportDb
84
-
85
-
86
-
87
-
88
-
89
26
  ###
90
27
  # add status
91
28
  module CatalogDb
@@ -94,34 +31,48 @@ module Metal
94
31
  def self.tables
95
32
 
96
33
  puts "==> table stats"
97
- catalog_path = SportDb::Import.config.catalog_path
98
- if catalog_path
99
- puts " #{File.basename(catalog_path)} in (#{File.dirname(catalog_path)})"
100
- puts " #{Country.count} countries / #{City.count} cities"
34
+ if Record.database?
35
+ db = Record.database
36
+ filename = db.filename
37
+ if filename # note - nil for memory or tempary db?
38
+ puts " #{File.basename(filename)} in (#{File.dirname(filename)})"
39
+ else
40
+ puts "no filename; memory or temporary db?"
41
+ end
42
+
43
+ ## pp Record.database
44
+ ## puts
45
+ puts " #{Country.count} countries / #{City.count} cities"
101
46
  puts " #{NationalTeam.count} national teams"
102
47
  puts " #{League.count} leagues"
103
48
  puts " #{Club.count} clubs"
104
49
  puts " #{Ground.count} grounds"
105
50
  ## add more
106
-
107
51
  else
108
52
  puts " - no catalog.db set - "
109
53
  end
110
54
 
111
- ## todo/fix:
112
- ## check if players_path configured???
113
- players_path = SportDb::Import.config.players_path
114
- if players_path
115
- puts " #{File.basename(players_path)} in (#{File.dirname(players_path)})"
55
+
56
+ if PlayerRecord.database?
57
+ db = PlayerRecord.database
58
+ filename = db.filename
59
+ if filename # note - nil for memory or tempary db?
60
+ puts " #{File.basename(filename)} in (#{File.dirname(filename)})"
61
+ else
62
+ puts "no filename; memory or temporary db?"
63
+ end
64
+
65
+ ## pp PlayerRecord.database
66
+ ## puts
116
67
  puts " #{Player.count} players"
117
68
  else
118
- puts " - no players.db set -"
69
+ puts " - no players.db set -"
119
70
  end
120
71
  end
121
72
 
122
73
  end # module Metal
123
74
  end # module CatalogDb
124
-
75
+
125
76
 
126
77
 
127
78
  ###
@@ -131,34 +82,34 @@ end # module CatalogDb
131
82
  ## what name to use?
132
83
  ## find_countries_for_league_clubs or such
133
84
  ## find_countries_for_league - why? why not?
134
- ## note - returns array of countries OR single country
85
+ ## note - returns array of countries OR single country
135
86
 
136
87
  def find_countries_for_league( league )
137
- ## todo/fix: assert league is a League with country record/struct !!!!!
88
+ ## todo/fix: assert league is a League with country record/struct !!!!!
138
89
 
139
- countries = []
90
+ countries = []
140
91
  countries << league.country ### assume league.country is already db record/struct - why? why not?
141
- ## check for 2nd countries for known leagues
92
+ ## check for 2nd countries for known leagues
142
93
  ## (re)try with second country - quick hacks for known leagues
143
94
  ## e.g. Swanse, cardiff in premier league
144
95
  ## san mariono in serie a (italy)
145
96
  ## monaco in ligue 1 (france)
146
97
  ## etc.
147
98
  ## add andorra to spanish la liga (e.g. andorra fc???)
148
-
99
+
149
100
  case league.country.key
150
- when 'eng' then countries << CatalogDb::Metal::Country._record('wal')
101
+ when 'eng' then countries << CatalogDb::Metal::Country._record('wal')
151
102
  when 'sco' then countries << CatalogDb::Metal::Country._record('eng')
152
- when 'ie' then countries << CatalogDb::Metal::Country._record('nir')
153
- when 'fr' then countries << CatalogDb::Metal::Country._record('mc')
154
- when 'es' then countries << CatalogDb::Metal::Country._record('ad')
103
+ when 'ie' then countries << CatalogDb::Metal::Country._record('nir')
104
+ when 'fr' then countries << CatalogDb::Metal::Country._record('mc')
105
+ when 'es' then countries << CatalogDb::Metal::Country._record('ad')
155
106
  when 'it' then countries << CatalogDb::Metal::Country._record('sm')
156
- when 'ch' then countries << CatalogDb::Metal::Country._record('li')
107
+ when 'ch' then countries << CatalogDb::Metal::Country._record('li')
157
108
  when 'us' then countries << CatalogDb::Metal::Country._record('ca')
158
109
  when 'au' then countries << CatalogDb::Metal::Country._record('nz')
159
- end
110
+ end
160
111
 
161
- ## use single ("unwrapped") item for one country
112
+ ## use single ("unwrapped") item for one country
162
113
  ## otherwise use array
163
114
  country = countries.size == 1 ? countries[0] : countries
164
115
  country
@@ -168,15 +119,8 @@ end
168
119
 
169
120
 
170
121
 
171
-
172
122
  require 'footballdb/data' ## pull in catalog.db (built-in/default data/db)
173
123
 
174
- ###
175
- ## add default/built-in catalog here - why? why not?
176
- ## todo/fix - set catalog_path on demand
177
- ## note: for now required for world search setup etc.
178
- SportDb::Import.config.catalog_path = "#{FootballDb::Data.data_dir}/catalog.db"
179
-
180
124
 
181
125
 
182
126
  puts SportDb::Module::Catalogs.banner # say hello
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sportdb-catalogs
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-22 00:00:00.000000000 Z
11
+ date: 2024-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: sportdb-formats
14
+ name: sportdb-structs
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 2.0.0
19
+ version: 0.3.1
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: 2.0.0
26
+ version: 0.3.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sqlite3
29
29
  requirement: !ruby/object:Gem::Requirement