Annotation of parser3/src/sql/mysql/parser3mysql.C, revision 1.8

1.1       paf         1: /** @file
                      2:        Parser: MySQL driver.
                      3: 
1.7       paf         4:        Copyright(c) 2001 ArtLebedev Group(http://www.artlebedev.com)
1.1       paf         5: 
1.7       paf         6:        Author: Alexander Petrosyan <paf@design.ru>(http://design.ru/paf)
1.1       paf         7: 
1.8     ! paf         8:        $Id: parser3mysql.C,v 1.7 2001/04/05 11:01:59 paf Exp $
1.1       paf         9: */
                     10: 
1.4       paf        11: #include <stdlib.h>
                     12: 
1.1       paf        13: #include "pa_sql_driver.h"
1.4       paf        14: #include "mysql.h"
1.7       paf        15: #include "pa_common.h" //
1.1       paf        16: 
1.4       paf        17: char *lsplit(char *string, char delim) {
                     18:     if(string) {
                     19:                char *v=strchr(string, delim);
                     20:                if(v) {
                     21:                        *v=0;
                     22:                        return v+1;
                     23:                }
                     24:     }
                     25:     return 0;
                     26: }
                     27: 
1.6       paf        28: /**
                     29:        MySQL server driver
                     30:        
                     31:        @todo 
                     32:                figure out about memory for errors:
                     33:                - static=add multithread locks
                     34:                - dynamic=who should free it up?
                     35: */
1.1       paf        36: class MySQL_Driver : public SQL_Driver {
                     37: public:
                     38: 
1.4       paf        39:        MySQL_Driver() : SQL_Driver() {
1.3       paf        40:        }
1.1       paf        41: 
                     42:        /// get api version
1.6       paf        43:        int api_version() { return SQL_DRIVER_API_VERSION; }
1.4       paf        44:        /// connect
1.6       paf        45:        void connect(
1.5       paf        46:                char *url, ///< @b user:pass@host[:port]/database
1.6       paf        47:                void **connection ///< output: MYSQL *
1.5       paf        48:                ) {
1.4       paf        49:                char *user=url;
                     50:                char *host=lsplit(user, '@');
                     51:                char *db=lsplit(host, '/');
                     52:                char *pwd=lsplit(user, ':');
                     53:                char *error_pos=0;
                     54:                char *port_cstr=lsplit(host, ':');
                     55:                int port=port_cstr?strtol(port_cstr, &error_pos, 0):0;
                     56: 
                     57:            MYSQL *mysql=mysql_init(NULL);
                     58:                if(!mysql_real_connect(mysql, 
                     59:                        host, user, pwd, db, port?port:MYSQL_PORT, NULL, 0))
1.6       paf        60:                        fservices->_throw(mysql_error(mysql));
1.4       paf        61: 
1.6       paf        62:                *(MYSQL **)connection=mysql;
1.1       paf        63:        }
1.6       paf        64:        void disconnect(void *connection) {
                     65:            mysql_close((MYSQL *)connection);
1.1       paf        66:        }
1.6       paf        67:        void commit(void *connection) {}
                     68:        void rollback(void *connection) {}
1.7       paf        69: 
1.8     ! paf        70:        bool ping(void *connection) {
        !            71:                return false;
        !            72:                return mysql_ping((MYSQL *)connection)==0;
        !            73:        }
        !            74: 
1.7       paf        75:        void query(void *connection, 
1.8     ! paf        76:                const char *statement, unsigned long offset, unsigned long limit,
1.7       paf        77:                unsigned int *column_count, Cell **columns, 
                     78:                unsigned long *row_count, Cell ***rows) {
                     79: 
                     80:                MYSQL *mysql=(MYSQL *)connection;
                     81:                MYSQL_RES *res=NULL;
1.8     ! paf        82: 
        !            83:                //mysql_character_set_name
        !            84:                //mysql_real_escape_string
        !            85:                //mysql_escape_string
1.7       paf        86:                
                     87:                if(mysql_query(mysql, statement)) 
                     88:                        fservices->_throw(mysql_error(mysql));
                     89:                if(!(res=mysql_store_result(mysql)) && mysql_field_count(mysql)) 
                     90:                        fservices->_throw(mysql_error(mysql));
                     91:                if(!res) {
                     92:                        // empty result
                     93:                        *row_count=0;
                     94:                        *column_count=0;
                     95:                        return;
                     96:                }
                     97:                
                     98:                *column_count=mysql_num_fields(res);
                     99:                *columns=(Cell *)fservices->malloc(sizeof(Cell)*(*column_count));
                    100: 
                    101:                *row_count=(unsigned long)mysql_num_rows(res);
                    102:                *rows=(Cell **)fservices->malloc(sizeof(Cell *)*(*row_count));
                    103:                
                    104:                for(unsigned int i=0; i<(*column_count); i++){
                    105:                        MYSQL_FIELD *field=mysql_fetch_field(res);
                    106:                        size_t size=strlen(field->name);
                    107:                        (*columns)[i].size=size;
                    108:                        (*columns)[i].ptr=fservices->malloc(size);
                    109:                        memcpy((*columns)[i].ptr, field->name, size);
                    110:                }
                    111:                
                    112:                for(unsigned long r=0; r<(*row_count); r++) 
                    113:                        if(MYSQL_ROW mysql_row=mysql_fetch_row(res)) { // never false..
                    114:                                unsigned long *lengths=mysql_fetch_lengths(res);
                    115:                                Cell *row=(Cell *)malloc(sizeof(Cell)*(*column_count));
                    116:                                (*rows)[r]=row;
                    117:                                for(unsigned int i=0; i<(*column_count); i++){
                    118:                                        size_t size=(size_t)lengths[i];
                    119:                                        row[i].size=size;
                    120:                                        row[i].ptr=fservices->malloc(size);
                    121:                                        memcpy(row[i].ptr, mysql_row[i], size);
                    122:                                }
                    123:                }
                    124:                
                    125:                mysql_free_result(res);
                    126:        }
1.1       paf       127: };
                    128: 
                    129: extern "C" SQL_Driver *create() {
                    130:        return new MySQL_Driver();
                    131: }

E-mail: