File Coverage

blib/lib/Sport/Analytics/NHL/DB.pm
Criterion Covered Total %
statement 36 76 47.3
branch 0 8 0.0
condition 3 29 10.3
subroutine 12 16 75.0
pod 4 4 100.0
total 55 133 41.3


line stmt bran cond sub pod time code
1             package Sport::Analytics::NHL::DB;
2              
3 54     54   1257 use strict;
  54         107  
  54         1508  
4 54     54   240 use warnings FATAL => 'all';
  54         97  
  54         1560  
5              
6 54     54   245 use Carp;
  54         109  
  54         2398  
7 54     54   1210 use POSIX;
  54         11295  
  54         406  
8              
9 54     54   108709 use Tie::IxHash;
  54         129037  
  54         1569  
10 54     54   20434 use boolean;
  54         56558  
  54         270  
11              
12 54     54   3205 use Sport::Analytics::NHL::Config;
  54         108  
  54         7966  
13 54     54   1045 use Sport::Analytics::NHL::LocalConfig;
  54         99  
  54         5335  
14 54     54   11518 use Sport::Analytics::NHL::Util;
  54         138  
  54         4093  
15              
16 54   33 54   15088 use if ! $ENV{HOCKEYDB_NODB} && $MONGO_DB, 'MongoDB';
  54         375  
  54         860  
17 54   33 54   2456 use if ! $ENV{HOCKEYDB_NODB} && $MONGO_DB, 'MongoDB::OID';
  54         112  
  54         480  
18 54   33 54   2359 use if ! $ENV{HOCKEYDB_NODB} && $MONGO_DB, 'MongoDB::MongoClient';
  54         116  
  54         410  
19              
20             =head1 NAME
21              
22             Sport::Analytics::NHL::DB - Interface to MongoDB to store NHL reports.
23              
24             =head1 SYNOPSYS
25              
26             Interface to MongoDB in order to store the semi-structured NHL reports into it. Provides the database handle and most of the bulky database operations. Does not subclass MongoDB - the handle is stored in the class's object.
27              
28             use Sport::Analytics::NHL::DB;
29             my $db = Sport::Analytics::NHL::DB->new();
30             my $team_id = $db->resolve_team_db('San Jose Sharks'); # $team_id becomes 'SJS'.
31              
32             =head1 METHODS
33              
34             =over 2
35              
36             =item C
37              
38             Constructor. Sets the database connection. Controlled by global variables:
39             * $MONGO_HOST - host of the mongodb server (def. 127.0.0.1)
40             * $MONGO_PORT - port of the mongodb server (def. 27017)
41             * $MONGO_DB - name of the mongo database (def 'hockey')
42             Also, the database can be specified via $ENV{HOCKEYDB_DBNAME}
43              
44             The database handle is stored in the dbh field of the object which is a blessed hashref.
45              
46             =item C
47              
48             Resolves a team by a given possible identifier to a normalized 3-letter identifier. The target identifiers are the keys to the %TEAMS hash in Sport::Analytics::NHL::Config.pm (q.v.)
49             Argument: the team identifier/name (e.g. 'Rangers')
50             Returns: the system identifier (e.g. NYR)
51              
52             =item C
53              
54             Inserts the collected schedule (see Sport::Analytics::NHL::Scraper), initializing the indexes for the schedule collection if necessary.
55             Collections: schedule
56             Arguments: the list of scheduled games with their defined fields
57             Returns: the number of the inserted games
58              
59             =item C
60              
61             Gets the list of ids of games already in the database
62             Collections: games
63             Arguments: optional - hashref containing the start_season and stop_season of the query
64             Returns: the arrayref of the ids of the existing games
65              
66             =back
67              
68             =cut
69              
70             our $DEFAULT_DB = 'hockey';
71             our $DEFAULT_HOST = '127.0.0.1';
72             our $DEFAULT_PORT = 27017;
73              
74             sub new ($;$) {
75              
76 0     0 1   my $class = shift;
77 0   0       my $database = shift || $ENV{HOCKEYDB_DBNAME} || $MONGO_DB || $DEFAULT_DB;
78              
79 0           my $self = {};
80 0   0       my $host = $MONGO_HOST || $DEFAULT_HOST;
81 0   0       my $port = $MONGO_PORT || $DEFAULT_PORT;
82 0           $self->{client} = MongoDB::MongoClient->new(
83             host => sprintf(
84             "mongodb://%s:%d", $host, $port
85             )
86             );
87 0   0       my $db = $database || $DEFAULT_DB;
88 0           $self->{dbh} = $self->{client}->get_database($db);
89 0           $ENV{HOCKEYDB_DBNAME} = $db;
90 0           verbose "Using Mongo database $db";
91 0           $self->{dbname} = $db;
92 0           bless $self, $class;
93 0           $self;
94             }
95              
96             sub resolve_team_db ($$) {
97              
98 0     0 1   my $self = shift;
99 0           my $team = shift;
100              
101 0           $team = uc $team;
102 0           my $teams_c = $self->{dbh}->get_collection('teams');
103              
104 0           my $team_db = $teams_c->find_one({
105             '$or' => [
106             { _id => $team },
107             { short => $team },
108             { long => $team },
109             { full => $team },
110             ],
111             });
112 0 0         $team_db ? $team_db->{_id} : undef;
113             }
114              
115             sub insert_schedule ($@) {
116              
117 0     0 1   my $self = shift;
118 0           my @games = @_;
119              
120 0 0         return 0 unless @games;
121 0           my $schedule_c = $self->{dbh}->get_collection('schedule');
122 0           my $schedule_x = $schedule_c->indexes();
123 0           $schedule_x->create_many(
124             { keys => [ game_id => 1 ], options => {unique => 1} },
125             { keys => [ date => 1 ], },
126             { keys => [ season => 1, stage => 1, season_id => 1 ] },
127             );
128             @games = grep {
129 0 0 0       if ($_->{stage} == $REGULAR || $_->{stage} == $PLAYOFF) {
130 0           $_->{game_id} += 0;
131 0           $_->{ts} += 0;
132             }
133 0           else { 0 }
134 0 0 0       } map(ref $_ && ref $_ eq 'ARRAY' ? @{$_} : $_, @games);
  0            
135 0           $schedule_c->delete_many({_id => { '$in' => [ map {$_->{_id}} @games ] } });
  0            
136 0           $schedule_c->insert_many([@games]);
137 0           debug "Inserted " . scalar(@games) . " games for season $games[0]->{season}";
138 0           scalar @games;
139             }
140              
141             sub get_existing_game_ids ($;$) {
142              
143 0     0 1   my $self = shift;
144 0   0       my $opts = shift || {
145             stop_season => $CURRENT_SEASON, start_season => $CURRENT_SEASON
146             };
147              
148             my @games = $self->{dbh}->get_collection('games')->find({
149             season => {
150             '$gte' => $opts->{start_season}+0,
151 0           '$lte' => $opts->{stop_season} +0
152             },
153             }, {_id => 1})->all();
154              
155 0           [ map($_->{_id}+0,@games) ];
156             }
157              
158             1;
159              
160             =head1 AUTHOR
161              
162             More Hockey Stats, C<< >>
163              
164             =head1 BUGS
165              
166             Please report any bugs or feature requests to C, or through
167             the web interface at L. I will be notified, and then you'll
168             automatically be notified of progress on your bug as I make changes.
169              
170              
171              
172              
173             =head1 SUPPORT
174              
175             You can find documentation for this module with the perldoc command.
176              
177             perldoc Sport::Analytics::NHL::DB
178              
179              
180             You can also look for information at:
181              
182             =over 4
183              
184             =item * RT: CPAN's request tracker (report bugs here)
185              
186             L
187              
188             =item * AnnoCPAN: Annotated CPAN documentation
189              
190             L
191              
192             =item * CPAN Ratings
193              
194             L
195              
196             =item * Search CPAN
197              
198             L
199              
200             =back
201              
202              
203             =head1 ACKNOWLEDGEMENTS
204              
205              
206             =head1 LICENSE AND COPYRIGHT
207              
208             Copyright 2018 More Hockey Stats.
209              
210             This program is released under the following license: gnu
211              
212             =cut