Mercurial > forge
changeset 11661:1b4e81051b66 octave-forge
Add converter for timestamp.
author | i7tiol |
---|---|
date | Sat, 27 Apr 2013 19:17:33 +0000 |
parents | cbff4e8a8af8 |
children | fbd81057dab0 |
files | main/database/NEWS main/database/doc/dev-postgresql/timeformats.txt main/database/inst/pq_exec_params.m main/database/src/converters.cc main/database/src/converters.h |
diffstat | 5 files changed, 142 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/main/database/NEWS Sat Apr 27 17:58:18 2013 +0000 +++ b/main/database/NEWS Sat Apr 27 19:17:33 2013 +0000 @@ -1,3 +1,5 @@ + ** New converter for type timestamp. + ** New function pq_conninfo. ** Fix for includes on Apple.
--- a/main/database/doc/dev-postgresql/timeformats.txt Sat Apr 27 17:58:18 2013 +0000 +++ b/main/database/doc/dev-postgresql/timeformats.txt Sat Apr 27 19:17:33 2013 +0000 @@ -1,7 +1,7 @@ timestamp: Timestamp (8 byte, float or int) (microseconds (int) or seconds -(float) before or after 'midnight' 2000-01-01; does not fit range?) +(float) before or after 2000-01-01 00:00) timestamptz:
--- a/main/database/inst/pq_exec_params.m Sat Apr 27 17:58:18 2013 +0000 +++ b/main/database/inst/pq_exec_params.m Sat Apr 27 19:17:33 2013 +0000 @@ -126,6 +126,10 @@ ## storing the 'small currency' (e.g. Cent) fraction in the last two ## digits ## @tab yes +## @item timestamp +## @tab 8-byte-time-value (see below), positive or negative time +## interval from 2000-01-01 00:00. +## @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), @@ -150,10 +154,17 @@ ## @tab yes ## @end multitable ## +## 8-byte-time-value: int64 scalar, representing microseconds, if server +## is configured for integer date/time; double scalar, representing +## seconds, if server is configured for float date/time (deprecated). +## There is no automatic conversion from an octave variable, an error is +## thrown if the wrong of both types is supplied. One can use +## @code{pq_conninfo} to query the respective server configuration. +## ## Octaves @code{NA} corresponds to a Postgresql NULL value (not ## @code{NaN}, which is interpreted as a value of a float type!). ## -## @seealso {pq_update_types} +## @seealso {pq_update_types, pq_conninfo} ## @end deftypefn ## PKG_ADD: __all_db_opts__ ("pq_exec_params");
--- a/main/database/src/converters.cc Sat Apr 27 17:58:18 2013 +0000 +++ b/main/database/src/converters.cc Sat Apr 27 19:17:33 2013 +0000 @@ -24,6 +24,7 @@ #include <libpq-fe.h> #include "converters.h" +#include "pq_connection.h" // remember to adjust OCT_PQ_NUM_CONVERTERS in converters.h @@ -664,6 +665,129 @@ /* end type money */ +// helpers for time types + +static inline octave_value time_8byte_to_octave (const char *c, bool int_dt) +{ + if (int_dt) + { + return octave_value (octave_int64 (int64_t (be64toh (*((int64_t *) c))))); + } + else + { + union + { + double d; + int64_t i; + } + swap; + + swap.i = be64toh (*((int64_t *) c)); + + return octave_value (swap.d); + } +} + +static inline int time_8byte_from_octave (const octave_value &ov, + oct_pq_dynvec_t &val, + bool int_dt) +{ + if (int_dt) + { + // don't convert automatically because of possible overflow + if (ov.is_float_type ()) + { + error ("floating point octave_value provided for 8-byte time value, but postgresql is configured for int64"); + return 1; + } + + int64_t i8 = ov.int64_scalar_value (); + + if (error_state) + { + error ("can not convert octave_value to int64 time value"); + return 1; + } + + OCT_PQ_PUT(val, int64_t, htobe64 (i8)) + + return 0; + } + else + { + // don't convert automatically because of possible loss of accuracy + if (ov.is_integer_type ()) + { + error ("integer type octave_value provided for 8-byte time value, but postgresql is configured for double"); + return 1; + } + + union + { + double d; + int64_t i; + } + swap; + + swap.d = ov.double_value (); + + if (error_state) + { + error ("can not convert octave_value to double time value"); + return 1; + } + + OCT_PQ_PUT(val, int64_t, htobe64 (swap.i)) + + return 0; + } +} + +// end helpers for time types + +/* type timestamp */ + +int to_octave_str_timestamp (const octave_pq_connection &conn, + const char *c, octave_value &ov, int nb) +{ + return 1; +} + +int to_octave_bin_timestamp (const octave_pq_connection &conn, + const char *c, octave_value &ov, int nb) +{ + ov = time_8byte_to_octave (c, conn.integer_datetimes); + + return 0; +} + +int from_octave_str_timestamp (const octave_pq_connection &conn, + const octave_value &ov, oct_pq_dynvec_t &val) +{ + return 1; +} + +int from_octave_bin_timestamp (const octave_pq_connection &conn, + const octave_value &ov, oct_pq_dynvec_t &val) +{ + return (time_8byte_from_octave (ov, val, conn.integer_datetimes)); +} + +oct_pq_conv_t conv_timestamp = {0, + 0, + oct_pq_el_oids_t (), + oct_pq_conv_cache_t (), + false, + false, + false, + "timestamp", + &to_octave_str_timestamp, + &to_octave_bin_timestamp, + &from_octave_str_timestamp, + &from_octave_bin_timestamp}; + +/* end type timestamp */ + oct_pq_conv_t *t_conv_ptrs[OCT_PQ_NUM_CONVERTERS] = {&conv_bool, &conv_oid, &conv_float8, @@ -676,6 +800,7 @@ &conv_int2, &conv_int4, &conv_int8, - &conv_money}; + &conv_money, + &conv_timestamp}; oct_pq_conv_ptrs_t conv_ptrs (OCT_PQ_NUM_CONVERTERS, t_conv_ptrs);