changeset 11706:95b91d8c9ee2 octave-forge

Make returned type information recursive over composite type elements.
author i7tiol
date Thu, 16 May 2013 17:12:25 +0000
parents fadbf9722a93
children b8949643063c
files main/database/DESCRIPTION main/database/NEWS main/database/inst/pq_exec_params.m main/database/src/command.cc main/database/src/command.h
diffstat 5 files changed, 81 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/main/database/DESCRIPTION	Thu May 16 10:48:31 2013 +0000
+++ b/main/database/DESCRIPTION	Thu May 16 17:12:25 2013 +0000
@@ -1,6 +1,6 @@
 Name: database
 Version: 2.1.1
-Date: 2013-05-15
+Date: 2013-05-16
 Author: Olaf Till <i7tiol@t-online.de>
 Maintainer: Olaf Till <i7tiol@t-online.de>
 Title: Database.
--- a/main/database/NEWS	Thu May 16 10:48:31 2013 +0000
+++ b/main/database/NEWS	Thu May 16 17:12:25 2013 +0000
@@ -1,6 +1,5 @@
  ** pq_exec_params: For queries, information on postgresql data types
-    of columns is also returned (but not recursively for elements of
-    composite types).
+    of columns is also returned.
 
  ** New converters for geometric types (point, lseg, (line,) box,
     circle, polygon, path).
--- a/main/database/inst/pq_exec_params.m	Thu May 16 10:48:31 2013 +0000
+++ b/main/database/inst/pq_exec_params.m	Thu May 16 17:12:25 2013 +0000
@@ -75,9 +75,11 @@
 ## headers), and @code{types} (a  structure-vector with the postgresql
 ## data types of the columns, subfields @code{name} (string with
 ## typename), @code{is_array} (boolean), @code{is_composite} (boolean),
-## and @code{is_enum} (boolean)). For copy commands nothing is returned.
-## For other commands, the output will be the number of affected rows in
-## the database.
+## @code{is_enum} (boolean), and @code{elements} (if @code{is_composite
+## == true}, structure-vector of element types, containing fields
+## corresponding to those of @code{types})). For copy commands nothing
+## is returned. For other commands, the output will be the number of
+## affected rows in the database.
 ##
 ## Mapping of currently implemented Postgresql types to Octave types
 ##
--- a/main/database/src/command.cc	Thu May 16 10:48:31 2013 +0000
+++ b/main/database/src/command.cc	Thu May 16 17:12:25 2013 +0000
@@ -176,6 +176,55 @@
     }
 }
 
+octave_map command::get_elements_typeinfo (oct_pq_conv_t *conv, bool &err)
+{
+  int nel = conv->el_oids.size ();
+
+  octave_map ret (dim_vector (1, nel));
+  Cell types_name (1, nel);
+  Cell types_array (1, nel);
+  Cell types_composite (1, nel);
+  Cell types_enum (1, nel);
+  Cell types_elements (1, nel);
+
+  for (int i = 0; i < nel; i++)
+    {
+      oct_pq_conv_t *el_conv;
+      oct_type_t oct_type;
+
+      if (! (el_conv = pgtype_from_spec (conv->el_oids[i], conv->conv_cache[i],
+                                         oct_type)))
+        {
+          err = true;
+          return ret;
+        }
+
+      types_name(i) = octave_value (el_conv->name);
+      types_array(i) = octave_value (oct_type == array);
+      types_enum(i) = octave_value (el_conv->is_enum);
+      types_composite(i) = octave_value (el_conv->is_composite);
+      if (el_conv->is_composite)
+        {
+          bool rec_err = false;
+          types_elements(i) = octave_value (get_elements_typeinfo (el_conv,
+                                                                   rec_err));
+          if (rec_err)
+            {
+              err = true;
+              return ret;
+            }
+        }
+    }
+
+  ret.assign ("name", types_name);
+  ret.assign ("is_array", types_array);
+  ret.assign ("is_composite", types_composite);
+  ret.assign ("is_enum", types_enum);
+  ret.assign ("elements", types_elements);
+
+  return ret;
+}
+
 oct_pq_conv_t *command::pgtype_from_spec (std::string &name,
                                           oct_type_t &oct_type)
 {
@@ -341,6 +390,7 @@
   Cell types_array (1, nf);
   Cell types_composite (1, nf);
   Cell types_enum (1, nf);
+  Cell types_elements (1, nf);
   octave_map types (dim_vector (1, nf));
 
   bool rtypes_given;
@@ -409,10 +459,30 @@
           simple_type_to_octave = conv->to_octave_str;
         }
 
+      // prepare type information
       types_name(j) = octave_value (conv->name);
       types_array(j) = octave_value (oct_type == array);
+      types_enum(j) = octave_value (conv->is_enum);
       types_composite(j) = octave_value (conv->is_composite);
-      types_enum(j) = octave_value (conv->is_enum);
+      if (conv->is_composite)
+        {
+          // To implement here: recursively go through the elements
+          // and return respective recursive structures. This has the
+          // side effect that all converters necessary for this query
+          // will be looked up and cached (if they aren't already), so
+          // in the actual conversion of composite types only cache
+          // reads are performed, no map lookups.
+
+          bool err = false;
+
+          types_elements(j) = octave_value (get_elements_typeinfo (conv, err));
+
+          if (err)
+            {
+              valid = 0;
+              break;
+            }
+        }
 
       for (int i = 0; i < nt; i++) // i is row
         {
@@ -471,6 +541,7 @@
       types.setfield ("is_array", types_array);
       types.setfield ("is_composite", types_composite);
       types.setfield ("is_enum", types_enum);
+      types.setfield ("elements", types_elements);
       ret.assign ("types", octave_value (types));
 
       return octave_value (ret);
--- a/main/database/src/command.h	Thu May 16 10:48:31 2013 +0000
+++ b/main/database/src/command.h	Thu May 16 17:12:25 2013 +0000
@@ -90,6 +90,8 @@
 
   typedef enum {simple, array, composite} oct_type_t;
 
+  octave_map get_elements_typeinfo (oct_pq_conv_t *conv, bool &err);
+
   void check_first_result (void)
     {
       if (! res)