ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/PApp-SQL/SQL.xs
(Generate patch)

Comparing PApp-SQL/SQL.xs (file contents):
Revision 1.4 by root, Fri Jan 26 15:25:59 2001 UTC vs.
Revision 1.5 by root, Sun Apr 22 14:38:28 2001 UTC

1#include "EXTERN.h" 1#include "EXTERN.h"
2#include "perl.h" 2#include "perl.h"
3#include "XSUB.h" 3#include "XSUB.h"
4 4
5#if (PERL_VERSION < 5) || ((PERL_VERSION == 5) && (PERL_SUBVERSION <= 6)) 5#if (PERL_VERSION < 5) || ((PERL_VERSION == 5) && (PERL_SUBVERSION <= 6))
6# define get_sv perl_get_sv 6# define get_sv perl_get_sv
7# define call_method perl_call_method 7# define call_method perl_call_method
8# define call_sv perl_call_sv
8#endif 9#endif
10
11#if (PERL_VERSION < 5) || ((PERL_VERSION == 5) && (PERL_SUBVERSION <= 5))
12# define CAN_UTF8 1
13#endif
14
15static SV *
16sql_upgrade_utf8 (SV *sv)
17{
18#if CAN_UTF8
19 if (SvPOK (sv))
20 sv_utf8_upgrade (sv);
21#endif
22 return sv;
23}
24
25static SV *
26sql_force_utf8 (SV *sv)
27{
28#if CAN_UTF8
29 if (SvPOK (sv))
30 SvUTF8_on (sv);
31#endif
32 return sv;
33}
34
35#define maybe_upgrade_utf8(utf8,sv) ((utf8) ? sql_upgrade_utf8 (sv) : (sv))
36#define maybe_force_utf8(utf8,sv) ((utf8) ? sql_force_utf8 (sv) : (sv))
9 37
10#define is_dbh(sv) ((sv) && sv_isobject (sv) && sv_derived_from ((sv), "DBI::db")) 38#define is_dbh(sv) ((sv) && sv_isobject (sv) && sv_derived_from ((sv), "DBI::db"))
11 39
12typedef struct lru_node { 40typedef struct lru_node {
13 struct lru_node *next; 41 struct lru_node *next;
19 SV *sth; 47 SV *sth;
20#if 0 /* method cache */ 48#if 0 /* method cache */
21 GV *execute; 49 GV *execute;
22 GV *bind_columns; 50 GV *bind_columns;
23 GV *fetch; 51 GV *fetch;
52 GV *finish;
24#endif 53#endif
25} lru_node; 54} lru_node;
26 55
27static lru_node lru_list; 56static lru_node lru_list;
28static int lru_size; 57static int lru_size;
137 } 166 }
138} 167}
139 168
140static GV *sql_exec; 169static GV *sql_exec;
141static GV *DBH; 170static GV *DBH;
171static SV *sv_prepare, *sv_execute, *sv_bind_columns, *sv_fetchrow_arrayref, *sv_finish;
172
173#define newconstpv(str) newSVpvn ((str), sizeof (str))
142 174
143MODULE = PApp::SQL PACKAGE = PApp::SQL 175MODULE = PApp::SQL PACKAGE = PApp::SQL
144 176
145PROTOTYPES: DISABLE 177PROTOTYPES: DISABLE
146 178
147BOOT: 179BOOT:
148{ 180{
149 sql_exec = gv_fetchpv ("PApp::SQL::sql_exec", TRUE, SVt_PV); 181 sql_exec = gv_fetchpv ("PApp::SQL::sql_exec", TRUE, SVt_PV);
150 DBH = gv_fetchpv ("PApp::SQL::DBH" , TRUE, SVt_PV); 182 DBH = gv_fetchpv ("PApp::SQL::DBH" , TRUE, SVt_PV);
183
184 if (!sv_prepare)
185 {
186 sv_prepare = newconstpv ("prepare");
187 sv_execute = newconstpv ("execute");
188 sv_bind_columns = newconstpv ("bind_columns");
189 sv_fetchrow_arrayref = newconstpv ("fetchrow_arrayref");
190 sv_finish = newconstpv ("finish");
191 }
151 192
152 /* apache might BOOT: twice :( */ 193 /* apache might BOOT: twice :( */
153 if (lru_size) 194 if (lru_size)
154 lru_cachesize (0); 195 lru_cachesize (0);
155 196
167 RETVAL 208 RETVAL
168 209
169void 210void
170sql_exec(...) 211sql_exec(...)
171 ALIAS: 212 ALIAS:
213 sql_uexec = 1
172 sql_fetch = 1 214 sql_fetch = 2
215 sql_ufetch = 3
173 sql_fetchall = 2 216 sql_fetchall = 4
217 sql_ufetchall = 5
174 sql_exists = 4 218 sql_exists = 6
219 sql_uexists = 7
175 PPCODE: 220 PPCODE:
176{ 221{
177 if (items == 0) 222 if (items == 0)
178 croak ("Usage: sql_exec [database-handle,] [bind-var-refs,... ] \"sql-statement\", [arguments, ...]"); 223 croak ("Usage: sql_exec [database-handle,] [bind-var-refs,... ] \"sql-statement\", [arguments, ...]");
179 else 224 else
218 if (!SvPOK (ST(arg))) 263 if (!SvPOK (ST(arg)))
219 croak ("sql_exec: sql-statement must be a string"); 264 croak ("sql_exec: sql-statement must be a string");
220 265
221 sql = ST(arg); arg++; 266 sql = ST(arg); arg++;
222 267
223 if (ix == 4) 268 if ((ix & ~1) == 6)
224 { 269 {
225 SV *neu = sv_2mortal (newSVpv ("select count(*) > 0 from ", 0)); 270 SV *neu = sv_2mortal (newSVpv ("select count(*) > 0 from ", 0));
226 sv_catsv (neu, sql); 271 sv_catsv (neu, sql);
227 sv_catpv (neu, " limit 1"); 272 sv_catpv (neu, " limit 1");
228 sql = neu; 273 sql = neu;
229 ix = 1; /* sql_fetch */ 274 ix -= 6; /* sql_fetch */
230 } 275 }
231 276
232 /* check cache for existing statement handle */ 277 /* check cache for existing statement handle */
233 sth = lru_fetch (dbh, sql); 278 sth = lru_fetch (dbh, sql);
234 if (!sth) 279 if (!sth)
236 PUSHMARK (SP); 281 PUSHMARK (SP);
237 EXTEND (SP, 2); 282 EXTEND (SP, 2);
238 PUSHs (dbh); 283 PUSHs (dbh);
239 PUSHs (sql); 284 PUSHs (sql);
240 PUTBACK; 285 PUTBACK;
241 count = call_method ("prepare", G_SCALAR); 286 count = call_sv (sv_prepare, G_METHOD | G_SCALAR);
242 SPAGAIN; 287 SPAGAIN;
243 288
244 if (count != 1) 289 if (count != 1)
245 croak ("sql_exec: unable to prepare() statement '%s': %s", 290 croak ("sql_exec: unable to prepare() statement '%s': %s",
246 SvPV (sql, dc), 291 SvPV (sql, dc),
254 PUSHMARK (SP); 299 PUSHMARK (SP);
255 EXTEND (SP, items - arg + 1); 300 EXTEND (SP, items - arg + 1);
256 PUSHs (sth); 301 PUSHs (sth);
257 while (items > arg) 302 while (items > arg)
258 { 303 {
259 PUSHs (ST(arg)); 304 PUSHs (maybe_upgrade_utf8 (ix & 1, ST(arg)));
260 arg++; 305 arg++;
261 } 306 }
262 307
263 PUTBACK; 308 PUTBACK;
264 /* { static GV *execute; 309 /* { static GV *execute;
265 if (!execute) execute = gv_fetchmethod_autoload(SvSTASH(SvRV(sth)), "execute", 0); 310 if (!execute) execute = gv_fetchmethod_autoload(SvSTASH(SvRV(sth)), "execute", 0);
266 count = call_sv(GvCV(execute), G_SCALAR); 311 count = call_sv(GvCV(execute), G_SCALAR);
267 }*/ 312 }*/
268 count = call_method ("execute", G_SCALAR); 313 count = call_sv (sv_execute, G_METHOD | G_SCALAR);
269 SPAGAIN; 314 SPAGAIN;
270 315
271 if (count != 1) 316 if (count != 1)
272 croak ("sql_exec: execute() didn't return any value ('%s'): %s", 317 croak ("sql_exec: execute() didn't return any value ('%s'): %s",
273 SvPV (sql, dc), 318 SvPV (sql, dc),
291 PUSHs (ST(bind_first)); 336 PUSHs (ST(bind_first));
292 bind_first++; 337 bind_first++;
293 } while (bind_first != bind_last); 338 } while (bind_first != bind_last);
294 339
295 PUTBACK; 340 PUTBACK;
296 count = call_method ("bind_columns", G_SCALAR); 341 count = call_sv (sv_bind_columns, G_METHOD | G_SCALAR);
297 SPAGAIN; 342 SPAGAIN;
298 343
299 if (count != 1) 344 if (count != 1)
300 croak ("sql_exec: bind_columns() didn't return any value ('%s'): %s", 345 croak ("sql_exec: bind_columns() didn't return any value ('%s'): %s",
301 SvPV (sql, dc), 346 SvPV (sql, dc),
308 } 353 }
309 354
310 /* free our arguments from the stack */ 355 /* free our arguments from the stack */
311 SP -= items; 356 SP -= items;
312 357
313 if (ix == 1) 358 if ((ix & ~1) == 2)
314 { /* sql_fetch */ 359 { /* sql_fetch */
315 SV *row; 360 SV *row;
316 361
317 PUSHMARK (SP); 362 PUSHMARK (SP);
318 XPUSHs (sth); 363 XPUSHs (sth);
319 PUTBACK; 364 PUTBACK;
320 count = call_method ("fetchrow_arrayref", G_SCALAR); 365 count = call_sv (sv_fetchrow_arrayref, G_METHOD | G_SCALAR);
321 SPAGAIN; 366 SPAGAIN;
322 367
323 if (count != 1) 368 if (count != 1)
324 abort (); 369 abort ();
325 370
334 case G_VOID: 379 case G_VOID:
335 /* no thing */ 380 /* no thing */
336 break; 381 break;
337 case G_SCALAR: 382 case G_SCALAR:
338 /* the first element */ 383 /* the first element */
339 XPUSHs (*av_fetch ((AV *)SvRV (row), 0, 1)); 384 XPUSHs (maybe_force_utf8 (ix & 1, *av_fetch ((AV *)SvRV (row), 0, 1)));
340 break; 385 break;
341 case G_ARRAY: 386 case G_ARRAY:
342 av = (AV *)SvRV (row); 387 av = (AV *)SvRV (row);
343 count = AvFILL (av) + 1; 388 count = AvFILL (av) + 1;
344 EXTEND (SP, count); 389 EXTEND (SP, count);
345 for (arg = 0; arg < count; arg++) 390 for (arg = 0; arg < count; arg++)
346 PUSHs (AvARRAY (av)[arg]); 391 PUSHs (maybe_force_utf8 (ix & 1, AvARRAY (av)[arg]));
347 392
348 break; 393 break;
349 default: 394 default:
350 abort (); 395 abort ();
351 } 396 }
352 } 397 }
353 } 398 }
354 else if (ix == 2) 399 else if ((ix & ~1) == 4)
355 { /* sql_fetchall */ 400 { /* sql_fetchall */
356 SV *rows; 401 SV *rows;
357 402
358 PUSHMARK (SP); 403 PUSHMARK (SP);
359 XPUSHs (sth); 404 XPUSHs (sth);
360 PUTBACK; 405 PUTBACK;
361 count = call_method ("fetchall_arrayref", G_SCALAR); 406 count = call_sv (sv_fetchrow_arrayref, G_METHOD | G_SCALAR);
362 SPAGAIN; 407 SPAGAIN;
363 408
364 if (count != 1) 409 if (count != 1)
365 abort (); 410 abort ();
366 411
376 int columns = AvFILL ((AV *)SvRV (AvARRAY(av)[0])) + 1; /* columns? */ 421 int columns = AvFILL ((AV *)SvRV (AvARRAY(av)[0])) + 1; /* columns? */
377 422
378 EXTEND (SP, count); 423 EXTEND (SP, count);
379 if (columns == 1) 424 if (columns == 1)
380 for (arg = 0; arg < count; arg++) 425 for (arg = 0; arg < count; arg++)
381 PUSHs (AvARRAY ((AV *)SvRV (AvARRAY (av)[arg]))[0]); 426 PUSHs (maybe_force_utf8 (ix & 1, AvARRAY ((AV *)SvRV (AvARRAY (av)[arg]))[0]));
382 else 427 else
383 for (arg = 0; arg < count; arg++) 428 for (arg = 0; arg < count; arg++)
384 PUSHs (AvARRAY (av)[arg]); 429 PUSHs (maybe_force_utf8 (ix & 1, AvARRAY (av)[arg]));
385 } 430 }
386 } 431 }
387 } 432 }
388 else 433 else
389 XPUSHs (sth); 434 XPUSHs (sth);
390 435
391 if (ix || GIMME_V == G_VOID) 436 if (ix > 1 || GIMME_V == G_VOID)
392 { 437 {
393 PUSHMARK (SP); 438 PUSHMARK (SP);
394 XPUSHs (sth); 439 XPUSHs (sth);
395 PUTBACK; 440 PUTBACK;
396 (void) call_method ("finish", G_DISCARD); 441 (void) call_sv (sv_finish, G_METHOD | G_DISCARD);
397 SPAGAIN; 442 SPAGAIN;
398 } 443 }
399 } 444 }
400} 445}
401 446

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines