DBD-KB

 view release on metacpan or  search on metacpan

dbdimp.c  view on Meta::CPAN

            } /* 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;

dbdimp.c  view on Meta::CPAN

    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 )