DBIx-Custom

 view release on metacpan or  search on metacpan

lib/DBIx/Custom.pm  view on Meta::CPAN

  # Created time and updated time
  if (defined $opt{ctime} || defined $opt{mtime}) {
    
    for my $param (@$params) {
      $param = {%$param};
    }
    my $now = $self->now;
    $now = $now->() if ref $now eq 'CODE';
    if (defined $opt{ctime}) {
      $_->{$opt{ctime}} = $now for @$params;
    }
    if (defined $opt{mtime}) {
      $_->{$opt{mtime}} = $now for @$params;
    }
  }
  
  # Merge id to parameter
  if (defined $opt{id} && !$multi) {
    
    _deprecate('0.39', "DBIx::Custom::insert method's id option is DEPRECATED!");
    
    for my $param (@$params) {
      $param = {%$param};
    }
    
    confess "insert id option must be specified with primary_key option"
      unless $opt{primary_key};
    $opt{primary_key} = [$opt{primary_key}] unless ref $opt{primary_key} eq 'ARRAY';
    $opt{id} = [$opt{id}] unless ref $opt{id} eq 'ARRAY';
    for (my $i = 0; $i < @{$opt{primary_key}}; $i++) {
      my $key = $opt{primary_key}->[$i];
      next if exists $params->[0]->{$key};
      $params->[0]->{$key} = $opt{id}->[$i];
    }
  }
  
  if ($opt{bulk_insert}) {
    $sql .= $self->_multi_values_clause($params, {wrap => $opt{wrap}}) . " ";
    my $new_param = {};
    $new_param->{$_} = [] for keys %{$params->[0]};
    for my $param (@$params) {
      push @{$new_param->{$_}}, $param->{$_} for keys %$param;
    }
    $params = [$new_param];
  }
  else {
    $sql .= $self->values_clause($params->[0], {wrap => $opt{wrap}}) . " ";
  }
  
  # Execute query
  if (@$params > 1) {
    for my $param (@$params) {
      $self->execute($sql, $param, %opt);
    }
  }
  else {
    $self->execute($sql, $params->[0], %opt);
  }
}

sub update {
  my $self = shift;

  # Options
  my $param = @_ % 2 ? shift : undef;
  my %opt = @_;
  $param ||= {};
  
  # Don't allow update all rows
  confess qq{update method where option must be specified } . _subname
    if !$opt{where} && !defined $opt{id} && !$opt{allow_update_all};
  
  # Created time and updated time
  if (defined $opt{mtime}) {
    $param = {%$param};
    my $now = $self->now;
    $now = $now->() if ref $now eq 'CODE';
    $param->{$opt{mtime}} = $self->now->();
  }

  # Assign clause
  my $assign_clause = $self->assign_clause($param, {wrap => $opt{wrap}});
  
  # Where
  my $where;
  if (defined $opt{id}) {
    $where = $self->_id_to_param($opt{id}, $opt{primary_key}, $opt{table}) ;
  }
  else {
    $where = $opt{where};
  }
  
  my $w = $self->_where_clause_and_param($where);
  
  # Merge update parameter with where parameter
  $param = $self->merge_param($param, $w->{param});
  
  # Update statement
  my $sql = "update ";
  $sql .= "$opt{prefix} " if defined $opt{prefix};
  $sql .= $self->_tq($opt{table}) . " set $assign_clause $w->{clause} ";
  
  # Execute query
  $self->execute($sql, $param, %opt);
}

sub update_all { shift->update(@_, allow_update_all => 1) };

sub values_clause {
  my ($self, $param, $opts) = @_;
  
  my $wrap = $opts->{wrap} || {};
  
  # Create insert parameter tag
  my ($q, $p) = $self->_qp;
  
  my $safety_character = $self->safety_character;
  
  my @columns;
  my @place_holders;
  for my $column (sort keys %$param) {
    confess qq{"$column" is not safety column name in values clause} . _subname
      unless $column =~ /^[$safety_character\.]+$/;

    push @columns, "$q$column$p";
    push @place_holders, ref $param->{$column} eq 'SCALAR' ? ${$param->{$column}} :
      $wrap->{$column} ? $wrap->{$column}->(":$column") :
      ":$column";
  }
  
  my $values_clause = '(' . join(', ', @columns) . ') values (' . join(', ', @place_holders) . ')';
  
  return $values_clause;
}

sub assign_clause {
  my ($self, $param, $opts) = @_;
  
  my $wrap = $opts->{wrap} || {};
  my ($q, $p) = $self->_qp;

  my $safety_character = $self->safety_character;

  my @set_values;
  for my $column (sort keys %$param) {
    confess qq{"$column" is not safety column name in assign clause} . _subname
      unless $column =~ /^[$safety_character\.]+$/;
      
    push @set_values, ref $param->{$column} eq 'SCALAR' ? "$q$column$p = " . ${$param->{$column}}
      : $wrap->{$column} ? "$q$column$p = " . $wrap->{$column}->(":$column")
      : "$q$column$p = :$column";
  }
  
  my $assign_clause = join(', ', @set_values);
  
  return $assign_clause;
}

sub where { DBIx::Custom::Where->new(dbi => shift, @_) }

sub type_rule {
  my $self = shift;

  $self->{_type_rule_is_called} = 1;
  
  if (@_) {
    my $type_rule = ref $_[0] eq 'HASH' ? $_[0] : {@_};

lib/DBIx/Custom.pm  view on Meta::CPAN

    elsif (ref $where eq 'ARRAY') {
      $obj = $self->where(clause => $where->[0], param => $where->[1], join => $where->[2]);
    }
    
    # Check where argument
    confess qq{"where" must be hash reference or DBIx::Custom::Where object}
        . qq{or array reference, which contains where clause and parameter}
        . _subname
      unless ref $obj eq 'DBIx::Custom::Where';

    $w->{clause} = $obj->to_string;
    $w->{param} = $obj->param;
    $w->{join} = $obj->{join};
  }
  elsif ($where) {
    $w->{clause} = "where $where";
  }
  
  return $w;
}

# DEPRECATED
our $AUTOLOAD;
sub AUTOLOAD {
  my $self = shift;
  
  _deprecate('0.39', "DBIx::Custom AUTOLOAD feature is DEPRECATED!");
  
  # Method name
  my ($package, $mname) = $AUTOLOAD =~ /^([\w\:]+)\:\:(\w+)$/;

  # Call method
  $self->{_methods} ||= {};
  if (my $method = $self->{_methods}->{$mname}) {
    return $self->$method(@_)
  }
  elsif ($self->{dbh} && (my $dbh_method = $self->dbh->can($mname))) {
    $self->dbh->$dbh_method(@_);
  }
  else {
    confess qq{Can't locate object method "$mname" via "$package" }
      . _subname;
  }
}
sub DESTROY {}

# DEPRECATED
sub helper {
  my $self = shift;
  
  _deprecate('0.39', "DBIx::Custom::helper method is DEPRECATED!");
  
  # Register method
  my $methods = ref $_[0] eq 'HASH' ? $_[0] : {@_};
  $self->{_methods} = {%{$self->{_methods} || {}}, %$methods};
  
  return $self;
}

# DEPRECATED
sub update_or_insert {

  _deprecate('0.39', "DBIx::Custom::update_or_insert method is DEPRECATED!");

  my ($self, $param, %opt) = @_;
  confess "update_or_insert method need primary_key and id option "
    unless defined $opt{id} && defined $opt{primary_key};
  my $statement_opt = $opt{option} || {};

  my $rows = $self->select(%opt, %{$statement_opt->{select} || {}})->all;
  if (@$rows == 0) {
    return $self->insert($param, %opt, %{$statement_opt->{insert} || {}});
  }
  elsif (@$rows == 1) {
    return 0 unless keys %$param;
    return $self->update($param, %opt, %{$statement_opt->{update} || {}});
  }
  else { confess "selected row must be one " . _subname }
}

# DEPRECATED
sub count {
  _deprecate('0.39', "DBIx::Custom::count method is DEPRECATED!");
  shift->select(column => 'count(*)', @_)->fetch_one->[0]
}

1;

=head1 NAME

DBIx::Custom - DBI extension to execute insert, update, delete, and select easily

=head1 SYNOPSIS

  use DBIx::Custom;
  
  # Connect
  my $dbi = DBIx::Custom->connect(
    "dbi:mysql:database=dbname",
    'ken',
    '!LFKD%$&',
    {mysql_enable_utf8 => 1}
  );
  
  # Create model
  $dbi->create_model('book');
  
  # Insert 
  $dbi->model('book')->insert({title => 'Perl', author => 'Ken'});
  
  # Update 
  $dbi->model('book')->update({title => 'Perl', author => 'Ken'}, where  => {id => 5});
  
  # Delete
  $dbi->model('book')->delete(where => {author => 'Ken'});
  
  # Select
  my $result = $dbi->model('book')->select(['title', 'author'], where  => {author => 'Ken'});
  
  # Select, more complex
  #   select book.title as book.title,



( run in 0.686 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )