+ DatabaseErrorFmt('CSV File Field count (%d) does not match dataset field count (%d).',[Fline.Count,CreateFieldDefs.Count],Dataset.FieldDefs.Dataset);
+ If FOptions.FirstLineAsFieldNames then
+ For I:=0 to FLine.Count-1 do
+ If (CompareText(FLine[i],CreateFieldDefs[i].Name)<>0) then
+ DatabaseErrorFmt('CSV File field %d: name "%s" does not match dataset field name "%s".',[I,FLine[i],CreateFieldDefs[i].Name],Dataset.FieldDefs.Dataset);
- // Note: optionally we can implement the use of SQLBindCol later for even more speed
- // TODO: finish this
- case FieldDef.DataType of
- ftWideString,ftFixedWideChar: // mapped to TWideStringField
- Res:=SQLGetData(ODBCCursor.FSTMTHandle, FieldDef.Index+1, SQL_C_WCHAR, buffer, FieldDef.Size+sizeof(WideChar), @StrLenOrInd); //buffer must contain space for the null-termination character
- ftGuid, ftFixedChar,ftString: // are mapped to a TStringField (including TGuidField)
- ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not get field data for field "%s" (index %d).',[FieldDef.Name, FieldDef.Index+1]);
- // Read the data if not NULL
- if StrLenOrInd<>SQL_NULL_DATA then
- begin
- CreateBlob:=true; // defer actual loading of blob data to LoadBlobIntoBuffer method
- //WriteLn('Deferring loading of blob of length ',StrLenOrInd);
- end;
- end;
- // TODO: Loading of other field types
- else
- raise EODBCException.CreateFmt('Tried to load field of unsupported field type %s',[Fieldtypenames[FieldDef.DataType]]);
- end;
- ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not get field data for field "%s" (index %d).',[FieldDef.Name, FieldDef.Index+1]);
- Result:=StrLenOrInd<>SQL_NULL_DATA; // Result indicates whether the value is non-null
- ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not get field data for field "%s" (index %d).',[FieldDef.Name, FieldDef.Index+1]);
- // Read the data if not NULL
- if StrLenOrInd<>SQL_NULL_DATA then
- begin
- // Determine size of buffer to use
- if StrLenOrInd<>SQL_NO_TOTAL then begin
- // Size is known on beforehand
- // set size & alloc buffer
- //WriteLn('Loading blob of length ',StrLenOrInd);
- ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not load blob data for field "%s" (index %d).',[FieldDef.Name, FieldDef.Index+1]);
- end;
- end else begin
- // Size is not known on beforehand; read data in chuncks; write to a TMemoryStream (which implements O(n) writing)
- BlobBufferSize:=DEFAULT_BLOB_BUFFER_SIZE;
- // init BlobBuffer and BlobMemoryStream to nil pointers
- BlobBuffer:=nil; // the buffer that will hold the chuncks of data; not to be confused with ABlobBuf^.BlobBuffer
- ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not load (partial) blob data for field "%s" (index %d).',[FieldDef.Name, FieldDef.Index+1]);
- // Append data in buffer to memorystream
- if (StrLenOrInd=SQL_NO_TOTAL) or (StrLenOrInd>BlobBufferSize) then
- BytesRead:=BlobBufferSize
- else
- BytesRead:=StrLenOrInd;
- BlobMemoryStream.Write(BlobBuffer^, BytesRead);
- until Res=SQL_SUCCESS;
- // Copy memory stream data to ABlobBuf^.BlobBuffer
- BlobBufferSize:=BlobMemoryStream.Size; // actual blob size
+ // Note: optionally we can implement the use of SQLBindCol later for even more speed
+ // TODO: finish this
+ case FieldDef.DataType of
+ ftWideString,ftFixedWideChar: // mapped to TWideStringField
+ Res:=SQLGetData(ODBCCursor.FSTMTHandle, FieldDef.Index+1, SQL_C_WCHAR, buffer, FieldDef.Size+sizeof(WideChar), @StrLenOrInd); //buffer must contain space for the null-termination character
+ ftGuid, ftFixedChar,ftString: // are mapped to a TStringField (including TGuidField)
+ ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not get field data for field "%s" (index %d).',[FieldDef.Name, FieldDef.Index+1]);
+ // Read the data if not NULL
+ if StrLenOrInd<>SQL_NULL_DATA then
+ begin
+ CreateBlob:=true; // defer actual loading of blob data to LoadBlobIntoBuffer method
+ //WriteLn('Deferring loading of blob of length ',StrLenOrInd);
+ end;
+ end;
+ // TODO: Loading of other field types
+ else
+ raise EODBCException.CreateFmt('Tried to load field of unsupported field type %s',[Fieldtypenames[FieldDef.DataType]]);
+ end;
+ ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not get field data for field "%s" (index %d).',[FieldDef.Name, FieldDef.Index+1]);
+ Result:=StrLenOrInd<>SQL_NULL_DATA; // Result indicates whether the value is non-null
+ ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not get field data for field "%s" (index %d).',[FieldDef.Name, FieldDef.Index+1]);
+ // Read the data if not NULL
+ if StrLenOrInd<>SQL_NULL_DATA then
+ begin
+ // Determine size of buffer to use
+ if StrLenOrInd<>SQL_NO_TOTAL then begin
+ // Size is known on beforehand
+ // set size & alloc buffer
+ //WriteLn('Loading blob of length ',StrLenOrInd);
+ ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not load blob data for field "%s" (index %d).',[FieldDef.Name, FieldDef.Index+1]);
+ end;
+ end else begin
+ // Size is not known on beforehand; read data in chuncks; write to a TMemoryStream (which implements O(n) writing)
+ BlobBufferSize:=DEFAULT_BLOB_BUFFER_SIZE;
+ // init BlobBuffer and BlobMemoryStream to nil pointers
+ BlobBuffer:=nil; // the buffer that will hold the chuncks of data; not to be confused with ABlobBuf^.BlobBuffer
+ ODBCCheckResult(Res, SQL_HANDLE_STMT, ODBCCursor.FSTMTHandle, 'Could not load (partial) blob data for field "%s" (index %d).',[FieldDef.Name, FieldDef.Index+1]);
+ // Append data in buffer to memorystream
+ if (StrLenOrInd=SQL_NO_TOTAL) or (StrLenOrInd>BlobBufferSize) then
+ BytesRead:=BlobBufferSize
+ else
+ BytesRead:=StrLenOrInd;
+ BlobMemoryStream.Write(BlobBuffer^, BytesRead);
+ until Res=SQL_SUCCESS;
+ // Copy memory stream data to ABlobBuf^.BlobBuffer
+ BlobBufferSize:=BlobMemoryStream.Size; // actual blob size
+ if not (sqSupportReturning in Connection.ConnOptions) then
+ Ignore(STestNotApplicable);
+ ExecuteDirect('create table FPDEV2 (id integer not null, a varchar(10) default ''abcde'', b varchar(5) default ''fgh'', constraint PK_FPDEV2 primary key(id))');
+ if Transaction.Active then
+ Transaction.Commit;
+ ExecuteDirect('insert into FPDEV2 (id) values (123)');
+ if Transaction.Active then
+ Transaction.Commit;
+ end;
+ FMyQ:=SQLDBConnector.Query;
+ FMyQ.SQL.Text:='select * from FPDEV2';
+// FMyQ.InsertSQL.Text:='insert into FPDEV2 (id) values (:id)';
+ AssertEquals('b not updated','',FMyQ.FieldByName('b').AsString);
+end;
+
+procedure TTestTSQLQuery.TestReturningUpdate;
+
+begin
+ with SQLDBConnector do
+ begin
+ if not (sqSupportReturning in Connection.ConnOptions) then
+ Ignore(STestNotApplicable);
+ ExecuteDirect('create table FPDEV2 (id integer not null, a varchar(10) default ''abcde'', b varchar(5) default ''fgh'', constraint PK_FPDEV2 primary key(id))');
+ CommitDDL;
+ ExecuteDirect('insert into FPDEV2 (id) values (1)');
+ ExecuteDirect('insert into FPDEV2 (id) values (2)');
+ end;
+ FMyQ:=SQLDBConnector.Query;
+ FMyQ.SQL.Text:='select * from FPDEV2';
+ FMyQ.Open;
+ With FMyQ.FieldByName('id') do
+ ProviderFlags:=ProviderFlags+[pfInKey];
+ With FMyQ.FieldByName('b') do
+ ProviderFlags:=[pfRefreshOnUpdate]; // Do not update, just fetch new value
+ SQLDBConnector.ExecuteDirect('update FPDEV2 set b=''b1'' where id=1');
+ SQLDBConnector.ExecuteDirect('update FPDEV2 set b=''b2'' where id=2');
+ t := TMyTest.CreateWithName('TestExpectExceptionNone');
+ res := t.CreateResultAndRun;
+ assertEquals('no test was run', 1, res.RunTests);
+ assertEquals('no Ignored Test present', 0, res.NumberOfIgnoredTests);
+ assertEquals('no failed Test present', 1, res.NumberOfFailures);
+ assertEquals('Correct error message','Error message : Exception EMyException expected but no exception was raised',TTestFailure(res.Failures[0]).ExceptionMessage);