add support for hashrefs in insert insert_hashref
Matt S Trout [Sun, 18 Mar 2018 19:38:21 +0000 (19:38 +0000)]
Changes
lib/SQL/Abstract.pm
t/01generate.t

diff --git a/Changes b/Changes
index e2ca8f4..f29d2fd 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,6 @@
 Revision history for SQL::Abstract
 
+    - Add support for hashrefs in insert
     - Remove obsolete documentation about arrayrefref as the $source
       argument for ->select (removed in version 1.74)
     - Factor out the field list part of SELECT for subclassability (GH#13)
index bd512ca..dd55fb4 100644 (file)
@@ -330,12 +330,25 @@ sub _insert_value {
       push @all_bind, @bind;
     },
 
-    # THINK: anything useful to do with a HASHREF ?
-    HASHREF => sub {       # (nothing, but old SQLA passed it through)
-      #TODO in SQLA >= 2.0 it will die instead
-      belch "HASH ref as bind value in insert is not supported";
-      push @values, '?';
-      push @all_bind, $self->_bindtype($column, $v);
+    HASHREF => sub {
+      my ($op, $arg, @rest) = %$v;
+
+      if (@rest or not $op =~ /^\-(.+)/) {
+        #TODO in SQLA >= 2.0 it will die instead
+        belch "Operator calls in insert must be in the form { -op => $arg }, if you wanted a plain HASH ref as a bind value, please use -value";
+        push @values, '?';
+        push @all_bind, $self->_bindtype($column, $v);
+        return;
+      }
+
+      # column may be undef and this currently triggers a croak in
+      # _where_unary_op for the potentially-sane-here -ident and -value
+      # (we should probably improve the test for the croak)
+      local $self->{_nested_func_lhs} = $column || 'INSERT_ANON_COLUMN_NAME';
+      my ($sql, @bind) = $self->_where_unary_op($1, $arg);
+
+      push @values, $sql;
+      push @all_bind, @bind;
     },
 
     SCALARREF => sub {          # literal SQL without bind
index ebe3aad..dd72def 100644 (file)
@@ -323,7 +323,7 @@ my @tests = (
               stmt   => 'INSERT INTO test (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)',
               stmt_q => 'INSERT INTO `test` (`a`, `b`, `c`, `d`, `e`) VALUES (?, ?, ?, ?, ?)',
               bind   => [qw/1 2 3 4/, { answer => 42}],
-              warns  => qr/HASH ref as bind value in insert is not supported/i,
+              warns  => qr/use -value/i,
       },
       {
               func   => 'update',
@@ -486,6 +486,13 @@ my @tests = (
       },
       {
               func   => 'insert',
+              args   => ['test', [ { -value => { foo => 'bar' } } ] ],
+              stmt   => 'INSERT INTO test VALUES (?)',
+              stmt_q => 'INSERT INTO `test` VALUES (?)',
+              bind   => [ { foo => 'bar' } ],
+      },
+      {
+              func   => 'insert',
               args   => ['test', [qw/1 2 3 4 5/], { returning => 'id' }],
               stmt   => 'INSERT INTO test VALUES (?, ?, ?, ?, ?) RETURNING id',
               stmt_q => 'INSERT INTO `test` VALUES (?, ?, ?, ?, ?) RETURNING `id`',