1 /**********************************************************************
2  * PostgreSQL::InServer::SPI
3  *
4  * SPI interface for plperl.
5  *
6  *    src/pl/plperl/SPI.xs
7  *
8  **********************************************************************/
9 
10 /* this must be first: */
11 #include "postgres.h"
12 
13 /* perl stuff */
14 #define PG_NEED_PERL_XSUB_H
15 #include "plperl.h"
16 #include "plperl_helpers.h"
17 
18 
19 MODULE = PostgreSQL::InServer::SPI PREFIX = spi_
20 
21 PROTOTYPES: ENABLE
22 VERSIONCHECK: DISABLE
23 
24 SV*
25 spi_spi_exec_query(sv, ...)
26 	SV* sv;
27 	PREINIT:
28 		HV *ret_hash;
29 		int limit = 0;
30 		char *query;
31 	CODE:
32 		if (items > 2)
33 			croak("Usage: spi_exec_query(query, limit) "
34 				  "or spi_exec_query(query)");
35 		if (items == 2)
36 			limit = SvIV(ST(1));
37 		query = sv2cstr(sv);
38 		ret_hash = plperl_spi_exec(query, limit);
39 		pfree(query);
40 		RETVAL = newRV_noinc((SV*) ret_hash);
41 	OUTPUT:
42 		RETVAL
43 
44 void
45 spi_return_next(rv)
46 	SV *rv;
47 	CODE:
48 		plperl_return_next(rv);
49 
50 SV *
51 spi_spi_query(sv)
52 	SV *sv;
53 	CODE:
54 		char* query = sv2cstr(sv);
55 		RETVAL = plperl_spi_query(query);
56 		pfree(query);
57 	OUTPUT:
58 		RETVAL
59 
60 SV *
61 spi_spi_fetchrow(sv)
62 	SV* sv;
63 	CODE:
64 		char* cursor = sv2cstr(sv);
65 		RETVAL = plperl_spi_fetchrow(cursor);
66 		pfree(cursor);
67 	OUTPUT:
68 		RETVAL
69 
70 SV*
71 spi_spi_prepare(sv, ...)
72 	SV* sv;
73 	CODE:
74 		int i;
75 		SV** argv;
76 		char* query = sv2cstr(sv);
77 		if (items < 1)
78 			Perl_croak(aTHX_ "Usage: spi_prepare(query, ...)");
79 		argv = ( SV**) palloc(( items - 1) * sizeof(SV*));
80 		for ( i = 1; i < items; i++)
81 			argv[i - 1] = ST(i);
82 		RETVAL = plperl_spi_prepare(query, items - 1, argv);
83 		pfree( argv);
84 		pfree(query);
85 	OUTPUT:
86 		RETVAL
87 
88 SV*
89 spi_spi_exec_prepared(sv, ...)
90 	SV* sv;
91 	PREINIT:
92 		HV *ret_hash;
93 	CODE:
94 		HV *attr = NULL;
95 		int i, offset = 1, argc;
96 		SV ** argv;
97 		char *query = sv2cstr(sv);
98 		if ( items < 1)
99 			Perl_croak(aTHX_ "Usage: spi_exec_prepared(query, [\\%%attr,] "
100 					   "[\\@bind_values])");
101 		if ( items > 1 && SvROK( ST( 1)) && SvTYPE( SvRV( ST( 1))) == SVt_PVHV)
102 		{
103 			attr = ( HV*) SvRV(ST(1));
104 			offset++;
105 		}
106 		argc = items - offset;
107 		argv = ( SV**) palloc( argc * sizeof(SV*));
108 		for ( i = 0; offset < items; offset++, i++)
109 			argv[i] = ST(offset);
110 		ret_hash = plperl_spi_exec_prepared(query, attr, argc, argv);
111 		RETVAL = newRV_noinc((SV*)ret_hash);
112 		pfree( argv);
113 		pfree(query);
114 	OUTPUT:
115 		RETVAL
116 
117 SV*
118 spi_spi_query_prepared(sv, ...)
119 	SV * sv;
120 	CODE:
121 		int i;
122 		SV ** argv;
123 		char *query = sv2cstr(sv);
124 		if ( items < 1)
125 			Perl_croak(aTHX_ "Usage: spi_query_prepared(query, "
126 					   "[\\@bind_values])");
127 		argv = ( SV**) palloc(( items - 1) * sizeof(SV*));
128 		for ( i = 1; i < items; i++)
129 			argv[i - 1] = ST(i);
130 		RETVAL = plperl_spi_query_prepared(query, items - 1, argv);
131 		pfree( argv);
132 		pfree(query);
133 	OUTPUT:
134 		RETVAL
135 
136 void
137 spi_spi_freeplan(sv)
138 	SV *sv;
139 	CODE:
140 		char *query = sv2cstr(sv);
141 		plperl_spi_freeplan(query);
142 		pfree(query);
143 
144 void
145 spi_spi_cursor_close(sv)
146 	SV *sv;
147 	CODE:
148 		char *cursor = sv2cstr(sv);
149 		plperl_spi_cursor_close(cursor);
150 		pfree(cursor);
151 
152 void
153 spi_spi_commit()
154 	CODE:
155 		plperl_spi_commit();
156 
157 void
158 spi_spi_rollback()
159 	CODE:
160 		plperl_spi_rollback();
161 
162 BOOT:
163     items = 0;  /* avoid 'unused variable' warning */
164