diff --git a/lib4d_sql/base64.c b/lib4d_sql/base64.c old mode 100644 new mode 100755 index 1958afc..b6c1730 --- a/lib4d_sql/base64.c +++ b/lib4d_sql/base64.c @@ -1,21 +1,22 @@ /* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2008 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: Jim Winstead | - +----------------------------------------------------------------------+ + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2008 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Jim Winstead | + +----------------------------------------------------------------------+ */ -/* $Id: base64.c,v 1.43.2.2.2.4 2007/12/31 07:20:12 sebastian Exp $ */ + +/* $Id: base64.c 287670 2009-08-25 08:35:39Z fourd $ */ #include #include @@ -55,13 +56,13 @@ static const short base64_reverse_table[256] = { /* {{{ php_base64_encode */ //PHPAPI -unsigned char *base64_encode(const unsigned char *str, int length, int *ret_length) +unsigned char *base64_encode(const char *str, size_t length, int *ret_length) { - const unsigned char *current = str; + const char *current = str; unsigned char *p; unsigned char *result; - if ((length + 2) < 0 || ((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2))) { + if (((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2))) { if (ret_length != NULL) { *ret_length = 0; } @@ -137,7 +138,7 @@ void php_base64_init(void) /* }}} */ //PHPAPI -unsigned char *base64_decode(const unsigned char *str, int length, int *ret_length) +unsigned char *base64_decode(const char *str, size_t length, int *ret_length) { return base64_decode_ex(str, length, ret_length, 0); } @@ -145,9 +146,9 @@ unsigned char *base64_decode(const unsigned char *str, int length, int *ret_leng /* {{{ php_base64_decode */ /* as above, but backwards. :) */ //PHPAPI -unsigned char *base64_decode_ex(const unsigned char *str, int length, int *ret_length, int strict) +unsigned char *base64_decode_ex(const char *str, size_t length, int *ret_length, int strict) { - const unsigned char *current = str; + const char *current = str; int ch, i = 0, j = 0, k; /* this sucks for threaded environments */ unsigned char *result; diff --git a/lib4d_sql/base64.h b/lib4d_sql/base64.h old mode 100644 new mode 100755 index c068f87..d405c6d --- a/lib4d_sql/base64.h +++ b/lib4d_sql/base64.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: base64.h,v 1.14.2.1.2.3 2007/12/31 07:20:12 sebastian Exp $ */ +/* $Id: base64.h 279540 2009-04-29 08:57:22Z splanquart $ */ #ifndef BASE64_H #define BASE64_H @@ -25,11 +25,11 @@ //PHP_FUNCTION(base64_encode); //PHPAPI extern -unsigned char *base64_encode(const unsigned char *, int, int *); +unsigned char *base64_encode(const char *, size_t, int *); //PHPAPI extern -unsigned char *base64_decode_ex(const unsigned char *, int, int *, int); +unsigned char *base64_decode_ex(const char *, size_t, int *, int); //PHPAPI extern -unsigned char *base64_decode(const unsigned char *, int, int *); +unsigned char *base64_decode(const char *, size_t, int *); #endif /* BASE64_H */ diff --git a/lib4d_sql/communication.c b/lib4d_sql/communication.c old mode 100644 new mode 100755 index ebbb71a..9feb113 --- a/lib4d_sql/communication.c +++ b/lib4d_sql/communication.c @@ -1,383 +1,616 @@ -#include "fourd.h" -#include "fourd_int.h" -#include "base64.h" -#include - - - - -int socket_connect(FOURD *cnx,const char *host,unsigned int port) -{ - //WSADATA wsaData; - - struct addrinfo *result = NULL, - *ptr = NULL, - hints; - int iResult=0; - //SOCKET ConnectSocket = INVALID_SOCKET; - - char sport[50]; - sprintf_s(sport,50,"%d",port); - - /* - // Initialize Winsock - iResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if (iResult != 0) { - Printf("WSAStartup failed: %d\n", iResult); - return 1; - } - */ - - //initialize Hints - ZeroMemory( &hints, sizeof(hints) ); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - // Resolve the server address and port - iResult = getaddrinfo(host, sport, &hints, &result); - if ( iResult != 0 ) { - Printf("getaddrinfo failed: %d : %s\n", iResult,gai_strerror(iResult)); - cnx->error_code=-iResult; - strncpy_s(cnx->error_string,2048,gai_strerror(iResult),2048); - return 1; - } - //Printf("getaddrinfo ok\n"); - - - // Attempt to connect to the first address returned by - // the call to getaddrinfo - ptr=result; - - // Create a SOCKET for connecting to server - cnx->socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); - if (cnx->socket == INVALID_SOCKET) { - Printf("Error at socket(): %ld\n", WSAGetLastError()); - cnx->error_code=-WSAGetLastError(); - strncpy_s(cnx->error_string,2048,"Unable to create socket",2048); - freeaddrinfo(result); - return 1; - } - //Printf("Socket Ok\n"); - // Connect to server. - iResult = connect( cnx->socket, ptr->ai_addr, (int)ptr->ai_addrlen); - if (iResult == SOCKET_ERROR) { - Printf("Error at socket(): %ld\n", WSAGetLastError()); - cnx->error_code=-WSAGetLastError(); - strncpy_s(cnx->error_string,2048,"Unable to connect to server",2048); - freeaddrinfo(result); - closesocket(cnx->socket); - cnx->socket = INVALID_SOCKET; - return 1; - } - //Printf("Connexion ok\n"); - - - - - // Should really try the next address returned by getaddrinfo - // if the connect call failed - // But for this simple example we just free the resources - // returned by getaddrinfo and print an error message - - freeaddrinfo(result); - - if (cnx->socket == INVALID_SOCKET) { - Printf("Unable to connect to server!\n"); - cnx->error_code=-1; - strncpy_s(cnx->error_string,2048,"Unable to connect to server",2048); - return 1; - } - //Printf("fin de la fonction\n"); - - return 0; -} - -void socket_disconnect(FOURD *cnx) -{ - int iResult=0; - // shutdown the send half of the connection since no more data will be sent - #ifdef WIN32 - iResult = shutdown(cnx->socket, SD_SEND); - if (iResult == SOCKET_ERROR) { - Printf("shutdown failed: %d\n", WSAGetLastError()); - closesocket(cnx->socket); - cnx->connected=0; - return ; - } - #endif - closesocket(cnx->socket); - cnx->connected=0; - //Printf("Disconnect ok\n"); -} -int socket_send(FOURD *cnx,const char*msg) -{ - int iResult; - //Printf("Send-len:%d\n",strlen(msg)) - Printf("Send:\n%s",msg); - // Send an initial buffer - iResult = send( cnx->socket, msg, (int)strlen(msg), 0 ); - if (iResult == SOCKET_ERROR) { - Printf("send failed: %d\n", WSAGetLastError()); - socket_disconnect(cnx); - return 1; - } - return 0; -} -int socket_send_data(FOURD *cnx,const char*msg,int len) -{ - int iResult; - Printf("Send:%d bytes\n",len); - PrintData(msg,len); - Printf("\n"); - // Send an initial buffer - iResult = send( cnx->socket, msg, len, 0 ); - if (iResult == SOCKET_ERROR) { - Printf("send failed: %d\n", WSAGetLastError()); - socket_disconnect(cnx); - return 1; - } - return 0; -} - -int socket_receiv_header(FOURD *cnx,FOURD_RESULT *state) -{ - int iResult=0; - int offset=0; - int len=0; - int crlf=0; - char *fin_header=NULL; - //read the HEADER only - do - { - offset+=iResult; - iResult = recv(cnx->socket,state->header+offset,1, 0); - len+=iResult; - if(len>3) - { - if(state->header[offset-3]=='\r' - &&state->header[offset-2]=='\n' - &&state->header[offset-1]=='\r' - &&state->header[offset ]=='\n') - crlf=1; - } - - }while(iResult>0 && !crlf); - if(!crlf) - { - Printf("Error: Header-end not found\n"); - return 1; - } - state->header[len]=0; - state->header_size=len; - Printf("Receiv:\n%s",state->header); - //there we must add reading data - //before analyse header - //see COLUMN-TYPES section - return 0; -} -int socket_receiv_data(FOURD *cnx,FOURD_RESULT *state) -{ - int iResult=0; - int offset=0; - int len=0; - int end_row=0; - unsigned int nbCol=state->row_type.nbColumn; - unsigned int nbRow=state->row_count_sent; - unsigned int r,c; - FOURD_TYPE *colType; - FOURD_ELEMENT *pElmt=NULL; - char status_code=0; - int elmt_size=0; - int elmts_offset=0; - Printf("---Debut de socket_receiv_data\n"); - colType=calloc(nbCol,sizeof(FOURD_TYPE)); - //bufferize Column type - for(c=0;crow_type.nbColumn;c++) - colType[c]=state->row_type.Column[c].type; - - /* allocate nbElmt in state->elmt */ - state->elmt=calloc(nbCol*nbRow,sizeof(FOURD_ELEMENT)); - - Printf("Debut de socket_receiv_data\n"); - Printf("state->row_count:%d\t\tstate->row_count_sent:%d\n",state->row_count,state->row_count_sent); - Printf("NbRow to read: %d\n",nbRow); - /* read all row */ - for(r=0;rupdateability) /* rowId is send only if row updateablisity */ - { - int row_id=0; - iResult = recv(cnx->socket,&status_code,sizeof(status_code), 0); - //Printf("status_code for row:0x%X\n",status_code); - len+=iResult; - switch(status_code) - { - case '0': - break; - case '1': - /* pElmt->elmt=calloc(vk_sizeof(colType[0]),1); */ - iResult = recv(cnx->socket,(char*)&row_id,sizeof(row_id), 0); - /* Printf("row_id:%d\n",row_id); */ - len+=iResult; - break; - case '2': - Printferr("Error during reading data\n"); - iResult = recv(cnx->socket,(char*)&(state->error_code),sizeof(state->error_code), 0); - len+=iResult; - return 1; /* return on error */ - break; - default: - Printferr("Status code 0x%X not supported in data\n",status_code); - break; - } - } - else { - Printf("Not read rowid\n"); - } - /* read all columns */ - for(c=0;celmt[elmts_offset]); - pElmt->type=colType[c]; - - //read column status code - iResult = recv(cnx->socket,&status_code,1, 0); - len+=iResult; - switch(status_code) - { - case '2'://error - Printferr("Error during reading data\n"); - iResult = recv(cnx->socket,(char*)&(state->error_code),sizeof(state->error_code), 0); - len+=iResult; - return 1;//on sort en erreur - break; - case '0'://null value - Printf("Read null value\n"); - pElmt->null=1; - break; - case '1'://value - pElmt->null=0; - switch(colType[c]) - { - case VK_BOOLEAN: - case VK_BYTE: - case VK_WORD: - case VK_LONG: - case VK_LONG8: - case VK_REAL: - case VK_DURATION: - pElmt->pValue=calloc(vk_sizeof(colType[c]),1); - iResult = recv(cnx->socket,(pElmt->pValue),vk_sizeof(colType[c]), 0); - len+=iResult; - //Printf("Long: %d\n",*((int*)pElmt->pValue)); - break; - case VK_TIMESTAMP: - { - FOURD_TIMESTAMP *tmp; - tmp=calloc(sizeof(FOURD_TIMESTAMP),1); - pElmt->pValue=tmp; - iResult = recv(cnx->socket,(char*)&(tmp->year),sizeof(short), 0); - len+=iResult; - iResult = recv(cnx->socket,&(tmp->mounth),sizeof(char), 0); - len+=iResult; - iResult = recv(cnx->socket,&(tmp->day),sizeof(char), 0); - len+=iResult; - iResult = recv(cnx->socket,(char*)&(tmp->milli),sizeof(unsigned int), 0); - len+=iResult; - } - break; - case VK_FLOAT: - { - //int exp;char sign;int data_length;void* data; - FOURD_FLOAT *tmp; - tmp=calloc(sizeof(FOURD_FLOAT),1); - pElmt->pValue=tmp; - - iResult = recv(cnx->socket,(char*)&(tmp->exp),sizeof(int), 0); - len+=iResult; - iResult = recv(cnx->socket,&(tmp->sign),sizeof(char), 0); - len+=iResult; - iResult = recv(cnx->socket,(char*)&(tmp->data_length),sizeof(int), 0); - len+=iResult; - iResult = recv(cnx->socket,(tmp->data),tmp->data_length, 0); - len+=iResult; - - //Printferr("Float not supported\n"); - } - break; - case VK_STRING: - { - int data_length=0; - FOURD_STRING *str; - //read negative value of length of string - str=calloc(1,sizeof(FOURD_STRING)); - pElmt->pValue=str; - iResult = recv(cnx->socket,(char*)&data_length,4, 0); - len+=iResult; - data_length=-data_length; - //Printf("Size of String: %d\n",data_length); - str->length=data_length; - str->data=calloc(1,data_length*2+2); - iResult = recv(cnx->socket,(str->data),(data_length*2), 0); - str->data[data_length*2]=0; - str->data[data_length*2+1]=0; - len+=iResult; - /* - { - int length=0; - char *chaine=NULL; - chaine=base64_encode((unsigned char*)str->data,data_length*2,&length); - Printf("Chaine: %s\n",chaine); - free(chaine); - }*/ - } - break; - case VK_IMAGE: - //Printferr("Image-Type not supported\n"); - //break; - case VK_BLOB: - { - int data_length=0; - FOURD_BLOB *blob; - //read negative value of length of string - blob=calloc(1,sizeof(FOURD_BLOB)); - pElmt->pValue=blob; - iResult = recv(cnx->socket,(char*)&data_length,4, 0); - len+=iResult; - blob->length=data_length; - blob->data=calloc(1,data_length); - iResult = recv(cnx->socket,blob->data,data_length, 0); - len+=iResult; - //Printf("Blob: %d Bytes\n",data_length); - } - Printferr("Blob not supported\n"); - break; - default: - Printferr("Type not supported (%s)\n",stringFromType(colType[c])); - break; - } - break; - default: - Printferr("Status code 0x%X not supported in data\n",status_code); - break; - } - } - } - Printf("---Fin de socket_receiv_data\n"); - return 0; -} -int socket_receiv_update_count(FOURD *cnx,FOURD_RESULT *state) -{ - FOURD_LONG8 data=0; - int iResult=0; - int len=0; - iResult = recv(cnx->socket,(char*)&data,8, 0); - len+=iResult; - Printf("Ox%X\n",data); - cnx->updated_row=data; - Printf("\n"); - - return 0; -} \ No newline at end of file +/* + +----------------------------------------------------------------------+ + | lib4D_SQL | + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | | + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | | + | Its original copy is usable under several licenses and is available | + | through the world-wide-web at the following url: | + | http://freshmeat.net/projects/lib4d_sql | + | | + | Unless required by applicable law or agreed to in writing, software | + | distributed under the License is distributed on an "AS IS" BASIS, | + | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | + | implied. See the License for the specific language governing | + | permissions and limitations under the License. | + +----------------------------------------------------------------------+ + | Contributed by: 4D , http://www.4d.com | + | Alter Way, http://www.alterway.fr | + | Authors: Stephane Planquart | + | Alexandre Morgaut | + +----------------------------------------------------------------------+ +*/ + +#include "fourd.h" +#include "fourd_int.h" +#include "base64.h" +#include +#include +#ifdef WIN32 +#define EINPROGRESS WSAEWOULDBLOCK +#else +#include +#endif + +long frecv(SOCKET s,unsigned char *buf,int len,int flags) +{ + int rec=0; + long iResult=0; + do{ + iResult=recv(s,buf+rec,len-rec, 0); + if(iResult<0){ + return iResult; + }else { + rec+=iResult; + } + }while(recerror_code=-iResult; + strncpy_s(cnx->error_string,2048,gai_strerror(iResult),2048); + return 1; + } + //Printf("getaddrinfo ok\n"); + + + // Attempt to connect to the first address returned by + // the call to getaddrinfo + ptr=result; + + // Create a SOCKET for connecting to server + cnx->socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); + if (cnx->socket == INVALID_SOCKET) { + Printf("Error at socket(): %ld\n", WSAGetLastError()); + cnx->error_code=-WSAGetLastError(); + strncpy_s(cnx->error_string,2048,"Unable to create socket",2048); + freeaddrinfo(result); + return 1; + } + //Printf("Socket Ok\n"); + // Connect to server. + iResult = connect( cnx->socket, ptr->ai_addr, (int)ptr->ai_addrlen); + if (iResult == SOCKET_ERROR) { + Printf("Error at socket(): %ld\n", WSAGetLastError()); + cnx->error_code=-WSAGetLastError(); + strncpy_s(cnx->error_string,2048,"Unable to connect to server",2048); + freeaddrinfo(result); + closesocket(cnx->socket); + cnx->socket = INVALID_SOCKET; + return 1; + } + //Printf("Connexion ok\n"); + + + + + // Should really try the next address returned by getaddrinfo + // if the connect call failed + // But for this simple example we just free the resources + // returned by getaddrinfo and print an error message + + freeaddrinfo(result); + + if (cnx->socket == INVALID_SOCKET) { + Printf("Unable to connect to server!\n"); + cnx->error_code=-1; + strncpy_s(cnx->error_string,2048,"Unable to connect to server",2048); + return 1; + } + //Printf("fin de la fonction\n"); + + return 0; +} + +void socket_disconnect(FOURD *cnx) +{ + // shutdown the send half of the connection since no more data will be sent + #ifdef WIN32 + iResult = shutdown(cnx->socket, SD_SEND); + if (iResult == SOCKET_ERROR) { + Printf("shutdown failed: %d\n", WSAGetLastError()); + closesocket(cnx->socket); + cnx->connected=0; + return ; + } + #endif + closesocket(cnx->socket); + cnx->connected=0; + //Printf("Disconnect ok\n"); +} + +int socket_send(FOURD *cnx,const char*msg) +{ + long iResult; + //Printf("Send-len:%d\n",strlen(msg)) + Printf("Send:\n%s",msg); + // Send an initial buffer + iResult = send( cnx->socket, msg, (int)strlen(msg), 0 ); + if (iResult == SOCKET_ERROR) { + Printf("send failed: %d\n", WSAGetLastError()); + socket_disconnect(cnx); + return 1; + } + return 0; +} +int socket_send_data(FOURD *cnx,const char*msg,int len) +{ + long iResult; + Printf("Send:%d bytes\n",len); + PrintData(msg,len); + Printf("\n"); + // Send an initial buffer + iResult = send( cnx->socket, msg, len, 0 ); + if (iResult == SOCKET_ERROR) { + Printf("send failed: %d\n", WSAGetLastError()); + socket_disconnect(cnx); + return 1; + } + return 0; +} + +int socket_receiv_header(FOURD *cnx,FOURD_RESULT *state) +{ + long iResult=0; + int offset=0; + int len=0; + int crlf=0; + //read the HEADER only + do + { + offset+=iResult; + iResult = recv(cnx->socket,state->header+offset,1, 0); + len+=iResult; + if(len>3) + { + if(state->header[offset-3]=='\r' + &&state->header[offset-2]=='\n' + &&state->header[offset-1]=='\r' + &&state->header[offset ]=='\n') + crlf=1; + } + + }while(iResult>0 && !crlf); + if(!crlf) + { + Printf("Error: Header-end not found\n"); + return 1; + } + state->header[len]=0; + state->header_size=len; + Printf("Receiv:\n%s",state->header); + //there we must add reading data + //before analyse header + //see COLUMN-TYPES section + return 0; +} +int socket_receiv_data(FOURD *cnx,FOURD_RESULT *state) +{ + long iResult=0; + int len=0; + //int end_row=0; + unsigned int nbCol=state->row_type.nbColumn; + unsigned int nbRow=state->row_count_sent; + unsigned int r,c; + FOURD_TYPE *colType; + FOURD_ELEMENT *pElmt=NULL; + unsigned char status_code=0; + //int elmt_size=0; + int elmts_offset=0; + Printf("---Debut de socket_receiv_data\n"); + colType=calloc(nbCol,sizeof(FOURD_TYPE)); + //bufferize Column type + for(c=0;crow_type.nbColumn;c++) + colType[c]=state->row_type.Column[c].type; + Printf("nbCol*nbRow:%d\n",nbCol*nbRow); + /* allocate nbElmt in state->elmt */ + state->elmt=calloc(nbCol*nbRow,sizeof(FOURD_ELEMENT)); + + Printf("Debut de socket_receiv_data\n"); + Printf("state->row_count:%d\t\tstate->row_count_sent:%d\n",state->row_count,state->row_count_sent); + Printf("NbRow to read: %d\n",nbRow); + /* read all row */ + for(r=0;rupdateability) /* rowId is send only if row updateablisity */ + { + int row_id=0; + status_code=0; + iResult = frecv(cnx->socket,&status_code,sizeof(status_code), 0); + //Printf("status_code for row:0x%X\n",status_code); + len+=iResult; + switch(status_code) + { + case '0': + break; + case '1': + /* pElmt->elmt=calloc(vk_sizeof(colType[0]),1); */ + iResult = frecv(cnx->socket,(unsigned char*)&row_id,sizeof(row_id), 0); + /* Printf("row_id:%d\n",row_id); */ + len+=iResult; + break; + case '2': + Printferr("Error during reading data\n"); + iResult = frecv(cnx->socket,(unsigned char*)&(state->error_code),sizeof(state->error_code), 0); + len+=iResult; + return 1; /* return on error */ + break; + default: + Printferr("Status code 0x%X not supported in data at row %d column %d\n",status_code,(elmts_offset-c+1)/nbCol+1,c+1); + break; + } + } + else { + Printf("Not read rowid\n"); + } + /* read all columns */ + for(c=0;celmt[elmts_offset]); + pElmt->type=colType[c]; + + //read column status code + status_code=0; + iResult = frecv(cnx->socket,&status_code,1, 0); + Printf("status: %2X\n",status_code); + len+=iResult; + switch(status_code) + { + case '2'://error + Printferr("Error during reading data\n"); + iResult = frecv(cnx->socket,(unsigned char*)&(state->error_code),sizeof(state->error_code), 0); + len+=iResult; + return 1;//on sort en erreur + break; + case '0'://null value + Printf("Read null value\n"); + pElmt->null=1; + break; + case '1'://value + pElmt->null=0; + switch(colType[c]) + { + case VK_BOOLEAN: + case VK_BYTE: + case VK_WORD: + case VK_LONG: + case VK_LONG8: + case VK_REAL: + case VK_DURATION: + pElmt->pValue=calloc(1,vk_sizeof(colType[c])); + iResult = frecv(cnx->socket,(pElmt->pValue),vk_sizeof(colType[c]), 0); + len+=iResult; + //Printf("Long: %d\n",*((int*)pElmt->pValue)); + break; + case VK_TIMESTAMP: + { + FOURD_TIMESTAMP *tmp; + tmp=calloc(1,sizeof(FOURD_TIMESTAMP)); + pElmt->pValue=tmp; + iResult = frecv(cnx->socket,(unsigned char*)&(tmp->year),sizeof(short), 0); + Printf("year: %04X",tmp->year); + len+=iResult; + iResult = frecv(cnx->socket,&(tmp->mounth),sizeof(char), 0); + Printf(" mounth: %02X",tmp->mounth); + len+=iResult; + iResult = frecv(cnx->socket,&(tmp->day),sizeof(char), 0); + Printf(" day: %02X",tmp->day); + len+=iResult; + iResult = frecv(cnx->socket,(unsigned char*)&(tmp->milli),sizeof(unsigned int), 0); + Printf(" milli: %08X\n",tmp->milli); + len+=iResult; + } + break; + case VK_FLOAT: + { + //int exp;char sign;int data_length;void* data; + FOURD_FLOAT *tmp; + tmp=calloc(1,sizeof(FOURD_FLOAT)); + pElmt->pValue=tmp; + + iResult = frecv(cnx->socket,(unsigned char*)&(tmp->exp),sizeof(int), 0); + len+=iResult; + iResult = frecv(cnx->socket,&(tmp->sign),sizeof(char), 0); + len+=iResult; + iResult = frecv(cnx->socket,(unsigned char*)&(tmp->data_length),sizeof(int), 0); + len+=iResult; + iResult = frecv(cnx->socket,(tmp->data),tmp->data_length, 0); + len+=iResult; + + Printferr("Float not supported\n"); + } + break; + case VK_STRING: + { + int data_length=0; + FOURD_STRING *str; + //read negative value of length of string + str=calloc(1,sizeof(FOURD_STRING)); + pElmt->pValue=str; + iResult = frecv(cnx->socket,(unsigned char*)&data_length,4, 0); + len+=iResult; + Printf("String length: %08X\n",data_length); + data_length=-data_length; + str->length=data_length; + str->data=calloc(data_length*2+2,1); + if(data_length==0){ //correct read for empty string + str->data[0]=0; + str->data[1]=0; + } + else { + iResult = frecv(cnx->socket,(str->data),(data_length*2), 0); + str->data[data_length*2]=0; + str->data[data_length*2+1]=0; + len+=iResult; + } + /* + { + int length=0; + char *chaine=NULL; + chaine=base64_encode((unsigned char*)str->data,data_length*2,&length); + Printf("Chaine: %s\n",chaine); + free(chaine); + }*/ + } + break; + case VK_IMAGE: + //Printferr("Image-Type not supported\n"); + //break; + case VK_BLOB: + { + int data_length=0; + FOURD_BLOB *blob; + //read negative value of length of string + blob=calloc(1,sizeof(FOURD_BLOB)); + pElmt->pValue=blob; + iResult = frecv(cnx->socket,(unsigned char*)&data_length,4, 0); + Printf("Blob length: %08X\n",data_length); + len+=iResult; + if(data_length==0){ + blob->length=0; + blob->data=NULL; + pElmt->null=1; + }else{ + blob->length=data_length; + blob->data=calloc(data_length,1); + iResult = frecv(cnx->socket,blob->data,data_length, 0); + len+=iResult; + } + //Printf("Blob: %d Bytes\n",data_length); + } + //Printferr("Blob not supported\n"); + break; + default: + Printferr("Type not supported (%s) at row %d column %d\n",stringFromType(colType[c]),(elmts_offset-c+1)/nbCol+1,c+1); + break; + } + break; + default: + Printferr("Status code 0x%X not supported in data at row %d column %d\n",status_code,(elmts_offset-c+1)/nbCol+1,c+1); + break; + } + } + } + Printf("---Fin de socket_receiv_data\n"); + free(colType); + return 0; +} +int socket_receiv_update_count(FOURD *cnx,FOURD_RESULT *state) +{ + FOURD_LONG8 data=0; + long iResult=0; + int len=0; + iResult = frecv(cnx->socket,(unsigned char*)&data,8, 0); + len+=iResult; + Printf("Ox%X\n",data); + cnx->updated_row=data; + Printf("\n"); + + return 0; +} +int set_sock_blocking(int socketd, int block) +{ + int ret = 0; + int flags; + int myflag = 0; + +#ifdef WIN32 + /* with ioctlsocket, a non-zero sets nonblocking, a zero sets blocking */ + flags = !block; + if (ioctlsocket(socketd, FIONBIO, &flags) == SOCKET_ERROR) { + /*char *error_string; + + error_string = php_socket_strerror(WSAGetLastError(), NULL, 0); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", error_string); + efree(error_string);*/ + ret = 1; + } +#else + flags = fcntl(socketd, F_GETFL); +#ifdef O_NONBLOCK + myflag = O_NONBLOCK; /* POSIX version */ +#elif defined(O_NDELAY) + myflag = O_NDELAY; /* old non-POSIX version */ +#endif + if (!block) { + flags |= myflag; + } else { + flags &= ~myflag; + } + fcntl(socketd, F_SETFL, flags); +#endif + return ret; +} + +int socket_connect_timeout(FOURD *cnx,const char *host,unsigned int port,int timeout) +{ + //WSADATA wsaData; + + struct addrinfo *result = NULL, + *ptr = NULL, + hints; + int iResult=0,valopt=0; + /*SOCKET ConnectSocket = INVALID_SOCKET; */ + struct timeval tv; + fd_set myset; + socklen_t lon; + + //int nbTryConnect=0; + char sport[50]; + sprintf_s(sport,50,"%d",port); + + /* + Initialize Winsock + iResult = WSAStartup(MAKEWORD(2,2), &wsaData); + if (iResult != 0) { + Printf("WSAStartup failed: %d\n", iResult); + return 1; + } + */ + + /* initialize Hints */ + ZeroMemory( &hints, sizeof(hints) ); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + /* Resolve the server address and port */ + iResult = getaddrinfo(host, sport, &hints, &result); + if ( iResult != 0 ) { + Printf("getaddrinfo failed: %d : %s\n", iResult,gai_strerror(iResult)); + cnx->error_code=-iResult; + strncpy_s(cnx->error_string,2048,gai_strerror(iResult),2048); + return 1; + } + /* Printf("getaddrinfo ok\n"); */ + + + /*Attempt to connect to the first address returned by + the call to getaddrinfo */ + ptr=result; + + /* Create a SOCKET for connecting to server */ + cnx->socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); + if (cnx->socket == INVALID_SOCKET) { + Printf("Error at socket(): %ld\n", WSAGetLastError()); + cnx->error_code=-WSAGetLastError(); + strncpy_s(cnx->error_string,2048,"Unable to create socket",2048); + freeaddrinfo(result); + return 1; + } + int flag=1; + // if we get an error here, we can safely ignore it. The connection may be slower, but it should + // still work. + setsockopt(cnx->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)); + + /* Printf("Socket Ok\n"); */ + /*set Non blocking socket */ + set_sock_blocking(cnx->socket,0); + /* Connect to server. */ + iResult = connect( cnx->socket, ptr->ai_addr, (int)ptr->ai_addrlen); + if(iResult<0){ + if (WSAGetLastError() == EINPROGRESS) { + tv.tv_sec = timeout; + tv.tv_usec = 0; + FD_ZERO(&myset); + FD_SET(cnx->socket, &myset); + if (select(cnx->socket+1, NULL, &myset, NULL, &tv) > 0) { + lon = sizeof(int); + getsockopt(cnx->socket, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon); + if (valopt) { + fprintf(stderr, "Error in connection() %d - %s\n", valopt, strerror(valopt)); + cnx->error_code=valopt; + strncpy_s(cnx->error_string,2048,strerror(valopt),2048); + freeaddrinfo(result); + closesocket(cnx->socket); + cnx->socket = INVALID_SOCKET; + return 1; + } + /*connection ok*/ + } + else { + /*fprintf(stderr, "Timeout or error() %d - %s\n", valopt, strerror(valopt)); */ + cnx->error_code=3011; + strncpy_s(cnx->error_string,2048,"Connect timed out",2048); + freeaddrinfo(result); + closesocket(cnx->socket); + cnx->socket = INVALID_SOCKET; + return 1; + } + } + else { + /*fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno)); */ + cnx->error_code=-WSAGetLastError(); + strncpy_s(cnx->error_string,2048,"Error connecting",2048); + freeaddrinfo(result); + closesocket(cnx->socket); + cnx->socket = INVALID_SOCKET; + return 1; + } + + + } + + /* Printf("Connexion ok\n"); */ + + + /*set blocking socket */ + set_sock_blocking(cnx->socket,1); + + + /* Should really try the next address returned by getaddrinfo + if the connect call failed + But for this simple example we just free the resources + returned by getaddrinfo and print an error message */ + + freeaddrinfo(result); + + if (cnx->socket == INVALID_SOCKET) { + Printf("Unable to connect to server!\n"); + cnx->error_code=-1; + strncpy_s(cnx->error_string,2048,"Unable to connect to server",2048); + return 1; + } + /* Printf("fin de la fonction\n"); */ + + return 0; +} diff --git a/lib4d_sql/fourd.c b/lib4d_sql/fourd.c old mode 100644 new mode 100755 index da31eb6..92fa357 --- a/lib4d_sql/fourd.c +++ b/lib4d_sql/fourd.c @@ -1,386 +1,487 @@ -#include "fourd.h" - -#include -#include -#include - -#include "fourd.h" -#include "fourd_int.h" - -FOURD* fourd_init() -{ - int iResult=0; - FOURD* cnx=calloc(1,sizeof(FOURD)); - - cnx->socket = INVALID_SOCKET; - cnx->connected=0; - cnx->init=0; - #ifdef WIN32 - // Initialize Winsock - iResult = WSAStartup(MAKEWORD(2,2), &cnx->wsaData); - if (iResult != 0) { - Printf("WSAStartup failed: %d\n", iResult); - return NULL; - } - #endif - cnx->init=1; - return cnx; -} - -int fourd_connect(FOURD *cnx,const char *host,const char *user,const char *password,const char *base,unsigned int port) -{ - if(!cnx->init) - { - //not init - Printferr("Erreur: FOURD object did not initialised\n"); - cnx->error_code=-1; - strncpy_s(cnx->error_string,2048,"FOURD object did not initialised",2048); - return 1; - } - if(cnx->connected) - { - //déjà connecter - Printferr("Erreur: already connected\n"); - cnx->error_code=-1; - strncpy_s(cnx->error_string,2048,"Already connected",2048); - return 1; - } - if(socket_connect_timeout(cnx,host,port,15)) - { - //erreur de connection - Printferr("Erreur in socket_connect\n"); - cnx->connected=0; - //cnx->error_code=-1; - //strncpy_s(cnx->error_string,2048,"Error during connection",2048); - return 1; - } - if(login(cnx,1,user,((password==NULL)?"":password),DEFAULT_IMAGE_TYPE)!=0) - { - //erreur de login - Printferr("Erreur: in login function\n"); - cnx->connected=0; - if(cnx->error_code==0) { - cnx->error_code=-1; - strncpy_s(cnx->error_string,2048,"Error during login",2048); - } - return 1; - } - cnx->connected=1; - //Printferr("Erreur: not erreur\n"); - cnx->error_code=0; - strncpy_s(cnx->error_string,2048,"",2048); - return 0; -} -int fourd_close(FOURD *cnx) -{ - if(logout(cnx,4)!=0) - return 1; - if(quit(cnx,5)!=0) - return 1; - socket_disconnect(cnx); - return 0; -} -void fourd_free(FOURD* cnx) -{ -#ifdef WIN32 - WSACleanup(); -#endif - free(cnx); -} - - -FOURD_LONG8 fourd_affected_rows(FOURD *cnx) -{ - return cnx->updated_row; -} -int fourd_errno(FOURD *cnx) -{ - return (int)cnx->error_code; -} -const char * fourd_error(FOURD *cnx) -{ - return cnx->error_string; -} -int fourd_exec(FOURD *cnx,const char *query) -{ - return _query(cnx,3,query,NULL); -} -FOURD_RESULT* fourd_query(FOURD *cnx,const char *query) -{ - FOURD_RESULT* result; - - result=calloc(1,sizeof(FOURD_RESULT)); - result->cnx=cnx; - if(_query(cnx,3,query,result)==0) - { - result->numRow=-1; - return result; - } - else - { - fourd_free_result(result); - return NULL; - } -} -void fourd_free_result(FOURD_RESULT *res) -{ - if(res!=NULL && res->elmt!=NULL) - _free_data_result(res); - Free(res); -} -int fourd_next_row(FOURD_RESULT *res) -{ - res->numRow++; - if(res->numRow>=res->row_count) - return 0; /*error*/ - if(res->numRow > res->first_row+res->row_count_sent-1) { /*row out of local result_set but in serveur statement */ - if(_fetch_result(res,123)) - return 0; - } - return 1; -} -int fourd_close_statement(FOURD_RESULT *res) -{ - if(close_statement(res,7)!=0) - return 1; - return 0; -} -FOURD_LONG * fourd_field_long(FOURD_RESULT *res,unsigned int numCol) -{ - unsigned int nbCol=res->row_type.nbColumn; - unsigned int nbRow=res->row_count; - FOURD_ELEMENT *elmt; - unsigned int indexElmt=0; /*index of element in table <> numRow*nbCol + numCol */ - //if(res->numRow>=nbRow) //what can is do in this case... - indexElmt=(res->numRow-res->first_row)*nbCol+numCol; - elmt=&(res->elmt[indexElmt]); - if(elmt->null==0) - { - FOURD_LONG x=*((int *)elmt->pValue); - //printf("/////%d//////",x); - return (FOURD_LONG *)elmt->pValue; - } - return 0; -} -FOURD_STRING * fourd_field_string(FOURD_RESULT *res,unsigned int numCol) -{ - int nbCol=res->row_type.nbColumn; - int nbRow=res->row_count; - unsigned int indexElmt=0; /*index of element in table <> numRow*nbCol + numCol */ - FOURD_ELEMENT *elmt=NULL; - //if(res->numRow>=nbRow) //what can is do in this case... - // return NULL; - indexElmt=(res->numRow-res->first_row)*nbCol+numCol; - elmt=&(res->elmt[indexElmt]); - if(elmt->null==0) - { - //FOURD_STRING x=*((int *)elmt->pValue); - //printf("/////%d//////",x); - FOURD_STRING *x=(FOURD_STRING *)elmt->pValue; - return x; - } - return NULL; -} -void * fourd_field(FOURD_RESULT *res,unsigned int numCol) -{ - unsigned int nbCol=res->row_type.nbColumn; - unsigned int nbRow=res->row_count; - unsigned int indexElmt=0; /*index of element in table <> numRow*nbCol + numCol */ - FOURD_ELEMENT *elmt=NULL; - - if(res->numRow>=nbRow){ - res->cnx->error_code=-1; - sprintf_s(res->cnx->error_string,2048,"num Row out of bounds",2048); - return NULL; - } - if(numCol>=nbCol){ - res->cnx->error_code=-1; - sprintf_s(res->cnx->error_string,2048,"num Column out of bounds",2048); - return NULL; - } - indexElmt=(res->numRow-res->first_row)*nbCol+numCol; - - elmt=&(res->elmt[indexElmt]); - if(elmt->null!=0) { /*if elmt is null*/ - return NULL; - } - return elmt->pValue; -} -int fourd_field_to_string(FOURD_RESULT *res,unsigned int numCol,char **value,int *len) -{ - unsigned int nbCol=res->row_type.nbColumn; - unsigned int nbRow=res->row_count; - FOURD_ELEMENT *elmt=NULL; - unsigned int indexElmt=0; /*index of element in table <> numRow*nbCol + numCol */ - if(res->numRow>=nbRow){ - *value=NULL; - *len=0; - res->cnx->error_code=-1; - sprintf_s(res->cnx->error_string,2048,"num Row out of bounds",2048); - return 0; - } - if(numCol>=nbCol){ - *value=NULL; - *len=0; - res->cnx->error_code=-1; - sprintf_s(res->cnx->error_string,2048,"num Column out of bounds",2048); - return 0; - } - indexElmt=(res->numRow-res->first_row)*nbCol+numCol; - elmt=&(res->elmt[indexElmt]); - if(elmt->null!=0) { /*if elmt is null*/ - *value=NULL; - *len=0; - } - else { - switch(elmt->type) { - case VK_BOOLEAN: - { - *value=calloc(2,sizeof(char)); - sprintf_s(*value,2,"%s",(*((FOURD_BOOLEAN *)elmt->pValue)==0?"1":"0")); - *len=strlen(*value); - return 1; - } - case VK_BYTE: - case VK_WORD: - case VK_LONG: - case VK_LONG8: - case VK_DURATION: - { - *value=calloc(22,sizeof(char)); - sprintf_s(*value,22,"%d",*((FOURD_LONG *)elmt->pValue)); - *len=strlen(*value); - return 1; - } - break; - case VK_REAL: - { - *value=calloc(64,sizeof(char)); - sprintf_s(*value,64,"%lf",*((FOURD_REAL *)elmt->pValue)); - *len=strlen(*value); - return 1; - } - break; - case VK_FLOAT: - //Varying length - return 0; - break; - case VK_TIME: - case VK_TIMESTAMP: - { - FOURD_TIMESTAMP *t=elmt->pValue; - unsigned int h,m,s,milli; - milli=t->milli; - h=milli/(60*60*1000); - milli-=h*(60*60*1000); - m=milli/(60*1000); - milli-=m*(60*1000); - s=milli/(1000); - milli-=s*(1000); - - *value=calloc(24,sizeof(char)); - sprintf_s(*value,24,"%0.4d/%0.2d/%0.2d %0.2d:%0.2d:%0.2d.%0.3d",t->year,t->mounth,t->day,h,m,s,milli); - *len=strlen(*value); - return 1; - } - case VK_STRING: - { - FOURD_STRING *str=elmt->pValue; - int size=0; - *value=NULL; - size=str->length; - *value=calloc(size,2); /*2 bytes per char*/ - memcpy(*value,str->data,str->length*2); - *len=str->length*2; - return 1; - } - case VK_BLOB: - case VK_IMAGE: - //Varying length - return 0; - break; - } - return 0; - } - return 0; -} - -const char * fourd_get_column_name(FOURD_RESULT *res,unsigned int numCol) -{ - unsigned int nbCol=res->row_type.nbColumn; - if(numCol>=nbCol || numCol<0) - return ""; - if(res->row_type.Column==NULL) - return ""; - return res->row_type.Column[numCol].sColumnName; -} -FOURD_TYPE fourd_get_column_type(FOURD_RESULT *res,unsigned int numCol) -{ - unsigned int nbCol=res->row_type.nbColumn; - FOURD_TYPE type=VK_UNKNOW; - if(numCol>=nbCol || numCol<0) - return 0; - if(res->row_type.Column==NULL) - return 0; - type=res->row_type.Column[numCol].type; - return type; -} -int fourd_num_columns(FOURD_RESULT *res) -{ - return res->row_type.nbColumn; -} - -FOURD_STATEMENT * fourd_prepare_statement(FOURD *cnx,const char *query) -{ - FOURD_STATEMENT* state=NULL; - if(cnx==NULL || !cnx->connected || query==NULL) - return NULL; - state=calloc(1,sizeof(FOURD_STATEMENT)); - state->cnx=cnx; - - /* allocate arbitrarily five elements in this table */ - state->nbAllocElement=5; - state->elmt=calloc(state->nbAllocElement,sizeof(FOURD_ELEMENT)); - state->nb_element=0; - - /* copy query into statement */ - sprintf_s(state->query,MAX_HEADER_SIZE,"%s",query); - return state; -} -int fourd_bind_param(FOURD_STATEMENT *state,unsigned int numParam,FOURD_TYPE type, void *val) -{ - /* realloc the size of memory if necessary */ - if(numParam>=state->nbAllocElement) { - state->nbAllocElement=numParam+5; - state->elmt=realloc(state->elmt,(sizeof(FOURD_ELEMENT)*state->nbAllocElement)); - } - if(numParam>=state->nb_element) { - state->nb_element=numParam+1; /*zero-based index */ - } - state->elmt[numParam].type=type; - if(val==NULL) { - state->elmt[numParam].null=1; - state->elmt[numParam].pValue=NULL; - } - else { - state->elmt[numParam].null=0; - state->elmt[numParam].pValue=_copy(type,val); - } - return 0; -} -FOURD_RESULT *fourd_exec_statement(FOURD_STATEMENT *state) -{ - FOURD_RESULT *result=NULL; - result=calloc(1,sizeof(FOURD_RESULT)); - result->cnx=state->cnx; - if(_query_param(state->cnx,6,state->query,state->nb_element,state->elmt,result)==0) - { - result->numRow=-1; - return result; - } - else - { - fourd_free_result(result); - return NULL; - } +/* + +----------------------------------------------------------------------+ + | lib4D_SQL | + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | | + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | | + | Its original copy is usable under several licenses and is available | + | through the world-wide-web at the following url: | + | http://freshmeat.net/projects/lib4d_sql | + | | + | Unless required by applicable law or agreed to in writing, software | + | distributed under the License is distributed on an "AS IS" BASIS, | + | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | + | implied. See the License for the specific language governing | + | permissions and limitations under the License. | + +----------------------------------------------------------------------+ + | Contributed by: 4D , http://www.4d.com | + | Alter Way, http://www.alterway.fr | + | Authors: Stephane Planquart | + | Alexandre Morgaut | + +----------------------------------------------------------------------+ +*/ + +#include "fourd.h" + +#include +#include +#include + +#include "fourd.h" +#include "fourd_int.h" + +FOURD* fourd_init() +{ + //int iResult=0; + FOURD* cnx=calloc(1,sizeof(FOURD)); + + cnx->socket = INVALID_SOCKET; + cnx->connected=0; + cnx->init=0; + #ifdef WIN32 + // Initialize Winsock + iResult = WSAStartup(MAKEWORD(2,2), &cnx->wsaData); + if (iResult != 0) { + Printf("WSAStartup failed: %d\n", iResult); + return NULL; + } + #endif + cnx->init=1; + fourd_set_preferred_image_types(cnx,DEFAULT_IMAGE_TYPE); + return cnx; +} + +int fourd_connect(FOURD *cnx,const char *host,const char *user,const char *password,const char *base,unsigned int port) +{ + if(!cnx->init) + { + //not init + Printferr("Erreur: FOURD object did not initialised\n"); + cnx->error_code=-1; + strncpy_s(cnx->error_string,2048,"FOURD object did not initialised",2048); + return 1; + } + if(cnx->connected) + { + //deja connecter + Printferr("Erreur: already connected\n"); + cnx->error_code=-1; + strncpy_s(cnx->error_string,2048,"Already connected",2048); + return 1; + } + if(socket_connect_timeout(cnx,host,port,15)) + { + //erreur de connection + Printferr("Erreur in socket_connect\n"); + cnx->connected=0; + //cnx->error_code=-1; + //strncpy_s(cnx->error_string,2048,"Error during connection",2048); + return 1; + } + if(dblogin(cnx,1,user,((password==NULL)?"":password),cnx->preferred_image_types)!=0) + { + //erreur de login + Printferr("Erreur: in login function\n"); + cnx->connected=0; + if(cnx->error_code==0) { + cnx->error_code=-1; + strncpy_s(cnx->error_string,2048,"Error during login",2048); + } + return 1; + } + cnx->connected=1; + //Printferr("Erreur: not erreur\n"); + cnx->error_code=0; + strncpy_s(cnx->error_string,2048,"",2048); + return 0; +} +int fourd_close(FOURD *cnx) +{ + if(dblogout(cnx,4)!=0) + return 1; + if(quit(cnx,5)!=0) + return 1; + socket_disconnect(cnx); + return 0; +} +void fourd_free(FOURD* cnx) +{ +#ifdef WIN32 + WSACleanup(); +#endif + if (cnx->preferred_image_types!=NULL) + free(cnx->preferred_image_types); + + free(cnx); +} + + +FOURD_LONG8 fourd_affected_rows(FOURD *cnx) +{ + return cnx->updated_row; +} +int fourd_errno(FOURD *cnx) +{ + return (int)cnx->error_code; +} +const char * fourd_error(FOURD *cnx) +{ + return cnx->error_string; +} +int fourd_exec(FOURD *cnx,const char *query) +{ + return _query(cnx,3,query,NULL,cnx->preferred_image_types,100); +} +FOURD_RESULT* fourd_query(FOURD *cnx,const char *query) +{ + FOURD_RESULT* result; + + result=calloc(1,sizeof(FOURD_RESULT)); + result->cnx=cnx; + if(_query(cnx,3,query,result,cnx->preferred_image_types,100)==0) + { + result->numRow=-1; + return result; + } + else + { + fourd_free_result(result); + return NULL; + } +} +void fourd_free_result(FOURD_RESULT *res) +{ + if(res!=NULL && res->elmt!=NULL) + _free_data_result(res); + free(res->row_type.Column); + Free(res); +} +int fourd_next_row(FOURD_RESULT *res) +{ + res->numRow++; + if(res->numRow>=res->row_count) + return 0; /*error*/ + if(res->numRow > res->first_row+res->row_count_sent-1) { /*row out of local result_set but in serveur statement */ + if(_fetch_result(res,123)) + return 0; + } + return 1; +} +int fourd_close_statement(FOURD_RESULT *res) +{ + if(close_statement(res,7)!=0) + return 1; + return 0; +} +FOURD_LONG * fourd_field_long(FOURD_RESULT *res,unsigned int numCol) +{ + unsigned int nbCol=res->row_type.nbColumn; + //unsigned int nbRow=res->row_count; + FOURD_ELEMENT *elmt; + unsigned int indexElmt=0; /*index of element in table <> numRow*nbCol + numCol */ + //if(res->numRow>=nbRow) //what can is do in this case... + indexElmt=(res->numRow-res->first_row)*nbCol+numCol; + elmt=&(res->elmt[indexElmt]); + if(elmt->null==0) + { + //FOURD_LONG x=*((int *)elmt->pValue); + //printf("/////%d//////",x); + return (FOURD_LONG *)elmt->pValue; + } + return 0; +} +FOURD_STRING * fourd_field_string(FOURD_RESULT *res,unsigned int numCol) +{ + int nbCol=res->row_type.nbColumn; + //int nbRow=res->row_count; + unsigned int indexElmt=0; /*index of element in table <> numRow*nbCol + numCol */ + FOURD_ELEMENT *elmt=NULL; + //if(res->numRow>=nbRow) //what can is do in this case... + // return NULL; + indexElmt=(res->numRow-res->first_row)*nbCol+numCol; + elmt=&(res->elmt[indexElmt]); + if(elmt->null==0) + { + //FOURD_STRING x=*((int *)elmt->pValue); + //printf("/////%d//////",x); + FOURD_STRING *x=(FOURD_STRING *)elmt->pValue; + return x; + } + return NULL; +} +void * fourd_field(FOURD_RESULT *res,unsigned int numCol) +{ + unsigned int nbCol=res->row_type.nbColumn; + unsigned int nbRow=res->row_count; + unsigned int indexElmt=0; /*index of element in table <> numRow*nbCol + numCol */ + FOURD_ELEMENT *elmt=NULL; + + if(res->numRow>=nbRow){ + res->cnx->error_code=-1; + sprintf_s(res->cnx->error_string,2048,"num Row out of bounds",2048); + return NULL; + } + if(numCol>=nbCol){ + res->cnx->error_code=-1; + sprintf_s(res->cnx->error_string,2048,"num Column out of bounds",2048); + return NULL; + } + indexElmt=(res->numRow-res->first_row)*nbCol+numCol; + + elmt=&(res->elmt[indexElmt]); + if(elmt->null!=0) { /*if elmt is null*/ + return NULL; + } + return elmt->pValue; +} + +int fourd_field_to_string(FOURD_RESULT *res,unsigned int numCol,char **value,size_t *len) +{ + unsigned int nbCol=res->row_type.nbColumn; + unsigned int nbRow=res->row_count; + FOURD_ELEMENT *elmt=NULL; + unsigned int indexElmt=0; /*index of element in table <> numRow*nbCol + numCol */ + if(res->numRow>=nbRow){ + *value=NULL; + *len=0; + res->cnx->error_code=-1; + sprintf_s(res->cnx->error_string,2048,"num Row out of bounds",2048); + return 0; + } + if(numCol>=nbCol){ + *value=NULL; + *len=0; + res->cnx->error_code=-1; + sprintf_s(res->cnx->error_string,2048,"num Column out of bounds",2048); + return 0; + } + indexElmt=(res->numRow-res->first_row)*nbCol+numCol; + elmt=&(res->elmt[indexElmt]); + if(elmt->null!=0) { /*if elmt is null*/ + *value=NULL; + *len=0; + } + else { + switch(elmt->type) { + case VK_BOOLEAN: + { + *value=calloc(2,sizeof(char)); + sprintf_s(*value,2,"%s",(*((FOURD_BOOLEAN *)elmt->pValue)==0?"1":"0")); + *len=strlen(*value); + return 1; + } + case VK_BYTE: + case VK_WORD: + case VK_LONG: + case VK_LONG8: + case VK_DURATION: + { + *value=calloc(22,sizeof(char)); + sprintf_s(*value,22,"%d",*((FOURD_LONG *)elmt->pValue)); + *len=strlen(*value); + return 1; + } + break; + case VK_REAL: + { + *value=calloc(64,sizeof(char)); + sprintf_s(*value,64,"%lf",*((FOURD_REAL *)elmt->pValue)); + *len=strlen(*value); + return 1; + } + break; + case VK_FLOAT: + //Varying length + return 0; + break; + case VK_TIME: + case VK_TIMESTAMP: + { + FOURD_TIMESTAMP *t=elmt->pValue; + unsigned int h,m,s,milli; + milli=t->milli; + h=milli/(60*60*1000); + milli-=h*(60*60*1000); + m=milli/(60*1000); + milli-=m*(60*1000); + s=milli/(1000); + milli-=s*(1000); + + *value=calloc(24,sizeof(char)); + sprintf_s(*value,24,"%0.4d/%0.2d/%0.2d %0.2d:%0.2d:%0.2d.%0.3d",t->year,t->mounth,t->day,h,m,s,milli); + *len=strlen(*value); + return 1; + } + case VK_STRING: + { + FOURD_STRING *str=elmt->pValue; + int size=0; + *value=NULL; + size=str->length; + *value=calloc(size,2); /*2 bytes per char*/ + memcpy(*value,str->data,str->length*2); + *len=str->length*2; + return 1; + } + case VK_BLOB: + case VK_IMAGE: + //Varying length + return 0; + break; + default: + return 0; //since this is what would happen if it just fell out of the switch statement anyway. + break; + } + return 0; + } + return 0; +} + +const char * fourd_get_column_name(FOURD_RESULT *res,unsigned int numCol) +{ + unsigned int nbCol=res->row_type.nbColumn; + if(numCol>=nbCol) + return ""; + if(res->row_type.Column==NULL) + return ""; + return res->row_type.Column[numCol].sColumnName; +} + +FOURD_TYPE fourd_get_column_type(FOURD_RESULT *res,unsigned int numCol) +{ + unsigned int nbCol=res->row_type.nbColumn; + FOURD_TYPE type=VK_UNKNOW; + if(numCol>=nbCol) + return 0; + if(res->row_type.Column==NULL) + return 0; + type=res->row_type.Column[numCol].type; + return type; +} + +int fourd_num_columns(FOURD_RESULT *res) +{ + return res->row_type.nbColumn; +} + +void fourd_free_statement(FOURD_STATEMENT *state){ + if (state->query!=NULL) + free(state->query); + + if(state->elmt!=NULL) + free(state->elmt); + + if (state->preferred_image_types!=NULL) + free(state->preferred_image_types); + + free(state); +} + +FOURD_STATEMENT * fourd_prepare_statement(FOURD *cnx,const char *query) +{ + FOURD_STATEMENT* state=NULL; + if(cnx==NULL || !cnx->connected || query==NULL) + return NULL; + + if(_prepare_statement(cnx, 3, query)!=0) + return NULL; + + state=calloc(1,sizeof(FOURD_STATEMENT)); + state->cnx=cnx; + state->query=(char *)malloc(strlen(query)+1); + + /* allocate arbitrarily five elements in this table */ + state->nbAllocElement=5; + state->elmt=calloc(state->nbAllocElement,sizeof(FOURD_ELEMENT)); + state->nb_element=0; + + /* copy query into statement */ + sprintf(state->query,"%s",query); + fourd_set_statement_preferred_image_types(state,cnx->preferred_image_types); + + return state; +} + + +int fourd_bind_param(FOURD_STATEMENT *state,unsigned int numParam,FOURD_TYPE type, void *val) +{ + /* realloc the size of memory if necessary */ + if(numParam>=state->nbAllocElement) { + state->nbAllocElement=numParam+5; + state->elmt=realloc(state->elmt,(sizeof(FOURD_ELEMENT)*state->nbAllocElement)); + } + if(numParam>=state->nb_element) { + state->nb_element=numParam+1; /*zero-based index */ + } + state->elmt[numParam].type=type; + if(val==NULL) { + state->elmt[numParam].null=1; + state->elmt[numParam].pValue=NULL; + } + else { + state->elmt[numParam].null=0; + state->elmt[numParam].pValue=_copy(type,val); + } + return 0; +} +FOURD_RESULT *fourd_exec_statement(FOURD_STATEMENT *state, int res_size) +{ + FOURD_RESULT *result=NULL; + result=calloc(1,sizeof(FOURD_RESULT)); + result->cnx=state->cnx; + if(_query_param(state->cnx,6,state->query,state->nb_element,state->elmt,result,state->preferred_image_types,res_size)==0) + { + result->numRow=-1; + return result; + } + else + { + fourd_free_result(result); + return NULL; + } +} +void fourd_set_preferred_image_types(FOURD* cnx,const char *types) +{ + if(cnx->preferred_image_types) { + Free(cnx->preferred_image_types); + } + if(types) { + cnx->preferred_image_types=malloc(strlen(types)+1); + sprintf_s(cnx->preferred_image_types,strlen(types)+1,"%s",types); + } + else { + cnx->preferred_image_types=NULL; + } + +} +void fourd_set_statement_preferred_image_types(FOURD_STATEMENT *state,const char *types) +{ + if(state->preferred_image_types) { + Free(state->preferred_image_types); + } + if(types) { + state->preferred_image_types=malloc(strlen(types)+1); + sprintf_s(state->preferred_image_types,strlen(types)+1,"%s",types); + } + else { + state->preferred_image_types=NULL; + } +} +const char* fourd_get_preferred_image_types(FOURD* cnx) +{ + return cnx->preferred_image_types; +} +const char* fourd_get_statement_preferred_image_types(FOURD_STATEMENT *state) +{ + return state->preferred_image_types; +} +void fourd_timeout(FOURD* cnx,int timeout) +{ + cnx->timeout=timeout; } \ No newline at end of file diff --git a/lib4d_sql/fourd.h b/lib4d_sql/fourd.h old mode 100644 new mode 100755 index 9dac57a..3144bd3 --- a/lib4d_sql/fourd.h +++ b/lib4d_sql/fourd.h @@ -1,252 +1,292 @@ -#ifndef __FOURD__ -#define __FOURD__ 1 - -#ifdef WIN32 -#include -#include -#include -#else - -#include -#include -#include -#include -#include /* close */ -#include -#include /* gethostbyname */ -#define INVALID_SOCKET -1 -#define SOCKET_ERROR -1 -#define closesocket(s) close(s) -typedef int SOCKET; -typedef struct sockaddr_in SOCKADDR_IN; -typedef struct sockaddr SOCKADDR; -typedef struct in_addr IN_ADDR; - -#endif - - -#define VERBOSE 0 - - -//taille maximal de 2K pour les envoi de requête -//#define BUFFER_LENGTH 131072 -//taille maximal de 128K pour les réponse -#define BUFFER_LENGTH 131072 -#define ERROR_STRING_LENGTH 2048 - -#define MAX_HEADER_SIZE 2048 -#define DEFAULT_IMAGE_TYPE "jpg" -#define MAX_LENGTH_COLUMN_NAME 255 - -#define FOURD_OK 0 -#define FOURD_ERROR 1 - - - -typedef enum -{ - VK_UNKNOW=0, - VK_BOOLEAN, - VK_BYTE, - VK_WORD, - VK_LONG, - VK_LONG8, - VK_REAL, - VK_FLOAT, - VK_TIME, - VK_TIMESTAMP, - VK_DURATION, - VK_TEXT, - VK_STRING, - VK_BLOB, - VK_IMAGE -}FOURD_TYPE; -/******************************/ -/* parse and format FOUR_TYPE */ -/******************************/ -FOURD_TYPE typeFromString(const char *type); -const char* stringFromType(FOURD_TYPE type); -/******************************************************************/ -/* vk_sizeof */ -/******************************************************************/ -/* return sizeof type or -1 if varying length or 0 if unknow type */ -/******************************************************************/ -int vk_sizeof(FOURD_TYPE type); - -/***************/ -/* Result-Type */ -/***************/ -typedef enum -{ - UNKNOW=0, - UPDATE_COUNT, - RESULT_SET -}FOURD_RESULT_TYPE; -FOURD_RESULT_TYPE resultTypeFromString(const char *type); -const char* stringFromResultType(FOURD_RESULT_TYPE type); - -/*********************/ -/* Structure of VK_* */ -/*********************/ -#ifdef WIN32 -typedef short FOURD_BOOLEAN; -typedef short FOURD_BYTE; -typedef short FOURD_WORD; -typedef int FOURD_LONG; -typedef __int64 FOURD_LONG8; -typedef double FOURD_REAL; -typedef struct{int exp;char sign;int data_length;void* data;}FOURD_FLOAT; -typedef struct{short year;char mounth;char day;unsigned int milli;}FOURD_TIMESTAMP; -typedef __int64 FOURD_DURATION;//in milliseconds -typedef struct{int length;unsigned char *data;}FOURD_STRING; -typedef struct{int length;void *data;}FOURD_BLOB; -//typedef struct{}FOURD_IMAGE; -#else -typedef short FOURD_BOOLEAN; -typedef short FOURD_BYTE; -typedef short FOURD_WORD; -typedef int FOURD_LONG; -typedef long long FOURD_LONG8; -typedef double FOURD_REAL; -typedef struct{int exp;char sign;int data_length;void* data;}FOURD_FLOAT; -typedef struct{short year;char mounth;char day;unsigned int milli;}FOURD_TIMESTAMP; -typedef long long FOURD_DURATION;//in milliseconds -typedef struct{int length;unsigned char *data;}FOURD_STRING; -typedef struct{int length;void *data;}FOURD_BLOB; -//typedef struct{}FOURD_IMAGE; - -#endif - - -typedef struct{ - //Socket Win32 -#ifdef WIN32 - WSADATA wsaData; - SOCKET socket; -#else - int socket; -#endif - - int init; /*boolean*/ - int connected; /*boolean*/ - - /*deprecated: use FOURD_RESULT*/ - /*char reponse[BUFFER_LENGTH]; - int reponse_len;*/ - - //status - int status;//1 pour OK, 0 pour KO - FOURD_LONG8 error_code; - char error_string[ERROR_STRING_LENGTH]; - - //updated row - FOURD_LONG8 updated_row; - -} FOURD; - -typedef struct{ - FOURD_TYPE type; - char null;//0 not null, 1 null - void *pValue; -}FOURD_ELEMENT; - -typedef struct{ - char sType[255]; - FOURD_TYPE type; - char sColumnName[MAX_LENGTH_COLUMN_NAME]; -}FOURD_COLUMN; - -typedef struct{ - unsigned int nbColumn; - FOURD_COLUMN *Column; -}FOURD_ROW_TYPE; - -typedef struct{ - FOURD *cnx; - char header[MAX_HEADER_SIZE]; - unsigned int header_size; - - /*state of statement (OK or KO)*/ - int status; /*FOURD_OK or FOURD_ERRROR*/ - FOURD_LONG8 error_code; - char error_string[ERROR_STRING_LENGTH]; - - /*result of parse header - RESULT_SET for select - UPDATE_COUNT for insert, update, delete*/ - FOURD_RESULT_TYPE resultType; - - /*Id of statement used with 4D SQL-serveur*/ - int id_statement; - /*Id commande use for request */ - int id_commande; - /*updateability is true or false */ - int updateability; - - /*total of row count */ - unsigned int row_count; - - /*row count in data buffer - for little select, row_count_sent = row_cout - for big select, row_count_sent = 100 for the first result_set - */ - unsigned int row_count_sent; - /*num of the first row - for the first response in big select - with default parametre on serveur : 0 */ - unsigned int first_row; - - /* row_type of this statement - containe column count, column name and column type*/ - FOURD_ROW_TYPE row_type; - - /*data*/ - FOURD_ELEMENT *elmt; - - /*current row index*/ - unsigned int numRow; -}FOURD_RESULT; - -typedef struct { - FOURD *cnx; - char query[MAX_HEADER_SIZE]; /*MAX_HEADER_SIZE is user because the query is insert into header*/ - unsigned int nb_element; - unsigned int nbAllocElement; - FOURD_ELEMENT *elmt; -}FOURD_STATEMENT; - - -FOURD* fourd_init(); -int fourd_connect(FOURD *cnx,const char *host,const char *user,const char *password,const char *base,unsigned int port); -int fourd_close(FOURD *cnx); -int fourd_exec(FOURD *cnx,const char *query); -FOURD_LONG8 fourd_affected_rows(FOURD *cnx); -//gestion des erreurs -int fourd_errno(FOURD *cnx); -const char * fourd_error(FOURD *cnx); -const char * fourd_sqlstate(FOURD *cnx); -void fourd_free(FOURD* cnx); - - -/*function on FOURD_RESULT*/ -FOURD_LONG8 fourd_num_rows(FOURD_RESULT *result); -FOURD_RESULT *fourd_query(FOURD *cnx,const char *query); -int fourd_close_statement(FOURD_RESULT *res); -void fourd_free_result(FOURD_RESULT *res); - -/*function for field*/ -FOURD_LONG * fourd_field_long(FOURD_RESULT *res,unsigned int numCol); -FOURD_STRING * fourd_field_string(FOURD_RESULT *res,unsigned int numCol); -void * fourd_field(FOURD_RESULT *res,unsigned int numCol); -int fourd_next_row(FOURD_RESULT *res); - -const char * fourd_get_column_name(FOURD_RESULT *res,unsigned int numCol); -FOURD_TYPE fourd_get_column_type(FOURD_RESULT *res,unsigned int numCol); -int fourd_num_columns(FOURD_RESULT *res); -int fourd_field_to_string(FOURD_RESULT *res,unsigned int numCol,char **value,int *len); - - -FOURD_STATEMENT * fourd_prepare_statement(FOURD *cnx,const char *query); -int fourd_bind_param(FOURD_STATEMENT *state,unsigned int numParam,FOURD_TYPE type, void *val); -FOURD_RESULT *fourd_exec_statement(FOURD_STATEMENT *state); -#endif +/* + +----------------------------------------------------------------------+ + | lib4D_SQL | + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | | + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | | + | Its original copy is usable under several licenses and is available | + | through the world-wide-web at the following url: | + | http://freshmeat.net/projects/lib4d_sql | + | | + | Unless required by applicable law or agreed to in writing, software | + | distributed under the License is distributed on an "AS IS" BASIS, | + | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | + | implied. See the License for the specific language governing | + | permissions and limitations under the License. | + +----------------------------------------------------------------------+ + | Contributed by: 4D , http://www.4d.com | + | Alter Way, http://www.alterway.fr | + | Authors: Stephane Planquart | + | Alexandre Morgaut | + +----------------------------------------------------------------------+ +*/ +#ifndef __FOURD__ +#define __FOURD__ 1 + +#ifdef WIN32 +#include +#include +#include +#else + +#include +#include +#include +#include +#include +#include /* close */ +#include +#include /* gethostbyname */ +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define closesocket(s) close(s) +typedef int SOCKET; +typedef struct sockaddr_in SOCKADDR_IN; +typedef struct sockaddr SOCKADDR; +typedef struct in_addr IN_ADDR; + +#endif + + +#define VERBOSE 0 + + +/* taille maximal de 2K pour les envoi de requÍte */ +/* #define BUFFER_LENGTH 131072 */ +/* taille maximal de 128K pour les rÈponse */ +#define BUFFER_LENGTH 131072 +#define ERROR_STRING_LENGTH 2048 + +#define MAX_HEADER_SIZE 2048 +#define DEFAULT_IMAGE_TYPE "jpg" +#define MAX_LENGTH_COLUMN_NAME 255 + +#define FOURD_OK 0 +#define FOURD_ERROR 1 + + + +typedef enum +{ + VK_UNKNOW=0, + VK_BOOLEAN, + VK_BYTE, + VK_WORD, + VK_LONG, + VK_LONG8, + VK_REAL, + VK_FLOAT, + VK_TIME, + VK_TIMESTAMP, + VK_DURATION, + VK_TEXT, + VK_STRING, + VK_BLOB, + VK_IMAGE +}FOURD_TYPE; +/******************************/ +/* parse and format FOUR_TYPE */ +/******************************/ +FOURD_TYPE typeFromString(const char *type); +const char* stringFromType(FOURD_TYPE type); +/******************************************************************/ +/* vk_sizeof */ +/******************************************************************/ +/* return sizeof type or -1 if varying length or 0 if unknow type */ +/******************************************************************/ +int vk_sizeof(FOURD_TYPE type); + +/***************/ +/* Result-Type */ +/***************/ +typedef enum +{ + UNKNOW=0, + UPDATE_COUNT, + RESULT_SET +}FOURD_RESULT_TYPE; +FOURD_RESULT_TYPE resultTypeFromString(const char *type); +const char* stringFromResultType(FOURD_RESULT_TYPE type); + +/*********************/ +/* Structure of VK_* */ +/*********************/ +#ifdef WIN32 +typedef short FOURD_BOOLEAN; +typedef short FOURD_BYTE; +typedef short FOURD_WORD; +typedef int FOURD_LONG; +typedef __int64 FOURD_LONG8; +typedef double FOURD_REAL; +typedef struct{int exp;char sign;int data_length;void* data;}FOURD_FLOAT; +typedef struct{short year;char mounth;char day;unsigned int milli;}FOURD_TIMESTAMP; +typedef __int64 FOURD_DURATION;//in milliseconds +typedef struct{int length;unsigned char *data;}FOURD_STRING; +typedef struct{int length;void *data;}FOURD_BLOB; +/* typedef struct{}FOURD_IMAGE; */ +#else +typedef short FOURD_BOOLEAN; +typedef short FOURD_BYTE; +typedef short FOURD_WORD; +typedef int FOURD_LONG; +typedef long long FOURD_LONG8; +typedef double FOURD_REAL; +typedef struct{int exp;unsigned char sign;int data_length;void* data;}FOURD_FLOAT; +typedef struct{short year;unsigned char mounth;unsigned char day;unsigned int milli;}FOURD_TIMESTAMP; +typedef long long FOURD_DURATION;//in milliseconds +typedef struct{int length;unsigned char *data;}FOURD_STRING; +typedef struct{int length;void *data;}FOURD_BLOB; +/* typedef struct{}FOURD_IMAGE; */ + +#endif + + +typedef struct{ + /* Socket Win32 */ +#ifdef WIN32 + WSADATA wsaData; + SOCKET socket; +#else + int socket; +#endif + + int init; /*boolean*/ + int connected; /*boolean*/ + + /*deprecated: use FOURD_RESULT*/ + /*char reponse[BUFFER_LENGTH]; + int reponse_len;*/ + + /* status */ + int status;//1 pour OK, 0 pour KO + FOURD_LONG8 error_code; + char error_string[ERROR_STRING_LENGTH]; + + /* updated row */ + FOURD_LONG8 updated_row; + + /* PREFERRED-IMAGE-TYPES */ + char *preferred_image_types; + int timeout; + +} FOURD; + +typedef struct{ + FOURD_TYPE type; + char null;//0 not null, 1 null + void *pValue; +}FOURD_ELEMENT; + +typedef struct{ + char sType[255]; + FOURD_TYPE type; + char sColumnName[MAX_LENGTH_COLUMN_NAME]; +}FOURD_COLUMN; + +typedef struct{ + unsigned int nbColumn; + FOURD_COLUMN *Column; +}FOURD_ROW_TYPE; + +typedef struct{ + FOURD *cnx; + char header[MAX_HEADER_SIZE]; + unsigned int header_size; + + /*state of statement (OK or KO)*/ + int status; /*FOURD_OK or FOURD_ERRROR*/ + FOURD_LONG8 error_code; + char error_string[ERROR_STRING_LENGTH]; + + /*result of parse header + RESULT_SET for select + UPDATE_COUNT for insert, update, delete*/ + FOURD_RESULT_TYPE resultType; + + /*Id of statement used with 4D SQL-serveur*/ + int id_statement; + /*Id commande use for request */ + int id_commande; + /*updateability is true or false */ + int updateability; + + /*total of row count */ + unsigned int row_count; + + /*row count in data buffer + for little select, row_count_sent = row_cout + for big select, row_count_sent = 100 for the first result_set + */ + unsigned int row_count_sent; + /*num of the first row + for the first response in big select + with default parametre on serveur : 0 */ + unsigned int first_row; + + /* row_type of this statement + containe column count, column name and column type*/ + FOURD_ROW_TYPE row_type; + + /*data*/ + FOURD_ELEMENT *elmt; + + /*current row index*/ + unsigned int numRow; +}FOURD_RESULT; + +typedef struct { + FOURD *cnx; + char *query; /*MAX_HEADER_SIZE is using because the query is insert into header*/ + unsigned int nb_element; + unsigned int nbAllocElement; + FOURD_ELEMENT *elmt; + /* PREFERRED-IMAGE-TYPES */ + char *preferred_image_types; +}FOURD_STATEMENT; + + +FOURD* fourd_init(); +int fourd_connect(FOURD *cnx,const char *host,const char *user,const char *password,const char *base,unsigned int port); +int fourd_close(FOURD *cnx); +int fourd_exec(FOURD *cnx,const char *query); +FOURD_LONG8 fourd_affected_rows(FOURD *cnx); +//gestion des erreurs +int fourd_errno(FOURD *cnx); +const char * fourd_error(FOURD *cnx); +const char * fourd_sqlstate(FOURD *cnx); +void fourd_free(FOURD* cnx); +void fourd_free_statement(FOURD_STATEMENT *state); +void fourd_timeout(FOURD* cnx,int timeout); + +/*function on FOURD_RESULT*/ +FOURD_LONG8 fourd_num_rows(FOURD_RESULT *result); +FOURD_RESULT *fourd_query(FOURD *cnx,const char *query); +int fourd_close_statement(FOURD_RESULT *res); +void fourd_free_result(FOURD_RESULT *res); + +/*function for field*/ +FOURD_LONG * fourd_field_long(FOURD_RESULT *res,unsigned int numCol); +FOURD_STRING * fourd_field_string(FOURD_RESULT *res,unsigned int numCol); +void * fourd_field(FOURD_RESULT *res,unsigned int numCol); +int fourd_next_row(FOURD_RESULT *res); + +const char * fourd_get_column_name(FOURD_RESULT *res,unsigned int numCol); +FOURD_TYPE fourd_get_column_type(FOURD_RESULT *res,unsigned int numCol); +int fourd_num_columns(FOURD_RESULT *res); +int fourd_field_to_string(FOURD_RESULT *res,unsigned int numCol,char **value,size_t *len); + +FOURD_STATEMENT * fourd_prepare_statement(FOURD *cnx,const char *query); +int fourd_bind_param(FOURD_STATEMENT *state,unsigned int numParam,FOURD_TYPE type, void *val); +FOURD_RESULT *fourd_exec_statement(FOURD_STATEMENT *state, int res_size); + +void fourd_set_preferred_image_types(FOURD* cnx,const char *types); +void fourd_set_statement_preferred_image_types(FOURD_STATEMENT *state,const char *types); +const char* fourd_get_preferred_image_types(FOURD* cnx); +const char* fourd_get_statement_preferred_image_types(FOURD_STATEMENT *state); +#endif diff --git a/lib4d_sql/fourd_int.h b/lib4d_sql/fourd_int.h old mode 100644 new mode 100755 index e269613..a6e3236 --- a/lib4d_sql/fourd_int.h +++ b/lib4d_sql/fourd_int.h @@ -1,68 +1,98 @@ -#ifndef __FOURD_INT__ -#define __FOURD_INT__ 1 -#include -#include -#include - -int Printf(const char* format,...); -int Printferr(const char* format,...); - -/*******************/ -/* communication.c */ -/*******************/ -int socket_connect(FOURD *cnx,const char *host,unsigned int port); -void socket_disconnect(FOURD *cnx); -int socket_send(FOURD *cnx,const char*msg); -int socket_send_data(FOURD *cnx,const char*msg,int len); -//int socket_receiv(FOURD *cnx); -int socket_receiv_header(FOURD *cnx,FOURD_RESULT *state); -int socket_receiv_data(FOURD *cnx,FOURD_RESULT *state); +/* + +----------------------------------------------------------------------+ + | lib4D_SQL | + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | | + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | | + | Its original copy is usable under several licenses and is available | + | through the world-wide-web at the following url: | + | http://freshmeat.net/projects/lib4d_sql | + | | + | Unless required by applicable law or agreed to in writing, software | + | distributed under the License is distributed on an "AS IS" BASIS, | + | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | + | implied. See the License for the specific language governing | + | permissions and limitations under the License. | + +----------------------------------------------------------------------+ + | Contributed by: 4D , http://www.4d.com | + | Alter Way, http://www.alterway.fr | + | Authors: Stephane Planquart | + | Alexandre Morgaut | + +----------------------------------------------------------------------+ +*/ +#ifndef __FOURD_INT__ +#define __FOURD_INT__ 1 +#include +#include +#include + +int Printf(const char* format,...); +int Printferr(const char* format,...); + +/*******************/ +/* communication.c */ +/*******************/ +int socket_connect(FOURD *cnx,const char *host,unsigned int port); +void socket_disconnect(FOURD *cnx); +int socket_send(FOURD *cnx,const char*msg); +int socket_send_data(FOURD *cnx,const char*msg,int len); +//int socket_receiv(FOURD *cnx); +int socket_receiv_header(FOURD *cnx,FOURD_RESULT *state); +int socket_receiv_data(FOURD *cnx,FOURD_RESULT *state); int socket_receiv_update_count(FOURD *cnx,FOURD_RESULT *state); int set_sock_blocking(int socketd, int block); -int socket_connect_timeout(FOURD *cnx,const char *host,unsigned int port,unsigned int timeout); -/*******************/ -/* fourd_interne.c */ -/*******************/ -//return 0 for OK et -1 for no readable header and error_code -int login(FOURD *cnx,unsigned short int id_cnx,const char *user,const char*pwd,const char*image_type); -int logout(FOURD *cnx,unsigned short int id_cmd); -int quit(FOURD *cnx,unsigned short int id_cmd); -//return 0 for OK et -1 for no readable header and error_code -int _query(FOURD *cnx,unsigned short int id_cmd,const char *request,FOURD_RESULT *result); -int __fetch_result(FOURD *cnx,unsigned short int id_cmd,int statement_id,int command_index,unsigned int first_row,unsigned int last_row,FOURD_RESULT *result); -int _fetch_result(FOURD_RESULT *res,unsigned short int id_cmd); -int get(const char* msg,const char* section,char *valeur,int max_length); -//FOURD_LONG8 get_status(FOURD* cnx); -//int traite_header_reponse(FOURD* cnx); -int traite_header_response(FOURD_RESULT* cnx); -FOURD_LONG8 _get_status(const char *header,int *status,FOURD_LONG8 *error_code,char *error_string); -int receiv_check(FOURD *cnx,FOURD_RESULT *state); -void _free_data_result(FOURD_RESULT *res); -//clear connection attribut -void _clear_atrr_cnx(FOURD *cnx); -int close_statement(FOURD_RESULT *res,unsigned short int id_cmd); - -int _query_param(FOURD *cnx,unsigned short int id_cmd, const char *request,unsigned int nbParam, const FOURD_ELEMENT *param,FOURD_RESULT *result); - -/*********************/ -/* Memory Allocation */ -/*********************/ -void *_copy(FOURD_TYPE type,void *org); -char *_serialize(char *data,int *size, FOURD_TYPE type, void *pObj); -void Free(void *p); -void FreeFloat(FOURD_FLOAT *p); -void FreeString(FOURD_STRING *p); -void FreeBlob(FOURD_BLOB *p); -void PrintData(const void *data,unsigned int size); -#ifndef WIN32 - void ZeroMemory (void *s, size_t n); -#define WSAGetLastError() errno -#define strtok_s(a,b,c) strtok(a,b) -#define strcpy_s(s,size,cs) strncpy(s,cs,size) -#define strncpy_s(s,ms,cs,size) strncpy(s,cs,size) - int sprintf_s(char *buff,int size,const char* format,...); - int _snprintf_s(char *buff, int size, int count, const char *format,...); -#endif - - -#endif +int socket_connect_timeout(FOURD *cnx,const char *host,unsigned int port,int timeout); +/*******************/ +/* fourd_interne.c */ +/*******************/ +//return 0 for OK et -1 for no readable header and error_code +int dblogin(FOURD *cnx,unsigned short int id_cnx,const char *user,const char*pwd,const char*image_type); +int dblogout(FOURD *cnx,unsigned short int id_cmd); +int quit(FOURD *cnx,unsigned short int id_cmd); +//return 0 for OK et -1 for no readable header and error_code +int _query(FOURD *cnx,unsigned short int id_cmd,const char *request,FOURD_RESULT *result,const char*image_type, int res_size); +int __fetch_result(FOURD *cnx,unsigned short int id_cmd,int statement_id,int command_index,unsigned int first_row,unsigned int last_row,FOURD_RESULT *result); +int _fetch_result(FOURD_RESULT *res,unsigned short int id_cmd); +int get(const char* msg,const char* section,char *valeur,int max_length); +//FOURD_LONG8 get_status(FOURD* cnx); +//int traite_header_reponse(FOURD* cnx); +int traite_header_response(FOURD_RESULT* cnx); +FOURD_LONG8 _get_status(const char *header,int *status,FOURD_LONG8 *error_code,char *error_string); +int receiv_check(FOURD *cnx,FOURD_RESULT *state); +void _free_data_result(FOURD_RESULT *res); +//clear connection attribut +void _clear_atrr_cnx(FOURD *cnx); +int close_statement(FOURD_RESULT *res,unsigned short int id_cmd); + +int _prepare_statement(FOURD *cnx,unsigned short int id_cmd,const char *request); +int _query_param(FOURD *cnx,unsigned short int id_cmd, const char *request,unsigned int nbParam, const FOURD_ELEMENT *param,FOURD_RESULT *result,const char*image_type, int res_size); +int _is_multi_query(const char *request); +int _valid_query(FOURD *cnx,const char *request); +/*********************/ +/* Memory Allocation */ +/*********************/ +void *_copy(FOURD_TYPE type,void *org); +char *_serialize(char *data,unsigned int *size, FOURD_TYPE type, void *pObj); +void Free(void *p); +void FreeFloat(FOURD_FLOAT *p); +void FreeString(FOURD_STRING *p); +void FreeBlob(FOURD_BLOB *p); +void PrintData(const void *data,unsigned int size); +#ifndef WIN32 + void ZeroMemory (void *s, size_t n); +#define WSAGetLastError() errno +#define strtok_s(a,b,c) strtok(a,b) +#define strcpy_s(s,size,cs) strncpy(s,cs,size) +#define strncpy_s(s,ms,cs,size) strncpy(s,cs,size) + int sprintf_s(char *buff,size_t size,const char* format,...); + int _snprintf_s(char *buff, size_t size, size_t count, const char *format,...); +#endif + + +#endif diff --git a/lib4d_sql/fourd_interne.c b/lib4d_sql/fourd_interne.c old mode 100644 new mode 100755 index 09ce6ef..40731a6 --- a/lib4d_sql/fourd_interne.c +++ b/lib4d_sql/fourd_interne.c @@ -1,797 +1,1021 @@ -#include "fourd.h" -#include "fourd_int.h" -#include "base64.h" -#include "utils.h" -#include +/* + +----------------------------------------------------------------------+ + | lib4D_SQL | + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | | + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | | + | Its original copy is usable under several licenses and is available | + | through the world-wide-web at the following url: | + | http://freshmeat.net/projects/lib4d_sql | + | | + | Unless required by applicable law or agreed to in writing, software | + | distributed under the License is distributed on an "AS IS" BASIS, | + | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | + | implied. See the License for the specific language governing | + | permissions and limitations under the License. | + +----------------------------------------------------------------------+ + | Contributed by: 4D , http://www.4d.com | + | Alter Way, http://www.alterway.fr | + | Authors: Stephane Planquart | + | Alexandre Morgaut | + +----------------------------------------------------------------------+ +*/ + +#include "fourd.h" +#include "fourd_int.h" +#include "base64.h" +#include "utils.h" +#include #define __STATEMENT_BASE64__ 1 -#define __LOGIN_BASE64__ 1 -int Printf(const char* format,...) -{ -#if VERBOSE - va_list ap; - va_start(ap,format); - vprintf(format,ap); - - return 0; -#else - return 0; -#endif -} -int Printferr(const char* format,...) -{ -#if VERBOSE - va_list ap; - va_start(ap,format); - vfprintf(stderr,format,ap); - - return 0; -#else - return 0; -#endif -} -#ifndef WIN32 -void ZeroMemory (void *s, size_t n) -{ - bzero(s,n); -} -int sprintf_s(char *buff,int size,const char* format,...) -{ - va_list ap; - va_start(ap,format); - vsnprintf(buff,size,format,ap); -} -int _snprintf_s(char *buff, int size, int count, const char *format,...) -{ - va_list ap; - va_start(ap,format); - vsnprintf(buff,((size>count)?count:size),format,ap); -} -int _snprintf(char *buff, int size, const char *format,...) -{ - va_list ap; - va_start(ap,format); - vsnprintf(buff,size,format,ap); -} -#endif -int login(FOURD *cnx,unsigned short int id_cnx,const char *user,const char*pwd,const char*image_type) -{ - char msg[2048]; +#define __LOGIN_BASE64__ 1 +int Printf(const char* format,...) +{ +#if VERBOSE + va_list ap; + va_start(ap,format); + vprintf(format,ap); + + return 0; +#else + return 0; +#endif +} +int Printferr(const char* format,...) +{ +#if VERBOSE + va_list ap; + va_start(ap,format); + vfprintf(stderr,format,ap); + + return 0; +#else + return 0; +#endif +} +#ifndef WIN32 +void ZeroMemory (void *s, size_t n) +{ + bzero(s,n); +} +int sprintf_s(char *buff,size_t size,const char* format,...) +{ + va_list ap; + va_start(ap,format); + vsnprintf(buff,size,format,ap); + return 0; +} +int _snprintf_s(char *buff, size_t size, size_t count, const char *format,...) +{ + va_list ap; + va_start(ap,format); + vsnprintf(buff,((size>count)?count:size),format,ap); + return 0; +} +int _snprintf(char *buff, int size, const char *format,...) +{ + va_list ap; + va_start(ap,format); + vsnprintf(buff,size,format,ap); + return 0; +} +#endif +int dblogin(FOURD *cnx,unsigned short int id_cnx,const char *user,const char*pwd,const char*image_type) +{ + char msg[2048]; FOURD_RESULT state; - char *user_b64=NULL,*pwd_b64=NULL; - int len; + unsigned char *user_b64=NULL,*pwd_b64=NULL; + int len; _clear_atrr_cnx(cnx); -#if __LOGIN_BASE64__ +#if __LOGIN_BASE64__ user_b64=base64_encode(user,strlen(user),&len); - pwd_b64=base64_encode(pwd,strlen(pwd),&len); + pwd_b64=base64_encode(pwd,strlen(pwd),&len); sprintf_s(msg,2048,"%03d LOGIN \r\nUSER-NAME-BASE64:%s\r\nUSER-PASSWORD-BASE64:%s\r\nPREFERRED-IMAGE-TYPES:%s\r\nREPLY-WITH-BASE64-TEXT:Y\r\nPROTOCOL-VERSION:0.1a\r\n\r\n",id_cnx,user_b64,pwd_b64,image_type); free(user_b64); - free(pwd_b64); + free(pwd_b64); #else sprintf_s(msg,2048,"%03d LOGIN \r\nUSER-NAME:%s\r\nUSER-PASSWORD:%s\r\nPREFERRED-IMAGE-TYPES:%s\r\nREPLY-WITH-BASE64-TEXT:Y\r\nPROTOCOL-VERSION:0.1a\r\n\r\n",id_cnx,user,pwd,image_type); -#endif - socket_send(cnx,msg); - if(receiv_check(cnx,&state)!=0) - return 1; - - return 0; -} -//return 0 if ok 1 if error -int _query(FOURD *cnx,unsigned short int id_cmd,const char *request,FOURD_RESULT *result) -{ - char msg[MAX_HEADER_SIZE]; +#endif + socket_send(cnx,msg); + if(receiv_check(cnx,&state)!=0) + return 1; + + return 0; +} +//return 0 if ok 1 if error +int _query(FOURD *cnx,unsigned short int id_cmd,const char *request,FOURD_RESULT *result,const char*image_type, int res_size) +{ + char *msg; FOURD_RESULT *res; - char *request_b64; + unsigned char *request_b64; int len; - Printf("---Debut de _query\n"); - _clear_atrr_cnx(cnx); - - if(result!=NULL) - res=result; - else + Printf("---Debut de _query\n"); + _clear_atrr_cnx(cnx); + if(!_valid_query(cnx,request)) { + return 1; + } + if(result!=NULL) + res=result; + else res=calloc(1,sizeof(FOURD_RESULT)); #if __STATEMENT_BASE64__ request_b64=base64_encode(request,strlen(request),&len); - sprintf_s(msg,2048,"%03d EXECUTE-STATEMENT\r\nSTATEMENT-BASE64:%s\r\nOutput-Mode:%s\r\n\r\n",id_cmd,request_b64,"release"); - Free(request_b64); -#else - sprintf_s(msg,2048,"%03d EXECUTE-STATEMENT\r\nSTATEMENT:%s\r\nOutput-Mode:%s\r\n\r\n",id_cmd,request,"release"); -#endif + char *format_str="%03d EXECUTE-STATEMENT\r\nSTATEMENT-BASE64:%s\r\nOutput-Mode:%s\r\nFIRST-PAGE-SIZE:%i\r\nPREFERRED-IMAGE-TYPES:%s\r\n\r\n"; + size_t buff_size=strlen(format_str)+strlen((const char *)request_b64)+42; //add some extra for the additional arguments and a bit more for good measure. + msg=(char *)malloc(buff_size); + snprintf(msg,buff_size,format_str,id_cmd,request_b64,"release",res_size,image_type); + free(request_b64); +#else + char *format_str="%03d EXECUTE-STATEMENT\r\nSTATEMENT:%s\r\nOutput-Mode:%s\r\nFIRST-PAGE-SIZE:%i\r\nPREFERRED-IMAGE-TYPES:%s\r\n\r\n"; + size_t buff_size=strlen(format_str)+strlen(request)+42; //add some extra for the additional arguments and a bit more for good measure. + msg=(char *)malloc(buff_size); + snprintf(msg, buff_size,format_str,id_cmd,request,"release",res_size,image_type); +#endif + cnx->updated_row=-1; - socket_send(cnx,msg); - if(receiv_check(cnx,res)!=0) { + socket_send(cnx,msg); + free(msg); + + if(receiv_check(cnx,res)!=0) return 1; - } - switch(res->resultType) { - case UPDATE_COUNT: - //get Update-count: Nb row updated - cnx->updated_row=-1; - socket_receiv_update_count(cnx,res); - _free_data_result(res); - break; - case RESULT_SET: - //get data - socket_receiv_data(cnx,res); - cnx->updated_row=-1; + + switch(res->resultType) { + case UPDATE_COUNT: + //get Update-count: Nb row updated + cnx->updated_row=-1; + socket_receiv_update_count(cnx,res); + _free_data_result(res); + break; + case RESULT_SET: + //get data + socket_receiv_data(cnx,res); + cnx->updated_row=-1; if(result==NULL) { - _free_data_result(res); - } - break; - default: - Printferr("Error: Result-Type not supported in query"); - } - //if(traite_header_reponse(cnx)!=0) - // return 1; + _free_data_result(res); + } + break; + default: + Printferr("Error: Result-Type not supported in query"); + } + //if(traite_header_reponse(cnx)!=0) + // return 1; if(result==NULL) { Free(res); } Printf("---Fin de _query\n"); - return 0; -} -int _query_param(FOURD *cnx,unsigned short int id_cmd, const char *request,unsigned int nbParam, const FOURD_ELEMENT *param,FOURD_RESULT *result) -{ - char msg[MAX_HEADER_SIZE]; + return 0; +} + +int _prepare_statement(FOURD *cnx,unsigned short int id_cmd,const char *request){ + char *msg; + FOURD_RESULT *res=calloc(1,sizeof(FOURD_RESULT)); + int len; + +#if __STATEMENT_BASE64__ + unsigned char *request_b64; + request_b64=base64_encode(request,strlen(request),&len); + char *format_str="%03d PREPARE-STATEMENT\r\nSTATEMENT-BASE64: %s\r\n\r\n"; + unsigned long buff_size=strlen(format_str)+strlen((const char *)request_b64)+2; //add some extra for good measure. + msg=(char *)malloc(buff_size); + snprintf(msg,buff_size,format_str,id_cmd,request_b64); + free(request_b64); +#else + char *format_str="%03d PREPARE-STATEMENT\r\nSTATEMENT: %s\r\n\r\n"; + unsigned long buff_size=strlen(format_str)+strlen(request)+2; //add some extra for good measure. + msg=(char *)malloc(buff_size); + snprintf(msg,buff_size,format_str,id_cmd,request_b64); +#endif + + cnx->updated_row=-1; + socket_send(cnx,msg); + free(msg); + + if(receiv_check(cnx,res)!=0) + return 1; + + switch(res->resultType) { + case UPDATE_COUNT: + //get Update-count: Nb row updated + cnx->updated_row=-1; + //socket_receiv_update_count(cnx,res); + _free_data_result(res); + break; + case RESULT_SET: + //get data + socket_receiv_data(cnx,res); + cnx->updated_row=-1; + break; + default: + Printferr("Error: Result-Type not supported in query"); + } + fourd_free_result(res); + + return 0; +} + +int _query_param(FOURD *cnx,unsigned short int id_cmd, const char *request,unsigned int nbParam, const FOURD_ELEMENT *param,FOURD_RESULT *result,const char*image_type,int res_size) +{ + char *msg=NULL; FOURD_RESULT *res; - char *request_b64; - int len; - char sParam[MAX_HEADER_SIZE]; - unsigned int i=0; - char *data=NULL; - unsigned int data_len=0; + unsigned char *request_b64=NULL; + int len; + char *sParam=NULL; + unsigned int i=0; + char *data=NULL; + unsigned int data_len=0; unsigned int size=0; - Printf("---Debut de _query_param\n"); - if(nbParam<=0) - return _query(cnx,id_cmd,request,result); - _clear_atrr_cnx(cnx); - - if(result!=NULL) - res=result; - else - res=calloc(1,sizeof(FOURD_RESULT)); - - - /* construct param list */ - sprintf_s(sParam,MAX_HEADER_SIZE-1,""); - for(i=0;iresultType) { - case UPDATE_COUNT: - //get Update-count: Nb row updated - socket_receiv_update_count(cnx,res); - _free_data_result(res); - break; - case RESULT_SET: - //get data - socket_receiv_data(cnx,res); - cnx->updated_row=-1; - if(result==NULL) { - _free_data_result(res); - } - break; - default: - Printferr("Error: Result-Type not supported in query"); - } - //if(traite_header_reponse(cnx)!=0) - // return 1; - if(result==NULL) - Free(res); - return 0; -} -/* low level commande - command_index and statement_id is identify by result of execute statement commande */ -int __fetch_result(FOURD *cnx,unsigned short int id_cmd,int statement_id,int command_index,unsigned int first_row,unsigned int last_row,FOURD_RESULT *result) -{ - char msg[2048]; - - - _clear_atrr_cnx(cnx); - - if(result==NULL) { - return 0; - } - sprintf_s(msg,2048,"%03d FETCH-RESULT\r\nSTATEMENT-ID:%d\r\nCOMMAND-INDEX:%03d\r\nFIRST-ROW-INDEX:%d\r\nLAST-ROW-INDEX:%d\r\nOutput-Mode:%s\r\n\r\n",id_cmd,statement_id,command_index,first_row,last_row,"release"); - socket_send(cnx,msg); - if(receiv_check(cnx,result)!=0) - return 1; - socket_receiv_data(cnx,result); - - return 0; -} -/*get next row set in result_set*/ -int _fetch_result(FOURD_RESULT *res,unsigned short int id_cmd) -{ - FOURD *cnx=res->cnx; - FOURD_RESULT *nRes=NULL; - void *last_data=NULL; - int id_statement=res->id_statement; - unsigned int first_row=res->first_row+res->row_count_sent; - unsigned int last_row=res->first_row+res->row_count_sent+99; - if(last_row>=res->row_count) { - last_row=res->row_count-1; - } - - nRes=calloc(1,sizeof(FOURD_RESULT)); - _clear_atrr_cnx(cnx); - /*set paramature unsed in socket_receiv */ - nRes->first_row=first_row; - nRes->row_count_sent=last_row-first_row+1; - nRes->cnx=res->cnx; - nRes->row_type=res->row_type; - /*get new Result set in new FOURD_RESULT*/ - if(__fetch_result(cnx,123,res->id_statement,0,first_row,last_row,nRes)){ - return 1; - } - /*switch data between res and nRes FOURD_RESULT*/ - last_data=res->elmt; - res->elmt=nRes->elmt; - nRes->elmt=last_data; /*important for free memory after */ - res->first_row=first_row; - res->row_count_sent=last_row-first_row+1; - res->error_code=nRes->error_code; - last_data=res->error_string; - sprintf_s(res->error_string,sizeof(res->error_string),"%s",nRes->error_string); - res->status=nRes->status; - - - /*free memory */ - _free_data_result(nRes); - Free(nRes); - - return 0; - -} -int close_statement(FOURD_RESULT *res,unsigned short int id_cmd) -{ - char msg[2048]; - FOURD *cnx=NULL; - FOURD_RESULT state; - - if(res==NULL) - return 0; - cnx=res->cnx; - _clear_atrr_cnx(cnx); - sprintf_s(msg,2048,"%03d CLOSE-STATEMENT\r\nSTATEMENT-ID:%d\r\n\r\n",id_cmd,res->id_statement); - socket_send(cnx,msg); - if(receiv_check(cnx,&state)!=0) { - return 1; - } - return 0; -} -//return 0 if ok 1 if error -int logout(FOURD *cnx,unsigned short int id_cmd) -{ - char msg[2048]; - FOURD_RESULT state; - _clear_atrr_cnx(cnx); - sprintf_s(msg,2048,"%03d LOGOUT\r\n\r\n",id_cmd); - socket_send(cnx,msg); - if(receiv_check(cnx,&state)!=0) { - return 1; - } - return 0; -} -int quit(FOURD *cnx,unsigned short int id_cmd) -{ - char msg[2048]; - FOURD_RESULT state; - _clear_atrr_cnx(cnx); - sprintf_s(msg,2048,"%03d QUIT\r\n\r\n",id_cmd); - socket_send(cnx,msg); - if(receiv_check(cnx,&state)!=0) { - return 1; - } - return 0; -} -int get(const char* msg,const char* section,char *valeur,int max_length) -{ - char *loc=NULL; - char *fin=NULL; - loc=strstr(msg,section); - if(loc==NULL) { - //printf("SECTION NON TROUVEE\n"); - return -1; - } - loc+=strlen(section); - loc=strstr(loc,":"); - if(loc==NULL) { - //printf("PAS DE : APRES LA SECTION\n"); - return -1; - } - loc++; - fin=strstr(loc,"\n"); - if(fin==NULL) { - //printf("PAS DE FIN DE LIGNE\n"); - return -1; - } - if(*(fin-1)=='\r') { - //Printf("IL Y A CRLF\n"); - #ifdef WIN32 - fin--; - #endif - } - - _snprintf_s(valeur,max_length,fin-loc,"%s",loc); - valeur[fin-loc]=0; - //printf("La section %s contient '%s'\n",section,valeur); - if(strstr(section,"-Base64")!=NULL) { - //decode la valeur - char *valeur_decode=NULL; - int len_dec=0; - valeur_decode=base64_decode(valeur,strlen(valeur),&len_dec); - valeur_decode[len_dec]=0; - strncpy_s(valeur,max_length,valeur_decode,(size_t)len_dec); - valeur[len_dec]=0; - free(valeur_decode); - } - return 0; -} -FOURD_LONG8 _get_status(const char *header,int *status, FOURD_LONG8 *error_code,char *error_string) -{ - char *loc=NULL,*fin=NULL,sStatus[50]; - *status=FOURD_ERROR; - loc=strstr(header," "); - if(loc==NULL) { - return -1; - } - loc++; - fin=strstr(loc,"\n"); - if(fin==NULL) { - return -1; - } - if(*(fin-1)=='\r') { - #ifdef WIN32 - fin--; - #endif - } - _snprintf_s(sStatus,50,fin-loc,"%s",loc); - status[fin-loc]=0; - if(strcmp(sStatus,"OK")==0) { - //it's ok - *error_code=0; - error_string[0]=0; - *status=FOURD_OK; - return 0; - } - else { - //there is an error - *status=FOURD_ERROR; - { - char error[50]; - get(header,"Error-Code",error,50); - *error_code=atoi(error); - } - get(header,"Error-Description",error_string,ERROR_STRING_LENGTH); - return *error_code; - } - return -1; -} - - -void _alias_str_replace(char *list_alias) -{ - char *loc=list_alias; - char *locm=NULL; - while((loc=strstr(loc,"] ["))!=NULL) { - if((loc-list_alias)>1) { - locm=loc; - locm--; - if(locm[0]!=']') { - loc[1]='\r'; - } - else { - loc++; - } - } - else { - loc[1]='\r'; - } - } -} -int traite_header_response(FOURD_RESULT* state) -{ - char *header=state->header; - FOURD_LONG8 ret_get_status=0; - //get status in the header - state->elmt=0; - ret_get_status=_get_status(state->header,&(state->status),&(state->error_code),state->error_string); - if(ret_get_status<0) { - //Technical error in parse header status - return 1; - } - else if(ret_get_status>0) { - //The header is error-header - //nothing to do with error-header - return 1; - } - //The header is ok-header - //get Column-Count - { - char column_count[250]; - if(get(header,"Column-Count",column_count,250)==0) { - state->row_type.nbColumn=atoi(column_count); - //memory allocate for column name and column type - state->row_type.Column=calloc(state->row_type.nbColumn,sizeof(FOURD_COLUMN)); - Printf("Column-Count:%d\n",state->row_type.nbColumn); - } - } - //get Column-Types - { - char column_type[2048]; - char *column=NULL; - unsigned int num=0; - char *context=NULL; - if(get(header,"Column-Types",column_type,2048)==0) { - Printf("Column-Types => '%s'\n",column_type); - column = strtok_s(column_type, " ",&context); - if(column!=NULL) - do{ - Printf("Column %d: %s (%s)\n",num+1,column,stringFromType(typeFromString(column))); - if(numrow_type.nbColumn) { - state->row_type.Column[num].type=typeFromString(column); - strncpy_s(state->row_type.Column[num].sType,255,column,strlen(column)+1); - } - else { - Printf("Error: There is more column than Column-Count\n"); - } - num++; - column = strtok_s(NULL, " ",&context); - }while(column!=NULL); - Printf("Fin de la lecture des colonnes\n"); - } - } - //get Column-Aliases-Base64 - { - char column_alias[2048]; - char *alias=NULL; - unsigned int num=0; - char *context=NULL; - if(get(header,"Column-Aliases-Base64",column_alias,2048)==0) { - /* delete the last espace char if exist */ - if(column_alias[strlen(column_alias)-1]==' ') { - column_alias[strlen(column_alias)-1]=0; - } - Printf("Column-Aliases-Base64 => '%s'\n",column_alias); - _alias_str_replace(column_alias); - alias = strtok_s(column_alias, "\r",&context); - if(alias!=NULL) - do{ - Printf("Alias %d: '%s'\n",num+1,alias); - if(numrow_type.nbColumn) { - /* erase [] */ - if(*alias=='[' && alias[strlen(alias)-1]==']') { - strncpy_s(state->row_type.Column[num].sColumnName,255,alias+1,strlen(alias)-2); - } else { - strncpy_s(state->row_type.Column[num].sColumnName,255,alias,strlen(alias)); - } - }else { - Printf("Error: There is more alias than Column-Count\n"); - } - num++; - alias = strtok_s(NULL, "\r",&context); - }while(alias!=NULL); - Printf("Fin de la lecture des alias\n"); - } - } - //get Row-Count - { - char row_count[250]; - if(get(header,"Row-Count",row_count,250)==0) { - state->row_count=atoi(row_count); - Printf("Row-Count:%d\n",state->row_count); - } - } - //get Row-Count-Sent - { - char row_count[250]; - if(get(header,"Row-Count-Sent",row_count,250)==0) { - Printf("Row-Count-Sent:\"%s\" <=lut\n",row_count); - state->row_count_sent=atoi(row_count); - Printf("Row-Count-Sent:%d\n",state->row_count_sent); - } - } - //get Statement-ID - { - char statement_id[250]; - if(get(header,"Statement-ID",statement_id,250)==0) { - state->id_statement=atoi(statement_id); - Printf("Statement-ID:%d\n",state->id_statement); - } - } - //Column-Updateability - { - char updateability[250]; - state->updateability=1; - if(get(header,"Column-Updateability",updateability,250)==0) { - state->updateability=(strstr(updateability,"Y")!=NULL); - Printf("Column-Updateability:%s\n",updateability); - Printf("Column-Updateability:%d\n",state->updateability); - } - } - //get Result-Type - { - char result_type[250]; - if(get(header,"Result-Type",result_type,250)==0) { - strstrip(result_type); - //if Result-Type containt more than 1 Result-type => multirequete => not supproted by this driver - if(strstr(result_type," ")!=NULL) - { - //multiquery not supproted by this driver - Printf("Result-Type:'%s'\n",result_type); - Printf("Position %d\n",strstr(result_type," ")-result_type); - Printferr("Error: Multiquery not supported\n"); - return 1; - } - state->resultType=resultTypeFromString(result_type); - switch(state->resultType) { - case UPDATE_COUNT: - break; - case RESULT_SET: - break; - case UNKNOW: - default: - Printf("Error: %d Result-Type not supported",result_type); - break; - } - } - } - return 0; -} - -int receiv_check(FOURD *cnx,FOURD_RESULT *state) +#else + char *msg_format="%03d EXECUTE-STATEMENT\r\nSTATEMENT:%s\r\nOutput-Mode:%s\r\nFIRST-PAGE-SIZE:%i\r\nPREFERRED-IMAGE-TYPES:%s\r\nPARAMETER-TYPES:%s\r\n\r\n"; + size_t msg_length=strlen(request)+strlen(msg_format)+strlen(image_type)+strlen(sParam)+20; + msg=malloc(msg_length); + snprintf(msg,msg_length,msg_format,id_cmd,request,"release",res_size,image_type,sParam); +#endif + + free(sParam); + + socket_send(cnx,msg); + free(msg); + socket_send_data(cnx,data,data_len); + if(receiv_check(cnx,res)!=0) + return 1; + + switch(res->resultType) { + case UPDATE_COUNT: + //get Update-count: Nb row updated + socket_receiv_update_count(cnx,res); + _free_data_result(res); + break; + case RESULT_SET: + //get data + socket_receiv_data(cnx,res); + cnx->updated_row=-1; + if(result==NULL) { + _free_data_result(res); + } + break; + default: + Printferr("Error: Result-Type not supported in query"); + } + //if(traite_header_reponse(cnx)!=0) + // return 1; + if(result==NULL) + Free(res); + return 0; +} + +/* low level commande + command_index and statement_id is identify by result of execute statement commande */ +int __fetch_result(FOURD *cnx,unsigned short int id_cmd,int statement_id,int command_index,unsigned int first_row,unsigned int last_row,FOURD_RESULT *result) { + char msg[2048]; + + _clear_atrr_cnx(cnx); + + if(result==NULL) { + return 0; + } + sprintf_s(msg,2048,"%03d FETCH-RESULT\r\nSTATEMENT-ID:%d\r\nCOMMAND-INDEX:%03d\r\nFIRST-ROW-INDEX:%d\r\nLAST-ROW-INDEX:%d\r\nOutput-Mode:%s\r\n\r\n",id_cmd,statement_id,command_index,first_row,last_row,"release"); + socket_send(cnx,msg); + if(receiv_check(cnx,result)!=0) + return 1; + socket_receiv_data(cnx,result); + + return 0; +} +/*get next row set in result_set*/ +int _fetch_result(FOURD_RESULT *res,unsigned short int id_cmd) +{ + FOURD *cnx=res->cnx; + FOURD_RESULT *nRes=NULL; + void *last_data=NULL; + //int id_statement=res->id_statement; + unsigned int first_row=res->first_row+res->row_count_sent; + unsigned int last_row=res->first_row+res->row_count_sent+99; + if(last_row>=res->row_count) { + last_row=res->row_count-1; + } + + nRes=calloc(1,sizeof(FOURD_RESULT)); + _clear_atrr_cnx(cnx); + /*set paramature unsed in socket_receiv */ + nRes->first_row=first_row; + nRes->row_count_sent=last_row-first_row+1; + nRes->cnx=res->cnx; + nRes->row_type=res->row_type; + nRes->updateability=res->updateability; + /*get new Result set in new FOURD_RESULT*/ + if(__fetch_result(cnx,123,res->id_statement,0,first_row,last_row,nRes)){ + return 1; + } + /*switch data between res and nRes FOURD_RESULT*/ + last_data=res->elmt; + res->elmt=nRes->elmt; + nRes->elmt=last_data; /*important for free memory after */ + res->first_row=first_row; + res->row_count_sent=last_row-first_row+1; + res->error_code=nRes->error_code; + last_data=res->error_string; + sprintf_s(res->error_string,sizeof(res->error_string),"%s",nRes->error_string); + res->status=nRes->status; + + + /*free memory */ + _free_data_result(nRes); + Free(nRes); + + return 0; + +} +int close_statement(FOURD_RESULT *res,unsigned short int id_cmd) +{ + char msg[2048]; + FOURD *cnx=NULL; + FOURD_RESULT state; + + if(res==NULL) + return 0; + cnx=res->cnx; + _clear_atrr_cnx(cnx); + sprintf_s(msg,2048,"%03d CLOSE-STATEMENT\r\nSTATEMENT-ID:%d\r\n\r\n",id_cmd,res->id_statement); + socket_send(cnx,msg); + if(receiv_check(cnx,&state)!=0) { + return 1; + } + return 0; +} +//return 0 if ok 1 if error +int dblogout(FOURD *cnx,unsigned short int id_cmd) +{ + char msg[2048]; + FOURD_RESULT state; + _clear_atrr_cnx(cnx); + sprintf_s(msg,2048,"%03d LOGOUT\r\n\r\n",id_cmd); + socket_send(cnx,msg); + if(receiv_check(cnx,&state)!=0) { + return 1; + } + return 0; +} +int quit(FOURD *cnx,unsigned short int id_cmd) +{ + char msg[2048]; + FOURD_RESULT state; + _clear_atrr_cnx(cnx); + sprintf_s(msg,2048,"%03d QUIT\r\n\r\n",id_cmd); + socket_send(cnx,msg); + if(receiv_check(cnx,&state)!=0) { + return 1; + } + return 0; +} +int get(const char* msg,const char* section,char *valeur,int max_length) +{ + char *loc=NULL; + char *fin=NULL; + loc=strstr(msg,section); + if(loc==NULL) { + //printf("SECTION NON TROUVEE\n"); + return -1; + } + loc+=strlen(section); + loc=strstr(loc,":"); + if(loc==NULL) { + //printf("PAS DE : APRES LA SECTION\n"); + return -1; + } + loc++; + fin=strstr(loc,"\n"); + if(fin==NULL) { + //printf("PAS DE FIN DE LIGNE\n"); + return -1; + } + if(*(fin-1)=='\r') { + //Printf("IL Y A CRLF\n"); + #ifdef WIN32 + fin--; + #endif + } + + _snprintf_s(valeur,max_length,fin-loc,"%s",loc); + valeur[fin-loc]=0; + //printf("La section %s contient '%s'\n",section,valeur); + if(strstr(section,"-Base64")!=NULL) { + //decode la valeur + unsigned char *valeur_decode=NULL; + int len_dec=0; + valeur_decode=base64_decode(valeur,strlen(valeur),&len_dec); + valeur_decode[len_dec]=0; + strncpy_s(valeur,max_length,(const char*)valeur_decode,(size_t)len_dec); + valeur[len_dec]=0; + free(valeur_decode); + } + return 0; +} +FOURD_LONG8 _get_status(const char *header,int *status, FOURD_LONG8 *error_code,char *error_string) +{ + char *loc=NULL,*fin=NULL,sStatus[50]; + *status=FOURD_ERROR; + loc=strstr(header," "); + if(loc==NULL) { + return -1; + } + loc++; + fin=strstr(loc,"\n"); + if(fin==NULL) { + return -1; + } + if(*(fin-1)=='\r') { + #ifdef WIN32 + fin--; + #endif + } + _snprintf_s(sStatus,50,fin-loc,"%s",loc); + status[fin-loc]=0; + if(strcmp(sStatus,"OK")==0) { + //it's ok + *error_code=0; + error_string[0]=0; + *status=FOURD_OK; + return 0; + } + else { + //there is an error + *status=FOURD_ERROR; + { + char error[50]; + get(header,"Error-Code",error,50); + *error_code=atoi(error); + } + get(header,"Error-Description",error_string,ERROR_STRING_LENGTH); + return *error_code; + } + return -1; +} + + +void _alias_str_replace(char *list_alias) +{ + char *loc=list_alias; + char *locm=NULL; + while((loc=strstr(loc,"] ["))!=NULL) { + if((loc-list_alias)>1) { + locm=loc; + locm--; + if(locm[0]!=']') { + loc[1]='\r'; + } + else { + loc++; + } + } + else { + loc[1]='\r'; + } + } +} +int traite_header_response(FOURD_RESULT* state) +{ + char *header=state->header; + FOURD_LONG8 ret_get_status=0; + //get status in the header + state->elmt=0; + ret_get_status=_get_status(state->header,&(state->status),&(state->error_code),state->error_string); + if(ret_get_status<0) { + //Technical error in parse header status + return 1; + } + else if(ret_get_status>0) { + //The header is error-header + //nothing to do with error-header + return 1; + } + //The header is ok-header + //get Column-Count + { + char column_count[250]; + if(get(header,"Column-Count",column_count,250)==0) { + state->row_type.nbColumn=atoi(column_count); + //memory allocate for column name and column type + state->row_type.Column=calloc(state->row_type.nbColumn,sizeof(FOURD_COLUMN)); + Printf("Column-Count:%d\n",state->row_type.nbColumn); + } + } + //get Column-Types + { + char column_type[2048]; + char *column=NULL; + unsigned int num=0; + //char *context=NULL; + if(get(header,"Column-Types",column_type,2048)==0) { + Printf("Column-Types => '%s'\n",column_type); + column = strtok_s(column_type, " ",&context); + if(column!=NULL) + do{ + Printf("Column %d: %s (%s)\n",num+1,column,stringFromType(typeFromString(column))); + if(numrow_type.nbColumn) { + state->row_type.Column[num].type=typeFromString(column); + strncpy_s(state->row_type.Column[num].sType,255,column,strlen(column)+1); + } + else { + Printf("Error: There is more column than Column-Count\n"); + } + num++; + column = strtok_s(NULL, " ",&context); + }while(column!=NULL); + Printf("Fin de la lecture des colonnes\n"); + } + } + //get Column-Aliases-Base64 + { + char column_alias[2048]; + char *alias=NULL; + unsigned int num=0; + //char *context=NULL; + if(get(header,"Column-Aliases-Base64",column_alias,2048)==0) { + /* delete the last espace char if exist */ + if(column_alias[strlen(column_alias)-1]==' ') { + column_alias[strlen(column_alias)-1]=0; + } + Printf("Column-Aliases-Base64 => '%s'\n",column_alias); + _alias_str_replace(column_alias); + alias = strtok_s(column_alias, "\r",&context); + if(alias!=NULL) + do{ + Printf("Alias %d: '%s'\n",num+1,alias); + if(numrow_type.nbColumn) { + /* erase [] */ + if(*alias=='[' && alias[strlen(alias)-1]==']') { + strncpy_s(state->row_type.Column[num].sColumnName,255,alias+1,strlen(alias)-2); + } else { + strncpy_s(state->row_type.Column[num].sColumnName,255,alias,strlen(alias)); + } + }else { + Printf("Error: There is more alias than Column-Count\n"); + } + num++; + alias = strtok_s(NULL, "\r",&context); + }while(alias!=NULL); + Printf("Fin de la lecture des alias\n"); + } + } + //get Row-Count + { + char row_count[250]; + if(get(header,"Row-Count",row_count,250)==0) { + state->row_count=atoi(row_count); + Printf("Row-Count:%d\n",state->row_count); + } + } + //get Row-Count-Sent + { + char row_count[250]; + if(get(header,"Row-Count-Sent",row_count,250)==0) { + Printf("Row-Count-Sent:\"%s\" <=lut\n",row_count); + state->row_count_sent=atoi(row_count); + Printf("Row-Count-Sent:%d\n",state->row_count_sent); + } + } + //get Statement-ID + { + char statement_id[250]; + if(get(header,"Statement-ID",statement_id,250)==0) { + state->id_statement=atoi(statement_id); + Printf("Statement-ID:%d\n",state->id_statement); + } + } + //Column-Updateability + { + char updateability[250]; + //state->updateability=1; + if(get(header,"Column-Updateability",updateability,250)==0) { + state->updateability=(strstr(updateability,"Y")!=NULL); + Printf("Column-Updateability:%s\n",updateability); + Printf("Column-Updateability:%d\n",state->updateability); + } + } + //get Result-Type + { + char result_type[250]; + if(get(header,"Result-Type",result_type,250)==0) { + strstrip(result_type); + //if Result-Type containt more than 1 Result-type => multirequete => not supproted by this driver + if(strstr(result_type," ")!=NULL) + { + //multiquery not supproted by this driver + Printf("Result-Type:'%s'\n",result_type); + Printf("Position %d\n",strstr(result_type," ")-result_type); + Printferr("Error: Multiquery not supported\n"); + return 1; + } + state->resultType=resultTypeFromString(result_type); + switch(state->resultType) { + case UPDATE_COUNT: + break; + case RESULT_SET: + break; + case UNKNOW: + default: + Printf("Error: %d Result-Type not supported",result_type); + break; + } + } + } + return 0; +} + +int receiv_check(FOURD *cnx,FOURD_RESULT *state) +{ socket_receiv_header(cnx,state); if(traite_header_response(state)!=0) { - Printferr("Error in traite_header_response\n"); - cnx->status=state->status; - cnx->error_code=state->error_code; - //_snprintf_s(cnx->error_string,ERROR_STRING_LENGTH,strlen(state->error_string),"%s",state->error_string); - _snprintf(cnx->error_string,ERROR_STRING_LENGTH,"%s",state->error_string); - //strncpy_s(cnx->error_string,ERROR_STRING_LENGTH,state->error_string,strlen(state->error_string)); - //printf("traite_header_response return 1=> une erreur\n"); - return 1; - } - cnx->status=state->status; - cnx->error_code=state->error_code; - strncpy_s(cnx->error_string,ERROR_STRING_LENGTH,state->error_string,ERROR_STRING_LENGTH); - return 0; -} -void _clear_atrr_cnx(FOURD *cnx) -{ - cnx->error_code=0L; - strcpy_s(cnx->error_string,ERROR_STRING_LENGTH,""); - cnx->updated_row=0L; -} -void _free_data_result(FOURD_RESULT *res) -{ - //res->elmt - unsigned int nbCol=res->row_type.nbColumn; - unsigned int nbRow=res->row_count_sent; - unsigned int nbElmt=nbCol*nbRow; - unsigned int i=0; - FOURD_ELEMENT *pElmt=res->elmt; - if(pElmt==NULL) { - return; - } - for(i=0;itype) { - case VK_BOOLEAN: - case VK_BYTE: - case VK_WORD: - case VK_LONG: - case VK_LONG8: - case VK_REAL: - case VK_DURATION: - case VK_TIMESTAMP: - case VK_FLOAT: - Free(pElmt->pValue); - break; - case VK_STRING: - FreeString((FOURD_STRING *)pElmt->pValue); - break; - case VK_BLOB: - FreeBlob((FOURD_BLOB *)pElmt->pValue); - break; - case VK_IMAGE: - Printferr("Image-Type not supported\n"); - break; - } - } -} -void *_copy(FOURD_TYPE type,void *org) -{ - void *buff=NULL; - int size=0; - if(org!=NULL) - { - switch(type) { - case VK_BOOLEAN: - case VK_BYTE: - case VK_WORD: - case VK_LONG: - Printf("*******Bind %d ********\n",*(FOURD_LONG*)org); - case VK_LONG8: - case VK_REAL: - case VK_DURATION: - case VK_TIMESTAMP: - buff=calloc(1,vk_sizeof(type)); - memcpy(buff,org,vk_sizeof(type)); - break; - case VK_FLOAT: - { - FOURD_FLOAT *f=org; - FOURD_FLOAT *cp=NULL; - cp=calloc(1,sizeof(FOURD_FLOAT)); - cp->data=calloc(1,f->data_length); - cp->exp=f->exp; - cp->sign=f->sign; - cp->data_length=f->data_length; - memcpy(cp->data,f->data,f->data_length); - buff=cp; - } - break; - case VK_STRING: - { - FOURD_STRING *src=org; - FOURD_STRING *cp=NULL; - cp=calloc(1,sizeof(FOURD_STRING)); - cp->data=calloc(src->length,2); /* 2 bytes per char */ - cp->length=src->length; - memcpy(cp->data,src->data,src->length*2); /* 2 bytes per char */ - buff=cp; - } - break; - case VK_BLOB: - { - FOURD_BLOB *src=org; - FOURD_BLOB *cp=NULL; - cp=calloc(1,sizeof(FOURD_BLOB)); - cp->data=calloc(src->length,1); - cp->length=src->length; - memcpy(cp->data,src->data,src->length); - buff=cp; - } - break; - case VK_IMAGE: - Printferr("Image-Type not supported\n"); - break; - } - } - return buff; -} -char *_serialize(char *data,int *size, FOURD_TYPE type, void *pObj) -{ - int lSize=0; - if(pObj!=NULL) { - switch(type) { - case VK_BOOLEAN: - case VK_BYTE: - case VK_WORD: - case VK_LONG: - Printf("*******Serialize %d ********\n",*(FOURD_LONG*)pObj); - case VK_LONG8: - case VK_REAL: - case VK_DURATION: - lSize=vk_sizeof(type); - data=realloc(data,(*size)+lSize); - memcpy(data+*size,pObj,lSize); - *size+=lSize; - break; - case VK_TIMESTAMP:/* Use other procedure for serialize this one because structure can align */ - { - FOURD_TIMESTAMP *o=pObj; - lSize=sizeof(o->year)+sizeof(o->mounth)+sizeof(o->day)+sizeof(o->milli); - data=realloc(data,(*size)+lSize); - memcpy(data+*size,&(o->year),2); - memcpy(data+*size+2,&(o->year),1); - memcpy(data+*size+3,&(o->year),1); - memcpy(data+*size+4,&(o->year),4); - *size+=lSize; - } - break; - case VK_FLOAT: - { - FOURD_FLOAT *o=pObj; - lSize=sizeof(o->exp)+sizeof(o->sign)+sizeof(o->data_length)+o->data_length; - data=realloc(data,(*size)+lSize); - memcpy(data+*size,&(o->exp),4); - memcpy(data+*size+4,&(o->sign),1); - memcpy(data+*size+5,&(o->data_length),4); - memcpy(data+*size+9,o->data,o->data_length); - *size+=lSize; - } - break; - case VK_STRING: - { - FOURD_STRING *o=pObj; - int len=o->length; - len=-len; - lSize=sizeof(o->length)+o->length*2; - data=realloc(data,(*size)+lSize); - memcpy(data+*size,&len,4); - memcpy(data+*size+4,o->data,o->length*2); - *size+=lSize; - } - break; - case VK_BLOB: - { - FOURD_BLOB *o=pObj; - lSize=sizeof(o->length)+o->length*2; - data=realloc(data,(*size)+lSize); - memcpy(data+*size,&(o->length),4); - memcpy(data+*size+4,o->data,o->length*2); - *size+=lSize; - } - break; - case VK_IMAGE: - Printferr("Image-Type not supported\n"); - break; - } - } - return data; -}void Free(void *p) -{ - if(p) { - free(p); - p=NULL; - } -} -void FreeFloat(FOURD_FLOAT *p) -{ - if(p) { - Free(p->data); - Free(p); - } -} -void FreeString(FOURD_STRING *p) -{ - if(p) { - Free(p->data); - Free(p); - } -} -void FreeBlob(FOURD_BLOB *p) -{ - if(p) { - Free(p->data); - Free(p); - } -} -void PrintData(const void *data,unsigned int size) -{ - const char *d=data; - unsigned int i=0; - if(size>=1) - Printf("0x%X",*(char *)(d+i)); - for(i=1;istatus=state->status; + cnx->error_code=state->error_code; + //_snprintf_s(cnx->error_string,ERROR_STRING_LENGTH,strlen(state->error_string),"%s",state->error_string); + _snprintf(cnx->error_string,ERROR_STRING_LENGTH,"%s",state->error_string); + //strncpy_s(cnx->error_string,ERROR_STRING_LENGTH,state->error_string,strlen(state->error_string)); + //printf("traite_header_response return 1=> une erreur\n"); + return 1; + } + cnx->status=state->status; + cnx->error_code=state->error_code; + strncpy_s(cnx->error_string,ERROR_STRING_LENGTH,state->error_string,ERROR_STRING_LENGTH); + return 0; +} +void _clear_atrr_cnx(FOURD *cnx) +{ + cnx->error_code=0L; + strcpy_s(cnx->error_string,ERROR_STRING_LENGTH,""); + cnx->updated_row=0L; +} +void _free_data_result(FOURD_RESULT *res) +{ + //res->elmt + unsigned int nbCol=res->row_type.nbColumn; + unsigned int nbRow=res->row_count_sent; + unsigned int nbElmt=nbCol*nbRow; + unsigned int i=0; + FOURD_ELEMENT *pElmt=res->elmt; + if(pElmt==NULL) { + return; + } + for(i=0;itype) { + case VK_BOOLEAN: + case VK_BYTE: + case VK_WORD: + case VK_LONG: + case VK_LONG8: + case VK_REAL: + case VK_DURATION: + case VK_TIMESTAMP: + case VK_FLOAT: + Free(pElmt->pValue); + break; + case VK_STRING: + FreeString((FOURD_STRING *)pElmt->pValue); + break; + case VK_BLOB: + FreeBlob((FOURD_BLOB *)pElmt->pValue); + break; + case VK_IMAGE: + Printferr("Image-Type not supported\n"); + break; + default: + break; + } + } + + free(res->elmt); +} + +void *_copy(FOURD_TYPE type,void *org) +{ + void *buff=NULL; + //int size=0; + if(org!=NULL) + { + switch(type) { + case VK_BOOLEAN: + case VK_BYTE: + case VK_WORD: + case VK_LONG: + Printf("*******Bind %d ********\n",*(FOURD_LONG*)org); + case VK_LONG8: + case VK_REAL: + case VK_DURATION: + case VK_TIMESTAMP: + buff=calloc(1,vk_sizeof(type)); + memcpy(buff,org,vk_sizeof(type)); + break; + case VK_FLOAT: + { + FOURD_FLOAT *f=org; + FOURD_FLOAT *cp=NULL; + cp=calloc(1,sizeof(FOURD_FLOAT)); + cp->data=calloc(1,f->data_length); + cp->exp=f->exp; + cp->sign=f->sign; + cp->data_length=f->data_length; + memcpy(cp->data,f->data,f->data_length); + buff=cp; + } + break; + case VK_STRING: + { + FOURD_STRING *src=org; + FOURD_STRING *cp=NULL; + cp=calloc(1,sizeof(FOURD_STRING)); + cp->data=calloc(src->length,2); /* 2 bytes per char */ + cp->length=src->length; + memcpy(cp->data,src->data,src->length*2); /* 2 bytes per char */ + buff=cp; + } + break; + case VK_BLOB: + { + FOURD_BLOB *src=org; + FOURD_BLOB *cp=NULL; + cp=calloc(1,sizeof(FOURD_BLOB)); + cp->data=calloc(src->length,1); + cp->length=src->length; + memcpy(cp->data,src->data,src->length); + buff=cp; + } + break; + case VK_IMAGE: + Printferr("Image-Type not supported\n"); + break; + default: + break; + } + } + return buff; +} +char *_serialize(char *data,unsigned int *size, FOURD_TYPE type, void *pObj) +{ + int lSize=0; + if(pObj!=NULL) { + switch(type) { + case VK_BOOLEAN: + case VK_BYTE: + case VK_WORD: + case VK_LONG: + Printf("*******Serialize %d ********\n",*(FOURD_LONG*)pObj); + case VK_LONG8: + case VK_REAL: + case VK_DURATION: + lSize=vk_sizeof(type); + data=realloc(data,(*size)+lSize); + memcpy(data+*size,pObj,lSize); + *size+=lSize; + break; + case VK_TIMESTAMP:/* Use other procedure for serialize this one because structure can align */ + { + FOURD_TIMESTAMP *o=pObj; + lSize=sizeof(o->year)+sizeof(o->mounth)+sizeof(o->day)+sizeof(o->milli); + data=realloc(data,(*size)+lSize); + memcpy(data+*size,&(o->year),2); + memcpy(data+*size+2,&(o->year),1); + memcpy(data+*size+3,&(o->year),1); + memcpy(data+*size+4,&(o->year),4); + *size+=lSize; + } + break; + case VK_FLOAT: + { + FOURD_FLOAT *o=pObj; + lSize=sizeof(o->exp)+sizeof(o->sign)+sizeof(o->data_length)+o->data_length; + data=realloc(data,(*size)+lSize); + memcpy(data+*size,&(o->exp),4); + memcpy(data+*size+4,&(o->sign),1); + memcpy(data+*size+5,&(o->data_length),4); + memcpy(data+*size+9,o->data,o->data_length); + *size+=lSize; + } + break; + case VK_STRING: + { + FOURD_STRING *o=pObj; + int len=o->length; + len=-len; + lSize=sizeof(o->length)+o->length*2; + data=realloc(data,(*size)+lSize); + memcpy(data+*size,&len,4); + memcpy(data+*size+4,o->data,o->length*2); + *size+=lSize; + } + break; + case VK_BLOB: + { + FOURD_BLOB *o=pObj; + lSize=sizeof(o->length)+o->length*2; + data=realloc(data,(*size)+lSize); + memcpy(data+*size,&(o->length),4); + memcpy(data+*size+4,o->data,o->length*2); + *size+=lSize; + } + break; + case VK_IMAGE: + Printferr("Image-Type not supported\n"); + break; + default: + break; + } + } + return data; +}void Free(void *p) +{ + if(p) { + free(p); + p=NULL; + } +} +void FreeFloat(FOURD_FLOAT *p) +{ + if(p) { + Free(p->data); + Free(p); + } +} +void FreeString(FOURD_STRING *p) +{ + if(p) { + Free(p->data); + Free(p); + } +} +void FreeBlob(FOURD_BLOB *p) +{ + if(p) { + Free(p->data); + Free(p); + } +} +void PrintData(const void *data,unsigned int size) +{ + const char *d=data; + unsigned int i=0; + if(size>=1) + Printf("0x%X",*(char *)(d+i)); + for(i=1;i1){ /* check the previous charactere */ + if(request[i-1]==']'){ + /* not end of colomn name */ + inCol=1; + /* printf("-"); */ + }else { + inCol=0; + /* printf("]"); */ + } + }else { + /* printf("_");*/ + } + } + + break; + case '\'': + if(!inCol){ + /* printf("'");*/ + if(inStr==0){ + inStr=1; + }else{ + inStr=0; + } + }else{ + /* printf("c"); */ + } + break; + case ';': + /* end of query */ + if(!inCol && !inStr){ + finFirst=1; + /* printf(";");*/ + }else { + /*printf("_");*/ + } + break; + default: + if(inCol){ + /* printf("C"); */ + } + else if(inStr){ + /* printf("S"); */ + } + else if(car==' '){ + /*printf(" ");*/ + }else{ + if(finFirst){ + /* printf("X"); */ + return 1; + }else { + /* printf("*"); */ + } + } + break; + } + + } + return 0; +} +int _valid_query(FOURD *cnx,const char *request) +{ + if(_is_multi_query(request)){ + cnx->error_code=-5001; + sprintf_s(cnx->error_string,2048,"MultiQuery not supported",2048); + return 0; + } + return 1; +} diff --git a/lib4d_sql/fourd_result.c b/lib4d_sql/fourd_result.c old mode 100644 new mode 100755 index 4648553..2c72a77 --- a/lib4d_sql/fourd_result.c +++ b/lib4d_sql/fourd_result.c @@ -1,6 +1,35 @@ -#include "fourd.h" -#include "fourd_int.h" -FOURD_LONG8 fourd_num_rows(FOURD_RESULT *result) -{ - return result->row_count; +/* + +----------------------------------------------------------------------+ + | lib4D_SQL | + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | | + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | | + | Its original copy is usable under several licenses and is available | + | through the world-wide-web at the following url: | + | http://freshmeat.net/projects/lib4d_sql | + | | + | Unless required by applicable law or agreed to in writing, software | + | distributed under the License is distributed on an "AS IS" BASIS, | + | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | + | implied. See the License for the specific language governing | + | permissions and limitations under the License. | + +----------------------------------------------------------------------+ + | Contributed by: 4D , http://www.4d.com | + | Alter Way, http://www.alterway.fr | + | Authors: Stephane Planquart | + | Alexandre Morgaut | + +----------------------------------------------------------------------+ +*/ + +#include "fourd.h" +#include "fourd_int.h" +FOURD_LONG8 fourd_num_rows(FOURD_RESULT *result) +{ + return result->row_count; } \ No newline at end of file diff --git a/lib4d_sql/fourd_type.c b/lib4d_sql/fourd_type.c old mode 100644 new mode 100755 index d1a9eda..e62b0c7 --- a/lib4d_sql/fourd_type.c +++ b/lib4d_sql/fourd_type.c @@ -1,137 +1,173 @@ -#include -#include - -extern int Printf(const char* format,...); -extern int Printferr(const char* format,...); -#include "fourd.h" -FOURD_TYPE typeFromString(const char *type) -{ - if(strcmp(type,"VK_BOOLEAN")==0) - return VK_BOOLEAN; - if(strcmp(type,"VK_BYTE")==0) - return VK_BYTE; - if(strcmp(type,"VK_WORD")==0) - return VK_WORD; - if(strcmp(type,"VK_LONG")==0) - return VK_LONG; - if(strcmp(type,"VK_LONG8")==0) - return VK_LONG8; - if(strcmp(type,"VK_REAL")==0) - return VK_REAL; - if(strcmp(type,"VK_FLOAT")==0) - return VK_FLOAT; - if(strcmp(type,"VK_TIMESTAMP")==0) - return VK_TIMESTAMP; - if(strcmp(type,"VK_TIME")==0) - return VK_TIMESTAMP; - if(strcmp(type,"VK_DURATION")==0) - return VK_DURATION; - if(strcmp(type,"VK_TEXT")==0) - return VK_STRING; - if(strcmp(type,"VK_STRING")==0) - return VK_STRING; - if(strcmp(type,"VK_BLOB")==0) - return VK_BLOB; - if(strcmp(type,"VK_IMAGE")==0) - return VK_IMAGE; - return VK_UNKNOW; -} -const char* stringFromType(FOURD_TYPE type) -{ - switch(type) - { - case VK_BOOLEAN: - return "VK_BOOLEAN"; - case VK_BYTE: - return "VK_BYTE"; - case VK_WORD: - return "VK_WORD"; - case VK_LONG: - return "VK_LONG"; - case VK_LONG8: - return "VK_LONG8"; - case VK_REAL: - return "VK_REAL"; - case VK_FLOAT: - return "VK_FLOAT"; - case VK_TIMESTAMP: - return "VK_TIMESTAMP"; - case VK_TIME: - return "VK_TIME"; - case VK_DURATION: - return "VK_DURATION"; - case VK_STRING: - return "VK_STRING"; - case VK_BLOB: - return "VK_BLOB"; - case VK_IMAGE: - return "VK_IMAGE"; - default: - return "VK_UNKNOW"; - break; - } -} -/******************************************************************/ -/* vk_sizeof */ -/******************************************************************/ -/* return sizeof type or -1 if varying length or 0 if unknow type */ -/******************************************************************/ -int vk_sizeof(FOURD_TYPE type) -{ - switch(type) - { - case VK_BOOLEAN: - case VK_BYTE: - case VK_WORD: - return 2; - break; - case VK_LONG: - return 4; - break; - case VK_LONG8: - case VK_REAL: - case VK_DURATION: - return 8; - break; - case VK_FLOAT: - //Varying length - return -1; - break; - case VK_TIME: - case VK_TIMESTAMP: - return 8; - break; - case VK_TEXT: - case VK_STRING: - case VK_BLOB: - case VK_IMAGE: - //Varying length - return -1; - break; - } - //error type not found - Printf("Error: Unknow type in vk_sizeof function\n"); - return 0; -} - -FOURD_RESULT_TYPE resultTypeFromString(const char *type) -{ - if(strcmp(type,"Update-Count")==0) - return UPDATE_COUNT; - if(strcmp(type,"Result-Set")==0) - return RESULT_SET; - return UNKNOW; -} -const char* stringFromResultType(FOURD_RESULT_TYPE type) -{ - switch(type) - { - case UPDATE_COUNT: - return "Update-Count"; - break; - case RESULT_SET: - return "Result-Set"; - break; - } - return "Unknow"; +/* + +----------------------------------------------------------------------+ + | lib4D_SQL | + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | | + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | | + | Its original copy is usable under several licenses and is available | + | through the world-wide-web at the following url: | + | http://freshmeat.net/projects/lib4d_sql | + | | + | Unless required by applicable law or agreed to in writing, software | + | distributed under the License is distributed on an "AS IS" BASIS, | + | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | + | implied. See the License for the specific language governing | + | permissions and limitations under the License. | + +----------------------------------------------------------------------+ + | Contributed by: 4D , http://www.4d.com | + | Alter Way, http://www.alterway.fr | + | Authors: Stephane Planquart | + | Alexandre Morgaut | + +----------------------------------------------------------------------+ +*/ + +#include +#include + +extern int Printf(const char* format,...); +extern int Printferr(const char* format,...); +#include "fourd.h" +FOURD_TYPE typeFromString(const char *type) +{ + if(strcmp(type,"VK_BOOLEAN")==0) + return VK_BOOLEAN; + if(strcmp(type,"VK_BYTE")==0) + return VK_BYTE; + if(strcmp(type,"VK_WORD")==0) + return VK_WORD; + if(strcmp(type,"VK_LONG")==0) + return VK_LONG; + if(strcmp(type,"VK_LONG8")==0) + return VK_LONG8; + if(strcmp(type,"VK_REAL")==0) + return VK_REAL; + if(strcmp(type,"VK_FLOAT")==0) + return VK_FLOAT; + if(strcmp(type,"VK_TIMESTAMP")==0) + return VK_TIMESTAMP; + if(strcmp(type,"VK_TIME")==0) + return VK_TIMESTAMP; + if(strcmp(type,"VK_DURATION")==0) + return VK_DURATION; + if(strcmp(type,"VK_TEXT")==0) + return VK_STRING; + if(strcmp(type,"VK_STRING")==0) + return VK_STRING; + if(strcmp(type,"VK_BLOB")==0) + return VK_BLOB; + if(strcmp(type,"VK_IMAGE")==0) + return VK_IMAGE; + return VK_UNKNOW; +} +const char* stringFromType(FOURD_TYPE type) +{ + switch(type) + { + case VK_BOOLEAN: + return "VK_BOOLEAN"; + case VK_BYTE: + return "VK_BYTE"; + case VK_WORD: + return "VK_WORD"; + case VK_LONG: + return "VK_LONG"; + case VK_LONG8: + return "VK_LONG8"; + case VK_REAL: + return "VK_REAL"; + case VK_FLOAT: + return "VK_FLOAT"; + case VK_TIMESTAMP: + return "VK_TIMESTAMP"; + case VK_TIME: + return "VK_TIME"; + case VK_DURATION: + return "VK_DURATION"; + case VK_STRING: + return "VK_STRING"; + case VK_BLOB: + return "VK_BLOB"; + case VK_IMAGE: + return "VK_IMAGE"; + default: + return "VK_UNKNOW"; + break; + } +} +/******************************************************************/ +/* vk_sizeof */ +/******************************************************************/ +/* return sizeof type or -1 if varying length or 0 if unknow type */ +/******************************************************************/ +int vk_sizeof(FOURD_TYPE type) +{ + switch(type) + { + case VK_BOOLEAN: + case VK_BYTE: + case VK_WORD: + return 2; + break; + case VK_LONG: + return 4; + break; + case VK_LONG8: + case VK_REAL: + case VK_DURATION: + return 8; + break; + case VK_FLOAT: + //Varying length + return -1; + break; + case VK_TIME: + case VK_TIMESTAMP: + return 8; + break; + case VK_TEXT: + case VK_STRING: + case VK_BLOB: + case VK_IMAGE: + //Varying length + return -1; + break; + default: + Printf("Error: Unknow type in vk_sizeof function\n"); + return 0; + break; + } + //error type not found. Should now be handled by the default switch case + Printf("Error: Unknow type in vk_sizeof function\n"); + return 0; +} + +FOURD_RESULT_TYPE resultTypeFromString(const char *type) +{ + if(strcmp(type,"Update-Count")==0) + return UPDATE_COUNT; + if(strcmp(type,"Result-Set")==0) + return RESULT_SET; + return UNKNOW; +} +const char* stringFromResultType(FOURD_RESULT_TYPE type) +{ + switch(type) + { + case UPDATE_COUNT: + return "Update-Count"; + break; + case RESULT_SET: + return "Result-Set"; + break; + default: + return "Unknown"; + break; + } + return "Unknown"; } \ No newline at end of file diff --git a/lib4d_sql/fourd_type.h b/lib4d_sql/fourd_type.h old mode 100644 new mode 100755 index d8c684b..574435f --- a/lib4d_sql/fourd_type.h +++ b/lib4d_sql/fourd_type.h @@ -1,59 +1,87 @@ -#ifndef __FOURD_TYPE__ -#define __FOURD_TYPE__ -typedef enum -{ - VK_UNKNOW=0, - VK_BOOLEAN, - VK_BYTE, - VK_WORD, - VK_LONG, - VK_LONG8, - VK_REAL, - VK_FLOAT, - VK_TIMESTAMP, - VK_DURATION, - VK_STRING, - VK_BLOB, - VK_IMAGE -}FOURD_TYPE; -/******************************/ -/* parse and format FOUR_TYPE */ -/******************************/ -FOURD_TYPE typeFromString(const char *type); -const char* stringFromType(FOURD_TYPE type); -/******************************************************************/ -/* vk_sizeof */ -/******************************************************************/ -/* return sizeof type or -1 if varying length or 0 if unknow type */ -/******************************************************************/ -int vk_sizeof(FOURD_TYPE type); - -/***************/ -/* Result-Type */ -/***************/ -typedef enum -{ - UNKNOW=0, - UPDATE_COUNT, - RESULT_SET -}FOURD_RESULT_TYPE; -FOURD_RESULT_TYPE resultTypeFromString(const char *type); -const char* stringFromResultType(FOURD_RESULT_TYPE type); - -/*********************/ -/* Structure of VK_* */ -/*********************/ -typedef short FOURD_BOOLEAN; -typedef short FOURD_BYTE; -typedef short FOURD_WORD; -typedef int FOURD_LONG; -typedef __int64 FOURD_LONG8; -typedef double FOURD_REAL; -typedef struct{int exp;char sign;int data_length;void* data;}FOURD_FLOAT; -typedef struct{short year;char mounth;char day;unsigned int milli;}FOURD_TIMESTAMP; -typedef __int64 FOURD_DURATION;//in milliseconds -typedef struct{int length;unsigned char *data;}FOURD_STRING; -typedef struct{unsigned int length;void *data;}FOURD_BLOB; -//typedef struct{}FOURD_IMAGE; - +/* + +----------------------------------------------------------------------+ + | lib4D_SQL | + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | | + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | | + | Its original copy is usable under several licenses and is available | + | through the world-wide-web at the following url: | + | http://freshmeat.net/projects/lib4d_sql | + | | + | Unless required by applicable law or agreed to in writing, software | + | distributed under the License is distributed on an "AS IS" BASIS, | + | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | + | implied. See the License for the specific language governing | + | permissions and limitations under the License. | + +----------------------------------------------------------------------+ + | Contributed by: 4D , http://www.4d.com | + | Alter Way, http://www.alterway.fr | + | Authors: Stephane Planquart | + | Alexandre Morgaut | + +----------------------------------------------------------------------+ +*/ +#ifndef __FOURD_TYPE__ +#define __FOURD_TYPE__ +typedef enum +{ + VK_UNKNOW=0, + VK_BOOLEAN, + VK_BYTE, + VK_WORD, + VK_LONG, + VK_LONG8, + VK_REAL, + VK_FLOAT, + VK_TIMESTAMP, + VK_DURATION, + VK_STRING, + VK_BLOB, + VK_IMAGE +}FOURD_TYPE; +/******************************/ +/* parse and format FOUR_TYPE */ +/******************************/ +FOURD_TYPE typeFromString(const char *type); +const char* stringFromType(FOURD_TYPE type); +/******************************************************************/ +/* vk_sizeof */ +/******************************************************************/ +/* return sizeof type or -1 if varying length or 0 if unknow type */ +/******************************************************************/ +int vk_sizeof(FOURD_TYPE type); + +/***************/ +/* Result-Type */ +/***************/ +typedef enum +{ + UNKNOW=0, + UPDATE_COUNT, + RESULT_SET +}FOURD_RESULT_TYPE; +FOURD_RESULT_TYPE resultTypeFromString(const char *type); +const char* stringFromResultType(FOURD_RESULT_TYPE type); + +/*********************/ +/* Structure of VK_* */ +/*********************/ +typedef short FOURD_BOOLEAN; +typedef short FOURD_BYTE; +typedef short FOURD_WORD; +typedef int FOURD_LONG; +typedef __int64 FOURD_LONG8; +typedef double FOURD_REAL; +typedef struct{int exp;char sign;int data_length;void* data;}FOURD_FLOAT; +typedef struct{short year;char mounth;char day;unsigned int milli;}FOURD_TIMESTAMP; +typedef __int64 FOURD_DURATION;//in milliseconds +typedef struct{int length;unsigned char *data;}FOURD_STRING; +typedef struct{unsigned int length;void *data;}FOURD_BLOB; +//typedef struct{}FOURD_IMAGE; + #endif \ No newline at end of file diff --git a/lib4d_sql/sqlstate.c b/lib4d_sql/sqlstate.c old mode 100644 new mode 100755 index 062e54f..1bec5eb --- a/lib4d_sql/sqlstate.c +++ b/lib4d_sql/sqlstate.c @@ -1,19 +1,48 @@ -#include "fourd.h" -const char * fourd_sqlstate(FOURD *cnx) -{ - switch(cnx->error_code){ - case -10060: return "08001";/* Unable to connect to server => Client unable to establish connection */ - case -1: return "01S00"; - /*case 1105: return "08004";*/ /* Failed to authenticate. => Server rejected the connection */ - - case 1101: return "42P01"; /* Failed to execute statement. => Undefined table <= TABLE DOES NOT EXIST */ +/* + +----------------------------------------------------------------------+ + | lib4D_SQL | + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | | + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | | + | Its original copy is usable under several licenses and is available | + | through the world-wide-web at the following url: | + | http://freshmeat.net/projects/lib4d_sql | + | | + | Unless required by applicable law or agreed to in writing, software | + | distributed under the License is distributed on an "AS IS" BASIS, | + | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | + | implied. See the License for the specific language governing | + | permissions and limitations under the License. | + +----------------------------------------------------------------------+ + | Contributed by: 4D , http://www.4d.com | + | Alter Way, http://www.alterway.fr | + | Authors: Stephane Planquart | + | Alexandre Morgaut | + +----------------------------------------------------------------------+ +*/ + +#include "fourd.h" +const char * fourd_sqlstate(FOURD *cnx) +{ + switch(cnx->error_code){ + case -10060: return "08001";/* Unable to connect to server => Client unable to establish connection */ + case -1: return "01S00"; + /*case 1105: return "08004";*/ /* Failed to authenticate. => Server rejected the connection */ + + case 1101: return "42P01"; /* Failed to execute statement. => Undefined table <= TABLE DOES NOT EXIST */ case 1102: return "42S22"; /* Column not found <= colonne DOES NOT EXIST*/ case 1103: return "42P01"; /* Undefined table <= TABLE NOT DECLARED IN FROM CLAUSE */ case 1104: return "42702"; /* Ambiguous column <= AMBIGUOUS COLUMN NAME */ case 1105: return "42P09"; /* Ambiguous alias <= TABLE ALIAS SAME AS TABLE NAME */ case 1106: return "42P09"; /* Ambiguous alias <= DUPLICATE TABLE ALIAS */ case 1107: return "42P09"; /* Ambiguous alias <= DUPLICATE TABLE IN FROM CLAUSE */ - case 1108: return "HY004"; /* Failed to execute statement. => Invalid SQL data type <= INCOMPATIBLE TYPES */ + case 1108: return "HY004"; /* Failed to execute statement. => Invalid SQL data type <= INCOMPATIBLE TYPES */ case 1109: return "HY000"; /* <= INVALID ORDER BY INDEX */ case 1110: return "42P08"; /* Ambiguous parameter <= WRONG AMOUNT OF PARAMETERS */ @@ -51,7 +80,7 @@ const char * fourd_sqlstate(FOURD *cnx) case 1133: return "21S01"; /* Insert value list does not match column list <= DUPLICATE COLUMN IN INSERT */ case 1134: return "23502"; /* Not null violation <= COLUMN DOES NOT ALLOW NULLS */ case 1135: return "42701"; /* Duplicate column <= DUPLICATE COLUMN IN UPDATE */ - case 1136: return "42P07"; /* Duplicate table <= TABLE ALREADY EXISTS */ + case 1136: return "42P07"; /* Duplicate table <= TABLE ALREADY EXISTS */ case 1137: return "42701"; /* Duplicate column <= DUPLICATE COLUMN IN CREATE TABLE */ case 1138: return "42701"; /* Duplicate column <= DUPLICATE COLUMN IN COLUMN LIST */ @@ -100,7 +129,7 @@ const char * fourd_sqlstate(FOURD *cnx) case 1220: return "HY000"; /* <= FAILED TO LOAD RECORD */ case 1221: return "HY000"; /* <= FAILED TO LOCK RECORD FOR WRITING */ case 1222: return "HY000"; /* <= FAILED TO PUT SQL LOCK ON A TABLE */ - + case 1301: return "42601"; /* Failed to parse statement. => Syntax error */ @@ -178,7 +207,7 @@ const char * fourd_sqlstate(FOURD *cnx) case 3013: return "HY000"; /* <= BASE64 ENCODING ERROR */ case 3014: return "HY000"; /* <= INVALID HEADER TERMINATOR */ - - default: return "HY000"; - } + case -5001: return "0LP01"; /* driver not support multiquery */ + default: return "HY000"; + } } \ No newline at end of file diff --git a/lib4d_sql/utils.c b/lib4d_sql/utils.c old mode 100644 new mode 100755 index 63ae27f..054de2b --- a/lib4d_sql/utils.c +++ b/lib4d_sql/utils.c @@ -1,22 +1,51 @@ -#include -#define isspace(x) (x==' ') -char *strstrip(char *s) -{ - size_t size; - char *end; - - size = strlen(s); - - if (!size) - return s; - - end = s + size - 1; - while (end != s && isspace(*end)) - end--; - *(end + 1) = '\0'; - - while (*s && isspace(*s)) - s++; - - return s; +/* + +----------------------------------------------------------------------+ + | lib4D_SQL | + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | | + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | | + | Its original copy is usable under several licenses and is available | + | through the world-wide-web at the following url: | + | http://freshmeat.net/projects/lib4d_sql | + | | + | Unless required by applicable law or agreed to in writing, software | + | distributed under the License is distributed on an "AS IS" BASIS, | + | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | + | implied. See the License for the specific language governing | + | permissions and limitations under the License. | + +----------------------------------------------------------------------+ + | Contributed by: 4D , http://www.4d.com | + | Alter Way, http://www.alterway.fr | + | Authors: Stephane Planquart | + | Alexandre Morgaut | + +----------------------------------------------------------------------+ +*/ + +#include +#define isspace(x) (x==' ') +char *strstrip(char *s) +{ + size_t size; + char *end; + + size = strlen(s); + + if (!size) + return s; + + end = s + size - 1; + while (end != s && isspace(*end)) + end--; + *(end + 1) = '\0'; + + while (*s && isspace(*s)) + s++; + + return s; } \ No newline at end of file diff --git a/lib4d_sql/utils.h b/lib4d_sql/utils.h old mode 100644 new mode 100755 index aeded97..deb8944 --- a/lib4d_sql/utils.h +++ b/lib4d_sql/utils.h @@ -1 +1,30 @@ +/* + +----------------------------------------------------------------------+ + | lib4D_SQL | + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | | + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | | + | Its original copy is usable under several licenses and is available | + | through the world-wide-web at the following url: | + | http://freshmeat.net/projects/lib4d_sql | + | | + | Unless required by applicable law or agreed to in writing, software | + | distributed under the License is distributed on an "AS IS" BASIS, | + | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | + | implied. See the License for the specific language governing | + | permissions and limitations under the License. | + +----------------------------------------------------------------------+ + | Contributed by: 4D , http://www.4d.com | + | Alter Way, http://www.alterway.fr | + | Authors: Stephane Planquart | + | Alexandre Morgaut | + +----------------------------------------------------------------------+ +*/ + char *strstrip(char *s); \ No newline at end of file