summaryrefslogtreecommitdiff
path: root/LedgerSMB/DBObject.pm
blob: 17e4e4b049b2c2264a1e112934febd0d26c1dd1b (plain)
  1. =head1 NAME
  2. LedgerSMB::DBObject - LedgerSMB class for building objects from db relations
  3. =head1 SYOPSIS
  4. This module creates object instances based on LedgerSMB's in-database ORM.
  5. =head1 METHODS
  6. =item find_method ($hashref, $function_name, @args)
  7. =item merge ($hashref, @attrs)
  8. copies @attrs from $hashref to $self.
  9. =head1 Copyright (C) 2007, The LedgerSMB core team.
  10. This file is licensed under the Gnu General Public License version 2, or at your
  11. option any later version. A copy of the license should have been included with
  12. your software.
  13. =back
  14. =cut
  15. package LedgerSMB::DBObject;
  16. use LedgerSMB;
  17. use strict;
  18. no strict 'refs';
  19. use warnings;
  20. our @ISA = qw(LedgerSMB);
  21. sub new {
  22. my $self = shift @_;
  23. my $lsmb = shift @_;
  24. if (! $lsmb->isa('LedgerSMB')){
  25. $self->error("Constructor called without LedgerSMB object arg");
  26. }
  27. $self = {};
  28. my $attr;
  29. for $attr (keys %{$lsmb}){
  30. $self->{$attr} = $lsmb->{$attr};
  31. }
  32. bless $self;
  33. }
  34. sub exec_method {
  35. my ($self) = shift @_;
  36. my ($funcname) = shift @_;
  37. my $query =
  38. "SELECT proname, proargnames FROM pg_proc WHERE proname = ?";
  39. my $sth = $self->{dbh}->prepare($query);
  40. $sth->execute($funcname);
  41. my $ref;
  42. $ref = $sth->fetchrow_hashref('NAME_lc');
  43. my $args = $ref->{proargnames};
  44. $args =~ s/\{(.*)\}/$1/;
  45. my @proc_args = split /,/, $args;
  46. if (!$ref){ # no such function
  47. $self->error("No such function: ", $funcname);
  48. die;
  49. }
  50. my $m_name = $ref->{proname};
  51. my @call_args;
  52. if ($args){
  53. for my $arg (@proc_args){
  54. if ($arg =~ s/^in_//){
  55. push @call_args, $self->{$arg};
  56. }
  57. }
  58. }
  59. else {
  60. @call_args = @_;
  61. }
  62. $self->callproc($funcname, @call_args);
  63. }
  64. sub run_custom_queries {
  65. my ($self, $tablename, $query_type, $linenum) = @_;
  66. my $dbh = $self->{dbh};
  67. if ($query_type !~ /^(select|insert|update)$/i){
  68. $self->error($locale->text(
  69. "Passed incorrect query type to run_custom_queries."
  70. ));
  71. }
  72. my @rc;
  73. my %temphash;
  74. my @templist;
  75. my @elements;
  76. my $query;
  77. my $ins_values;
  78. if ($linenum){
  79. $linenum = "_$linenum";
  80. }
  81. $query_type = uc($query_type);
  82. for (@{$self->{custom_db_fields}{$tablename}}){
  83. @elements = split (/:/, $_);
  84. push @{$temphash{$elements[0]}}, $elements[1];
  85. }
  86. for (keys %temphash){
  87. my @data;
  88. my $ins_values;
  89. $query = "$query_type ";
  90. if ($query_type eq 'UPDATE'){
  91. $query = "DELETE FROM $_ WHERE row_id = ?";
  92. my $sth = $dbh->prepare($query);
  93. $sth->execute->($self->{"id"."$linenum"})
  94. || $self->dberror($query);
  95. } elsif ($query_type eq 'INSERT'){
  96. $query .= " INTO $_ (";
  97. }
  98. my $first = 1;
  99. for (@{$temphash{$_}}){
  100. $query .= "$_";
  101. if ($query_type eq 'UPDATE'){
  102. $query .= '= ?';
  103. }
  104. $ins_values .= "?, ";
  105. $query .= ", ";
  106. $first = 0;
  107. if ($query_type eq 'UPDATE' or $query_type eq 'INSERT'){
  108. push @data, $self->{"$_$linenum"};
  109. }
  110. }
  111. if ($query_type ne 'INSERT'){
  112. $query =~ s/, $//;
  113. }
  114. if ($query_type eq 'SELECT'){
  115. $query .= " FROM $_";
  116. }
  117. if ($query_type eq 'SELECT' or $query_type eq 'UPDATE'){
  118. $query .= " WHERE row_id = ?";
  119. }
  120. if ($query_type eq 'INSERT'){
  121. $query .= " row_id) VALUES ($ins_values ?)";
  122. }
  123. if ($query_type eq 'SELECT'){
  124. push @rc, [ $query ];
  125. } else {
  126. unshift (@data, $query);
  127. push @rc, [ @data ];
  128. }
  129. }
  130. if ($query_type eq 'INSERT'){
  131. for (@rc){
  132. $query = shift (@{$_});
  133. $sth = $dbh->prepare($query)
  134. || $self->db_error($query);
  135. $sth->execute(@{$_}, $self->{id})
  136. || $self->dberror($query);;
  137. $sth->finish;
  138. $did_insert = 1;
  139. }
  140. } elsif ($query_type eq 'UPDATE'){
  141. @rc = $self->run_custom_queries(
  142. $tablename, 'INSERT', $linenum);
  143. } elsif ($query_type eq 'SELECT'){
  144. for (@rc){
  145. $query = shift @{$_};
  146. $sth = $self->{dbh}->prepare($query);
  147. $sth->execute($self->{id});
  148. $ref = $sth->fetchrow_hashref(NAME_lc);
  149. for (keys %{$ref}){
  150. $self->{$_} = $ref->{$_};
  151. }
  152. }
  153. }
  154. @rc;
  155. }
  156. 1;