/* Allocating data and length arrays, if needed, and initing them in certain cases. DataPtr should be ensured to be not NULL */ SQLRETURN MADB_InitBulkOperBuffers(MADB_Stmt *Stmt, MADB_DescRecord *CRec, void *DataPtr, SQLLEN *OctetLengthPtr, SQLLEN *IndicatorPtr, SQLSMALLINT SqlType, MYSQL_BIND *MaBind) { BOOL VariableLengthMadbType= TRUE; MaBind->buffer_length= 0; MaBind->buffer_type= MADB_GetMaDBTypeAndLength(CRec->ConciseType, &MaBind->is_unsigned, &MaBind->buffer_length); /* For fixed length types MADB_GetMaDBTypeAndLength has set buffer_length */ if (MaBind->buffer_length != 0) { VariableLengthMadbType= FALSE; } switch (CRec->ConciseType) { case CHAR_BINARY_TYPES: if (SqlType == SQL_BIT) { CRec->InternalBuffer= MADB_CALLOC(Stmt->Bulk.ArraySize); MaBind->buffer_length= 1; break; } case DATETIME_TYPES: if (CanUseStructArrForDatetime(Stmt) == TRUE) { CRec->InternalBuffer= MADB_ALLOC(Stmt->Bulk.ArraySize*sizeof(MYSQL_TIME)); MaBind->buffer_length= sizeof(MYSQL_TIME); break; } /* Otherwise falling thru and allocating array of pointers */ case WCHAR_TYPES: case SQL_C_NUMERIC: CRec->InternalBuffer= MADB_CALLOC(Stmt->Bulk.ArraySize*sizeof(char*)); MaBind->buffer_length= sizeof(char*); break; default: MaBind->buffer= DataPtr; if (MaBind->buffer_length == 0) { MaBind->buffer_length= sizeof(char*); } } if (MaBind->buffer != DataPtr) { MaBind->buffer= CRec->InternalBuffer; if (MaBind->buffer == NULL) { return MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0); } CRec->InternalBuffer= NULL; /* Need to reset this pointer, so the memory won't be freed (accidentally) */ } return MADB_SetBulkOperLengthArr(Stmt, CRec, OctetLengthPtr, IndicatorPtr, DataPtr, MaBind, VariableLengthMadbType); }
unsigned int GetMultiStatements(MADB_Stmt *Stmt, BOOL ExecDirect) { int i= 0; unsigned int MaxParams= 0; char *p= Stmt->Query.RefinedText; Stmt->MultiStmtNr= 0; Stmt->MultiStmts= (MYSQL_STMT **)MADB_CALLOC(sizeof(MYSQL_STMT) * STMT_COUNT(Stmt->Query)); while (p < Stmt->Query.RefinedText + Stmt->Query.RefinedLength) { Stmt->MultiStmts[i]= i == 0 ? Stmt->stmt : MADB_NewStmtHandle(Stmt); MDBUG_C_PRINT(Stmt->Connection, "-->inited&preparing %0x(%d,%s)", Stmt->MultiStmts[i], i, p); if (mysql_stmt_prepare(Stmt->MultiStmts[i], p, (unsigned long)strlen(p))) { MADB_SetNativeError(&Stmt->Error, SQL_HANDLE_STMT, Stmt->MultiStmts[i]); CloseMultiStatements(Stmt); /* Last paranoid attempt make sure that we did not have a parsing error. More to preserve "backward-compatimility" - we did this before, but before trying to prepare "multi-statement". */ if (i == 0 && Stmt->Error.NativeError !=1295 /*ER_UNSUPPORTED_PS*/) { Stmt->stmt= MADB_NewStmtHandle(Stmt); if (mysql_stmt_prepare(Stmt->stmt, STMT_STRING(Stmt), (unsigned long)strlen(STMT_STRING(Stmt)))) { mysql_stmt_close(Stmt->stmt); Stmt->stmt= NULL; } else { MADB_DeleteSubqueries(&Stmt->Query); return 0; } } return 1; } if (mysql_stmt_param_count(Stmt->MultiStmts[i]) > MaxParams) { MaxParams= mysql_stmt_param_count(Stmt->MultiStmts[i]); } p+= strlen(p) + 1; ++i; } if (MaxParams) { Stmt->params= (MYSQL_BIND *)MADB_CALLOC(sizeof(MYSQL_BIND) * MaxParams); } return 0; }
/* {{{ MADB_Dsn_Init() */ MADB_Dsn *MADB_DSN_Init() { MADB_Dsn *Dsn; if ((Dsn= (MADB_Dsn *)MADB_CALLOC(sizeof(MADB_Dsn)))) { Dsn->FreeMe= TRUE; Dsn->Keys= (MADB_DsnKey *)&DsnKeys; } return Dsn; }
char *GetFieldStrVal(int Dialog, int Field, char* (*allocator)(size_t)) { int rc; size_t len= Edit_GetTextLength(GetDlgItem(hwndTab[Dialog], Field)); char *p; if (allocator) { p= allocator(len * sizeof(char) + 2); } else { p= (char *)MADB_CALLOC(len * sizeof(char) + 2); } if (p) rc= Edit_GetText(GetDlgItem(hwndTab[Dialog], Field), p, len+1); return p; }
/* {{{ MADB_DescInit */ MADB_Desc *MADB_DescInit(MADB_Dbc *Dbc,enum enum_madb_desc_type DescType, my_bool isExternal) { MADB_Desc *Desc; if (!(Desc= (MADB_Desc *)MADB_CALLOC(sizeof(MADB_Desc)))) return NULL; Desc->DescType= DescType; if (my_init_dynamic_array(&Desc->Records, sizeof(MADB_DescRecord), 0, 0)) { MADB_FREE(Desc); Desc= NULL; } if (isExternal) { if (my_init_dynamic_array(&Desc->Stmts, sizeof(MADB_Stmt**), 0, 0)) { MADB_DescFree(Desc, FALSE); Desc= NULL; } else { Desc->Dbc= Dbc; EnterCriticalSection(&Dbc->cs); Desc->ListItem.data= (void *)Desc; Dbc->Descrs= list_add(Dbc->Descrs, &Desc->ListItem); LeaveCriticalSection(&Dbc->cs); } } if (Desc) Desc->AppType= isExternal; Desc->Header.ArraySize= 1; return Desc; }
unsigned int GetMultiStatements(MADB_Stmt *Stmt, char *StmtStr, size_t Length) { char *p, *last, *prev= NULL; unsigned int statements= 1; int quote[2]= {0,0}, comment= 0; char *end; MYSQL_STMT *stmt; p= last= StmtStr; stmt= mysql_stmt_init(Stmt->Connection->mariadb); /* if the entire stmt string passes, we don't have multistatement */ if (stmt && !mysql_stmt_prepare(stmt, StmtStr, Length)) { mysql_stmt_close(stmt); return 1; } mysql_stmt_close(stmt); /* make sure we don't have trailing whitespace or semicolon */ if (Length) { end= StmtStr + Length - 1; while (end > StmtStr && (isspace(*end) || *end == ';')) end--; Length= end - StmtStr; } while (p < StmtStr + Length) { switch (*p) { case ';': if (!quote[0] && !quote[1] && !comment) { statements++; last= p + 1; *p= 0; } break; case '/': if (!comment && (p < StmtStr + Length + 1) && (char)*(p+1) == '*') comment= 1; else if (comment && (p > StmtStr) && (char)*(p-1) == '*') comment= 0; break; case '\"': if (prev && *prev != '\\') quote[0] = !quote[0]; break; case 39: if (prev && *prev != '\\') quote[1] = !quote[1]; break; default: break; } prev= p; p++; } if (statements > 1) { int i=0; unsigned int MaxParams= 0; p= StmtStr; Stmt->MultiStmtCount= 0; Stmt->MultiStmtNr= 0; Stmt->MultiStmts= (MYSQL_STMT **)MADB_CALLOC(sizeof(MYSQL_STMT) * statements); while (p < StmtStr + Length) { Stmt->MultiStmts[i]= mysql_stmt_init(Stmt->Connection->mariadb); if (mysql_stmt_prepare(Stmt->MultiStmts[i], p, strlen(p))) { MADB_SetNativeError(&Stmt->Error, SQL_HANDLE_STMT, Stmt->MultiStmts[i]); CloseMultiStatements(Stmt); return 0; } if (mysql_stmt_param_count(Stmt->MultiStmts[i]) > MaxParams) MaxParams= mysql_stmt_param_count(Stmt->MultiStmts[i]); p+= strlen(p) + 1; ++i; ++Stmt->MultiStmtCount; } if (MaxParams) Stmt->params= (MYSQL_BIND *)MADB_CALLOC(sizeof(MYSQL_BIND) * MaxParams); } return statements; }