Mercurial > forge
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);