globegit-postgresql-plruby 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Changes +121 -0
- data/README.markdown +155 -0
- data/Rakefile +48 -0
- data/docs/plruby.rb +1931 -0
- data/ex_trans.sql +33 -0
- data/extconf.rb +267 -0
- data/plruby.html +1454 -0
- data/plruby.rd +1571 -0
- data/postgresql-plruby.gemspec +56 -0
- data/src/conversions.h +5 -0
- data/src/conversions/basic/conversions.h +25 -0
- data/src/conversions/basic/extconf.rb +8 -0
- data/src/conversions/basic/plruby_basic.c +357 -0
- data/src/conversions/bitstring/bitstring.sql +75 -0
- data/src/conversions/bitstring/conversions.h +15 -0
- data/src/conversions/bitstring/extconf.rb +8 -0
- data/src/conversions/bitstring/plruby_bitstring.c +579 -0
- data/src/conversions/convcommon.h +129 -0
- data/src/conversions/datetime/conversions.h +13 -0
- data/src/conversions/datetime/extconf.rb +8 -0
- data/src/conversions/datetime/plruby_datetime.c +269 -0
- data/src/conversions/geometry/conversions.h +37 -0
- data/src/conversions/geometry/extconf.rb +8 -0
- data/src/conversions/geometry/geometry.sql +196 -0
- data/src/conversions/geometry/plruby_geometry.c +2494 -0
- data/src/conversions/network/conversions.h +21 -0
- data/src/conversions/network/extconf.rb +8 -0
- data/src/conversions/network/network.sql +63 -0
- data/src/conversions/network/plruby_network.c +537 -0
- data/src/package.h +20 -0
- data/src/plpl.c +1708 -0
- data/src/plplan.c +893 -0
- data/src/plruby.c +1676 -0
- data/src/plruby.h +324 -0
- data/src/pltrans.c +388 -0
- data/test/conv_bitstring/b.rb +45 -0
- data/test/conv_bitstring/runtest +26 -0
- data/test/conv_bitstring/test.expected.73 +148 -0
- data/test/conv_bitstring/test.expected.74 +148 -0
- data/test/conv_bitstring/test.expected.80 +148 -0
- data/test/conv_bitstring/test.expected.81 +148 -0
- data/test/conv_bitstring/test.expected.82 +148 -0
- data/test/conv_bitstring/test.expected.83 +148 -0
- data/test/conv_bitstring/test.expected.84 +148 -0
- data/test/conv_bitstring/test.out +148 -0
- data/test/conv_bitstring/test_mklang.sql +8 -0
- data/test/conv_bitstring/test_queries.sql +63 -0
- data/test/conv_bitstring/test_queries.sql.in +63 -0
- data/test/conv_geometry/b.rb +45 -0
- data/test/conv_geometry/runtest +26 -0
- data/test/conv_geometry/test.expected.73 +265 -0
- data/test/conv_geometry/test.expected.74 +265 -0
- data/test/conv_geometry/test.expected.80 +265 -0
- data/test/conv_geometry/test.expected.81 +265 -0
- data/test/conv_geometry/test.expected.82 +265 -0
- data/test/conv_geometry/test.expected.83 +265 -0
- data/test/conv_geometry/test.expected.84 +265 -0
- data/test/conv_geometry/test.out +265 -0
- data/test/conv_geometry/test_mklang.sql +8 -0
- data/test/conv_geometry/test_queries.sql +194 -0
- data/test/conv_geometry/test_queries.sql.in +194 -0
- data/test/conv_network/b.rb +45 -0
- data/test/conv_network/runtest +26 -0
- data/test/conv_network/test.expected.73 +213 -0
- data/test/conv_network/test.expected.74 +237 -0
- data/test/conv_network/test.expected.80 +237 -0
- data/test/conv_network/test.expected.81 +237 -0
- data/test/conv_network/test.expected.82 +237 -0
- data/test/conv_network/test.expected.83 +237 -0
- data/test/conv_network/test.expected.84 +237 -0
- data/test/conv_network/test.out +237 -0
- data/test/conv_network/test_mklang.sql +8 -0
- data/test/conv_network/test_queries.sql +60 -0
- data/test/conv_network/test_queries.sql.in +60 -0
- data/test/plp/b.rb +34 -0
- data/test/plp/runtest +29 -0
- data/test/plp/test.expected.73 +472 -0
- data/test/plp/test.expected.74 +472 -0
- data/test/plp/test.expected.75 +472 -0
- data/test/plp/test.expected.80 +472 -0
- data/test/plp/test.expected.81 +472 -0
- data/test/plp/test.expected.82 +472 -0
- data/test/plp/test.expected.83 +472 -0
- data/test/plp/test.expected.84 +472 -0
- data/test/plp/test.out +472 -0
- data/test/plp/test_mklang.sql +8 -0
- data/test/plp/test_queries.sql +273 -0
- data/test/plp/test_setup.sql +931 -0
- data/test/plp/test_setup.sql.in +931 -0
- data/test/plt/b.rb +34 -0
- data/test/plt/runtest +29 -0
- data/test/plt/test.expected.73 +178 -0
- data/test/plt/test.expected.74 +178 -0
- data/test/plt/test.expected.75 +178 -0
- data/test/plt/test.expected.80 +178 -0
- data/test/plt/test.expected.81 +178 -0
- data/test/plt/test.expected.82 +178 -0
- data/test/plt/test.expected.83 +164 -0
- data/test/plt/test.expected.84 +168 -0
- data/test/plt/test.out +168 -0
- data/test/plt/test_mklang.sql +8 -0
- data/test/plt/test_queries.sql +72 -0
- data/test/plt/test_setup.sql +252 -0
- data/test/plt/test_setup.sql.in +252 -0
- data/test/range/b.rb +45 -0
- data/test/range/runtest +26 -0
- data/test/range/test.expected.73 +396 -0
- data/test/range/test.expected.73.in +396 -0
- data/test/range/test.expected.74 +396 -0
- data/test/range/test.expected.74.in +396 -0
- data/test/range/test.expected.75 +396 -0
- data/test/range/test.expected.75.in +396 -0
- data/test/range/test.expected.80 +396 -0
- data/test/range/test.expected.81 +397 -0
- data/test/range/test.expected.82 +397 -0
- data/test/range/test.expected.83 +397 -0
- data/test/range/test.expected.84 +399 -0
- data/test/range/test.out +399 -0
- data/test/range/test_mklang.sql +8 -0
- data/test/range/test_queries.sql +249 -0
- data/test/range/test_queries.sql.in +249 -0
- metadata +207 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rbconfig'
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = 'globegit-postgresql-plruby'
|
6
|
+
spec.version = '0.5.4'
|
7
|
+
spec.authors = ['Akinori MUSHA', 'Guy Decoux']
|
8
|
+
spec.license = 'Ruby'
|
9
|
+
spec.email = 'akinori@musha.org'
|
10
|
+
spec.homepage = 'https://github.com/knu/postgresql-plruby'
|
11
|
+
spec.summary = 'Enable Ruby for use as a procedural language within PostgreSQL'
|
12
|
+
spec.test_files = Dir['test/test*']
|
13
|
+
spec.extensions = ['extconf.rb']
|
14
|
+
spec.files = Dir['**/*'].reject{ |f| f.include?('git') || f.include?('tmp') }
|
15
|
+
|
16
|
+
spec.rubyforge_project = 'plruby'
|
17
|
+
|
18
|
+
spec.extra_rdoc_files = [
|
19
|
+
'README.markdown',
|
20
|
+
'Changes'
|
21
|
+
] + Dir['ext/*.c']
|
22
|
+
|
23
|
+
spec.description = <<-EOF
|
24
|
+
PL/Ruby is a loadable procedural language for the PostgreSQL database
|
25
|
+
system that enables the Ruby language to create functions and trigger
|
26
|
+
procedures.
|
27
|
+
EOF
|
28
|
+
|
29
|
+
plruby_bin = 'plruby.' + Config::CONFIG['DLEXT']
|
30
|
+
plruby_dir = File.join('postgresql-plruby-' + spec.version.to_s, 'src')
|
31
|
+
path_to_binary = File.join(Gem.dir, 'gems', plruby_dir, plruby_bin)
|
32
|
+
|
33
|
+
possible_paths = Gem.path.map{ |path|
|
34
|
+
File.join(path, 'gems', plruby_dir, plruby_bin)
|
35
|
+
}
|
36
|
+
|
37
|
+
spec.post_install_message = <<-EOF
|
38
|
+
|
39
|
+
Now run the following commands from within a postgresql shell in order
|
40
|
+
to create the plruby language on in database server:
|
41
|
+
|
42
|
+
create function plruby_call_handler() returns language_handler
|
43
|
+
as '#{path_to_binary}'
|
44
|
+
language 'C';
|
45
|
+
|
46
|
+
create trusted language 'plruby'
|
47
|
+
handler plruby_call_handler
|
48
|
+
lancompiler 'PL/Ruby';
|
49
|
+
|
50
|
+
NOTE: Your actual path to #{plruby_bin} may be different. Possible
|
51
|
+
paths to the plruby binary are:
|
52
|
+
|
53
|
+
#{possible_paths.join("\n ")}
|
54
|
+
|
55
|
+
EOF
|
56
|
+
end
|
data/src/conversions.h
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
{
|
2
|
+
extern void plruby_require(char *);
|
3
|
+
|
4
|
+
plruby_require("plruby/plruby_basic");
|
5
|
+
rb_hash_aset(plruby_classes, INT2NUM(OIDOID), rb_cFixnum);
|
6
|
+
rb_hash_aset(plruby_classes, INT2NUM(INT2OID), rb_cFixnum);
|
7
|
+
rb_hash_aset(plruby_classes, INT2NUM(INT4OID), rb_cFixnum);
|
8
|
+
rb_hash_aset(plruby_classes, INT2NUM(INT8OID), rb_cFixnum);
|
9
|
+
|
10
|
+
rb_hash_aset(plruby_classes, INT2NUM(FLOAT4OID), rb_cFloat);
|
11
|
+
rb_hash_aset(plruby_classes, INT2NUM(FLOAT8OID), rb_cFloat);
|
12
|
+
rb_hash_aset(plruby_classes, INT2NUM(CASHOID), rb_cFloat);
|
13
|
+
rb_hash_aset(plruby_classes, INT2NUM(NUMERICOID), rb_cFloat);
|
14
|
+
|
15
|
+
rb_hash_aset(plruby_classes, INT2NUM(TIMESTAMPOID), rb_cTime);
|
16
|
+
rb_hash_aset(plruby_classes, INT2NUM(TIMESTAMPTZOID), rb_cTime);
|
17
|
+
rb_hash_aset(plruby_classes, INT2NUM(ABSTIMEOID), rb_cTime);
|
18
|
+
rb_hash_aset(plruby_classes, INT2NUM(DATEOID), rb_cTime);
|
19
|
+
rb_hash_aset(plruby_classes, INT2NUM(RELTIMEOID), rb_cTime);
|
20
|
+
rb_hash_aset(plruby_classes, INT2NUM(INTERVALOID), rb_cTime);
|
21
|
+
rb_hash_aset(plruby_classes, INT2NUM(TIMETZOID), rb_cTime);
|
22
|
+
rb_hash_aset(plruby_classes, INT2NUM(TIMEOID), rb_cTime);
|
23
|
+
|
24
|
+
rb_hash_aset(plruby_classes, ULONG2NUM(BYTEAOID), rb_cString);
|
25
|
+
}
|
@@ -0,0 +1,357 @@
|
|
1
|
+
#include "convcommon.h"
|
2
|
+
|
3
|
+
#include <utils/cash.h>
|
4
|
+
#include <utils/date.h>
|
5
|
+
#include <utils/nabstime.h>
|
6
|
+
#include <utils/pg_locale.h>
|
7
|
+
#include <utils/timestamp.h>
|
8
|
+
#include <math.h>
|
9
|
+
|
10
|
+
static double cash_divisor;
|
11
|
+
static Timestamp epoch;
|
12
|
+
static ID id_at, id_to_f, id_to_i, id_usec;
|
13
|
+
|
14
|
+
static VALUE
|
15
|
+
pl_fixnum_s_datum(VALUE obj, VALUE a)
|
16
|
+
{
|
17
|
+
Oid typoid;
|
18
|
+
Datum value;
|
19
|
+
|
20
|
+
value = plruby_datum_get(a, &typoid);
|
21
|
+
switch (typoid) {
|
22
|
+
case OIDOID:
|
23
|
+
return UINT2NUM(DatumGetObjectId(value));
|
24
|
+
|
25
|
+
case INT2OID:
|
26
|
+
return INT2NUM(DatumGetInt16(value));
|
27
|
+
|
28
|
+
case INT4OID:
|
29
|
+
return INT2NUM(DatumGetInt32(value));
|
30
|
+
|
31
|
+
case INT8OID:
|
32
|
+
return LL2NUM(DatumGetInt64(value));
|
33
|
+
|
34
|
+
default:
|
35
|
+
rb_raise(rb_eArgError, "unknown OID type %d", typoid);
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
static VALUE
|
40
|
+
pl_fixnum_to_datum(VALUE obj, VALUE a)
|
41
|
+
{
|
42
|
+
Datum d;
|
43
|
+
|
44
|
+
switch (plruby_datum_oid(a, NULL)) {
|
45
|
+
case OIDOID:
|
46
|
+
d = ObjectIdGetDatum(NUM2UINT(obj));
|
47
|
+
break;
|
48
|
+
|
49
|
+
case INT2OID:
|
50
|
+
d = Int16GetDatum(NUM2INT(obj));
|
51
|
+
break;
|
52
|
+
|
53
|
+
case INT4OID:
|
54
|
+
d = Int32GetDatum(NUM2INT(obj));
|
55
|
+
break;
|
56
|
+
|
57
|
+
case INT8OID:
|
58
|
+
d = Int64GetDatum(NUM2LL(obj));
|
59
|
+
break;
|
60
|
+
|
61
|
+
default:
|
62
|
+
return Qnil;
|
63
|
+
}
|
64
|
+
return plruby_datum_set(a, d);
|
65
|
+
}
|
66
|
+
|
67
|
+
static VALUE
|
68
|
+
pl_float_s_datum(VALUE obj, VALUE a)
|
69
|
+
{
|
70
|
+
Oid typoid;
|
71
|
+
Datum value;
|
72
|
+
double result;
|
73
|
+
|
74
|
+
value = plruby_datum_get(a, &typoid);
|
75
|
+
switch (typoid) {
|
76
|
+
case FLOAT4OID:
|
77
|
+
result = DatumGetFloat4(value);
|
78
|
+
break;
|
79
|
+
|
80
|
+
case FLOAT8OID:
|
81
|
+
result = DatumGetFloat8(value);
|
82
|
+
break;
|
83
|
+
|
84
|
+
case CASHOID:
|
85
|
+
result = (double) *(Cash *) DatumGetPointer(value) / cash_divisor;
|
86
|
+
break;
|
87
|
+
|
88
|
+
case NUMERICOID:
|
89
|
+
result = DatumGetFloat8(plruby_dfc1(numeric_float8, value));
|
90
|
+
break;
|
91
|
+
|
92
|
+
default:
|
93
|
+
rb_raise(rb_eArgError, "unknown OID type %d", typoid);
|
94
|
+
}
|
95
|
+
return rb_float_new(result);
|
96
|
+
}
|
97
|
+
|
98
|
+
extern double round();
|
99
|
+
|
100
|
+
static VALUE
|
101
|
+
pl_float_to_datum(VALUE obj, VALUE a)
|
102
|
+
{
|
103
|
+
double value;
|
104
|
+
Datum d;
|
105
|
+
|
106
|
+
value = RFLOAT_VALUE(obj);
|
107
|
+
switch (plruby_datum_oid(a, NULL)) {
|
108
|
+
case FLOAT4OID:
|
109
|
+
d = Float4GetDatum((float4)value);
|
110
|
+
break;
|
111
|
+
|
112
|
+
case FLOAT8OID:
|
113
|
+
d = Float8GetDatum((float8)value);
|
114
|
+
break;
|
115
|
+
|
116
|
+
case CASHOID:
|
117
|
+
{
|
118
|
+
Cash *cash = (Cash *) palloc(sizeof(Cash));
|
119
|
+
*cash = (Cash) round(value * cash_divisor);
|
120
|
+
d = PointerGetDatum(cash);
|
121
|
+
break;
|
122
|
+
}
|
123
|
+
|
124
|
+
case NUMERICOID:
|
125
|
+
d = plruby_dfc1(float8_numeric, Float8GetDatum((float8)value));
|
126
|
+
break;
|
127
|
+
|
128
|
+
default:
|
129
|
+
return Qnil;
|
130
|
+
}
|
131
|
+
return plruby_datum_set(a, d);
|
132
|
+
}
|
133
|
+
|
134
|
+
static VALUE
|
135
|
+
pl_str_s_datum(VALUE klass, VALUE a)
|
136
|
+
{
|
137
|
+
bytea *data;
|
138
|
+
Oid typoid;
|
139
|
+
Datum value;
|
140
|
+
|
141
|
+
value = plruby_datum_get(a, &typoid);
|
142
|
+
if (typoid != BYTEAOID) {
|
143
|
+
return Qnil;
|
144
|
+
}
|
145
|
+
data = DatumGetByteaP(value);
|
146
|
+
return rb_str_new(VARDATA(data), VARSIZE(data) - VARHDRSZ);
|
147
|
+
}
|
148
|
+
|
149
|
+
static VALUE
|
150
|
+
pl_str_to_datum(VALUE obj, VALUE a)
|
151
|
+
{
|
152
|
+
bytea *data;
|
153
|
+
size_t len;
|
154
|
+
|
155
|
+
/* Converts BYTEA only. */
|
156
|
+
if (plruby_datum_oid(a, NULL) != BYTEAOID)
|
157
|
+
return Qnil;
|
158
|
+
|
159
|
+
len = RSTRING_LEN(obj);
|
160
|
+
data = palloc(VARHDRSZ + len);
|
161
|
+
memcpy(VARDATA(data), RSTRING_PTR(obj), len);
|
162
|
+
#ifdef SET_VARSIZE
|
163
|
+
SET_VARSIZE(data, VARHDRSZ + len);
|
164
|
+
#else
|
165
|
+
VARATT_SIZEP(data) = VARHDRSZ + len;
|
166
|
+
#endif
|
167
|
+
return plruby_datum_set(a, PointerGetDatum(data));
|
168
|
+
}
|
169
|
+
|
170
|
+
static VALUE
|
171
|
+
pl_time_s_datum(VALUE klass, VALUE a)
|
172
|
+
{
|
173
|
+
Timestamp ts;
|
174
|
+
Oid typoid;
|
175
|
+
Datum value;
|
176
|
+
|
177
|
+
/*
|
178
|
+
* INTERVAL and RELTIME are converted to Float (number of seconds).
|
179
|
+
* For INTERVALs containing nonzero month/year component, duration of one
|
180
|
+
* month is assumed to be 30*24*60*60 seconds. A special type has to be
|
181
|
+
* created for this, because of the months/year components and also because
|
182
|
+
* long or short enough numbers do not convert back right (exponential
|
183
|
+
* notation of INTERVALs is not accepted by Postgres).
|
184
|
+
*
|
185
|
+
* TIMESTAMP, TIMESTAMP WITH TIME ZONE, ABSTIME, DATE are converted to klass
|
186
|
+
* (Time), naturally.
|
187
|
+
*
|
188
|
+
* TIME and TIME WITH TIME ZONE are also converted to klass (Time), as in
|
189
|
+
* the (totally broken anyway) 0.4.3 implementation. The result is that
|
190
|
+
* specific time since Unix epoch. That makes little sense (the reverse
|
191
|
+
* conversion of the result breaks anyway), but some at least. A special
|
192
|
+
* type has to be created for this.
|
193
|
+
*/
|
194
|
+
value = plruby_datum_get(a, &typoid);
|
195
|
+
switch (typoid) {
|
196
|
+
/* Time interval types. */
|
197
|
+
|
198
|
+
case RELTIMEOID:
|
199
|
+
value = plruby_dfc1(reltime_interval, value);
|
200
|
+
/* ... */
|
201
|
+
case INTERVALOID:
|
202
|
+
{
|
203
|
+
Interval *iv = DatumGetIntervalP(value);
|
204
|
+
|
205
|
+
return rb_float_new((double) iv->month * 30*24*60*60 +
|
206
|
+
iv->time
|
207
|
+
#ifdef HAVE_INT64_TIMESTAMP
|
208
|
+
/ 1E6
|
209
|
+
#endif
|
210
|
+
);
|
211
|
+
}
|
212
|
+
|
213
|
+
/*
|
214
|
+
* Time of day types.
|
215
|
+
*
|
216
|
+
* No separate conversion code is written, abusing the coincidence of C
|
217
|
+
* types used for TimeADT and Timestamp (int64 or double, depending on
|
218
|
+
* HAVE_INT64_TIMESTAMP). The proper implementation would use a special
|
219
|
+
* type anyway, see above.
|
220
|
+
*/
|
221
|
+
|
222
|
+
case TIMETZOID:
|
223
|
+
{
|
224
|
+
TimeTzADT *timetz = DatumGetTimeTzADTP(value);
|
225
|
+
|
226
|
+
/* Shift according to the timezone. */
|
227
|
+
ts = timetz->time + (Timestamp) timetz->zone
|
228
|
+
#ifdef HAVE_INT64_TIMESTAMP
|
229
|
+
* 1000000
|
230
|
+
#endif
|
231
|
+
;
|
232
|
+
}
|
233
|
+
goto convert;
|
234
|
+
|
235
|
+
case TIMEOID:
|
236
|
+
ts = (Timestamp) DatumGetTimeADT(value);
|
237
|
+
goto convert;
|
238
|
+
|
239
|
+
/* The rest of types end up as a Timestamp in `value'. */
|
240
|
+
|
241
|
+
case ABSTIMEOID:
|
242
|
+
value = plruby_dfc1(abstime_timestamptz, value);
|
243
|
+
break;
|
244
|
+
|
245
|
+
case DATEOID:
|
246
|
+
value = plruby_dfc1(date_timestamptz, value);
|
247
|
+
break;
|
248
|
+
|
249
|
+
case TIMESTAMPOID:
|
250
|
+
case TIMESTAMPTZOID:
|
251
|
+
break;
|
252
|
+
|
253
|
+
default:
|
254
|
+
rb_raise(rb_eTypeError, "%s: incompatible type OID %u",
|
255
|
+
rb_class2name(klass), typoid);
|
256
|
+
}
|
257
|
+
|
258
|
+
ts = DatumGetTimestamp(value) - epoch;
|
259
|
+
|
260
|
+
convert:
|
261
|
+
return rb_funcall(klass, id_at,
|
262
|
+
#ifndef HAVE_INT64_TIMESTAMP
|
263
|
+
1, rb_float_new(ts)
|
264
|
+
#else
|
265
|
+
2, LONG2NUM(ts / 1000000), ULONG2NUM(ts % 1000000)
|
266
|
+
#endif
|
267
|
+
);
|
268
|
+
}
|
269
|
+
|
270
|
+
static VALUE
|
271
|
+
pl_time_to_datum(VALUE obj, VALUE a)
|
272
|
+
{
|
273
|
+
PGFunction conv;
|
274
|
+
Datum d;
|
275
|
+
int typoid;
|
276
|
+
|
277
|
+
typoid = plruby_datum_oid(a, NULL);
|
278
|
+
switch (typoid) {
|
279
|
+
case ABSTIMEOID:
|
280
|
+
case DATEOID:
|
281
|
+
case TIMEOID:
|
282
|
+
case TIMESTAMPOID:
|
283
|
+
case TIMESTAMPTZOID:
|
284
|
+
case TIMETZOID:
|
285
|
+
break;
|
286
|
+
|
287
|
+
default:
|
288
|
+
return Qnil;
|
289
|
+
}
|
290
|
+
|
291
|
+
/* Convert Time to TimestampTz first. */
|
292
|
+
#ifndef HAVE_INT64_TIMESTAMP
|
293
|
+
d = TimestampTzGetDatum(epoch + NUM2DBL(rb_funcall(obj, id_to_f, 0)));
|
294
|
+
#else
|
295
|
+
d = TimestampTzGetDatum(epoch + (TimestampTz)
|
296
|
+
NUM2LONG(rb_funcall(obj, id_to_i, 0)) * 1000000 +
|
297
|
+
NUM2ULONG(rb_funcall(obj, id_usec, 0)));
|
298
|
+
#endif
|
299
|
+
|
300
|
+
conv = NULL;
|
301
|
+
switch (typoid) {
|
302
|
+
case ABSTIMEOID:
|
303
|
+
conv = timestamptz_abstime;
|
304
|
+
break;
|
305
|
+
|
306
|
+
case DATEOID:
|
307
|
+
conv = timestamptz_date;
|
308
|
+
break;
|
309
|
+
|
310
|
+
case TIMEOID:
|
311
|
+
conv = timestamptz_time;
|
312
|
+
break;
|
313
|
+
|
314
|
+
case TIMESTAMPOID:
|
315
|
+
conv = timestamptz_timestamp;
|
316
|
+
break;
|
317
|
+
|
318
|
+
case TIMESTAMPTZOID:
|
319
|
+
break;
|
320
|
+
|
321
|
+
case TIMETZOID:
|
322
|
+
conv = timestamptz_timetz;
|
323
|
+
break;
|
324
|
+
}
|
325
|
+
|
326
|
+
if (conv == NULL) {
|
327
|
+
return Qnil;
|
328
|
+
}
|
329
|
+
d = plruby_dfc1(conv, d);
|
330
|
+
return plruby_datum_set(a, d);
|
331
|
+
}
|
332
|
+
|
333
|
+
void Init_plruby_basic()
|
334
|
+
{
|
335
|
+
int fpoint;
|
336
|
+
struct lconv *lconvert = PGLC_localeconv();
|
337
|
+
|
338
|
+
fpoint = lconvert->frac_digits;
|
339
|
+
if (fpoint < 0 || fpoint > 10) {
|
340
|
+
fpoint = 2;
|
341
|
+
}
|
342
|
+
cash_divisor = pow(10.0, fpoint);
|
343
|
+
epoch = SetEpochTimestamp();
|
344
|
+
id_at = rb_intern("at");
|
345
|
+
id_to_f = rb_intern("to_f");
|
346
|
+
id_to_i = rb_intern("to_i");
|
347
|
+
id_usec = rb_intern("usec");
|
348
|
+
|
349
|
+
rb_define_singleton_method(rb_cFixnum, "from_datum", pl_fixnum_s_datum, 1);
|
350
|
+
rb_define_method(rb_cFixnum, "to_datum", pl_fixnum_to_datum, 1);
|
351
|
+
rb_define_singleton_method(rb_cFloat, "from_datum", pl_float_s_datum, 1);
|
352
|
+
rb_define_method(rb_cFloat, "to_datum", pl_float_to_datum, 1);
|
353
|
+
rb_define_singleton_method(rb_cString, "from_datum", pl_str_s_datum, 1);
|
354
|
+
rb_define_method(rb_cString, "to_datum", pl_str_to_datum, 1);
|
355
|
+
rb_define_singleton_method(rb_cTime, "from_datum", pl_time_s_datum, 1);
|
356
|
+
rb_define_method(rb_cTime, "to_datum", pl_time_to_datum, 1);
|
357
|
+
}
|