RideLogicDBI.pm 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. package RideLogicDBI;
  2. use strict;
  3. use DBI;
  4. use POSIX;
  5. our $debug = 0;
  6. our $PACKAGE = 'RideLogicDBI';
  7. require Exporter;
  8. #use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  9. use vars qw( @ISA );
  10. #$VERSION = "0.01";
  11. @ISA = qw(Exporter);
  12. #@EXPORT = qw( debug_print );
  13. #@EXPORT_OK = qw( debug_print );
  14. #%EXPORT_TAGS = ( DEFAULT => [ qw( &debug_print ) ] );
  15. #our @ISA = qw(Exporter);
  16. our %CON ;
  17. our $data_source;
  18. our $username;
  19. our $password;
  20. our $attr_href;
  21. my $PACKAGE_NAME = "RideLogicDBI";
  22. my %session;
  23. my %session_active;
  24. my %session_inactive;
  25. my %session_ref_count;
  26. my %query;
  27. my %query_usage;
  28. sub debug_print {
  29. print "SESSION:\n";
  30. foreach my $k (keys(%session)) {
  31. print "$k ";
  32. foreach my $t (keys(%{$session{$k}})) {
  33. print " ($t ", $session{$k}->{$t}, ")";
  34. }
  35. print "\n";
  36. }
  37. print "\n";
  38. print "SESSION_ACTIVE:\n";
  39. foreach my $k (keys(%session_active)) {
  40. print "$k ";
  41. foreach my $t (keys(%{$session_active{$k}})) {
  42. print " ($t ", $session_active{$k}->{$t}, ")";
  43. }
  44. print "\n";
  45. }
  46. print "\n";
  47. print "SESSION_INACTIVE:\n";
  48. foreach my $k (keys(%session_inactive)) {
  49. print "$k ";
  50. foreach my $t (keys(%{$session_inactive{$k}})) {
  51. print " ($t ", $session_inactive{$k}->{$t}, ")";
  52. }
  53. print "\n";
  54. }
  55. print "\n";
  56. print "SESSION_REF_COUNT:\n";
  57. foreach my $k (keys(%session_ref_count)) {
  58. print "$k ", $session_ref_count{$k}, "\n";
  59. }
  60. }
  61. sub construct_key {
  62. my ($a, $b, $c, $h) = @_;
  63. my $h_k = "";
  64. if (defined($h))
  65. {
  66. foreach my $t (sort(keys(%$h)))
  67. {
  68. my ($x, $y) = ($t, $h->{$t});
  69. $x =~ s/([\\:])/\\$1/g;
  70. $y =~ s/([\\:])/\\$1/g;
  71. $h_k .= ":$x:$y";
  72. }
  73. }
  74. $a =~ s/([\\:])/\\$1/g;
  75. $b =~ s/([\\:])/\\$1/g;
  76. $c =~ s/([\\:])/\\$1/g;
  77. return "$a:$b:$c$h_k";
  78. }
  79. # remove from inactive hash
  80. # add to active hash
  81. # return session key
  82. sub activate_from_inactive_pool {
  83. my $k = shift;
  84. my $href = $session_inactive{$k};
  85. my ($ref, $v) = each %$href;
  86. delete $href->{$ref};
  87. delete $session_inactive{$k} if (scalar(keys(%{$href}))==0);
  88. my $session_key = $k . ":" . $ref;
  89. $session_active{$k}->{$ref} = 1;
  90. $session{$session_key}->{'active_timestamp'} = strftime "%a %b %e %H:%M:%S %Y", localtime;
  91. return $session_key;
  92. }
  93. sub deactivate_from_active_pool {
  94. my $session_key = shift;
  95. my $orig_sess = $session_key;
  96. $session_key =~ m/(.*):(\d+)$/;
  97. my ($k, $ref) = ($1, $2);
  98. delete $session_active{$k}->{$ref};
  99. delete $session_active{$k} if !scalar(keys(%{$session_active{$k}}));
  100. $session_inactive{$k} = {} if !exists($session_inactive{$k});
  101. $session_inactive{$k}->{$ref} = 1;
  102. }
  103. sub create_new_db_session {
  104. my ($k, $dsn, $user, $pass, $attr) = @_;
  105. my $ref = "0";
  106. my $dbh = DBI->connect($dsn, $user, $pass, $attr);
  107. return undef if (!$dbh);
  108. my $dbh_ref = \$dbh;
  109. if (!exists($session_ref_count{$k}))
  110. {
  111. $session_ref_count{$k} = 1;
  112. }
  113. else
  114. {
  115. $ref = $session_ref_count{$k}++;
  116. }
  117. my $session_key = $k . ":" . $ref;
  118. $session{$session_key} = {};
  119. $session{$session_key}->{'dbh_ref'} = $dbh_ref;
  120. $session{$session_key}->{'active_timestamp'} = strftime "%a %b %e %H:%M:%S %Y", localtime;
  121. $session{$session_key}->{'lock_active'} = 0;
  122. $query{$session_key} = {};
  123. $query_usage{$session_key} = {};
  124. $session_active{$k}->{$ref} = 1;
  125. return $session_key;
  126. }
  127. sub connect {
  128. my ($class_name, $dsn, $user, $pass, $attr) = @_;
  129. my $k = construct_key($dsn, $user, $pass, $attr);
  130. my $session_key = ( exists($session_inactive{$k}) ?
  131. activate_from_inactive_pool($k) :
  132. create_new_db_session($k, $dsn, $user, $pass, $attr) );
  133. return undef if !$session_key;
  134. my $class = {};
  135. $class->{'key'} = $session_key;
  136. $class->{'dbh_ref'} = $session{$session_key}->{'dbh_ref'};
  137. $class->{'active_timestamp'} = $session{$session_key}->{'active_timestamp'};
  138. bless($class, $class_name);
  139. my $dbh_ref = $session{$session_key}->{'dbh_ref'};
  140. if ( !( defined($$dbh_ref) && $$dbh_ref->ping) )
  141. {
  142. $$dbh_ref = DBI->connect($dsn, $user, $pass, $attr);
  143. $query{$session_key} = {};
  144. $query_usage{$session_key} = {};
  145. return undef if !$$dbh_ref;
  146. }
  147. return $class;
  148. }
  149. sub DESTROY {
  150. my $self = shift;
  151. deactivate_from_active_pool($self->{'key'});
  152. }
  153. sub prepare {
  154. my $self = shift;
  155. my $query = shift;
  156. my $session_key = $self->{'key'};
  157. my $dbh = ${$self->{'dbh_ref'}};
  158. if ( !defined($query{$session_key}->{$query}) )
  159. {
  160. $query{$session_key}->{$query} = $dbh->prepare($query);
  161. $query_usage{$session_key}->{$query} = 0;
  162. }
  163. $query_usage{$session_key}->{$query}++;
  164. return $query{$session_key}->{$query};
  165. }
  166. sub begin_work {
  167. my $self = shift;
  168. my $dbh = ${$self->{'dbh_ref'}};
  169. $dbh->begin_work();
  170. }
  171. sub finish {
  172. my $self = shift;
  173. my $r = shift;
  174. my $dbh = ${$self->{'dbh_ref'}};
  175. if ($r) {
  176. $dbh->commit();
  177. } else {
  178. $dbh->rollback();
  179. }
  180. }
  181. sub rollback {
  182. my $self = shift;
  183. my $dbh = ${$self->{'dbh_ref'}};
  184. $dbh->rollback();
  185. }
  186. sub commit {
  187. my $self = shift;
  188. my $dbh = ${$self->{'dbh_ref'}};
  189. $dbh->commit();
  190. }
  191. sub last_insert_id {
  192. my $self = shift;
  193. my $dbh = ${$self->{'dbh_ref'}};
  194. return $dbh->last_insert_id(undef, undef, undef, undef);
  195. }
  196. sub raise_error {
  197. my $self = shift;
  198. my $val = shift;
  199. my $dbh = ${$self->{'dbh_ref'}};
  200. return $dbh->{RaiseError} = $val;
  201. }
  202. sub rows {
  203. my $self = shift;
  204. my $dbh = ${$self->{'dbh_ref'}};
  205. return $dbh->rows;
  206. }
  207. sub errstr {
  208. my $self = shift;
  209. my $dbh = ${$self->{'dbh_ref'}};
  210. return $dbh->errstr;
  211. }
  212. sub lock_active {
  213. my $self = shift;
  214. my $v = shift;
  215. $self->{'lock_active'} = $v if defined($v);
  216. return $self->{'lock_active'};
  217. }
  218. sub disable_locking {
  219. my $self = shift;
  220. return $self->lock_active(1);
  221. }
  222. sub enable_locking {
  223. my $self = shift;
  224. return $self->lock_active(0);
  225. }
  226. sub get_query_usage_ref {
  227. my $self = shift;
  228. my $s = $self->{'key'};
  229. return $query_usage{$s};
  230. }
  231. return 1;