DBD-KB
view release on metacpan or search on metacpan
} /* end first scan */
/* Not found? Move to the next letter after the dollarsign and move on */
if (!found) {
statement -= dollaroffset;
if (!ch) {
ch = 1; /* So the top loop still works */
statement--;
}
continue;
}
/* We only need to create a dollarstring if something was between the two dollar signs */
if (dollaroffset >= 1) {
New(0, dollarstring, dollaroffset, char); /* note: a true array, not a null-terminated string */
strncpy(dollarstring, statement-dollaroffset, dollaroffset);
}
/* Move on and see if the quote is ever closed */
dollarsize = dollaroffset;
found = DBDPG_FALSE;
while ((ch = *statement++)) {
dollaroffset++;
if (inside_dollar) {
/* Special case of $$ */
if (dollarsize < 1) {
found = DBDPG_TRUE;
break;
}
if (ch == dollarstring[xlen++]) {
/* Got a total match? */
if (xlen >= dollarsize) {
found = DBDPG_TRUE;
statement++;
dollaroffset--;
break;
}
}
else { /* False dollar string: reset */
inside_dollar=0;
xlen=0;
/* Fall through in case this is a dollar sign */
}
}
if ('$' == ch) {
inside_dollar = DBDPG_TRUE;
}
}
/* Once here, we are either rewinding, or are done parsing the string */
/* If end of string, rewind one character */
if (0==ch) {
dollaroffset--;
}
if (dollarstring)
Safefree(dollarstring);
/* Advance our cursor to the current position */
currpos += dollaroffset+1;
statement--; /* Rewind statement by one */
/* If not found, might be end of string, so set ch */
if (!found) {
ch = 1;
}
/* Regardless if found or not, we send it back */
continue;
} /* end dollar quoting */
/* All we care about at this point is placeholder characters and end of string */
if ('?' != ch && '$' != ch && ':' != ch && 0!=ch) {
continue;
}
/*
If this placeholder is escaped, we rewrite the string to remove the
backslash, and move on as if there is no placeholder.
The use of $dbh->{pg_placeholder_escaped} = 0 is left as an emergency measure.
It will probably be removed at some point.
*/
if ('\\' == oldch && imp_dbh->ph_escaped) {
if (! statement_rewritten) {
Renew(original_statement, strlen(statement-currpos)+1, char);
Copy(statement-currpos, original_statement, strlen(statement-currpos)+1, char);
statement_rewritten = DBDPG_TRUE;
}
/* copy the placeholder-like character but ignore the backslash */
char *p = statement-2;
while(*p++) {
*(p-1) = *p;
}
/* We need to adjust these items because we just rewrote 'statement'! */
statement--;
currpos--;
ch = *statement;
continue;
}
/* We might slurp in a placeholder, so mark the character before the current one */
/* In other words, inside of "ABC?", set sectionstop to point to "C" */
sectionstop=currpos-1;
/* Figure out if we have a placeholder */
placeholder_type = PLACEHOLDER_NONE;
/* Dollar sign placeholder style */
if ('$' == ch && isDIGIT(*statement)) {
if ('0' == *statement)
croak("Invalid placeholder value");
while(isDIGIT(*statement)) {
++statement;
++currpos;
}
placeholder_type = PLACEHOLDER_DOLLAR;
bool reprepare = DBDPG_FALSE;
int pg_type = 0;
char * value_string = NULL;
bool is_array = DBDPG_FALSE;
maxlen = 0; /* not used, this makes the compiler happy */
if (TSTART_slow) TRC(DBILOGFP, "%sBegin dbd_bind_ph (ph_name: %s)\n",
THEADER_slow,
neatsvpv(ph_name,0));
if (0==imp_sth->numphs)
croak("Statement has no placeholders to bind");
/* Check the placeholder name and transform to a standard form */
if (SvGMAGICAL(ph_name)) {
(void)mg_get(ph_name);
}
name = SvPV(ph_name, name_len);
if (PLACEHOLDER_COLON == imp_sth->placeholder_type) {
if (':' != *name) {
croak("Placeholders must begin with ':' when using the \":foo\" style");
}
}
else {
for (x=0; *(name+x); x++) {
if (!isDIGIT(*(name+x)) && (x!=0 || '$'!=*(name+x))) {
croak("Placeholder should be in the format \"$1\"\n");
}
}
}
/* Find the placeholder in question */
if (PLACEHOLDER_COLON == imp_sth->placeholder_type) {
for (x=0,currph=imp_sth->ph; NULL != currph; currph = currph->nextph) {
if (0==strcmp(currph->fooname, name)) {
x=1;
break;
}
}
if (0==x)
croak("Cannot bind unknown placeholder '%s'", name);
}
else { /* We have a number */
if ('$' == *name)
name++;
phnum = atoi(name);
if (phnum < 1 || phnum > imp_sth->numphs)
croak("Cannot bind unknown placeholder %d (%s)", phnum, neatsvpv(ph_name,0));
for (x=1,currph=imp_sth->ph; NULL != currph; currph = currph->nextph,x++) {
if (x==phnum)
break;
}
}
/* Check the value */
if (SvTYPE(newvalue) > SVt_PVLV) { /* hook for later array logic */
croak("Cannot bind a non-scalar value (%s)", neatsvpv(newvalue,0));
}
/* dbi handle allowed for cursor variables */
if (SvROK(newvalue) &&!IS_DBI_HANDLE(newvalue)) {
if (sv_isa(newvalue, "DBD::KB::DefaultValue")
|| sv_isa(newvalue, "DBI::DefaultValue")) {
/* This is a special type */
Safefree(currph->value);
currph->value = NULL;
currph->valuelen = 0;
currph->isdefault = DBDPG_TRUE;
imp_sth->has_default = DBDPG_TRUE;
}
else if (sv_isa(newvalue, "DBD::KB::Current")) {
/* This is a special type */
Safefree(currph->value);
currph->value = NULL;
currph->valuelen = 0;
currph->iscurrent = DBDPG_TRUE;
imp_sth->has_current = DBDPG_TRUE;
}
else if (SvTYPE(SvRV(newvalue)) == SVt_PVAV) {
SV * quotedval;
quotedval = pg_stringify_array(newvalue,",",imp_dbh->pg_server_version,imp_dbh->pg_utf8_flag);
currph->valuelen = sv_len(quotedval);
Renew(currph->value, currph->valuelen+1, char); /* freed in dbd_st_destroy */
Copy(SvUTF8(quotedval) ? SvPVutf8_nolen(quotedval) : SvPV_nolen(quotedval),
currph->value, currph->valuelen+1, char);
currph->bind_type = pg_type_data(PG_CSTRINGARRAY);
sv_2mortal(quotedval);
is_array = DBDPG_TRUE;
}
else if (!SvAMAGIC(newvalue)) {
/*
We want to allow magic scalars on through - but we cannot check above,
because sometimes DBD::KB::DefaultValue arrives as one!
*/
croak("Cannot bind a reference\n");
}
}
if (TRACE5_slow) {
TRC(DBILOGFP, "%sBind (%s) (type=%ld)\n", THEADER_slow, name, (long)sql_type);
if (attribs) {
TRC(DBILOGFP, "%sBind attribs (%s)", THEADER_slow, neatsvpv(attribs,0));
}
}
if (is_inout) {
currph->isinout = DBDPG_TRUE;
imp_sth->use_inout = DBDPG_TRUE;
currph->inout = newvalue; /* Reference to a scalar */
}
/* We ignore attribs for these special cases */
if (currph->isdefault || currph->iscurrent || (is_array && !SvAMAGIC(newvalue))) {
if (NULL == currph->bind_type) {
imp_sth->numbound++;
currph->bind_type = pg_type_data(PG_UNKNOWN);
}
if (TEND_slow) TRC(DBILOGFP, "%sEnd dbd_bind_ph (special)\n", THEADER_slow);
return 1;
}
( run in 1.070 second using v1.01-cache-2.11-cpan-39bf76dae61 )