changeset 11408:6c22f62f2b64 octave-forge

Resumed to and finished copy-in/-out only from/to files.
author i7tiol
date Tue, 22 Jan 2013 19:30:46 +0000
parents f4098c7d5b35
children 21794ea37065
files main/database/NEWS main/database/doc/README-postgresql main/database/src/command.cc main/database/src/command.h main/database/src/pq_exec.cc
diffstat 5 files changed, 39 insertions(+), 353 deletions(-) [+]
line wrap: on
line diff
--- a/main/database/NEWS	Tue Jan 22 18:45:48 2013 +0000
+++ b/main/database/NEWS	Tue Jan 22 19:30:46 2013 +0000
@@ -12,13 +12,15 @@
 pq_exec_params: execute an SQL command with optional parameters and
                 return result,
 
-pq_update_types: used if defined types change during connection time.
+pq_update_types: used if defined types change during connection time,
 
-pq_lo_import: import large object from client side
+pq_lo_import: import large object from client side,
 
-pq_lo_export: export large object to client side
+pq_lo_export: export large object to client side,
 
-pq_lo_unlink: delete large object
+pq_lo_unlink: delete large object,
+
+pq_close: disconnect from database.
 
 
 Features:
@@ -40,15 +42,15 @@
 
 
 Alpha, but can already be useful. Not all base types implemented yet,
-also no enum types yet. Copy in and copy are not yet implemented. The
-other commands should work. The whole framework including conversion
-of composite and array types with the resulting possible recursion and
-a number of base types are implemented. Large object import, export,
-and unlink works.
+also no enum types yet. All commands should work with pq_exec_params,
+copy from stdin and copy to stdout are implemented from/to files at
+client side. The whole framework including conversion of composite and
+array types with the resulting possible recursion and a number of base
+types are implemented. Large object import, export, and unlink works.
 
-Please report bugs. If you want to implement a new type-converter
-yourself, you can do it in converters.cc and tell me (package
-maintainer) about it. See converters.h for the meaning of fields in
-the oct_pq_conv_t structure. Presently only the binary converters are
-needed, the string converters can be stubs returning an error value
-(1).
+Please report bugs. If you want to implement a new type-converter for
+a base type yourself, you can do it in converters.cc and tell me
+(package maintainer) about it. See converters.h for the meaning of
+fields in the oct_pq_conv_t structure. Presently only the binary
+converters are needed, the string converters can be stubs returning an
+error value (1).
--- a/main/database/doc/README-postgresql	Tue Jan 22 18:45:48 2013 +0000
+++ b/main/database/doc/README-postgresql	Tue Jan 22 19:30:46 2013 +0000
@@ -39,11 +39,11 @@
 
 
 Alpha, but can already be useful. Not all base types implemented yet,
-also no enum types yet. Copy in and copy are not yet implemented. The
-other commands should work. The whole framework including conversion
-of composite and array types with the resulting possible recursion and
-a number of base types are implemented. Large object import, export,
-and unlink works.
+also no enum types yet. All commands should work with pq_exec_params,
+copy from stdin and copy to stdout are implemented from/to files at
+client side. The whole framework including conversion of composite and
+array types with the resulting possible recursion and a number of base
+types are implemented. Large object import, export, and unlink works.
 
 Please report bugs. If you want to implement a new type-converter for
 a base type yourself, you can do it in converters.cc and tell me
--- a/main/database/src/command.cc	Tue Jan 22 18:45:48 2013 +0000
+++ b/main/database/src/command.cc	Tue Jan 22 19:30:46 2013 +0000
@@ -248,11 +248,7 @@
 }
 
 octave_value command::process_single_result (const std::string &infile,
-                                             const std::string &outfile,
-                                             int nargout,
-                                             const Cell &data,
-                                             bool cin_oids,
-                                             const Cell &cin_types)
+                                             const std::string &outfile)
 {
   octave_value retval;
 
@@ -282,10 +278,10 @@
           retval = tuples_ok_handler ();
           break;
         case PGRES_COPY_OUT:
-          retval = copy_out_handler (outfile, nargout);
+          retval = copy_out_handler (outfile);
           break;
         case PGRES_COPY_IN:
-          retval = copy_in_handler (infile, data, cin_oids, cin_types);
+          retval = copy_in_handler (infile);
           break;
         }
 
@@ -444,7 +440,7 @@
     }
 }
 
-octave_value command::copy_out_handler (const std::string &outfile, int nargout)
+octave_value command::copy_out_handler (const std::string &outfile)
 {
   octave_value retval;
 
@@ -486,32 +482,17 @@
           else
             error ("unexpectedly got no result information");
         }
-
-      if (error_state)
-        valid = 0;
-    }
-  else if (nargout)
-    {
-      // return output data
-
-      error ("copy-out to variable not yet implemented");
-
-      valid = 0;
     }
   else
-    {
-      error ("neither output argument nor filename given for copy-out");
+    error ("no filename given for copy-out");
 
-      valid = 0;
-    }
+  if (error_state)
+    valid = 0;
 
   return retval;
 }
 
-octave_value command::copy_in_handler (const std::string &infile,
-                                       const Cell &data,
-                                       bool oids,
-                                       const Cell &cin_types)
+octave_value command::copy_in_handler (const std::string &infile)
 {
   octave_value retval;
 
@@ -587,225 +568,9 @@
                 error ("unexpectedly got no result information");
             }
         }
-
-      if (error_state)
-        valid = 0;
-    }
-  else if (! data.is_empty ())
-    {
-      // read input from argument
-
-      dim_vector dv = data.dims ();
-      octave_idx_type r = dv(0);
-      octave_idx_type c = dv(1);
-
-      octave_idx_type nf = PQnfields (res);
-      if (c != nf + oids)
-        {
-          error ("argument for copy-in has unexpected number of columns");
-
-          PQputCopyEnd
-            (cptr, "argument for copy-in has unexpected number of columns");
-        }
-      else if (! PQbinaryTuples (res))
-        {
-          error ("copy-in from argument must use binary mode");
-
-          PQputCopyEnd (cptr, "copy-in from argument must use binary mode");
-        }
-      else
-        {
-          for (octave_idx_type j = 0; j < c; j++)
-            if (! PQfformat (res, j))
-              {
-                error ("copy-in from argument must use binary mode in all columns");
-
-                PQputCopyEnd (cptr, "copy-in from argument must use binary mode in all columns");
-
-                break;
-              }
-        }
-
-      if (error_state)
-        {
-          error ("server error: %s", PQerrorMessage (cptr));
-
-          valid = 0;
-
-          return retval;
-        }
-
-#define COPY_HEADER_SIZE 19
-      char header [COPY_HEADER_SIZE];
-      memset (header, 0, COPY_HEADER_SIZE);
-      strcpy (header, "PGCOPY\n\377\r\n\0");
-      *((uint32_t *) (&header[11])) = htobe32 (uint32_t (oids) << 16);
-
-      char trailer [2];
-      *((int16_t *) (&trailer)) = htobe16 (int16_t (-1));
-
-      if (PQputCopyData (cptr, header, COPY_HEADER_SIZE) == -1)
-        {
-          PQputCopyEnd (cptr, "could not send header");
-
-          error ("server error: %s", PQerrorMessage (cptr));
-        }
-      else
-        {
-          oct_type_t oct_types [c];
-          oct_pq_conv_t *convs [c];
-          // FIXME: this can't prevent repetition of lookups in recursive types
-          bool type_determined [c];
-          memset (type_determined, 0, sizeof (type_determined));
-
-          for (octave_idx_type i = 0; i < r; i++) // i is row
-            {
-              int16_t fc = htobe16 (int16_t (nf));
-              if (PQputCopyData (cptr, (char *) &fc, 2) == -1)
-                {
-                  error ("%s", PQerrorMessage (cptr));
-
-                  PQputCopyEnd (cptr, "error sending field count");
-
-                  error ("server error: %s", PQerrorMessage (cptr));
-
-                  break;
-                }
-
-              // j is column of argument data
-              for (octave_idx_type j = 0; j < c; j++)
-                {
-                  if (data(i, j).is_real_scalar () &&
-                      data(i, j).isna ().bool_value ())
-                    {
-                      int32_t t = htobe32 (int32_t (-1));
-                      if (PQputCopyData (cptr, (char *) &t, 4) == -1)
-                        {
-                          error ("could not send NULL in copy-in");
-
-                          break;
-                        }
-                    }
-                  else
-                    {
-                      if (! type_determined [j])
-                        {
-                          if ((j == 0) && oids)
-                            {
-                              std::string t ("oid");
-                              convs[0] = pgtype_from_spec (t, oct_types[0]);
-                            }
-                          else
-                            {
-                              if (cin_types(j).is_empty ())
-                                {
-                                  oct_types[j] = simple;
-
-                                  if (! (convs[j] =
-                                         pgtype_from_octtype (data(i, j))))
-                                    {
-                                      error ("could not determine type in column %i for copy-in",
-                                             j);
-
-                                      break;
-                                    }
-                                }
-                              else
-                                {
-                                  std::string s = cin_types(j).string_value ();
-                                  if (error_state)
-                                    {
-                                      error ("column type specification no string");
-
-                                      break;
-                                    }
-
-                                  if (! (convs[j] =
-                                         pgtype_from_spec (s, oct_types[j])))
-                                    {
-                                      error ("invalid column type specification");
-
-                                      break;
-                                    }
-                                }
-                            }
-
-                          type_determined [j] = true;
-                        } // ! type_determined [j]
-
-                      oct_pq_dynvec_t val;
-
-                      bool conversion_failed = false;
-                      switch (oct_types[j])
-                        {
-                        case simple:
-                          if (convs[j]->from_octave_bin (data(i, j), val))
-                            conversion_failed = true;
-                          break;
-
-                        case array:
-                          if (from_octave_bin_array (data(i, j), val, convs[j]))
-                            conversion_failed = true;
-
-                        case composite:
-                          if (from_octave_bin_composite (data(i, j), val,
-                                                         convs[j]))
-                            conversion_failed = true;
-
-                        default:
-                          // should not get here
-                          error ("internal error, undefined type identifier");
-                        }
-
-                      if (conversion_failed)
-                        error ("could not convert data(%i, %i) for copy-in",
-                               i, j);
-                      else
-                        if (PQputCopyData (cptr, &(val.front ()),
-                                           val.size ()) == -1)
-                          error ("could not send copy-in data");
-
-                      if (error_state) break;
-                    }
-                } // column of argument data
-
-              if (error_state)
-                {
-                  PQputCopyEnd (cptr, "error sending copy-in data");
-
-                  error ("server error: %s", PQerrorMessage (cptr));
-
-                  break;
-                }
-            } // row of argument data
-        }
-
-      if (! error_state)
-        if (PQputCopyData (cptr, trailer, 2) == -1)
-          {
-            PQputCopyEnd (cptr, "could not send trailer");
-
-            error ("%s", PQerrorMessage (cptr));
-          }
-
-      if (! error_state)
-        if (PQputCopyEnd (cptr, NULL) == -1)
-          error ("%s", PQerrorMessage (cptr));
-        else
-          {
-            PQclear (res);
-
-            if (res = PQgetResult (cptr))
-              {
-                if ((state = PQresultStatus (res)) == PGRES_FATAL_ERROR)
-                  error ("server error in copy-in: %s", PQerrorMessage (cptr));
-              }
-            else
-              error ("unexpectedly got no result information");
-          }
     }
   else
-    error ("neither data nor filename given for copy-in");
+    error ("no filename given for copy-in");
 
   if (error_state)
     valid = 0;
--- a/main/database/src/command.h	Tue Jan 22 18:45:48 2013 +0000
+++ b/main/database/src/command.h	Tue Jan 22 19:30:46 2013 +0000
@@ -72,15 +72,11 @@
   {
     Cell c;
     // inlining should prevent the additional copy
-    return process_single_result ("", "", 0, c, false, c);
+    return process_single_result ("", "");
   }
 
   octave_value process_single_result (const std::string &infile,
-                                      const std::string &outfile,
-                                      int nargout,
-                                      const Cell &data,
-                                      bool cin_oids,
-                                      const Cell &cin_types);
+                                      const std::string &outfile);
 
   int good (void) {return valid;}
 
@@ -113,10 +109,9 @@
 
   octave_value tuples_ok_handler (void);
 
-  octave_value copy_out_handler (const std::string &, int);
+  octave_value copy_out_handler (const std::string &);
 
-  octave_value copy_in_handler (const std::string &, const Cell &, bool oids,
-                                const Cell &cin_types);
+  octave_value copy_in_handler (const std::string &);
 
   oct_pq_conv_t *pgtype_from_octtype (const octave_value &);
 
--- a/main/database/src/pq_exec.cc	Tue Jan 22 18:45:48 2013 +0000
+++ b/main/database/src/pq_exec.cc	Tue Jan 22 19:30:46 2013 +0000
@@ -113,8 +113,9 @@
 Settings currently understood by @code{pq_exec_params}:\n\
 \n\
 @code{param_types}: One-dimensional cell-array with type specifications for parameters in @var{params}. If present, must have the same length as @var{params}. Entries may be empty if no specification is necessary (see below). Type specifications are strings corresponding to the entries returned by @code{SELECT typname FROM pg_type WHERE typarray != 0 OR typtype = 'c';}, optionally having @code{[]} appended (without space) to indicate an array.\n\
+@code{copy_in_path}, @code{copy_out_path}: Path to files at the client side for @code{copy from stdin} and @code{copy to stdout}, respectively.\n\
 \n\
-For queries (commands potentially returning data), the output will be a structure with fields @code{data} (containing a cell array with the data, columns correspond to returned database columns, rows correspond to returned tuples) and @code{columns} (containing the column headers). Copy commands do not work as yet. For other commands, the output will be the number of affected rows in the database.\n\
+For queries (commands potentially returning data), the output will be a structure with fields @code{data} (containing a cell array with the data, columns correspond to returned database columns, rows correspond to returned tuples) and @code{columns} (containing the column headers). For copy commands nothing is returned. For other commands, the output will be the number of affected rows in the database.\n\
 \n\
 Mapping of currently implemented Postgresql types to Octave types\n\
 \n\
@@ -181,7 +182,7 @@
   if (nargs == 1 && args(0).is_string () &&
       args(0).string_value () == "defaults")
     {
-      octave_value_list f_args (12);
+      octave_value_list f_args (6);
       Matrix a;
       Cell c;
 
@@ -191,12 +192,6 @@
       f_args(3) = octave_value ("");
       f_args(4) = octave_value ("copy_out_path");
       f_args(5) = octave_value ("");
-      f_args(6) = octave_value ("copy_in_data");
-      f_args(7) = octave_value (c);
-      f_args(8) = octave_value ("copy_in_oids");
-      f_args(9) = octave_value (false);
-      f_args(10) = octave_value ("copy_in_types");
-      f_args(11) = octave_value (c);
 
       return feval ("setdbopts", f_args, 1);
     }
@@ -337,42 +332,6 @@
       return retval;
     }
 
-  f_args(1) = octave_value ("copy_in_data");
-  f_args(2) = octave_value (Cell ());
-
-  f_ret = feval ("getdbopts", f_args, 1);
-  Cell cin_data = f_ret(0).cell_value ();
-  if (error_state)
-    {
-      error ("could not convert copy_in_data to cell");
-
-      return retval;
-    }
-
-  f_args(1) = octave_value ("copy_in_oids");
-  f_args(2) = octave_value (false);
-
-  f_ret = feval ("getdbopts", f_args, 1);
-  bool cin_oids = f_ret(0).bool_value ();
-  if (error_state)
-    {
-      error ("could not convert copy_in_oids to bool");
-
-      return retval;
-    }
-
-  f_args(1) = octave_value ("copy_in_types");
-  f_args(2) = octave_value (Cell ());
-
-  f_ret = feval ("getdbopts", f_args, 1);
-  Cell cin_types = f_ret(0).cell_value ();
-  if (error_state)
-    {
-      error ("could not convert copy_in_types to cell");
-
-      return retval;
-    }
-
   // check option settings
 
   if (ptypes.length () != nparams)
@@ -383,40 +342,6 @@
       return retval;
     }
 
-  if (nargout && ! cout_path.empty ())
-    {
-      error ("%s: copy out pathname and output argument may not be both given",
-             fname.c_str ());
-
-      return retval;
-    }
-
-  if (! cin_path.empty () && ! cin_data.is_empty ())
-    {
-      error ("%s: copy in pathname and copy in data may not be both given",
-             fname.c_str ());
-
-      return retval;
-    }
-
-  dim_vector cind_dv = cin_data.dims ();
-  if (cind_dv.length () > 2)
-    {
-      error ("%s: copy-in data must not be more than two-dimensional",
-             fname.c_str ());
-
-      return retval;
-    }
-
-  if (cin_types.is_empty ())
-    cin_types.resize (dim_vector (1, cind_dv(1)));
-  if (cin_types.numel () != cind_dv(1))
-    {
-      error ("%s: copy_in_types has wrong number of elements");
-
-      return retval;
-    }
-
   //
 
   Cell rtypes;
@@ -424,8 +349,7 @@
   command c (oct_pq_conn, cmd, params, ptypes, rtypes, fname);
 
   if (c.good ())
-    retval = c.process_single_result
-      (cin_path, cout_path, nargout, cin_data, cin_oids, cin_types);
+    retval = c.process_single_result (cin_path, cout_path);
 
   return retval;
 }