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.12 by root, Thu Apr 11 01:02:10 2002 UTC vs.
Revision 1.19 by root, Sat Jan 19 07:38:52 2008 UTC

10 10
11#if (PERL_VERSION > 5) || ((PERL_VERSION == 5) && (PERL_SUBVERSION >= 6)) 11#if (PERL_VERSION > 5) || ((PERL_VERSION == 5) && (PERL_SUBVERSION >= 6))
12# define CAN_UTF8 1 12# define CAN_UTF8 1
13#endif 13#endif
14 14
15#define MAX_CACHED_STATEMENT_SIZE 8192
16
15static SV * 17static SV *
16sql_upgrade_utf8 (SV *sv) 18sql_upgrade_utf8 (SV *sv)
17{ 19{
18#if CAN_UTF8 20#if CAN_UTF8
19 if (SvPOK (sv)) 21 if (SvPOK (sv))
21#endif 23#endif
22 return sv; 24 return sv;
23} 25}
24 26
25static SV * 27static SV *
26sql_force_utf8 (SV *sv) 28mortalcopy_and_maybe_force_utf8(int utf8, SV *sv)
27{ 29{
30 sv = sv_mortalcopy (sv);
28#if CAN_UTF8 31#if CAN_UTF8
29 if (SvPOK (sv)) 32 if (utf8 && SvPOK (sv))
30 SvUTF8_on (sv); 33 SvUTF8_on (sv);
31#endif 34#endif
32 return sv; 35 return sv;
33} 36}
34 37
35#define maybe_upgrade_utf8(utf8,sv) ((utf8) ? sql_upgrade_utf8 (sv) : (sv)) 38#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))
37 39
38#define is_dbh(sv) ((sv) && sv_isobject (sv) && sv_derived_from ((sv), "DBI::db")) 40#define is_dbh(sv) ((sv) && sv_isobject (sv) && sv_derived_from ((sv), "DBI::db"))
39 41
40typedef struct lru_node { 42typedef struct lru_node {
41 struct lru_node *next; 43 struct lru_node *next;
60#define lru_init lru_list.next = &lru_list; lru_list.prev = &lru_list /* other fields are zero */ 62#define lru_init lru_list.next = &lru_list; lru_list.prev = &lru_list /* other fields are zero */
61 63
62/* this is primitive, yet effective */ 64/* this is primitive, yet effective */
63/* the returned value must never be zero (or bad things will happen) */ 65/* the returned value must never be zero (or bad things will happen) */
64#define lru_hash do { \ 66#define lru_hash do { \
65 hash = (((U32)dbh)>>2); \ 67 hash = (((U32)(long)dbh)>>2); \
66 hash += *statement;\ 68 hash += *statement;\
67 hash += len; \ 69 hash += len; \
68} while (0) 70} while (0)
69 71
70/* fetch and "use" */ 72/* fetch and "use" */
290 SvPV (sql, dc), 292 SvPV (sql, dc),
291 SvPV (get_sv ("DBI::errstr", TRUE), dd)); 293 SvPV (get_sv ("DBI::errstr", TRUE), dd));
292 294
293 sth = POPs; 295 sth = POPs;
294 296
297 if (SvLEN (sql) < MAX_CACHED_STATEMENT_SIZE)
295 lru_store (dbh, sql, sth); 298 lru_store (dbh, sql, sth);
296 } 299 }
297 300
298 PUSHMARK (SP); 301 PUSHMARK (SP);
299 EXTEND (SP, items - arg + 1); 302 EXTEND (SP, items - arg + 1);
300 PUSHs (sth); 303 PUSHs (sth);
301 while (items > arg) 304 while (items > arg)
302 { 305 {
306 SV *sv = ST(arg);
307 /* we sv_mortalcopy magical values since DBI seems to have a memory
308 * leak when magical values are passed into execute().
309 */
303 PUSHs (maybe_upgrade_utf8 (ix & 1, ST(arg))); 310 PUSHs (maybe_upgrade_utf8 (ix & 1, SvMAGICAL(sv) ? sv_mortalcopy(sv) : sv));
304 arg++; 311 arg++;
305 } 312 }
306 313
307 PUTBACK; 314 PUTBACK;
308 /* { static GV *execute; 315 /* { static GV *execute;
330 { 337 {
331 PUSHMARK (SP); 338 PUSHMARK (SP);
332 EXTEND (SP, bind_last - bind_first + 2); 339 EXTEND (SP, bind_last - bind_first + 2);
333 PUSHs (sth); 340 PUSHs (sth);
334 do { 341 do {
342#if CAN_UTF8
343 if (ix & 1)
344 SvUTF8_on (SvRV(ST(bind_first)));
345#endif
335 PUSHs (ST(bind_first)); 346 PUSHs (ST(bind_first));
336 bind_first++; 347 bind_first++;
337 } while (bind_first != bind_last); 348 } while (bind_first != bind_last);
338 349
339 PUTBACK; 350 PUTBACK;
343 if (count != 1) 354 if (count != 1)
344 croak ("sql_exec: bind_columns() didn't return any value ('%s'): %s", 355 croak ("sql_exec: bind_columns() didn't return any value ('%s'): %s",
345 SvPV (sql, dc), 356 SvPV (sql, dc),
346 SvPV (get_sv ("DBI::errstr", TRUE), dd)); 357 SvPV (get_sv ("DBI::errstr", TRUE), dd));
347 358
348 if (!SvOK (POPs)) 359 if (!SvOK (TOPs))
349 croak ("sql_exec: bind_columns() didn't return a true ('%s'): %s", 360 croak ("sql_exec: bind_columns() didn't return a true ('%s'): %s",
350 SvPV (sql, dc), 361 SvPV (sql, dc),
351 SvPV (get_sv ("DBI::errstr", TRUE), dd)); 362 SvPV (get_sv ("DBI::errstr", TRUE), dd));
363
352 } 364 POPs;
365 }
353 366
354 /* free our arguments from the stack */ 367 /* restore our arguments again */
355 SP -= items; 368 SP -= items;
356 369
357 if ((ix & ~1) == 2) 370 if ((ix & ~1) == 2)
358 { /* sql_fetch */ 371 { /* sql_fetch */
359 SV *row; 372 SV *row;
378 case G_VOID: 391 case G_VOID:
379 /* no thing */ 392 /* no thing */
380 break; 393 break;
381 case G_SCALAR: 394 case G_SCALAR:
382 /* the first element */ 395 /* the first element */
383 XPUSHs (maybe_force_utf8 (ix & 1, *av_fetch ((AV *)SvRV (row), 0, 1))); 396 XPUSHs (mortalcopy_and_maybe_force_utf8 (ix & 1, *av_fetch ((AV *)SvRV (row), 0, 1)));
384 break; 397 break;
385 case G_ARRAY: 398 case G_ARRAY:
386 av = (AV *)SvRV (row); 399 av = (AV *)SvRV (row);
387 count = AvFILL (av) + 1; 400 count = AvFILL (av) + 1;
388 EXTEND (SP, count); 401 EXTEND (SP, count);
389 for (arg = 0; arg < count; arg++) 402 for (arg = 0; arg < count; arg++)
390 PUSHs (maybe_force_utf8 (ix & 1, AvARRAY (av)[arg])); 403 PUSHs (mortalcopy_and_maybe_force_utf8 (ix & 1, AvARRAY (av)[arg]));
391 404
392 break; 405 break;
393 default: 406 default:
394 abort (); 407 abort ();
395 } 408 }
420 int columns = AvFILL ((AV *) SvRV (AvARRAY (av)[0])) + 1; /* columns? */ 433 int columns = AvFILL ((AV *) SvRV (AvARRAY (av)[0])) + 1; /* columns? */
421 434
422 EXTEND (SP, count); 435 EXTEND (SP, count);
423 if (columns == 1) 436 if (columns == 1)
424 for (arg = 0; arg < count; arg++) 437 for (arg = 0; arg < count; arg++)
425 PUSHs (maybe_force_utf8 (ix & 1, AvARRAY ((AV *)SvRV (AvARRAY (av)[arg]))[0])); 438 PUSHs (mortalcopy_and_maybe_force_utf8 (ix & 1, AvARRAY ((AV *)SvRV (AvARRAY (av)[arg]))[0]));
426 else 439 else
427 for (arg = 0; arg < count; arg++) 440 for (arg = 0; arg < count; arg++)
428 PUSHs (maybe_force_utf8 (ix & 1, AvARRAY (av)[arg])); 441 PUSHs (mortalcopy_and_maybe_force_utf8 (ix & 1, AvARRAY (av)[arg]));
429 } 442 }
430 } 443 }
431 } 444 }
432 else 445 else
433 XPUSHs (sth); 446 XPUSHs (sth);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines