Permalink
Browse files

Support conversion from JSON to record.

  • Loading branch information...
1 parent 43de836 commit f79200fb1da3caa1bdbc1e8cdd1611a2f578e269 @ItGacky ItGacky committed Aug 26, 2010
Showing with 59 additions and 3 deletions.
  1. +5 −1 expected/plv8.out
  2. +32 −1 plv8.cc
  3. +1 −0 plv8.h
  4. +21 −1 plv8_type.cc
View
@@ -176,7 +176,11 @@ $$
$$
LANGUAGE plv8;
SELECT scalar_to_record(1, 'a');
-ERROR: JSON to record is not implemented yet
+ scalar_to_record
+------------------
+ (1,a)
+(1 row)
+
CREATE FUNCTION record_to_text(x rec) RETURNS text AS
$$
return JSON.stringify(x);
View
33 plv8.cc
@@ -752,7 +752,8 @@ Converter::Converter(TupleDesc tupdesc) :
// TODO: use prototype instead of per tuple fields to reduce
// memory consumption.
-Handle<Object> Converter::ToValue(HeapTuple tuple)
+Handle<Object>
+Converter::ToValue(HeapTuple tuple)
{
Handle<Object> obj = Object::New();
@@ -768,6 +769,36 @@ Handle<Object> Converter::ToValue(HeapTuple tuple)
return obj;
}
+Datum
+Converter::ToDatum(Handle<v8::Value> value)
+{
+ TryCatch try_catch;
+
+ Handle<Object> obj = Handle<Object>::Cast(value);
+ if (obj.IsEmpty())
+ throw js_error(try_catch);
+
+ /*
+ * Use vector<char> instead of vector<bool> because <bool> version is
+ * s specialized and different from bool[].
+ */
+ std::vector<Datum> values(m_tupdesc->natts);
+ std::vector<char> nulls(m_tupdesc->natts);
+
+ for (int c = 0; c < m_tupdesc->natts; c++)
+ {
+ Handle<v8::Value> attr = obj->Get(m_colnames[c]);
+ if (attr.IsEmpty() || attr->IsUndefined() || attr->IsNull())
+ nulls[c] = true;
+ else
+ values[c] = ::ToDatum(attr, (bool *) &nulls[c], &m_coltypes[c]);
+ }
+
+ HeapTuple tuple = heap_form_tuple(m_tupdesc, &values[0], (bool *) &nulls[0]);
+
+ return HeapTupleGetDatum(tuple);
+}
+
js_error::js_error() throw()
: m_msg(NULL), m_detail(NULL)
{
View
1 plv8.h
@@ -92,6 +92,7 @@ class Converter
public:
Converter(TupleDesc tupdesc);
v8::Handle<v8::Object> ToValue(HeapTuple tuple);
+ Datum ToDatum(v8::Handle<v8::Value> value);
private:
Converter(const Converter&);
View
@@ -182,13 +182,33 @@ ToArrayDatum(Handle<v8::Value> value, bool *isnull, plv8_type *type)
static Datum
ToRecordDatum(Handle<v8::Value> value, bool *isnull, plv8_type *type)
{
+ Datum result;
+ TupleDesc tupdesc;
+
if (value->IsUndefined() || value->IsNull())
{
*isnull = true;
return (Datum) 0;
}
- throw js_error("JSON to record is not implemented yet");
+ PG_TRY();
+ {
+ tupdesc = lookup_rowtype_tupdesc(type->typid, -1);
+ }
+ PG_CATCH();
+ {
+ throw pg_error();
+ }
+ PG_END_TRY();
+
+ Converter conv(tupdesc);
+
+ result = conv.ToDatum(value);
+
+ ReleaseTupleDesc(tupdesc);
+
+ *isnull = false;
+ return result;
}
Handle<v8::Value>

0 comments on commit f79200f

Please sign in to comment.