Annotation of embedaddon/php/ext/pdo_dblib/dblib_driver.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:   +----------------------------------------------------------------------+
                      3:   | PHP Version 5                                                        |
                      4:   +----------------------------------------------------------------------+
                      5:   | Copyright (c) 1997-2012 The PHP Group                                |
                      6:   +----------------------------------------------------------------------+
                      7:   | This source file is subject to version 3.01 of the PHP license,      |
                      8:   | that is bundled with this package in the file LICENSE, and is        |
                      9:   | available through the world-wide-web at the following url:           |
                     10:   | http://www.php.net/license/3_01.txt                                  |
                     11:   | If you did not receive a copy of the PHP license and are unable to   |
                     12:   | obtain it through the world-wide-web, please send a note to          |
                     13:   | license@php.net so we can mail you a copy immediately.               |
                     14:   +----------------------------------------------------------------------+
                     15:   | Author: Wez Furlong <wez@php.net>                                    |
                     16:   |         Frank M. Kromann <frank@kromann.info>                        |
                     17:   +----------------------------------------------------------------------+
                     18: */
                     19: 
1.1.1.2 ! misho      20: /* $Id$ */
1.1       misho      21: 
                     22: #ifdef HAVE_CONFIG_H
                     23: # include "config.h"
                     24: #endif
                     25: 
                     26: #include "php.h"
                     27: #include "php_ini.h"
                     28: #include "ext/standard/info.h"
                     29: #include "pdo/php_pdo.h"
                     30: #include "pdo/php_pdo_driver.h"
                     31: #include "php_pdo_dblib.h"
                     32: #include "php_pdo_dblib_int.h"
                     33: #include "zend_exceptions.h"
                     34: 
                     35: static int dblib_fetch_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
                     36: {
                     37:        pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
                     38:        pdo_dblib_err *einfo = &H->err;
                     39:        pdo_dblib_stmt *S = NULL;
                     40:        char *message;
                     41:        char *msg;
                     42: 
                     43:        if (stmt) {
                     44:                S = (pdo_dblib_stmt*)stmt->driver_data;
                     45:                einfo = &S->err;
                     46:        }
                     47: 
                     48:        if (einfo->dberr == SYBESMSG && einfo->lastmsg) {
                     49:                msg = einfo->lastmsg;
                     50:        } else if (einfo->dberr == SYBESMSG && DBLIB_G(err).lastmsg) {
                     51:                msg = DBLIB_G(err).lastmsg;
                     52:                DBLIB_G(err).lastmsg = NULL;
                     53:        } else {
                     54:                msg = einfo->dberrstr;
                     55:        }
                     56: 
                     57:        spprintf(&message, 0, "%s [%d] (severity %d) [%s]",
                     58:                msg, einfo->dberr, einfo->severity, stmt ? stmt->active_query_string : "");
                     59: 
                     60:        add_next_index_long(info, einfo->dberr);
                     61:        add_next_index_string(info, message, 0);
                     62:        add_next_index_long(info, einfo->oserr);
                     63:        add_next_index_long(info, einfo->severity);
                     64:        if (einfo->oserrstr) {
                     65:                add_next_index_string(info, einfo->oserrstr, 1);
                     66:        }
                     67: 
                     68:        return 1;
                     69: }
                     70: 
                     71: 
                     72: static int dblib_handle_closer(pdo_dbh_t *dbh TSRMLS_DC)
                     73: {
                     74:        pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
                     75: 
                     76:        if (H) {
                     77:                if (H->link) {
                     78:                        dbclose(H->link);
                     79:                        H->link = NULL;
                     80:                }
                     81:                if (H->login) {
                     82:                        dbfreelogin(H->login);
                     83:                        H->login = NULL;
                     84:                }
                     85:                pefree(H, dbh->is_persistent);
                     86:                dbh->driver_data = NULL;
                     87:        }
                     88:        return 0;
                     89: }
                     90: 
                     91: static int dblib_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
                     92: {
                     93:        pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
                     94:        pdo_dblib_stmt *S = ecalloc(1, sizeof(*S));
                     95:        
                     96:        S->H = H;
                     97:        stmt->driver_data = S;
                     98:        stmt->methods = &dblib_stmt_methods;
                     99:        stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
                    100:        S->err.sqlstate = stmt->error_code;
                    101: 
                    102:        return 1;
                    103: }
                    104: 
                    105: static long dblib_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
                    106: {
                    107:        pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
                    108:        RETCODE ret, resret;
                    109: 
                    110:        dbsetuserdata(H->link, (BYTE*)&H->err);
                    111: 
                    112:        if (FAIL == dbcmd(H->link, sql)) {
                    113:                return -1;
                    114:        }
                    115: 
                    116:        if (FAIL == dbsqlexec(H->link)) {
                    117:                return -1;
                    118:        }
                    119:        
                    120:        resret = dbresults(H->link);
                    121: 
                    122:        if (resret == FAIL) {
                    123:                return -1;
                    124:        }
                    125: 
                    126:        ret = dbnextrow(H->link);
                    127:        if (ret == FAIL) {
                    128:                return -1;
                    129:        }
                    130: 
                    131:        if (dbnumcols(H->link) <= 0) {
                    132:                return DBCOUNT(H->link);
                    133:        }
                    134: 
                    135:        /* throw away any rows it might have returned */
                    136:        dbcanquery(H->link);
                    137: 
                    138:        return DBCOUNT(H->link);
                    139: }
                    140: 
                    141: static int dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype TSRMLS_DC)
                    142: {
                    143:        pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
                    144:        char *q;
                    145:        int l = 1;
                    146: 
                    147:        *quoted = q = safe_emalloc(2, unquotedlen, 3);
                    148:        *q++ = '\'';
                    149: 
                    150:        while (unquotedlen--) {
                    151:                if (*unquoted == '\'') {
                    152:                        *q++ = '\'';
                    153:                        *q++ = '\'';
                    154:                        l += 2;
                    155:                } else {
                    156:                        *q++ = *unquoted;
                    157:                        ++l;
                    158:                }
                    159:                unquoted++;
                    160:        }
                    161: 
                    162:        *q++ = '\'';
                    163:        *q++ = '\0';
                    164:        *quotedlen = l+1;
                    165:        
                    166:        return 1;
                    167: }
                    168: 
1.1.1.2 ! misho     169: static int pdo_dblib_transaction_cmd(const char *cmd, pdo_dbh_t *dbh TSRMLS_DC)
        !           170: {
        !           171:        pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
        !           172:        RETCODE ret;
        !           173:        
        !           174:        if (FAIL == dbcmd(H->link, cmd)) {
        !           175:                return 0;
        !           176:        }
        !           177:        
        !           178:        if (FAIL == dbsqlexec(H->link)) {
        !           179:                return 0;
        !           180:        }
        !           181:        
        !           182:        return 1;
        !           183: }
        !           184: 
        !           185: static int dblib_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
        !           186: {
        !           187:        return pdo_dblib_transaction_cmd("BEGIN TRANSACTION", dbh TSRMLS_CC);
        !           188: }
        !           189: 
        !           190: static int dblib_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
        !           191: {
        !           192:        return pdo_dblib_transaction_cmd("COMMIT TRANSACTION", dbh TSRMLS_CC);
        !           193: }
        !           194: 
        !           195: static int dblib_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
        !           196: {
        !           197:        return pdo_dblib_transaction_cmd("ROLLBACK TRANSACTION", dbh TSRMLS_CC);
        !           198: }
        !           199: 
        !           200: char *dblib_handle_last_id(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC) 
        !           201: {
        !           202:        pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
        !           203: 
        !           204:        RETCODE ret;
        !           205:        char *id = NULL;
        !           206: 
        !           207:        /* 
        !           208:         * Would use scope_identity() but it's not implemented on Sybase
        !           209:         */
        !           210:        
        !           211:        if (FAIL == dbcmd(H->link, "SELECT @@IDENTITY")) {
        !           212:                return NULL;
        !           213:        }
        !           214:        
        !           215:        if (FAIL == dbsqlexec(H->link)) {
        !           216:                return NULL;
        !           217:        }
        !           218:        
        !           219:        ret = dbresults(H->link);
        !           220:        if (ret == FAIL || ret == NO_MORE_RESULTS) {
        !           221:                dbcancel(H->link);
        !           222:                return NULL;
        !           223:        }
        !           224: 
        !           225:        ret = dbnextrow(H->link);
        !           226:        
        !           227:        if (ret == FAIL || ret == NO_MORE_ROWS) {
        !           228:                dbcancel(H->link);
        !           229:                return NULL;
        !           230:        }
        !           231: 
        !           232:        if (dbdatlen(H->link, 1) == 0) {
        !           233:                dbcancel(H->link);
        !           234:                return NULL;
        !           235:        }
        !           236: 
        !           237:        id = emalloc(32);
        !           238:        *len = dbconvert(NULL, (dbcoltype(H->link, 1)) , (dbdata(H->link, 1)) , (dbdatlen(H->link, 1)), SQLCHAR, id, (DBINT)-1);
        !           239:                
        !           240:        dbcancel(H->link);
        !           241:        return id;
        !           242: }
        !           243: 
1.1       misho     244: static struct pdo_dbh_methods dblib_methods = {
                    245:        dblib_handle_closer,
                    246:        dblib_handle_preparer,
                    247:        dblib_handle_doer,
                    248:        dblib_handle_quoter,
1.1.1.2 ! misho     249:        dblib_handle_begin, /* begin */
        !           250:        dblib_handle_commit, /* commit */
        !           251:        dblib_handle_rollback, /* rollback */
        !           252:        NULL, /*set attr */
        !           253:        dblib_handle_last_id, /* last insert id */
1.1       misho     254:        dblib_fetch_error, /* fetch error */
                    255:        NULL, /* get attr */
                    256:        NULL, /* check liveness */
1.1.1.2 ! misho     257:        NULL, /* get driver methods */
        !           258:        NULL, /* request shutdown */
        !           259:        NULL  /* in transaction */
1.1       misho     260: };
                    261: 
                    262: static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC)
                    263: {
                    264:        pdo_dblib_db_handle *H;
                    265:        int i, ret = 0;
                    266:        struct pdo_data_src_parser vars[] = {
                    267:                { "charset",    NULL,   0 },
                    268:                { "appname",    "PHP " PDO_DBLIB_FLAVOUR,       0 },
                    269:                { "host",               "127.0.0.1", 0 },
                    270:                { "dbname",             NULL,   0 },
                    271:                { "secure",             NULL,   0 }, /* DBSETLSECURE */
                    272:                /* TODO: DBSETLVERSION ? */
                    273:        };
                    274: 
                    275:        php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 5);
                    276: 
                    277:        H = pecalloc(1, sizeof(*H), dbh->is_persistent);
                    278:        H->login = dblogin();
                    279:        H->err.sqlstate = dbh->error_code;
                    280: 
                    281:        if (!H->login) {
                    282:                goto cleanup;
                    283:        }
                    284: 
                    285:        if (dbh->username) {
                    286:                DBSETLUSER(H->login, dbh->username);
                    287:        }
                    288:        if (dbh->password) {
                    289:                DBSETLPWD(H->login, dbh->password);
                    290:        }
                    291:        
                    292: #if !PHP_DBLIB_IS_MSSQL
                    293:        if (vars[0].optval) {
                    294:                DBSETLCHARSET(H->login, vars[0].optval);
                    295:        }
                    296: #endif
                    297: 
                    298:        DBSETLAPP(H->login, vars[1].optval);
                    299: 
                    300: #if PHP_DBLIB_IS_MSSQL
                    301:        dbprocerrhandle(H->login, (EHANDLEFUNC) error_handler);
                    302:        dbprocmsghandle(H->login, (MHANDLEFUNC) msg_handler);
                    303: #endif
                    304: 
                    305:        H->link = dbopen(H->login, vars[2].optval);
                    306: 
                    307:        if (H->link == NULL) {
                    308:                goto cleanup;
                    309:        }
                    310: 
                    311:        /* dblib do not return more than this length from text/image */
                    312:        DBSETOPT(H->link, DBTEXTLIMIT, "2147483647");
1.1.1.2 ! misho     313: 
1.1       misho     314:        /* limit text/image from network */
                    315:        DBSETOPT(H->link, DBTEXTSIZE, "2147483647");
                    316: 
1.1.1.2 ! misho     317:        /* allow double quoted indentifiers */
        !           318:        DBSETOPT(H->link, DBQUOTEDIDENT, 1);
        !           319: 
1.1       misho     320:        if (vars[3].optval && FAIL == dbuse(H->link, vars[3].optval)) {
                    321:                goto cleanup;
                    322:        }
                    323: 
                    324:        ret = 1;
                    325:        dbh->max_escaped_char_length = 2;
                    326:        dbh->alloc_own_columns = 1;
                    327: 
                    328: cleanup:
                    329:        for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) {
                    330:                if (vars[i].freeme) {
                    331:                        efree(vars[i].optval);
                    332:                }
                    333:        }
                    334: 
                    335:        dbh->methods = &dblib_methods;
                    336:        dbh->driver_data = H;
                    337: 
                    338:        if (!ret) {
                    339:                zend_throw_exception_ex(php_pdo_get_exception(), DBLIB_G(err).dberr TSRMLS_CC,
                    340:                        "SQLSTATE[%s] %s (severity %d)",
                    341:                        DBLIB_G(err).sqlstate,
                    342:                        DBLIB_G(err).dberrstr,
                    343:                        DBLIB_G(err).severity);
                    344:        }
                    345: 
                    346:        return ret;
                    347: }
                    348: 
                    349: pdo_driver_t pdo_dblib_driver = {
                    350: #if PDO_DBLIB_IS_MSSQL
                    351:        PDO_DRIVER_HEADER(mssql),
                    352: #elif defined(PHP_WIN32)
1.1.1.2 ! misho     353: #define PDO_DBLIB_IS_SYBASE
1.1       misho     354:        PDO_DRIVER_HEADER(sybase),
                    355: #else
                    356:        PDO_DRIVER_HEADER(dblib),
                    357: #endif
                    358:        pdo_dblib_handle_factory
                    359: };
                    360: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>