changeset 11697:9e624fa135a1 octave-forge

Added converters for geometric types.
author i7tiol
date Sun, 12 May 2013 10:19:34 +0000
parents a69badc25735
children b3cbebad8a26
files main/database/DESCRIPTION main/database/NEWS main/database/inst/pq_exec_params.m main/database/src/command.cc main/database/src/converters.cc main/database/src/converters.h
diffstat 6 files changed, 537 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/main/database/DESCRIPTION	Fri May 10 14:06:23 2013 +0000
+++ b/main/database/DESCRIPTION	Sun May 12 10:19:34 2013 +0000
@@ -1,6 +1,6 @@
 Name: database
 Version: 2.1.1
-Date: 2013-04-28
+Date: 2013-05-12
 Author: Olaf Till <i7tiol@t-online.de>
 Maintainer: Olaf Till <i7tiol@t-online.de>
 Title: Database.
--- a/main/database/NEWS	Fri May 10 14:06:23 2013 +0000
+++ b/main/database/NEWS	Sun May 12 10:19:34 2013 +0000
@@ -1,3 +1,6 @@
+ ** New converters for geometric types (point, lseg, (line,) box,
+    circle, polygon, path).
+
  ** New converters for date/time types (timestamp, timestamptz, time,
     timetz, date, interval).
 
--- a/main/database/inst/pq_exec_params.m	Fri May 10 14:06:23 2013 +0000
+++ b/main/database/inst/pq_exec_params.m	Sun May 12 10:19:34 2013 +0000
@@ -147,6 +147,29 @@
 ## @tab 3-element cell array with 8-byte-time-value (see below), int32
 ## (days), and int32 (months)
 ## @tab yes
+## @item point
+## @tab geometric point data for one point (see below)
+## @tab no
+## @item lseg
+## @tab geometric point data for two points (see below)
+## @tab no
+## @item line (not yet implemented by postgresql-9.2.4)
+## @tab as lseg
+## @tab yes
+## @item box
+## @tab as lseg
+## @tab yes
+## @item cirle
+## @tab real vector (not uint8) with 3 elements, no. 1 and 2 centre
+## coordinates, no. 3 radius
+## @tab no
+## @item polygon
+## @tab geometric point data (see below)
+## @tab yes
+## @item path
+## @tab structure with fields @code{closed} (boolean, is path closed?)
+## and @code{path} (geometric point data, see below).
+## @tab yes
 ## @item any array
 ## @tab Structure with fields @code{data} (holding a cell-array with
 ## entries of a type corresponding to the Postgresql element type),
@@ -178,6 +201,12 @@
 ## thrown if the wrong of both types is supplied. One can use
 ## @code{pq_conninfo} to query the respective server configuration.
 ##
+## geometric point data: any real array (but not of type uint8, for this
+## is reserved for bytea) with even number of elements. Two adjacent
+## elements (adjacent if indexed with a single index) define a pair of
+## 2D point coordinates. In converting from postgresql data, dimensions
+## of Octave geometric point data will be chosen to be (2, n_points).
+##
 ## Octaves @code{NA} corresponds to a Postgresql NULL value (not
 ## @code{NaN}, which is interpreted as a value of a float type!).
 ##
--- a/main/database/src/command.cc	Fri May 10 14:06:23 2013 +0000
+++ b/main/database/src/command.cc	Sun May 12 10:19:34 2013 +0000
@@ -905,5 +905,23 @@
       return conn.name_conv_map["text"];
     }
 
+  // is_real_type() is true for strings, so is_numeric_type() would
+  // still be needed if strings were not recognized above
+  if (param.is_real_type ())
+    {
+      switch (param.numel ())
+        {
+        case 2:
+          // printf ("point\n");
+          return conn.name_conv_map["point"];
+        case 3:
+          // printf ("circle\n");
+          return conn.name_conv_map["circle"];
+        case 4:
+          // printf ("lseg\n");
+          return conn.name_conv_map["lseg"];
+        }
+    }
+
   ERROR_RETURN_NO_PG_TYPE
 }
--- a/main/database/src/converters.cc	Fri May 10 14:06:23 2013 +0000
+++ b/main/database/src/converters.cc	Sun May 12 10:19:34 2013 +0000
@@ -18,6 +18,7 @@
 */
 
 #include <octave/oct.h>
+#include <octave/ov-struct.h>
 #include <octave/ov-float.h>
 #include <octave/ov-uint8.h>
 #include <octave/Cell.h>
@@ -1050,8 +1051,483 @@
                            &from_octave_str_date,
                            &from_octave_bin_date};
 
+/* end type date */
 
-/* end type date */
+/* type point */
+
+int to_octave_str_point (const octave_pq_connection &conn,
+                         const char *c, octave_value &ov, int nb)
+{
+  return 1;
+}
+
+int to_octave_bin_point (const octave_pq_connection &conn,
+                         const char *c, octave_value &ov, int nb)
+{
+  ColumnVector m (2);
+
+  union
+  {
+    double d;
+    int64_t i;
+  }
+  swap;
+
+  for (int id = 0; id < 2; id++, c += 8)
+    {
+      swap.i = be64toh (*((int64_t *) c));
+
+      m(id) = swap.d;
+    }
+
+  ov = octave_value (m);
+
+  return 0;
+}
+
+int from_octave_str_point (const octave_pq_connection &conn,
+                           const octave_value &ov, oct_pq_dynvec_t &val)
+{
+  return 1;
+}
+
+int from_octave_bin_point (const octave_pq_connection &conn,
+                           const octave_value &ov, oct_pq_dynvec_t &val)
+{
+  NDArray m = ov.array_value ();
+
+  if (error_state || m.numel () != 2)
+    {
+      error ("can not convert octave_value to point representation");
+      return 1;
+    }
+
+  union
+  {
+    double d;
+    int64_t i;
+  }
+  swap;
+
+  for (int id = 0; id < 2; id++)
+    {
+      swap.d = m(id);
+
+      OCT_PQ_PUT(val, int64_t, htobe64 (swap.i))
+    }
+
+  return 0;
+}
+
+oct_pq_conv_t conv_point = {0,
+                            0,
+                            oct_pq_el_oids_t (),
+                            oct_pq_conv_cache_t (),
+                            false,
+                            false,
+                            false,
+                            "point",
+                            &to_octave_str_point,
+                            &to_octave_bin_point,
+                            &from_octave_str_point,
+                            &from_octave_bin_point};
+
+/* end type point */
+
+/* type lseg */
+
+int to_octave_str_lseg (const octave_pq_connection &conn,
+                        const char *c, octave_value &ov, int nb)
+{
+  return 1;
+}
+
+int to_octave_bin_lseg (const octave_pq_connection &conn,
+                        const char *c, octave_value &ov, int nb)
+{
+  Matrix m (2, 2);
+
+  union
+  {
+    double d;
+    int64_t i;
+  }
+  swap;
+
+  for (int id = 0; id < 4; id++, c += 8)
+    {
+      swap.i = be64toh (*((int64_t *) c));
+
+      m(id) = swap.d;
+    }
+
+  ov = octave_value (m);
+
+  return 0;
+}
+
+int from_octave_str_lseg (const octave_pq_connection &conn,
+                          const octave_value &ov, oct_pq_dynvec_t &val)
+{
+  return 1;
+}
+
+int from_octave_bin_lseg (const octave_pq_connection &conn,
+                          const octave_value &ov, oct_pq_dynvec_t &val)
+{
+  NDArray m = ov.array_value ();
+
+  if (error_state || m.numel () != 4)
+    {
+      error ("can not convert octave_value to 4 doubles");
+      return 1;
+    }
+
+  union
+  {
+    double d;
+    int64_t i;
+  }
+  swap;
+
+  for (int id = 0; id < 4; id++)
+    {
+      swap.d = m(id);
+
+      OCT_PQ_PUT(val, int64_t, htobe64 (swap.i))
+    }
+
+  return 0;
+}
+
+oct_pq_conv_t conv_lseg = {0,
+                           0,
+                           oct_pq_el_oids_t (),
+                           oct_pq_conv_cache_t (),
+                           false,
+                           false,
+                           false,
+                           "lseg",
+                           &to_octave_str_lseg,
+                           &to_octave_bin_lseg,
+                           &from_octave_str_lseg,
+                           &from_octave_bin_lseg};
+
+/* end type lseg */
+
+/* type line */
+
+oct_pq_conv_t conv_line = {0,
+                           0,
+                           oct_pq_el_oids_t (),
+                           oct_pq_conv_cache_t (),
+                           false,
+                           false,
+                           false,
+                           "line",
+                           &to_octave_str_lseg,
+                           &to_octave_bin_lseg,
+                           &from_octave_str_lseg,
+                           &from_octave_bin_lseg};
+
+/* end type line */
+
+/* type box */
+
+oct_pq_conv_t conv_box = {0,
+                          0,
+                          oct_pq_el_oids_t (),
+                          oct_pq_conv_cache_t (),
+                          false,
+                          false,
+                          false,
+                          "box",
+                          &to_octave_str_lseg,
+                          &to_octave_bin_lseg,
+                          &from_octave_str_lseg,
+                          &from_octave_bin_lseg};
+
+/* end type box */
+
+/* type circle */
+
+int to_octave_str_circle (const octave_pq_connection &conn,
+                          const char *c, octave_value &ov, int nb)
+{
+  return 1;
+}
+
+int to_octave_bin_circle (const octave_pq_connection &conn,
+                          const char *c, octave_value &ov, int nb)
+{
+  ColumnVector m (3);
+
+  union
+  {
+    double d;
+    int64_t i;
+  }
+  swap;
+
+  for (int id = 0; id < 3; id++, c += 8)
+    {
+      swap.i = be64toh (*((int64_t *) c));
+
+      m(id) = swap.d;
+    }
+
+  ov = octave_value (m);
+
+  return 0;
+}
+
+int from_octave_str_circle (const octave_pq_connection &conn,
+                            const octave_value &ov, oct_pq_dynvec_t &val)
+{
+  return 1;
+}
+
+int from_octave_bin_circle (const octave_pq_connection &conn,
+                            const octave_value &ov, oct_pq_dynvec_t &val)
+{
+  NDArray m = ov.array_value ();
+
+  if (error_state || m.numel () != 3)
+    {
+      error ("can not convert octave_value to circle representation");
+      return 1;
+    }
+
+  union
+  {
+    double d;
+    int64_t i;
+  }
+  swap;
+
+  for (int id = 0; id < 3; id++)
+    {
+      swap.d = m(id);
+
+      OCT_PQ_PUT(val, int64_t, htobe64 (swap.i))
+    }
+
+  return 0;
+}
+
+oct_pq_conv_t conv_circle = {0,
+                             0,
+                             oct_pq_el_oids_t (),
+                             oct_pq_conv_cache_t (),
+                             false,
+                             false,
+                             false,
+                             "circle",
+                             &to_octave_str_circle,
+                             &to_octave_bin_circle,
+                             &from_octave_str_circle,
+                             &from_octave_bin_circle};
+
+/* end type circle */
+
+/* type polygon */
+
+int to_octave_str_polygon (const octave_pq_connection &conn,
+                           const char *c, octave_value &ov, int nb)
+{
+  return 1;
+}
+
+int to_octave_bin_polygon (const octave_pq_connection &conn,
+                           const char *c, octave_value &ov, int nb)
+{
+  int32_t np = int32_t (be32toh (*((int32_t *) c)));
+
+  c += 4;
+
+  Matrix m (2, np);
+
+  union
+  {
+    double d;
+    int64_t i;
+  }
+  swap;
+
+  for (int id = 0; id < np * 2; id++, c += 8)
+    {
+      swap.i = be64toh (*((int64_t *) c));
+
+      m(id) = swap.d;
+    }
+
+  ov = octave_value (m);
+
+  return 0;
+}
+
+int from_octave_str_polygon (const octave_pq_connection &conn,
+                             const octave_value &ov, oct_pq_dynvec_t &val)
+{
+  return 1;
+}
+
+int from_octave_bin_polygon (const octave_pq_connection &conn,
+                             const octave_value &ov, oct_pq_dynvec_t &val)
+{
+  octave_idx_type nel;
+
+  NDArray m = ov.array_value ();
+
+  if (error_state || (nel = m.numel ()) % 2)
+    {
+      error ("can not convert octave_value to polygon representation");
+      return 1;
+    }
+
+  union
+  {
+    double d;
+    int64_t i;
+  }
+  swap;
+
+  int32_t np = nel / 2;
+
+  OCT_PQ_PUT(val, int32_t, htobe32 (np))
+
+  for (int id = 0; id < nel; id++)
+    {
+      swap.d = m(id);
+
+      OCT_PQ_PUT(val, int64_t, htobe64 (swap.i))
+    }
+
+  return 0;
+}
+
+oct_pq_conv_t conv_polygon = {0,
+                              0,
+                              oct_pq_el_oids_t (),
+                              oct_pq_conv_cache_t (),
+                              false,
+                              false,
+                              false,
+                              "polygon",
+                              &to_octave_str_polygon,
+                              &to_octave_bin_polygon,
+                              &from_octave_str_polygon,
+                              &from_octave_bin_polygon};
+
+/* end type polygon */
+
+/* type path */
+
+int to_octave_str_path (const octave_pq_connection &conn,
+                        const char *c, octave_value &ov, int nb)
+{
+  return 1;
+}
+
+int to_octave_bin_path (const octave_pq_connection &conn,
+                        const char *c, octave_value &ov, int nb)
+{
+  bool closed = bool (*(c++));
+
+  int32_t np = int32_t (be32toh (*((int32_t *) c)));
+
+  c += 4;
+
+  Matrix m (2, np);
+
+  union
+  {
+    double d;
+    int64_t i;
+  }
+  swap;
+
+  for (int id = 0; id < np * 2; id++, c += 8)
+    {
+      swap.i = be64toh (*((int64_t *) c));
+
+      m(id) = swap.d;
+    }
+
+  octave_scalar_map tp;
+  tp.assign ("closed", octave_value (closed));
+  tp.assign ("path", octave_value (m));
+
+  ov = octave_value (tp);
+
+  return 0;
+}
+
+int from_octave_str_path (const octave_pq_connection &conn,
+                          const octave_value &ov, oct_pq_dynvec_t &val)
+{
+  return 1;
+}
+
+int from_octave_bin_path (const octave_pq_connection &conn,
+                          const octave_value &ov, oct_pq_dynvec_t &val)
+{
+  octave_scalar_map tp = ov.scalar_map_value ();
+  if (error_state || ! tp.isfield ("closed") || ! tp.isfield ("path"))
+    {
+      error ("can not convert octave_value to path representation");
+      return 1;
+    }
+
+  octave_idx_type nel;
+
+  char closed = char (tp.contents ("closed").bool_value ());
+
+  NDArray m = tp.contents ("path").array_value ();
+
+  if (error_state || (nel = m.numel ()) % 2)
+    {
+      error ("can not convert octave_value to path representation");
+      return 1;
+    }
+
+  union
+  {
+    double d;
+    int64_t i;
+  }
+  swap;
+
+  int32_t np = nel / 2;
+
+  val.push_back (closed);
+
+  OCT_PQ_PUT(val, int32_t, htobe32 (np))
+
+  for (int id = 0; id < nel; id++)
+    {
+      swap.d = m(id);
+
+      OCT_PQ_PUT(val, int64_t, htobe64 (swap.i))
+    }
+
+  return 0;
+}
+
+oct_pq_conv_t conv_path = {0,
+                           0,
+                           oct_pq_el_oids_t (),
+                           oct_pq_conv_cache_t (),
+                           false,
+                           false,
+                           false,
+                           "path",
+                           &to_octave_str_path,
+                           &to_octave_bin_path,
+                           &from_octave_str_path,
+                           &from_octave_bin_path};
+
+/* end type path */
 
 oct_pq_conv_t *t_conv_ptrs[OCT_PQ_NUM_CONVERTERS] = {&conv_bool,
                                                      &conv_oid,
@@ -1071,6 +1547,13 @@
                                                      &conv_interval,
                                                      &conv_time,
                                                      &conv_timetz,
-                                                     &conv_date};
+                                                     &conv_date,
+                                                     &conv_point,
+                                                     &conv_lseg,
+                                                     &conv_line,
+                                                     &conv_box,
+                                                     &conv_circle,
+                                                     &conv_polygon,
+                                                     &conv_path};
 
 oct_pq_conv_ptrs_t conv_ptrs (OCT_PQ_NUM_CONVERTERS, t_conv_ptrs);
--- a/main/database/src/converters.h	Fri May 10 14:06:23 2013 +0000
+++ b/main/database/src/converters.h	Sun May 12 10:19:34 2013 +0000
@@ -32,7 +32,7 @@
 
 #include "wrap_endian.h"
 
-#define OCT_PQ_NUM_CONVERTERS 19
+#define OCT_PQ_NUM_CONVERTERS 26
 
 typedef std::vector<char> oct_pq_dynvec_t;