File Coverage

blib/lib/CTM/Base/MainClass.pm
Criterion Covered Total %
statement 63 135 46.6
branch 7 46 15.2
condition 9 61 14.7
subroutine 15 23 65.2
pod n/a
total 94 265 35.4


line stmt bran cond sub pod time code
1             #------------------------------------------------------------------------------------------------------
2             # OBJET : "Classe abstraite" des modules CTM::ReadEM et CTM::ReadServer
3             # APPLICATION : Control-M
4             # AUTEUR : Yoann Le Garff
5             # DATE DE CREATION : 01/10/2014
6             #------------------------------------------------------------------------------------------------------
7             # USAGE / AIDE
8             # perldoc CTM::Base::MainClass
9             #------------------------------------------------------------------------------------------------------
10              
11             #-> BEGIN
12              
13             #----> ** initialisation **
14              
15             package CTM::Base::MainClass;
16              
17 1     1   8 use strict;
  1         2  
  1         40  
18 1     1   5 use warnings;
  1         2  
  1         33  
19              
20 1         95 use base qw/
21             CTM::Base
22 1     1   5 /;
  1         1  
23              
24 1         103 use Carp qw/
25             carp
26             croak
27 1     1   13 /;
  1         2  
28 1         69 use String::Util qw/
29             hascontent
30             crunch
31 1     1   716 /;
  1         5286  
32 1         37 use Scalar::Util qw/
33             blessed
34 1     1   6 /;
  1         0  
35 1         4 use POSIX qw/
36             :signal_h
37 1     1   582 /;
  1         5497  
38 1     1   1525 use Try::Tiny;
  1         1806  
  1         50  
39 1         48 use Perl::OSType qw/
40             is_os_type
41 1     1   446 /;
  1         325  
42 1     1   1465 use DBI;
  1         13538  
  1         1548  
43              
44             #----> ** variables de classe **
45              
46             our $VERSION = 0.181;
47              
48             #----> ** methodes privees **
49              
50             #-> wrappers methodes DBI
51              
52             my $_doesTablesExists = sub {
53             my ($self, @tablesName) = @_;
54             my @inexistingSQLTables;
55             for (@tablesName) {
56             my $sth = $self->_DBI()->table_info(undef, 'public', $_, 'TABLE');
57             if ($sth->execute()) {
58             push @inexistingSQLTables, $_ unless ($sth->fetchrow_array());
59             } else {
60             return 0, crunch($self->_DBI()->errstr());
61             }
62             }
63             return 1, \@inexistingSQLTables;
64             };
65              
66             #----> ** methodes protegees **
67              
68             #-> constructeurs/destructeurs
69              
70             sub _new {
71 2     2   6 my ($class, %params) = @_;
72 2         16 my $subName = (caller 0)[3];
73 2 50       17 if (caller->isa(__PACKAGE__)) {
74 2         3 my $self = {};
75 2 50 33     28 if (defined $params{version} && defined $params{DBMSType} && defined $params{DBMSAddress} && defined $params{DBMSPort} && defined $params{DBMSInstance} && defined $params{DBMSUser}) {
      33        
      33        
      33        
      33        
76 2         3 $self->{_version} = $params{version};
77 2         4 $self->{DBMSType} = $params{DBMSType};
78 2         5 $self->{DBMSAddress} = $params{DBMSAddress};
79 2         3 $self->{DBMSPort} = $params{DBMSPort};
80 2         3 $self->{DBMSInstance} = $params{DBMSInstance};
81 2         3 $self->{DBMSUser} = $params{DBMSUser};
82 2 50       4 $self->{DBMSPassword} = exists $params{DBMSPassword} ? $params{DBMSPassword} : undef;
83 2   50     9 $self->{DBMSConnectTimeout} = $params{DBMSConnectTimeout} || 0;
84 2   50     7 $self->{CTM::Base::_verboseObjProperty} = $params{CTM::Base::_verboseObjProperty} || 0;
85             } else {
86 0         0 croak(CTM::Base::_myErrorMessage($subName, CTM::Base::_myUsageMessage($subName, "")));
87             }
88 2         5 $self->{CTM::Base::_workingObjProperty} = 0;
89 2         3 $self->{CTM::Base::_errorsObjProperty} = [];
90 2         3 $self->{CTM::Base::_DBIObjProperty} = undef;
91 2         3 $self->{CTM::Base::_sessionIsConnectedObjProperty} = 0;
92 2   33     5 $class = ref $class || $class;
93 2         8 return bless $self, $class;
94             } else {
95 0         0 carp(_myErrorMessage($subName, "tentative d'utilisation d'une methode protegee."));
96             }
97 0         0 return 0;
98             };
99              
100             sub _connect {
101 0     0   0 my ($subName, $self, @tablesToTest) = ((caller 0)[3], @_);
102 0 0       0 if (caller->isa(__PACKAGE__)) {
103 0         0 $self->unshiftError();
104 0 0 0     0 if (defined $self->{_version} && $self->{_version} =~ /^[678]$/ && defined $self->{DBMSType} && $self->{DBMSType} =~ /^(Pg|Oracle|mysql|Sybase|ODBC)$/ && hascontent($self->{DBMSAddress}) && defined $self->{DBMSPort} && $self->{DBMSPort} =~ /^\d+$/ && $self->{DBMSPort} >= 0 && $self->{DBMSPort} <= 65535 && defined hascontent($self->{DBMSInstance}) && hascontent($self->{DBMSUser}) && defined $self->{DBMSConnectTimeout} && $self->{DBMSConnectTimeout} =~ /^\d+$/) {
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
105 0 0       0 unless ($self->isSessionSeemAlive()) {
106 0 0       0 if (eval 'require DBD::' . $self->{DBMSType}) {
107 0         0 my $myOSIsUnix = is_os_type('Unix', 'dragonfly');
108             my $ALRMDieSub = sub {
109 0     0   0 die "'DBI' : impossible de se connecter (timeout atteint) a la base '" . $self->{DBMSType} . ", instance '" . $self->{DBMSInstance} . "' du serveur '" . $self->{DBMSType} . "'.";
110 0         0 };
111 0         0 my $oldaction;
112 0 0       0 if ($myOSIsUnix) {
113 0         0 my $mask = POSIX::SigSet->new(SIGALRM);
114 0         0 my $action = POSIX::SigAction->new(
115             \&$ALRMDieSub,
116             $mask
117             );
118 0         0 $oldaction = POSIX::SigAction->new();
119 0         0 sigaction(SIGALRM, $action, $oldaction);
120             } else {
121 0         0 local $SIG{ALRM} = \&$ALRMDieSub;
122             }
123             try {
124 0     0   0 my $connectionString = 'dbi:' . $self->{DBMSType};
125 0 0       0 if ($self->{DBMSType} eq 'ODBC') {
126 0         0 $connectionString .= ':driver={SQL Server};server=' . $self->{DBMSAddress} . ',' . $self->{DBMSPort} . ';database=' . $self->{DBMSInstance};
127             } else {
128 0         0 $connectionString .= ':host=' . $self->{DBMSAddress} . ';database=' . $self->{DBMSInstance} . ';port=' . $self->{DBMSPort};
129             }
130 0         0 alarm $self->{DBMSConnectTimeout};
131 0         0 $self->{CTM::Base::_DBIObjProperty} = DBI->connect(
132             $connectionString,
133             $self->{DBMSUser},
134             $self->{DBMSPassword},
135             {
136             RaiseError => 0,
137             PrintError => 0,
138             AutoCommit => 1
139             }
140             );
141 0 0       0 $self->_addError(CTM::Base::_myErrorMessage($subName, "'DBI' : '" . crunch($DBI::errstr) . "'.")) if (defined $DBI::errstr);
142             } catch {
143 0     0   0 $self->_addError(CTM::Base::_myErrorMessage($subName, $_));
144             } finally {
145 0     0   0 alarm 0;
146 0 0       0 sigaction(SIGALRM, $oldaction) if ($myOSIsUnix);
147 0         0 };
148 0 0       0 unless (defined $self->getError()) {
149 0         0 my ($situation, $inexistingSQLTables) = $self->$_doesTablesExists(@tablesToTest);
150 0 0       0 if ($situation) {
151 0 0       0 unless (@{$inexistingSQLTables}) {
  0         0  
152 0         0 $self->_tagSessionAsConnected();
153 0         0 return 1;
154             } else {
155 0         0 $self->_addError(CTM::Base::_myErrorMessage($subName, "la connexion au SGBD est etablie mais il manque une ou plusieurs tables ('" . join("', '", @{$inexistingSQLTables}) . "') qui sont requises ."));
  0         0  
156             }
157             } else {
158 0         0 $self->_addError(CTM::Base::_myErrorMessage($subName, "la connexion est etablie mais la methode DBI 'execute()' a echouee : '" . $inexistingSQLTables . "'."));
159             }
160             }
161             } else {
162 0         0 $self->_addError(CTM::Base::_myErrorMessage($subName, "impossible de charger le module 'DBD::" . $self->{DBMSType} . "' : '" . crunch($@) . "'. Les drivers disponibles sont '" . $self->_DBI()->available_drivers() . "'."));
163             }
164             } else {
165 0         0 $self->_addError(CTM::Base::_myErrorMessage($subName, "impossible de se connecter car cette instance est deja connectee."));
166             }
167             } else {
168 0         0 croak(CTM::Base::_myErrorMessage($subName, CTM::Base::_myUsageMessage($subName, "")));
169             }
170             } else {
171 0         0 carp(_myErrorMessage($subName, "tentative d'utilisation d'une methode protegee."));
172             }
173 0         0 return 0;
174             };
175              
176             sub _disconnect {
177 1     1   7 my ($self, $subName) = (shift, (caller 0)[3]);
178 1 50       5 if (caller->isa(__PACKAGE__)) {
179 1         6 $self->unshiftError();
180 1 50       3 if ($self->isSessionSeemAlive()) {
181 0 0       0 if ($self->_DBI()->disconnect()) {
182 0         0 $self->_tagSessionAsDisconnected();
183 0         0 return 1;
184             } else {
185 0         0 $self->_addError(CTM::Base::_myErrorMessage($subName, 'DBI : ' . crunch($self->_DBI()->errstr())));
186             }
187             } else {
188 1         3 $self->_addError(CTM::Base::_myErrorMessage($subName, "impossible de clore la connexion car cette instance n'est pas connectee."));
189             }
190             } else {
191 0         0 carp(_myErrorMessage($subName, "tentative d'utilisation d'une methode protegee."));
192             }
193 1         3 return 0;
194             };
195              
196             #-> accesseurs/mutateurs
197              
198             sub _DBI {
199 2     2   2 my ($self, $property, $value) = @_;
200 2 50       10 if (caller->isa(__PACKAGE__)) {
201 2         13 return $self->{CTM::Base::_DBIObjProperty}
202             } else {
203 0         0 carp(_myErrorMessage((caller 0)[3], "tentative d'utilisation d'une methode protegee."));
204             }
205 0         0 return 0;
206             }
207              
208             sub _tagSessionAsConnected {
209 0     0   0 my ($self, $property, $value) = @_;
210 0 0       0 if (caller->isa(__PACKAGE__)) {
211 0         0 return $self->_setObjProperty(CTM::Base::_sessionIsConnectedObjProperty, 1);
212             } else {
213 0         0 carp(_myErrorMessage((caller 0)[3], "tentative d'utilisation d'une methode protegee."));
214             }
215 0         0 return 0;
216             }
217              
218             sub _tagSessionAsDisconnected {
219 0     0   0 my ($self, $property, $value) = @_;
220 0 0       0 if (caller->isa(__PACKAGE__)) {
221 0         0 return $self->_setObjProperty(CTM::Base::_sessionIsConnectedObjProperty, 0);
222             } else {
223 0         0 carp(_myErrorMessage((caller 0)[3], "tentative d'utilisation d'une methode protegee."));
224             }
225 0         0 return 0;
226             }
227              
228             sub _isSessionAlive {
229 0     0   0 my ($self, $subName) = (shift, (caller 0)[3]);
230 0 0       0 if (caller->isa(__PACKAGE__)) {
231 0         0 $self->unshiftError();
232 0 0       0 if ($self->isSessionSeemAlive()) {
233 0         0 return $self->_DBI()->ping();
234             } else {
235 0         0 $self->_addError(CTM::Base::_myErrorMessage($subName, "impossible de tester l'etat de la connexion au SGBD car celle ci n'est pas active."));
236             }
237             } else {
238 0         0 carp(_myErrorMessage($subName, "tentative d'utilisation d'une methode protegee."));
239             }
240 0         0 return 0;
241             }
242              
243             sub _isSessionSeemAlive {
244 2     2   3 my $self = shift;
245 2 50       7 if (caller->isa(__PACKAGE__)) {
246 2   33     6 return blessed($self->_DBI()) && $self->_DBI()->isa('DBI::db') && $self->{CTM::Base::_sessionIsConnectedObjProperty};
247             } else {
248 0           carp(_myErrorMessage((caller 0)[3], "tentative d'utilisation d'une methode protegee."));
249             }
250 0           return 0;
251             }
252              
253             #-> Perl BuiltIn
254              
255             BEGIN {
256 1     1   19 *AUTOLOAD = \&CTM::Base::AUTOLOAD;
257             }
258              
259             1;
260              
261             #-> END
262              
263             __END__