~ubuntu-branches/ubuntu/oneiric/postgresql-pljava/oneiric-201109061811

« back to all changes in this revision

Viewing changes to src/C/pljava/type/SingleRowWriter.c

  • Committer: Bazaar Package Importer
  • Author(s): Peter Eisentraut
  • Date: 2006-06-26 10:44:55 UTC
  • mfrom: (1.1.1 upstream) (3.1.1 edgy)
  • Revision ID: james.westby@ubuntu.com-20060626104455-135i9wosat2k8vvt
Tags: 1.3.0-1
* New upstream release (closes: #375199)
* Built for postgresql 8.1 (closes: #339641)
* Rebuilt for new libgcj library (closes: #369986)
* Updated copyright file
* Updated standards version
* Made use of cdbs simple patchsys

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (c) 2004, 2005 TADA AB - Taby Sweden
3
 
 * Distributed under the terms shown in the file COPYRIGHT
4
 
 * found in the root folder of this project or at
5
 
 * http://eng.tada.se/osprojects/COPYRIGHT.html
6
 
 *
7
 
 * @author Thomas Hallgren
8
 
 */
9
 
#include <postgres.h>
10
 
#include <funcapi.h>
11
 
#include <utils/typcache.h>
12
 
 
13
 
#include "pljava/backports.h"
14
 
#include "pljava/MemoryContext.h"
15
 
#include "pljava/type/Type_priv.h"
16
 
#include "pljava/type/ComplexType.h"
17
 
#include "pljava/type/TupleDesc.h"
18
 
#include "pljava/type/SingleRowWriter.h"
19
 
 
20
 
/*
21
 
 * void primitive type.
22
 
 */
23
 
static jclass s_SingleRowWriter_class;
24
 
static jmethodID s_SingleRowWriter_init;
25
 
static jmethodID s_SingleRowWriter_getTupleAndClear;
26
 
static TypeClass s_SingleRowWriterClass;
27
 
static HashMap s_idCache;
28
 
#if (PGSQL_MAJOR_VER >= 8)
29
 
static HashMap s_modCache;
30
 
#endif
31
 
 
32
 
/*
33
 
 * This function is a bit special in that it adds an additional parameter
34
 
 * to the parameter list (a java.sql.ResultSet implemented as a
35
 
 * SingleRowWriter) and calls a boolean method. It's assumed that the
36
 
 * SingleRowWriter has been initialized with values if the method returns
37
 
 * true. If so, the values are obtained in the form of a HeapTuple which in
38
 
 * turn is returned (as a Datum) from this method.
39
 
 * 
40
 
 * NOTE! It's an absolute prerequisite that the args argument has room for
41
 
 * one extra parameter.
42
 
 */
43
 
static Datum _SingleRowWriter_invoke(Type self, JNIEnv* env, jclass cls, jmethodID method, jvalue* args, PG_FUNCTION_ARGS)
44
 
{
45
 
        bool saveIcj = isCallingJava;
46
 
        bool hasRow;
47
 
        Datum result = 0;
48
 
        TupleDesc tupleDesc = Type_getTupleDesc(self, fcinfo);
49
 
        jobject jtd = TupleDesc_create(env, tupleDesc);
50
 
        jobject singleRowWriter = SingleRowWriter_create(env, jtd);
51
 
        int numArgs = fcinfo->nargs;
52
 
        (*env)->DeleteLocalRef(env, jtd);
53
 
 
54
 
        /* It's guaranteed that the args array has room for one more
55
 
         * argument.
56
 
         */
57
 
        args[numArgs].l = singleRowWriter;
58
 
 
59
 
        isCallingJava = true;
60
 
        hasRow = ((*env)->CallStaticBooleanMethodA(env, cls, method, args) == JNI_TRUE);
61
 
        isCallingJava = saveIcj;
62
 
 
63
 
        if(hasRow)
64
 
        {
65
 
                /* Obtain tuple and return it as a Datum. Must be done using a more
66
 
                 * durable context.
67
 
                 */
68
 
                MemoryContext currCtx = MemoryContext_switchToUpperContext();
69
 
                HeapTuple tuple = SingleRowWriter_getTupleAndClear(env, singleRowWriter);
70
 
#if (PGSQL_MAJOR_VER == 7 && PGSQL_MINOR_VER < 5)
71
 
            result = TupleGetDatum(TupleDescGetSlot(tupleDesc), tuple);
72
 
#else
73
 
            result = HeapTupleGetDatum(tuple);
74
 
#endif
75
 
                MemoryContextSwitchTo(currCtx);
76
 
        }
77
 
        else
78
 
                fcinfo->isnull = true;
79
 
 
80
 
        (*env)->DeleteLocalRef(env, singleRowWriter);
81
 
        return result;
82
 
}
83
 
 
84
 
jobject SingleRowWriter_create(JNIEnv* env, jobject tupleDesc)
85
 
{
86
 
        jobject result;
87
 
        if(tupleDesc == 0)
88
 
                return 0;
89
 
 
90
 
        result = PgObject_newJavaObject(env, s_SingleRowWriter_class, s_SingleRowWriter_init, tupleDesc);
91
 
        return result;
92
 
}
93
 
 
94
 
HeapTuple SingleRowWriter_getTupleAndClear(JNIEnv* env, jobject jrps)
95
 
{
96
 
        jobject tuple;
97
 
        HeapTuple result;
98
 
        bool saveIcj = isCallingJava;
99
 
 
100
 
        if(jrps == 0)
101
 
                return 0;
102
 
 
103
 
        isCallingJava = true;
104
 
        tuple = (*env)->CallObjectMethod(env, jrps, s_SingleRowWriter_getTupleAndClear);
105
 
        isCallingJava = saveIcj;
106
 
        if(tuple == 0)
107
 
                return 0;
108
 
 
109
 
        result = (HeapTuple)NativeStruct_getStruct(env, tuple);
110
 
        (*env)->DeleteLocalRef(env, tuple);
111
 
        return result;
112
 
}
113
 
 
114
 
static jvalue _SingleRowWriter_coerceDatum(Type self, JNIEnv* env, Datum nothing)
115
 
{
116
 
        jvalue result;
117
 
        result.j = 0L;
118
 
        return result;
119
 
}
120
 
 
121
 
static Datum _SingleRowWriter_coerceObject(Type self, JNIEnv* env, jobject nothing)
122
 
{
123
 
        return 0;
124
 
}
125
 
 
126
 
static Type SingleRowWriter_obtain(Oid typeId)
127
 
{
128
 
#if (PGSQL_MAJOR_VER < 8)
129
 
        return (Type)ComplexType_createType(
130
 
                s_SingleRowWriterClass, s_idCache, typeId, lookup_rowtype_tupdesc(typeId, -1));
131
 
#else
132
 
        return (Type)ComplexType_createType(
133
 
                s_SingleRowWriterClass, s_idCache, s_modCache, lookup_rowtype_tupdesc(typeId, -1));
134
 
#endif
135
 
}
136
 
 
137
 
Type SingleRowWriter_createType(Oid typid, TupleDesc tupleDesc)
138
 
{
139
 
#if (PGSQL_MAJOR_VER < 8)
140
 
        return (Type)ComplexType_createType(
141
 
                s_SingleRowWriterClass, s_idCache, typid, tupleDesc);
142
 
#else
143
 
        return (Type)ComplexType_createType(
144
 
                s_SingleRowWriterClass, s_idCache, s_modCache, tupleDesc);
145
 
#endif
146
 
}
147
 
 
148
 
/* Make this datatype available to the postgres system.
149
 
 */
150
 
extern Datum SingleRowWriter_initialize(PG_FUNCTION_ARGS);
151
 
PG_FUNCTION_INFO_V1(SingleRowWriter_initialize);
152
 
Datum SingleRowWriter_initialize(PG_FUNCTION_ARGS)
153
 
{
154
 
        JNIEnv* env = (JNIEnv*)PG_GETARG_POINTER(0);
155
 
 
156
 
        s_SingleRowWriter_class = (*env)->NewGlobalRef(
157
 
                                env, PgObject_getJavaClass(env, "org/postgresql/pljava/jdbc/SingleRowWriter"));
158
 
 
159
 
        s_SingleRowWriter_init = PgObject_getJavaMethod(
160
 
                                env, s_SingleRowWriter_class, "<init>", "(Lorg/postgresql/pljava/internal/TupleDesc;)V");
161
 
 
162
 
        s_SingleRowWriter_getTupleAndClear = PgObject_getJavaMethod(
163
 
                                env, s_SingleRowWriter_class, "getTupleAndClear", "()Lorg/postgresql/pljava/internal/Tuple;");
164
 
 
165
 
        s_idCache = HashMap_create(13, TopMemoryContext);
166
 
#if (PGSQL_MAJOR_VER >= 8)
167
 
        s_modCache = HashMap_create(13, TopMemoryContext);
168
 
#endif
169
 
 
170
 
        s_SingleRowWriterClass = ComplexTypeClass_alloc("type.SingleRowWriter");
171
 
        s_SingleRowWriterClass->JNISignature = "Ljava/sql/ResultSet;";
172
 
        s_SingleRowWriterClass->javaTypeName = "java.lang.ResultSet";
173
 
        s_SingleRowWriterClass->coerceDatum  = _SingleRowWriter_coerceDatum;
174
 
        s_SingleRowWriterClass->coerceObject = _SingleRowWriter_coerceObject;
175
 
        s_SingleRowWriterClass->invoke       = _SingleRowWriter_invoke;
176
 
 
177
 
        Type_registerJavaType("org.postgresql.pljava.jdbc.SingleRowWriter", SingleRowWriter_obtain);
178
 
        PG_RETURN_VOID();
179
 
}