Browse Source

--- Merging r23134 into '.':
U packages/fcl-db/tests/testdbbasics.pas
--- Merging r23138 into '.':
U packages/fcl-db/tests/testfieldtypes.pas
U packages/fcl-db/src/sqldb/postgres/pqconnection.pp
--- Merging r23139 into '.':
U packages/fcl-db/src/sqldb/sqldb.pp
G packages/fcl-db/src/sqldb/postgres/pqconnection.pp
--- Merging r23140 into '.':
G packages/fcl-db/src/sqldb/postgres/pqconnection.pp
--- Merging r23141 into '.':
U packages/fcl-db/src/sqldb/sqlite/sqlite3conn.pp
--- Merging r23148 into '.':
U packages/fcl-db/src/sqldb/oracle/oracleconnection.pp
--- Merging r23161 into '.':
G packages/fcl-db/tests/testdbbasics.pas
--- Merging r23162 into '.':
U packages/fcl-db/tests/dbtestframework_gui.lpi
A packages/fcl-db/tests/inieditor.lfm
U packages/fcl-db/tests/dbtestframework_gui.lpr
A packages/fcl-db/tests/inieditor.pas
--- Merging r23163 into '.':
G packages/fcl-db/src/sqldb/postgres/pqconnection.pp
--- Merging r23164 into '.':
G packages/fcl-db/tests/dbtestframework_gui.lpr
A packages/fcl-db/tests/testdbexport.pas
U packages/fcl-db/tests/dbtestframework.pas
D packages/fcl-db/tests/dbfexporttest.lpr
D packages/fcl-db/tests/XMLXSDExportTest.lpr
D packages/fcl-db/tests/xmlxsdexporttestcase1.pas
D packages/fcl-db/tests/dbfexporttest.lpi
D packages/fcl-db/tests/XMLXSDExportTest.lpi
--- Merging r23165 into '.':
U packages/fcl-db/tests/testdbexport.pas

# revisions: 23134,23138,23139,23140,23141,23148,23161,23162,23163,23164,23165
r23134 | reiniero | 2012-12-11 14:39:39 +0100 (Tue, 11 Dec 2012) | 1 line
Changed paths:
M /trunk/packages/fcl-db/tests/testdbbasics.pas

* fcl-db tests: clarified TTestBufDatasetDBBasics.TestIndexEditRecord error messages/description
r23138 | lacak | 2012-12-14 07:22:05 +0100 (Fri, 14 Dec 2012) | 2 lines
Changed paths:
M /trunk/packages/fcl-db/src/sqldb/postgres/pqconnection.pp
M /trunk/packages/fcl-db/tests/testfieldtypes.pas

fcl-db: postgresql: do not clear result of PQexec if result set is returned (PGRES_TUPLES_OK) + test
simplify error handling
r23139 | lacak | 2012-12-14 08:00:39 +0100 (Fri, 14 Dec 2012) | 1 line
Changed paths:
M /trunk/packages/fcl-db/src/sqldb/postgres/pqconnection.pp
M /trunk/packages/fcl-db/src/sqldb/sqldb.pp

fcl-db: formatting (char case)
r23140 | lacak | 2012-12-14 10:33:43 +0100 (Fri, 14 Dec 2012) | 2 lines
Changed paths:
M /trunk/packages/fcl-db/src/sqldb/postgres/pqconnection.pp

fcl-db: postgresql: correct message for unpreparation.
(note: if preparation of one statement failed and there are other already prepared statements (f.e. selects), then when Rollback used CloseDatasets is called which lead to Unpreparation of all datasets, which fails with : "current transaction is aborted, commands ignored until end of transaction block" ...)
r23141 | lacak | 2012-12-14 10:54:02 +0100 (Fri, 14 Dec 2012) | 1 line
Changed paths:
M /trunk/packages/fcl-db/src/sqldb/sqlite/sqlite3conn.pp

fcl-db: sqlite: increase max allowed column length. Fix for existing test TestStringLargerThen8192.
r23148 | ludob | 2012-12-15 16:52:08 +0100 (Sat, 15 Dec 2012) | 1 line
Changed paths:
M /trunk/packages/fcl-db/src/sqldb/oracle/oracleconnection.pp

Oracleconnection: added support for TSQLCurser.FSelectable
r23161 | lacak | 2012-12-17 07:57:43 +0100 (Mon, 17 Dec 2012) | 1 line
Changed paths:
M /trunk/packages/fcl-db/tests/testdbbasics.pas

fcl-db: test: for UniDirectional datasets is RecNo=-1 (also in Delphi), so fix test.
r23162 | reiniero | 2012-12-17 14:15:20 +0100 (Mon, 17 Dec 2012) | 1 line
Changed paths:
M /trunk/packages/fcl-db/tests/dbtestframework_gui.lpi
M /trunk/packages/fcl-db/tests/dbtestframework_gui.lpr
A /trunk/packages/fcl-db/tests/inieditor.lfm
A /trunk/packages/fcl-db/tests/inieditor.pas

+ fcl-db tests: GUI test framework: add db connector selector/editor. Addresses issue #23483
r23163 | lacak | 2012-12-17 14:22:19 +0100 (Mon, 17 Dec 2012) | 2 lines
Changed paths:
M /trunk/packages/fcl-db/src/sqldb/postgres/pqconnection.pp

fcl-db: postgresql: add schema name into schema query.
stSysTables should return only system tables.
r23164 | reiniero | 2012-12-17 16:26:28 +0100 (Mon, 17 Dec 2012) | 5 lines
Changed paths:
D /trunk/packages/fcl-db/tests/XMLXSDExportTest.lpi
D /trunk/packages/fcl-db/tests/XMLXSDExportTest.lpr
D /trunk/packages/fcl-db/tests/dbfexporttest.lpi
D /trunk/packages/fcl-db/tests/dbfexporttest.lpr
M /trunk/packages/fcl-db/tests/dbtestframework.pas
M /trunk/packages/fcl-db/tests/dbtestframework_gui.lpr
A /trunk/packages/fcl-db/tests/testdbexport.pas
D /trunk/packages/fcl-db/tests/xmlxsdexporttestcase1.pas

+ sqldb: db test framework:
- consolidate db export tests into db test framework; remove existing xmlxsd and dbf export tests.
- add tests for other exports (rtf, tex, csv, sql..)
- Tests give an access violation but that is probably caused by dataset code. Ludo Brand's analysis:
Can reproduce the problem. Something wrong with the dataset. The length of the blob is 1G although the blob is initialised with an empty string. This obviously causes a sigsegv because there is no 1G of data to copy from. Looking further into it.
r23165 | reiniero | 2012-12-17 16:56:40 +0100 (Mon, 17 Dec 2012) | 4 lines
Changed paths:
M /trunk/packages/fcl-db/tests/testdbexport.pas

+ sqldb: db test framework:
- consolidate csv export test from issue #20268
- fix output filenames so that naming collisions are less likely

git-svn-id: branches/fixes_2_6@24933 -

marco 12 years ago
parent
commit
f470631dff

+ 3 - 5
.gitattributes

@@ -2006,17 +2006,15 @@ packages/fcl-db/src/sqlite/testds.pas svneol=native#text/plain
 packages/fcl-db/tests/Makefile -text
 packages/fcl-db/tests/Makefile.fpc -text
 packages/fcl-db/tests/README.txt svneol=native#text/plain
-packages/fcl-db/tests/XMLXSDExportTest.lpi svneol=native#text/plain
-packages/fcl-db/tests/XMLXSDExportTest.lpr svneol=native#text/plain
 packages/fcl-db/tests/bufdatasettoolsunit.pas svneol=native#text/plain
 packages/fcl-db/tests/database.ini.txt svneol=native#text/plain
-packages/fcl-db/tests/dbfexporttest.lpi svneol=native#text/plain
-packages/fcl-db/tests/dbfexporttest.lpr svneol=native#text/plain
 packages/fcl-db/tests/dbfexporttestcase1.pas svneol=native#text/plain
 packages/fcl-db/tests/dbftoolsunit.pas svneol=native#text/plain
 packages/fcl-db/tests/dbtestframework.pas svneol=native#text/plain
 packages/fcl-db/tests/dbtestframework_gui.lpi svneol=native#text/plain
 packages/fcl-db/tests/dbtestframework_gui.lpr svneol=native#text/plain
+packages/fcl-db/tests/inieditor.lfm svneol=native#text/plain
+packages/fcl-db/tests/inieditor.pas svneol=native#text/plain
 packages/fcl-db/tests/memdstoolsunit.pas svneol=native#text/plain
 packages/fcl-db/tests/sdfdstoolsunit.pas svneol=native#text/plain
 packages/fcl-db/tests/sqldbtoolsunit.pas svneol=native#text/plain
@@ -2029,6 +2027,7 @@ packages/fcl-db/tests/testbasics.pas svneol=native#text/plain
 packages/fcl-db/tests/testbufdatasetstreams.pas svneol=native#text/plain
 packages/fcl-db/tests/testdatasources.pas svneol=native#text/plain
 packages/fcl-db/tests/testdbbasics.pas svneol=native#text/plain
+packages/fcl-db/tests/testdbexport.pas svneol=native#text/plain
 packages/fcl-db/tests/testdddiff.pp svneol=native#text/plain
 packages/fcl-db/tests/testfieldtypes.pas svneol=native#text/plain
 packages/fcl-db/tests/testjsondataset.pp svneol=native#text/plain
@@ -2039,7 +2038,6 @@ packages/fcl-db/tests/testsqlscanner.lpi svneol=native#text/plain
 packages/fcl-db/tests/testsqlscanner.lpr svneol=native#text/plain
 packages/fcl-db/tests/testsqlscript.pas svneol=native#text/plain
 packages/fcl-db/tests/toolsunit.pas svneol=native#text/plain
-packages/fcl-db/tests/xmlxsdexporttestcase1.pas svneol=native#text/plain
 packages/fcl-extra/Makefile svneol=native#text/plain
 packages/fcl-extra/Makefile.fpc svneol=native#text/plain
 packages/fcl-extra/examples/Makefile svneol=native#text/plain

+ 19 - 0
packages/fcl-db/src/sqldb/oracle/oracleconnection.pp

@@ -517,11 +517,30 @@ var tel      : integer;
     OFieldType   : ub2;
     OFieldSize   : sb4;
 
+    stmttype     : ub2;
+
 begin
   with cursor as TOracleCursor do
     begin
     if OCIStmtPrepare2(TOracleTrans(ATransaction.Handle).FOciSvcCtx,FOciStmt,FOciError,@buf[1],length(buf),nil,0,OCI_NTV_SYNTAX,OCI_DEFAULT) = OCI_ERROR then
       HandleError;
+    //get statement type
+    if OCIAttrGet(FOciStmt,OCI_HTYPE_STMT,@stmttype,nil,OCI_ATTR_STMT_TYPE,FOciError) = OCI_ERROR then
+      HandleError;
+    case stmttype of
+      OCI_STMT_SELECT:FStatementType := stSelect;
+      OCI_STMT_UPDATE:FStatementType := stUpdate;
+      OCI_STMT_DELETE:FStatementType := stDelete;
+      OCI_STMT_INSERT:FStatementType := stInsert;
+      OCI_STMT_CREATE,
+      OCI_STMT_DROP,
+      OCI_STMT_DECLARE,
+      OCI_STMT_ALTER:FStatementType := stDDL;
+    else
+      FStatementType := stUnknown;
+    end;
+    if FStatementType in [stUpdate,stDelete,stInsert,stDDL] then
+      FSelectable:=false;
     if assigned(AParams) then
       begin
       setlength(ParamBuffers,AParams.Count);

+ 45 - 50
packages/fcl-db/src/sqldb/postgres/pqconnection.pp

@@ -49,7 +49,7 @@ type
     FConnectString       : string;
     FSQLDatabaseHandle   : pointer;
     FIntegerDateTimes    : boolean;
-    procedure CheckResultError(res: PPGresult; conn:PPGconn; ErrMsg: string);
+    procedure CheckResultError(var res: PPGresult; conn:PPGconn; ErrMsg: string);
     function GetPQDatabaseError(res : PPGresult;ErrMsg: string):EPQDatabaseError;
     function TranslateFldType(res : PPGresult; Tuple : integer; out Size : integer) : TFieldType;
     procedure ExecuteDirectPG(const Query : String);
@@ -117,6 +117,7 @@ ResourceString
   SErrFieldDefsFailed = 'Can not extract field information from query';
   SErrFetchFailed = 'Fetch of data failed';
   SErrPrepareFailed = 'Preparation of query failed.';
+  SErrUnPrepareFailed = 'Unpreparation of query failed.';
 
 const Oid_Bool     = 16;
       Oid_Bytea    = 17;
@@ -348,7 +349,7 @@ begin
 
 end;
 
-procedure TPQConnection.CheckResultError(res: PPGresult; conn: PPGconn;
+procedure TPQConnection.CheckResultError(var res: PPGresult; conn: PPGconn;
   ErrMsg: string);
 var
   E: EPQDatabaseError;
@@ -357,7 +358,8 @@ begin
   if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
     begin
     E:=GetPQDatabaseError(res,ErrMsg);
-    pqclear(res);
+    PQclear(res);
+    res:=nil;
     if assigned(conn) then
       PQFinish(conn);
     raise E;
@@ -481,7 +483,6 @@ begin
 end;
 
 Procedure TPQConnection.DeAllocateCursorHandle(var cursor : TSQLCursor);
-
 begin
   FreeAndNil(cursor);
 end;
@@ -497,7 +498,7 @@ procedure TPQConnection.PrepareStatement(cursor: TSQLCursor;ATransaction : TSQLT
 const TypeStrings : array[TFieldType] of string =
     (
       'Unknown',   // ftUnknown
-      'text',     // ftString
+      'text',      // ftString
       'smallint',  // ftSmallint
       'int',       // ftInteger
       'int',       // ftWord
@@ -556,10 +557,10 @@ begin
       // Only available for pq 8.0, so don't use it...
       // Res := pqprepare(tr,'prepst'+name+nr,pchar(buf),params.Count,pchar(''));
       s := 'prepare '+StmtName+' ';
-      if Assigned(AParams) and (AParams.count > 0) then
+      if Assigned(AParams) and (AParams.Count > 0) then
         begin
         s := s + '(';
-        for i := 0 to AParams.count-1 do if TypeStrings[AParams[i].DataType] <> 'Unknown' then
+        for i := 0 to AParams.Count-1 do if TypeStrings[AParams[i].DataType] <> 'Unknown' then
           s := s + TypeStrings[AParams[i].DataType] + ','
         else
           begin
@@ -572,7 +573,7 @@ begin
         buf := AParams.ParseSQL(buf,false,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psPostgreSQL);
         end;
       s := s + ' as ' + buf;
-      res := pqexec(tr.PGConn,pchar(s));
+      res := PQexec(tr.PGConn,pchar(s));
       CheckResultError(res,nil,SErrPrepareFailed);
       // if statement is INSERT, UPDATE, DELETE with RETURNING clause, then
       // override the statement type derrived by parsing the query.
@@ -586,31 +587,27 @@ begin
       FPrepared := True;
       end
     else
-      statement := AParams.ParseSQL(buf,false,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psPostgreSQL);
+      Statement := AParams.ParseSQL(buf,false,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psPostgreSQL);
     end;
 end;
 
 procedure TPQConnection.UnPrepareStatement(cursor : TSQLCursor);
-var
-  E: EPQDatabaseError;
-
 begin
-  with (cursor as TPQCursor) do if FPrepared then
+  with (cursor as TPQCursor) do
     begin
-    if not tr.ErrorOccured then
+    PQclear(res);
+    res:=nil;
+    if FPrepared then
       begin
-      PQclear(res);
-      res := pqexec(tr.PGConn,pchar('deallocate '+StmtName));
-      if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
+      if not tr.ErrorOccured then
         begin
-          E:=GetPQDatabaseError(res,SErrPrepareFailed);
-          pqclear(res);
-          raise E;
-        end
-      else
-        pqclear(res);
+        res := PQexec(tr.PGConn,pchar('deallocate '+StmtName));
+        CheckResultError(res,nil,SErrUnPrepareFailed);
+        PQclear(res);
+        res:=nil;
+        end;
+      FPrepared := False;
       end;
-    FPrepared := False;
     end;
 end;
 
@@ -623,21 +620,20 @@ var ar  : array of pchar;
     ParamNames,
     ParamValues : array of string;
     cash: int64;
-    E: EPQDatabaseError;
 
 begin
   with cursor as TPQCursor do
     begin
+    PQclear(res);
     if FStatementType in [stInsert,stUpdate,stDelete,stSelect] then
       begin
-      pqclear(res);
-      if Assigned(AParams) and (AParams.count > 0) then
+      if Assigned(AParams) and (AParams.Count > 0) then
         begin
-        l:=Aparams.count;
+        l:=AParams.Count;
         setlength(ar,l);
         setlength(lengths,l);
         setlength(formats,l);
-        for i := 0 to AParams.count -1 do if not AParams[i].IsNull then
+        for i := 0 to AParams.Count -1 do if not AParams[i].IsNull then
           begin
           case AParams[i].DataType of
             ftDateTime:
@@ -669,8 +665,8 @@ begin
           end
         else
           FreeAndNil(ar[i]);
-        res := PQexecPrepared(tr.PGConn,pchar(StmtName),Aparams.count,@Ar[0],@Lengths[0],@Formats[0],1);
-        for i := 0 to AParams.count -1 do
+        res := PQexecPrepared(tr.PGConn,pchar(StmtName),AParams.Count,@Ar[0],@Lengths[0],@Formats[0],1);
+        for i := 0 to AParams.Count -1 do
           FreeMem(ar[i]);
         end
       else
@@ -680,37 +676,36 @@ begin
       begin
       tr := TPQTrans(aTransaction.Handle);
 
-      if Assigned(AParams) and (AParams.count > 0) then
+      if Assigned(AParams) and (AParams.Count > 0) then
         begin
         setlength(ParamNames,AParams.Count);
         setlength(ParamValues,AParams.Count);
-        for i := 0 to AParams.count -1 do
+        for i := 0 to AParams.Count -1 do
           begin
-          ParamNames[AParams.count-i-1] := '$'+inttostr(AParams[i].index+1);
-          ParamValues[AParams.count-i-1] := GetAsSQLText(AParams[i]);
+          ParamNames[AParams.Count-i-1] := '$'+inttostr(AParams[i].index+1);
+          ParamValues[AParams.Count-i-1] := GetAsSQLText(AParams[i]);
           end;
-        s := stringsreplace(statement,ParamNames,ParamValues,[rfReplaceAll]);
+        s := stringsreplace(Statement,ParamNames,ParamValues,[rfReplaceAll]);
         end
       else
         s := Statement;
-      res := pqexec(tr.PGConn,pchar(s));
-      if (PQresultStatus(res) in [PGRES_COMMAND_OK,PGRES_TUPLES_OK]) then
+      res := PQexec(tr.PGConn,pchar(s));
+      if (PQresultStatus(res) in [PGRES_COMMAND_OK]) then
         begin
-          pqclear(res); 
-          res:=nil;
+        PQclear(res);
+        res:=nil;
         end;
       end;
+
     if assigned(res) and not (PQresultStatus(res) in [PGRES_COMMAND_OK,PGRES_TUPLES_OK]) then
       begin
-      E:=GetPQDatabaseError(res,SErrExecuteFailed);
-      pqclear(res);
-
       tr.ErrorOccured := True;
 // Don't perform the rollback, only make it possible to do a rollback.
 // The other databases also don't do this.
 //      atransaction.Rollback;
-      raise E;
+      CheckResultError(res,nil,SErrExecuteFailed);
       end;
+
     FSelectable := assigned(res) and (PQresultStatus(res)=PGRES_TUPLES_OK);
     end;
 end;
@@ -1010,25 +1005,25 @@ begin
     stTables     : s := 'select '+
                           'relfilenode              as recno, '+
                           '''' + DatabaseName + ''' as catalog_name, '+
-                          '''''                     as schema_name, '+
+                          'nspname                  as schema_name, '+
                           'relname                  as table_name, '+
                           '0                        as table_type '+
                         'from '+
-                          'pg_class '+
+                          'pg_class c left join pg_namespace n on c.relnamespace=n.oid '+
                         'where '+
-                          '(relowner > 1) and relkind=''r''' +
+                          'relkind=''r''' +
                         'order by relname';
 
     stSysTables  : s := 'select '+
                           'relfilenode              as recno, '+
                           '''' + DatabaseName + ''' as catalog_name, '+
-                          '''''                     as schema_name, '+
+                          'nspname                  as schema_name, '+
                           'relname                  as table_name, '+
                           '0                        as table_type '+
                         'from '+
-                          'pg_class '+
+                          'pg_class c left join pg_namespace n on c.relnamespace=n.oid '+
                         'where '+
-                          'relkind=''r''' +
+                          'relkind=''r'' and nspname=''pg_catalog'' ' + // only system tables
                         'order by relname';
     stColumns    : s := 'select '+
                           'a.attnum                 as recno, '+

+ 16 - 16
packages/fcl-db/src/sqldb/sqldb.pp

@@ -628,8 +628,8 @@ begin
 
     Cursor := AllocateCursorHandle;
     Cursor.FStatementType := stUnknown;
-    PrepareStatement(cursor,ATransaction,SQL,Nil);
-    execute(cursor,ATransaction, Nil);
+    PrepareStatement(Cursor,ATransaction,SQL,Nil);
+    Execute(Cursor,ATransaction, Nil);
     UnPrepareStatement(Cursor);
   finally;
     DeAllocateCursorHandle(Cursor);
@@ -644,7 +644,7 @@ end;
 procedure TSQLConnection.SetPort(const AValue: cardinal);
 begin
   if AValue<>0 then
-    params.Values['Port']:=IntToStr(AValue)
+    Params.Values['Port']:=IntToStr(AValue)
   else with params do if IndexOfName('Port') > -1 then
     Delete(IndexOfName('Port'));
 end;
@@ -1051,7 +1051,7 @@ begin
 
   if ServerFiltered then s := AddFilter(s);
 
-  TSQLConnection(Database).PrepareStatement(Fcursor,(transaction as tsqltransaction),S,FParams);
+  TSQLConnection(Database).PrepareStatement(FCursor,(Transaction as TSQLTransaction),S,FParams);
 
   Execute;
   inherited InternalOpen;
@@ -1123,22 +1123,22 @@ begin
     // and thus calls unprepare.
     // A call to unprepare while the cursor is not prepared at all can lead to
     // unpredictable results.
-    if not assigned(fcursor) then
+    if not assigned(FCursor) then
       FCursor := Db.AllocateCursorHandle;
     FCursor.FSelectable:=True; // let PrepareStatement and/or Execute alter it
     FCursor.FStatementType:=StmType;
     FCursor.FSchemaType := FSchemaType;
     if ServerFiltered then
       begin
-      If LogEvent(detprepare) then
+      If LogEvent(detPrepare) then
         Log(detPrepare,AddFilter(FSQLBuf));
-      Db.PrepareStatement(Fcursor,sqltr,AddFilter(FSQLBuf),FParams)
+      Db.PrepareStatement(FCursor,sqltr,AddFilter(FSQLBuf),FParams)
       end
     else
       begin
-      If LogEvent(detprepare) then
+      If LogEvent(detPrepare) then
         Log(detPrepare,FSQLBuf);
-      Db.PrepareStatement(Fcursor,sqltr,FSQLBuf,FParams);
+      Db.PrepareStatement(FCursor,sqltr,FSQLBuf,FParams);
       end;
     FCursor.FInitFieldDef := FCursor.FSelectable;
     end;
@@ -1167,7 +1167,7 @@ begin
   if not FCursor.FSelectable then
     Exit;
 
-  if not FIsEof then FIsEOF := not TSQLConnection(Database).Fetch(Fcursor);
+  if not FIsEof then FIsEOF := not TSQLConnection(Database).Fetch(FCursor);
   Result := not FIsEOF;
 end;
 
@@ -1177,7 +1177,7 @@ begin
     FMasterLink.CopyParamsFromMaster(False);
   If LogEvent(detExecute) then
     Log(detExecute,FSQLBuf);
-  TSQLConnection(Database).execute(Fcursor,Transaction as tsqltransaction, FParams);
+  TSQLConnection(Database).Execute(FCursor,Transaction as TSQLTransaction, FParams);
 end;
 
 function TCustomSQLQuery.LoadField(FieldDef : TFieldDef;buffer : pointer; out CreateBlob : boolean) : boolean;
@@ -1227,7 +1227,7 @@ begin
   try
     FieldDefs.Clear;
     if not Assigned(Database) then DatabaseError(SErrDatabasenAssigned);
-    TSQLConnection(Database).AddFieldDefs(fcursor,FieldDefs);
+    TSQLConnection(Database).AddFieldDefs(FCursor,FieldDefs);
   finally
     FLoadingFieldDefs := False;
     if Assigned(FCursor) then FCursor.FInitFieldDef := false;
@@ -1421,7 +1421,7 @@ begin
   ReadFromFile:=IsReadFromPacket;
   if ReadFromFile then
     begin
-    if not assigned(fcursor) then
+    if not assigned(FCursor) then
       FCursor := TSQLConnection(Database).AllocateCursorHandle;
     FCursor.FSelectable:=True;
     FCursor.FStatementType:=stSelect;
@@ -1499,7 +1499,7 @@ begin
   finally
     // FCursor has to be assigned, or else the prepare went wrong before PrepareStatment was
     // called, so UnPrepareStatement shoudn't be called either
-    if (not IsPrepared) and (assigned(database)) and (assigned(FCursor)) then TSQLConnection(database).UnPrepareStatement(Fcursor);
+    if (not IsPrepared) and (assigned(database)) and (assigned(FCursor)) then TSQLConnection(database).UnPrepareStatement(FCursor);
   end;
 end;
 
@@ -1765,7 +1765,7 @@ end;
 procedure TCustomSQLQuery.LoadBlobIntoBuffer(FieldDef: TFieldDef;
   ABlobBuf: PBufBlobField);
 begin
-  TSQLConnection(DataBase).LoadBlobIntoBuffer(FieldDef, ABlobBuf, FCursor,(Transaction as tsqltransaction));
+  TSQLConnection(DataBase).LoadBlobIntoBuffer(FieldDef, ABlobBuf, FCursor,(Transaction as TSQLTransaction));
 end;
 
 procedure TCustomSQLQuery.BeforeRefreshOpenCursor;
@@ -1817,7 +1817,7 @@ begin
   FInsertSQL.Assign(AValue);
 end;
 
-Procedure TCustomSQLQuery.SetDataSource(AVAlue : TDatasource);
+Procedure TCustomSQLQuery.SetDataSource(AValue : TDatasource);
 
 Var
   DS : TDatasource;

+ 1 - 1
packages/fcl-db/src/sqldb/sqlite/sqlite3conn.pp

@@ -477,7 +477,7 @@ begin
                  size1 := 255; //sql: if length is omitted then length is 1
                  size2 := 0;
                  ExtractPrecisionAndScale(FD, size1, size2);
-                 if size1 > dsMaxStringSize then size1 := dsMaxStringSize;
+                 if size1 > MaxSmallint then size1 := MaxSmallint;
                end;
       ftBCD:   begin
                  size2 := MaxBCDPrecision; //sql: if a precision is omitted, then use implementation-defined

+ 0 - 102
packages/fcl-db/tests/XMLXSDExportTest.lpi

@@ -1,102 +0,0 @@
-<?xml version="1.0"?>
-<CONFIG>
-  <ProjectOptions>
-    <Version Value="9"/>
-    <PathDelim Value="\"/>
-    <General>
-      <Flags>
-        <SaveOnlyProjectUnits Value="True"/>
-      </Flags>
-      <SessionStorage Value="InProjectDir"/>
-      <MainUnit Value="0"/>
-      <ResourceType Value="res"/>
-    </General>
-    <i18n>
-      <EnableI18N LFM="False"/>
-    </i18n>
-    <VersionInfo>
-      <StringTable ProductVersion=""/>
-    </VersionInfo>
-    <BuildModes Count="2">
-      <Item1 Name="Default" Default="True"/>
-      <Item2 Name="Debug">
-        <CompilerOptions>
-          <Version Value="11"/>
-          <PathDelim Value="\"/>
-          <SearchPaths>
-            <IncludeFiles Value="$(ProjOutDir)"/>
-          </SearchPaths>
-          <Linking>
-            <Debugging>
-              <DebugInfoType Value="dsStabs"/>
-            </Debugging>
-          </Linking>
-          <Other>
-            <CompilerMessages>
-              <UseMsgFile Value="True"/>
-            </CompilerMessages>
-            <CompilerPath Value="$(CompPath)"/>
-          </Other>
-        </CompilerOptions>
-      </Item2>
-    </BuildModes>
-    <PublishOptions>
-      <Version Value="2"/>
-      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
-      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
-    </PublishOptions>
-    <RunParams>
-      <local>
-        <FormatVersion Value="1"/>
-        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
-      </local>
-    </RunParams>
-    <RequiredPackages Count="1">
-      <Item1>
-        <PackageName Value="FCL"/>
-      </Item1>
-    </RequiredPackages>
-    <Units Count="2">
-      <Unit0>
-        <Filename Value="XMLXSDExportTest.lpr"/>
-        <IsPartOfProject Value="True"/>
-        <UnitName Value="XMLXSDExportTest"/>
-      </Unit0>
-      <Unit1>
-        <Filename Value="xmlxsdexporttestcase1.pas"/>
-        <IsPartOfProject Value="True"/>
-        <UnitName Value="XMLXSDExportTestCase1"/>
-      </Unit1>
-    </Units>
-  </ProjectOptions>
-  <CompilerOptions>
-    <Version Value="11"/>
-    <PathDelim Value="\"/>
-    <Target>
-      <Filename Value="XMLXSDExportTest"/>
-    </Target>
-    <SearchPaths>
-      <IncludeFiles Value="$(ProjOutDir)"/>
-      <UnitOutputDirectory Value="units\$(TargetCPU)-$(TargetOS)\"/>
-    </SearchPaths>
-    <Other>
-      <CompilerMessages>
-        <UseMsgFile Value="True"/>
-      </CompilerMessages>
-      <CompilerPath Value="$(CompPath)"/>
-    </Other>
-  </CompilerOptions>
-  <Debugging>
-    <Exceptions Count="3">
-      <Item1>
-        <Name Value="EAbort"/>
-      </Item1>
-      <Item2>
-        <Name Value="ECodetoolError"/>
-      </Item2>
-      <Item3>
-        <Name Value="EFOpenError"/>
-      </Item3>
-    </Exceptions>
-  </Debugging>
-</CONFIG>

+ 0 - 27
packages/fcl-db/tests/XMLXSDExportTest.lpr

@@ -1,27 +0,0 @@
-program XMLXSDExportTest;
-
-{$mode objfpc}{$H+}
-
-uses
-  Classes,
-  consoletestrunner,
-  XMLXSDExportTestCase1;
-
-type
-
-  { TLazTestRunner }
-
-  TMyTestRunner = class(TTestRunner)
-  protected
-    // override the protected methods of TTestRunner to customize its behavior
-  end;
-
-var
-  Application: TMyTestRunner;
-
-begin
-  Application := TMyTestRunner.Create(nil);
-  Application.Initialize;
-  Application.Run;
-  Application.Free;
-end.

+ 0 - 113
packages/fcl-db/tests/dbfexporttest.lpi

@@ -1,113 +0,0 @@
-<?xml version="1.0"?>
-<CONFIG>
-  <ProjectOptions>
-    <Version Value="9"/>
-    <PathDelim Value="\"/>
-    <General>
-      <Flags>
-        <SaveOnlyProjectUnits Value="True"/>
-      </Flags>
-      <SessionStorage Value="InProjectDir"/>
-      <MainUnit Value="0"/>
-      <Title Value="dbfexporttest"/>
-      <ResourceType Value="res"/>
-    </General>
-    <i18n>
-      <EnableI18N LFM="False"/>
-    </i18n>
-    <VersionInfo>
-      <StringTable ProductVersion=""/>
-    </VersionInfo>
-    <BuildModes Count="2">
-      <Item1 Name="Default" Default="True"/>
-      <Item2 Name="Debug">
-        <CompilerOptions>
-          <Version Value="11"/>
-          <PathDelim Value="\"/>
-          <SearchPaths>
-            <IncludeFiles Value="$(ProjOutDir)"/>
-          </SearchPaths>
-          <CodeGeneration>
-            <Checks>
-              <IOChecks Value="True"/>
-              <RangeChecks Value="True"/>
-              <OverflowChecks Value="True"/>
-              <StackChecks Value="True"/>
-            </Checks>
-          </CodeGeneration>
-          <Linking>
-            <Debugging>
-              <DebugInfoType Value="dsDwarf2Set"/>
-              <UseHeaptrc Value="True"/>
-            </Debugging>
-          </Linking>
-          <Other>
-            <CompilerMessages>
-              <UseMsgFile Value="True"/>
-            </CompilerMessages>
-            <CompilerPath Value="$(CompPath)"/>
-          </Other>
-        </CompilerOptions>
-      </Item2>
-    </BuildModes>
-    <PublishOptions>
-      <Version Value="2"/>
-      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
-      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
-    </PublishOptions>
-    <RunParams>
-      <local>
-        <FormatVersion Value="1"/>
-        <CommandLineParams Value="-a --format=plain"/>
-        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
-      </local>
-    </RunParams>
-    <RequiredPackages Count="1">
-      <Item1>
-        <PackageName Value="FCL"/>
-      </Item1>
-    </RequiredPackages>
-    <Units Count="2">
-      <Unit0>
-        <Filename Value="dbfexporttest.lpr"/>
-        <IsPartOfProject Value="True"/>
-        <UnitName Value="dbfexporttest"/>
-      </Unit0>
-      <Unit1>
-        <Filename Value="dbfexporttestcase1.pas"/>
-        <IsPartOfProject Value="True"/>
-        <UnitName Value="dbfexporttestcase1"/>
-      </Unit1>
-    </Units>
-  </ProjectOptions>
-  <CompilerOptions>
-    <Version Value="11"/>
-    <PathDelim Value="\"/>
-    <Target>
-      <Filename Value="dbfexporttest"/>
-    </Target>
-    <SearchPaths>
-      <IncludeFiles Value="$(ProjOutDir)"/>
-      <UnitOutputDirectory Value="units\$(TargetCPU)-$(TargetOS)"/>
-    </SearchPaths>
-    <Other>
-      <CompilerMessages>
-        <UseMsgFile Value="True"/>
-      </CompilerMessages>
-      <CompilerPath Value="$(CompPath)"/>
-    </Other>
-  </CompilerOptions>
-  <Debugging>
-    <Exceptions Count="3">
-      <Item1>
-        <Name Value="EAbort"/>
-      </Item1>
-      <Item2>
-        <Name Value="ECodetoolError"/>
-      </Item2>
-      <Item3>
-        <Name Value="EFOpenError"/>
-      </Item3>
-    </Exceptions>
-  </Debugging>
-</CONFIG>

+ 0 - 28
packages/fcl-db/tests/dbfexporttest.lpr

@@ -1,28 +0,0 @@
-program dbfexporttest;
-
-{$mode objfpc}{$H+}
-
-uses
-  Classes,
-  consoletestrunner,
-  dbfexporttestcase1;
-
-type
-
-  { TLazTestRunner }
-
-  TMyTestRunner = class(TTestRunner)
-  protected
-    // override the protected methods of TTestRunner to customize its behavior
-  end;
-
-var
-  Application: TMyTestRunner;
-
-begin
-  Application := TMyTestRunner.Create(nil);
-  Application.Initialize;
-  Application.Run;
-  Application.Free;
-end.
-

+ 1 - 0
packages/fcl-db/tests/dbtestframework.pas

@@ -25,6 +25,7 @@ uses
   TestDBBasics,
   TestBufDatasetStreams,
   TestSpecificTBufDataset,
+  TestDBExport,
   consoletestrunner;
 
 Procedure LegacyOutput;

+ 7 - 4
packages/fcl-db/tests/dbtestframework_gui.lpi

@@ -42,16 +42,19 @@
         <FormatVersion Value="1"/>
       </local>
     </RunParams>
-    <RequiredPackages Count="3">
+    <RequiredPackages Count="4">
       <Item1>
-        <PackageName Value="FPCUnitTestRunner"/>
+        <PackageName Value="SynEdit"/>
       </Item1>
       <Item2>
-        <PackageName Value="LCL"/>
+        <PackageName Value="FPCUnitTestRunner"/>
       </Item2>
       <Item3>
-        <PackageName Value="FCL"/>
+        <PackageName Value="LCL"/>
       </Item3>
+      <Item4>
+        <PackageName Value="FCL"/>
+      </Item4>
     </RequiredPackages>
     <Units Count="1">
       <Unit0>

+ 17 - 2
packages/fcl-db/tests/dbtestframework_gui.lpr

@@ -10,7 +10,9 @@ program dbtestframework_gui;
 // the .ppu files before you can build fcl-db in the regular way. (Using fpmake)
 
 uses
-  Interfaces, Forms, GuiTestRunner,
+  Interfaces, Forms,
+  // GUI:
+  GuiTestRunner, inieditor,
   // Generic DB test framework units
   ToolsUnit,
   // Connectors for different database-types
@@ -26,12 +28,25 @@ uses
   TestDBBasics,
   TestDatasources,
   TestBufDatasetStreams,
-  TestSpecificTBufDataset;
+  TestSpecificTBufDataset,
+  TestDBExport;
 
 {$R *.res}
 
+var
+  DBSelectForm: TFormIniEditor;
 begin
   Application.Initialize;
+  DBSelectForm:=TFormIniEditor.Create(nil);
+  try
+    DBSelectForm.INIFile:='database.ini';
+    DBSelectForm.ProfileSelectSection:='Database';
+    DBSelectForm.ProfileSelectKey:='type';
+    // We can ignore resulting db selection as the file is saved already:
+    DBSelectForm.ShowModal;
+  finally
+    DBSelectForm.Free;
+  end;
   Application.CreateForm(TGuiTestRunner, TestRunner);
   Application.Run;
 end.

+ 579 - 0
packages/fcl-db/tests/inieditor.lfm

@@ -0,0 +1,579 @@
+object FormIniEditor: TFormIniEditor
+  Left = 238
+  Height = 501
+  Top = 145
+  Width = 754
+  Caption = 'Select/edit profile'
+  ClientHeight = 501
+  ClientWidth = 754
+  OnCloseQuery = FormCloseQuery
+  OnCreate = FormCreate
+  OnDestroy = FormDestroy
+  OnDropFiles = FormDropFiles
+  OnShow = FormShow
+  LCLVersion = '1.1'
+  inline SynMemo: TSynMemo
+    Cursor = crIBeam
+    Left = 8
+    Height = 360
+    Top = 88
+    Width = 736
+    Font.Height = -13
+    Font.Name = 'Courier New'
+    Font.Pitch = fpFixed
+    Font.Quality = fqNonAntialiased
+    ParentColor = False
+    ParentFont = False
+    TabOrder = 2
+    Gutter.Width = 57
+    Gutter.MouseActions = <>
+    Highlighter = SynIniHighlighter
+    Keystrokes = <    
+      item
+        Command = ecUp
+        ShortCut = 38
+      end    
+      item
+        Command = ecSelUp
+        ShortCut = 8230
+      end    
+      item
+        Command = ecScrollUp
+        ShortCut = 16422
+      end    
+      item
+        Command = ecDown
+        ShortCut = 40
+      end    
+      item
+        Command = ecSelDown
+        ShortCut = 8232
+      end    
+      item
+        Command = ecScrollDown
+        ShortCut = 16424
+      end    
+      item
+        Command = ecLeft
+        ShortCut = 37
+      end    
+      item
+        Command = ecSelLeft
+        ShortCut = 8229
+      end    
+      item
+        Command = ecWordLeft
+        ShortCut = 16421
+      end    
+      item
+        Command = ecSelWordLeft
+        ShortCut = 24613
+      end    
+      item
+        Command = ecRight
+        ShortCut = 39
+      end    
+      item
+        Command = ecSelRight
+        ShortCut = 8231
+      end    
+      item
+        Command = ecWordRight
+        ShortCut = 16423
+      end    
+      item
+        Command = ecSelWordRight
+        ShortCut = 24615
+      end    
+      item
+        Command = ecPageDown
+        ShortCut = 34
+      end    
+      item
+        Command = ecSelPageDown
+        ShortCut = 8226
+      end    
+      item
+        Command = ecPageBottom
+        ShortCut = 16418
+      end    
+      item
+        Command = ecSelPageBottom
+        ShortCut = 24610
+      end    
+      item
+        Command = ecPageUp
+        ShortCut = 33
+      end    
+      item
+        Command = ecSelPageUp
+        ShortCut = 8225
+      end    
+      item
+        Command = ecPageTop
+        ShortCut = 16417
+      end    
+      item
+        Command = ecSelPageTop
+        ShortCut = 24609
+      end    
+      item
+        Command = ecLineStart
+        ShortCut = 36
+      end    
+      item
+        Command = ecSelLineStart
+        ShortCut = 8228
+      end    
+      item
+        Command = ecEditorTop
+        ShortCut = 16420
+      end    
+      item
+        Command = ecSelEditorTop
+        ShortCut = 24612
+      end    
+      item
+        Command = ecLineEnd
+        ShortCut = 35
+      end    
+      item
+        Command = ecSelLineEnd
+        ShortCut = 8227
+      end    
+      item
+        Command = ecEditorBottom
+        ShortCut = 16419
+      end    
+      item
+        Command = ecSelEditorBottom
+        ShortCut = 24611
+      end    
+      item
+        Command = ecToggleMode
+        ShortCut = 45
+      end    
+      item
+        Command = ecCopy
+        ShortCut = 16429
+      end    
+      item
+        Command = ecPaste
+        ShortCut = 8237
+      end    
+      item
+        Command = ecDeleteChar
+        ShortCut = 46
+      end    
+      item
+        Command = ecCut
+        ShortCut = 8238
+      end    
+      item
+        Command = ecDeleteLastChar
+        ShortCut = 8
+      end    
+      item
+        Command = ecDeleteLastChar
+        ShortCut = 8200
+      end    
+      item
+        Command = ecDeleteLastWord
+        ShortCut = 16392
+      end    
+      item
+        Command = ecUndo
+        ShortCut = 32776
+      end    
+      item
+        Command = ecRedo
+        ShortCut = 40968
+      end    
+      item
+        Command = ecLineBreak
+        ShortCut = 13
+      end    
+      item
+        Command = ecSelectAll
+        ShortCut = 16449
+      end    
+      item
+        Command = ecCopy
+        ShortCut = 16451
+      end    
+      item
+        Command = ecBlockIndent
+        ShortCut = 24649
+      end    
+      item
+        Command = ecLineBreak
+        ShortCut = 16461
+      end    
+      item
+        Command = ecInsertLine
+        ShortCut = 16462
+      end    
+      item
+        Command = ecDeleteWord
+        ShortCut = 16468
+      end    
+      item
+        Command = ecBlockUnindent
+        ShortCut = 24661
+      end    
+      item
+        Command = ecPaste
+        ShortCut = 16470
+      end    
+      item
+        Command = ecCut
+        ShortCut = 16472
+      end    
+      item
+        Command = ecDeleteLine
+        ShortCut = 16473
+      end    
+      item
+        Command = ecDeleteEOL
+        ShortCut = 24665
+      end    
+      item
+        Command = ecUndo
+        ShortCut = 16474
+      end    
+      item
+        Command = ecRedo
+        ShortCut = 24666
+      end    
+      item
+        Command = ecGotoMarker0
+        ShortCut = 16432
+      end    
+      item
+        Command = ecGotoMarker1
+        ShortCut = 16433
+      end    
+      item
+        Command = ecGotoMarker2
+        ShortCut = 16434
+      end    
+      item
+        Command = ecGotoMarker3
+        ShortCut = 16435
+      end    
+      item
+        Command = ecGotoMarker4
+        ShortCut = 16436
+      end    
+      item
+        Command = ecGotoMarker5
+        ShortCut = 16437
+      end    
+      item
+        Command = ecGotoMarker6
+        ShortCut = 16438
+      end    
+      item
+        Command = ecGotoMarker7
+        ShortCut = 16439
+      end    
+      item
+        Command = ecGotoMarker8
+        ShortCut = 16440
+      end    
+      item
+        Command = ecGotoMarker9
+        ShortCut = 16441
+      end    
+      item
+        Command = ecSetMarker0
+        ShortCut = 24624
+      end    
+      item
+        Command = ecSetMarker1
+        ShortCut = 24625
+      end    
+      item
+        Command = ecSetMarker2
+        ShortCut = 24626
+      end    
+      item
+        Command = ecSetMarker3
+        ShortCut = 24627
+      end    
+      item
+        Command = ecSetMarker4
+        ShortCut = 24628
+      end    
+      item
+        Command = ecSetMarker5
+        ShortCut = 24629
+      end    
+      item
+        Command = ecSetMarker6
+        ShortCut = 24630
+      end    
+      item
+        Command = ecSetMarker7
+        ShortCut = 24631
+      end    
+      item
+        Command = ecSetMarker8
+        ShortCut = 24632
+      end    
+      item
+        Command = ecSetMarker9
+        ShortCut = 24633
+      end    
+      item
+        Command = EcFoldLevel1
+        ShortCut = 41009
+      end    
+      item
+        Command = EcFoldLevel2
+        ShortCut = 41010
+      end    
+      item
+        Command = EcFoldLevel1
+        ShortCut = 41011
+      end    
+      item
+        Command = EcFoldLevel1
+        ShortCut = 41012
+      end    
+      item
+        Command = EcFoldLevel1
+        ShortCut = 41013
+      end    
+      item
+        Command = EcFoldLevel6
+        ShortCut = 41014
+      end    
+      item
+        Command = EcFoldLevel7
+        ShortCut = 41015
+      end    
+      item
+        Command = EcFoldLevel8
+        ShortCut = 41016
+      end    
+      item
+        Command = EcFoldLevel9
+        ShortCut = 41017
+      end    
+      item
+        Command = EcFoldLevel0
+        ShortCut = 41008
+      end    
+      item
+        Command = EcFoldCurrent
+        ShortCut = 41005
+      end    
+      item
+        Command = EcUnFoldCurrent
+        ShortCut = 41003
+      end    
+      item
+        Command = EcToggleMarkupWord
+        ShortCut = 32845
+      end    
+      item
+        Command = ecNormalSelect
+        ShortCut = 24654
+      end    
+      item
+        Command = ecColumnSelect
+        ShortCut = 24643
+      end    
+      item
+        Command = ecLineSelect
+        ShortCut = 24652
+      end    
+      item
+        Command = ecTab
+        ShortCut = 9
+      end    
+      item
+        Command = ecShiftTab
+        ShortCut = 8201
+      end    
+      item
+        Command = ecMatchBracket
+        ShortCut = 24642
+      end    
+      item
+        Command = ecColSelUp
+        ShortCut = 40998
+      end    
+      item
+        Command = ecColSelDown
+        ShortCut = 41000
+      end    
+      item
+        Command = ecColSelLeft
+        ShortCut = 40997
+      end    
+      item
+        Command = ecColSelRight
+        ShortCut = 40999
+      end    
+      item
+        Command = ecColSelPageDown
+        ShortCut = 40994
+      end    
+      item
+        Command = ecColSelPageBottom
+        ShortCut = 57378
+      end    
+      item
+        Command = ecColSelPageUp
+        ShortCut = 40993
+      end    
+      item
+        Command = ecColSelPageTop
+        ShortCut = 57377
+      end    
+      item
+        Command = ecColSelLineStart
+        ShortCut = 40996
+      end    
+      item
+        Command = ecColSelLineEnd
+        ShortCut = 40995
+      end    
+      item
+        Command = ecColSelEditorTop
+        ShortCut = 57380
+      end    
+      item
+        Command = ecColSelEditorBottom
+        ShortCut = 57379
+      end>
+    MouseActions = <>
+    MouseSelActions = <>
+    Lines.Strings = (
+      ''
+    )
+    SelectedColor.BackPriority = 50
+    SelectedColor.ForePriority = 50
+    SelectedColor.FramePriority = 50
+    SelectedColor.BoldPriority = 50
+    SelectedColor.ItalicPriority = 50
+    SelectedColor.UnderlinePriority = 50
+    OnStatusChange = SynMemoStatusChange
+    inline SynLeftGutterPartList1: TSynGutterPartList
+      object SynGutterMarks1: TSynGutterMarks
+        Width = 24
+        MouseActions = <>
+      end
+      object SynGutterLineNumber1: TSynGutterLineNumber
+        Width = 17
+        MouseActions = <>
+        MarkupInfo.Background = clBtnFace
+        MarkupInfo.Foreground = clNone
+        DigitCount = 2
+        ShowOnlyLineNumbersMultiplesOf = 1
+        ZeroStart = False
+        LeadingZeros = False
+      end
+      object SynGutterChanges1: TSynGutterChanges
+        Width = 4
+        MouseActions = <>
+        ModifiedColor = 59900
+        SavedColor = clGreen
+      end
+      object SynGutterSeparator1: TSynGutterSeparator
+        Width = 2
+        MouseActions = <>
+      end
+      object SynGutterCodeFolding1: TSynGutterCodeFolding
+        MouseActions = <>
+        MarkupInfo.Background = clNone
+        MarkupInfo.Foreground = clGray
+        MouseActionsExpanded = <>
+        MouseActionsCollapsed = <>
+      end
+    end
+  end
+  object FileNameEdit: TFileNameEdit
+    Left = 56
+    Height = 23
+    Top = 24
+    Width = 368
+    OnAcceptFileName = FileNameEditAcceptFileName
+    FilterIndex = 0
+    HideDirectories = False
+    ButtonWidth = 23
+    NumGlyphs = 1
+    MaxLength = 0
+    TabOrder = 0
+  end
+  object INIFileLabel: TLabel
+    Left = 8
+    Height = 15
+    Top = 24
+    Width = 34
+    Caption = 'INI file'
+    ParentColor = False
+  end
+  object ProfileSelect: TComboBox
+    Left = 56
+    Height = 23
+    Hint = 'Choose the profile you want to enable'
+    Top = 61
+    Width = 164
+    ItemHeight = 15
+    OnSelect = ProfileSelectSelect
+    Sorted = True
+    TabOrder = 1
+  end
+  object ProfileLabel: TLabel
+    Left = 8
+    Height = 15
+    Top = 64
+    Width = 34
+    Caption = 'Profile'
+    ParentColor = False
+  end
+  object OKButton: TButton
+    Left = 664
+    Height = 25
+    Top = 456
+    Width = 75
+    Caption = '&OK'
+    Default = True
+    ModalResult = 1
+    TabOrder = 4
+  end
+  object CancelButton: TButton
+    Left = 568
+    Height = 25
+    Top = 456
+    Width = 75
+    Cancel = True
+    Caption = '&Cancel'
+    ModalResult = 2
+    OnClick = CancelButtonClick
+    TabOrder = 3
+  end
+  object SynIniHighlighter: TSynIniSyn
+    DefaultFilter = 'INI Files (*.ini)|*.ini'
+    Enabled = False
+    CommentAttri.FrameEdges = sfeAround
+    TextAttri.FrameEdges = sfeAround
+    SectionAttri.FrameEdges = sfeAround
+    KeyAttri.FrameEdges = sfeAround
+    NumberAttri.FrameEdges = sfeAround
+    SpaceAttri.FrameEdges = sfeAround
+    StringAttri.FrameEdges = sfeAround
+    SymbolAttri.FrameEdges = sfeAround
+    left = 32
+    top = 456
+  end
+  object GUITimer: TIdleTimer
+    AutoEnabled = True
+    OnTimer = GUITimerTimer
+    left = 560
+    top = 16
+  end
+end

+ 251 - 0
packages/fcl-db/tests/inieditor.pas

@@ -0,0 +1,251 @@
+unit inieditor;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, FileUtil, Forms, Controls,
+  Graphics, Dialogs, StdCtrls, EditBtn, ExtCtrls,
+  IniFiles, lazutf8, SynEdit,SynMemo,{SynEditTypes,}SynHighlighterIni, SynEditTypes;
+
+type
+
+  { TFormIniEditor }
+
+  TFormIniEditor = class(TForm)
+    GUITimer: TIdleTimer;
+    OKButton: TButton;
+    CancelButton: TButton;
+    ProfileSelect: TComboBox;
+    FileNameEdit: TFileNameEdit;
+    INIFileLabel: TLabel;
+    ProfileLabel: TLabel;
+    SynIniHighlighter: TSynIniSyn;
+    SynMemo: TSynMemo;
+    procedure CancelButtonClick(Sender: TObject);
+
+    procedure FileNameEditAcceptFileName(Sender: TObject; var Value: String);
+    procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
+    procedure FormCreate(Sender: TObject);
+    procedure FormDestroy(Sender: TObject);
+    procedure FormDropFiles(Sender: TObject; const FileNames: array of String);
+    procedure FormShow(Sender: TObject);
+    procedure GUITimerTimer(Sender: TObject);
+    procedure ProfileSelectSelect(Sender: TObject);
+    procedure SynMemoStatusChange(Sender: TObject; Changes: TSynStatusChanges);
+  private
+    FIniFilename: string;
+    FIniStream: TMemoryStream;
+    FMustReloadProfileSelect: boolean;
+    FSaveChanges: boolean; //If off, don't save any changes (e.g. when canceling form)
+    FProfileSelectKey: string;
+    FProfileSelectSection: string;
+    FProfileSelectValue: string;
+    procedure LoadGUI(KeepCursorPosition: boolean; LoadSynmemo: boolean; LoadProfileselect: boolean); //Loads GUI elements from backing stream
+    procedure SetIniFilename(AValue: string); //Loads file into stream
+    procedure SetProfileSelectKey(AValue: string);
+    procedure SetProfileSelectSection(AValue: string);
+    // Saves synmemo contents to memory stream and optionally to file, too
+    procedure SynMemoSave(AlsoToFile: boolean);
+    { private declarations }
+  public
+    // File to be edited/viewed:
+    property INIFile: string read FIniFilename write SetIniFilename;
+    // Section name where profile selection is to be stored. If nothing, the root/top level will be used
+    property ProfileSelectSection: string read FProfileSelectSection write SetProfileSelectSection;
+    // Key to be used for storing selected profile
+    // If empty, don't use the select profile combobox
+    property ProfileSelectKey: string read FProfileSelectKey write SetProfileSelectKey;
+    // The value the user selected
+    property ProfileSelectValue: string read FProfileSelectValue;
+  end;
+
+var
+  Form1: TFormIniEditor;
+
+implementation
+
+{$R *.lfm}
+
+{ TFormIniEditor }
+
+
+procedure TFormIniEditor.FormDropFiles(Sender: TObject;
+  const FileNames: array of String);
+begin
+  // Go through property for reload file+reload GUI code
+  IniFile:=FileNames[0];
+end;
+
+procedure TFormIniEditor.FormShow(Sender: TObject);
+begin
+  if FileNameEdit.FileName='' then
+    FileNameEdit.FileName:=ExpandFileNameUTF8(FIniFilename);
+end;
+
+procedure TFormIniEditor.GUITimerTimer(Sender: TObject);
+begin
+  if FMustReloadProfileSelect then
+    LoadGUI(true,false,true);
+end;
+
+procedure TFormIniEditor.ProfileSelectSelect(Sender: TObject);
+// Save selected profile
+var
+  MyIniFile: TIniFile;
+begin
+  FProfileSelectValue:=ProfileSelect.Text;
+  if FProfileSelectValue<>'' then
+  begin
+    // Save any changes in synmemo
+    SynMemoSave(false);
+    FIniStream.Position:=0; //Load from beginning
+    MyIniFile := TIniFile.Create(FIniStream, True);
+    FIniStream.Position:=0; //Needed to save again
+    try
+      MyIniFile.WriteString(FProfileSelectSection,FProfileSelectKey,FProfileSelectValue);
+    finally
+      MyIniFile.Free;
+    end;
+    LoadGUI(true,true,true);
+  end;
+end;
+
+procedure TFormIniEditor.SynMemoStatusChange(Sender: TObject;
+  Changes: TSynStatusChanges);
+begin
+  // If user edits the profile name directly or edits/deletes/adds
+  // one of the section names, the combobox will need to be refreshed.
+  // Pass this on to a timer so it gets done without disturbing the updates
+  if (FMustReloadProfileSelect=false) and (scModified in Changes) then
+  begin
+    //todo: test for section line or key=value
+    FMustReloadProfileSelect:=true;
+  end;
+end;
+
+procedure TFormIniEditor.LoadGUI(KeepCursorPosition: boolean; LoadSynmemo: boolean; LoadProfileselect: boolean);
+var
+  MyIniFile : TIniFile;
+  OldPos: TPoint;
+  ProfIndex: integer;
+  Sections: TStringList;
+begin
+  SynMemo.BeginUpdate(false);
+  if LoadSynMemo then
+  begin
+    OldPos:=SynMemo.CaretXY;
+    FIniStream.Position:=0; //Load from beginning
+    SynMemo.Lines.LoadFromStream(FIniStream);
+  end;
+  FIniStream.Position:=0; //Load from beginning
+  MyIniFile := TIniFile.Create(FIniStream, True);
+  FIniStream.Position:=0; //In case we want to save
+  Sections:=TStringList.Create;
+  try
+    if LoadProfileselect then
+    begin
+      Sections.Sorted:=true;
+      MyIniFile.ReadSections(Sections);
+      // Now take out the one where the profile is stored as it will confuse users
+      if Sections.Find(FProfileSelectSection, ProfIndex) then
+        Sections.Delete(ProfIndex);
+      ProfileSelect.Clear;
+      ProfileSelect.Items.AddStrings(Sections);
+      FProfileSelectValue:=MyIniFile.ReadString(FProfileSelectSection,FProfileSelectKey,'');
+      ProfileSelect.Text:=FProfileSelectValue;
+      FMustReloadProfileSelect:=false;
+    end;
+
+    // restore cursor/caret position
+    if LoadSynMemo and KeepCursorPosition then
+      SynMemo.CaretXY:=OldPos;
+  finally
+    MyIniFile.Free;
+    Sections.Free;
+    SynMemo.EndUpdate;
+  end;
+end;
+
+procedure TFormIniEditor.SetIniFilename(AValue: string);
+begin
+  if FIniFilename=AValue then Exit;
+  FIniFilename:=AValue;
+  if FIniFileName<>'' then
+  begin
+    try
+      FIniStream.Clear;
+      FIniStream.LoadFromFile(FIniFilename);
+    except
+      on E: Exception do
+        ShowMessage('Error loading file '+FIniFilename+': '+E.Message);
+    end;
+    LoadGUI(false,true,true);
+  end;
+end;
+
+procedure TFormIniEditor.SetProfileSelectKey(AValue: string);
+begin
+  if FProfileSelectKey=AValue then Exit;
+  FProfileSelectKey:=AValue;
+  if (FProfileSelectKey<>'') and (FProfileSelectSection<>'') then
+    LoadGUI(false,true,true);
+end;
+
+procedure TFormIniEditor.SetProfileSelectSection(AValue: string);
+begin
+  if FProfileSelectSection=AValue then Exit;
+  FProfileSelectSection:=AValue;
+  if (FProfileSelectKey<>'') and (FProfileSelectSection<>'') then
+    LoadGUI(false,true,true);
+end;
+
+procedure TFormIniEditor.SynMemoSave(AlsoToFile: boolean);
+begin
+  if FSaveChanges then
+  begin
+    FIniStream.Clear;
+    FIniStream.Position:=0; //Save from beginning
+    SynMemo.Lines.SaveToStream(FiniStream);
+    FIniStream.Position:=0; //Save from beginning
+    if AlsoToFile and (FIniFileName<>'') then
+      FIniStream.SaveToFile(FIniFilename);
+  end;
+end;
+
+
+procedure TFormIniEditor.CancelButtonClick(Sender: TObject);
+begin
+  FSaveChanges:=false;
+end;
+
+
+
+procedure TFormIniEditor.FileNameEditAcceptFileName(Sender: TObject;
+  var Value: String);
+begin
+  // go through the property to load new file
+  INIFile:=Value;
+end;
+
+procedure TFormIniEditor.FormCloseQuery(Sender: TObject; var CanClose: boolean);
+begin
+  // Save any uncommitted changes
+  //todo: only if dirty synmemo changestamp?; also check if this is best event
+  SynMemoSave(true);
+end;
+
+procedure TFormIniEditor.FormCreate(Sender: TObject);
+begin
+  FIniStream:=TMemoryStream.Create;
+  FSaveChanges:=true; //allow editing
+end;
+
+procedure TFormIniEditor.FormDestroy(Sender: TObject);
+begin
+  FIniStream.Free;
+end;
+
+end.
+

+ 20 - 11
packages/fcl-db/tests/testdbbasics.pas

@@ -244,7 +244,10 @@ begin
     begin
     Open;
 
-    CheckEquals(1,RecNo);
+    if IsUniDirectional then
+      CheckEquals(-1,RecNo)
+    else
+      CheckEquals(1,RecNo);
     CheckEquals(1,RecordCount);
 
     CheckEquals(2,FieldCount);
@@ -2007,6 +2010,9 @@ begin
 end;
 
 procedure TTestBufDatasetDBBasics.TestIndexEditRecord;
+// Tests index sorting for string field type by
+// editing an existing record in the middle
+// with a value at the end of the alphabet
 var ds : TCustomBufDataset;
     AFieldType : TFieldType;
     i : integer;
@@ -2019,22 +2025,25 @@ begin
     AFieldType:=ftString;
     AddIndex('testindex','F'+FieldTypeNames[AfieldType],[]);
     IndexName:='testindex';
-    open;
+    open; //Record 0
     OldStringValue:=FieldByName('F'+FieldTypeNames[AfieldType]).AsString;
-    next;
-    CheckTrue(OldStringValue<=FieldByName('F'+FieldTypeNames[AfieldType]).AsString);
+    next; //Now on record 1
+    CheckTrue(OldStringValue<=FieldByName('F'+FieldTypeNames[AfieldType]).AsString,'Record 0 must be smaller than record 1 with asc sorted index');
     OldStringValue:=FieldByName('F'+FieldTypeNames[AfieldType]).AsString;
-    next;
-    CheckTrue(AnsiCompareStr(OldStringValue,FieldByName('F'+FieldTypeNames[AfieldType]).AsString)<=0);
-    prior;
-    
+    next; //Now on record 2
+    CheckTrue(AnsiCompareStr(OldStringValue,FieldByName('F'+FieldTypeNames[AfieldType]).AsString)<=0,'Record 1 must be smaller than record 2 with asc sorted index');
+
+    prior; //Now on record 1
     edit;
-    FieldByName('F'+FieldTypeNames[AfieldType]).AsString := 'ZZZ';
+    FieldByName('F'+FieldTypeNames[AfieldType]).AsString := 'ZZZ'; //should be sorted last
     post;
-    prior;
+
+    prior; // Now on record 0
+    // Check ZZZ is sorted on/after record 0
     CheckTrue(AnsiCompareStr('ZZZ',FieldByName('F'+FieldTypeNames[AfieldType]).AsString)>=0, 'Prior>');
     next;
-    next;
+    next; // Now on record 2
+    // Check ZZZ is sorted on/before record 2
     CheckTrue(AnsiCompareStr('ZZZ',FieldByName('F'+FieldTypeNames[AfieldType]).AsString)<=0, 'Next<');
     close;
     end;

+ 703 - 0
packages/fcl-db/tests/testdbexport.pas

@@ -0,0 +1,703 @@
+unit TestDBExport;
+
+{
+  Unit tests which are common to all datasets. Tests export to various formats.
+}
+
+{$IFDEF FPC}
+  {$mode Delphi}{$H+}
+{$ENDIF}
+
+interface
+
+uses
+  fpcunit, testregistry,
+  Classes, SysUtils, db, ToolsUnit, bufdataset,
+  fpDBExport, fpXMLXSDExport, fpdbfexport, fpcsvexport, fpfixedexport,
+  fpSimpleXMLExport, fpsimplejsonexport, fpSQLExport,
+  fptexexport, fprtfexport;
+
+
+type
+  TDetailedExportFormats = (efDBaseIII, efDBaseIV, efDBaseVII, efCSV, efFixedLengthText, efFoxpro,
+    efJSON, efRTF, efSQL, efTeX, efXML, efXMLXSDAccess, efXMLXSDADONet, efXMLXSDClientDataset, efXMLXSDExcel);
+const
+  TDetailedExportExtensions: array [TDetailedExportFormats] of string[5] =
+    ('.dbf','.dbf','.dbf','.csv','.txt','.dbf','.json','.rtf','.sql','.tex',
+    '.xml','.xml','.xml','.xml','.xml'); //File extension for the corresponding TExportFormat
+type
+  { TTestDBExport }
+  TTestDBExport = class(TTestCase)
+  private
+    FExportTempDir: string; //directory where test files are placed
+    FKeepFilesAfterTest: boolean; //remove files after testing?
+    function FieldSupported(const FieldType: TFieldType;
+      const ExportSubFormat: TDetailedExportFormats): boolean; //Checks if output dataset supports a certain field type
+    procedure GenericExportTest(Exporter: TCustomDatasetExporter; ExportFormat: TDetailedExportFormats);
+    function GetFileSize(const FileName: string): integer; //Gets a file's size
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+    procedure TestDBFExport_DBaseIV;
+    procedure TestDBFExport_DBaseVII;
+    procedure TestDBFExport_FoxPro;
+    procedure TestCSVExport; //tests csv export with default values
+    procedure TestCSVExport_RFC4180WithHeader; //tests csv export with settings that match RFC4180
+    procedure TestCSVExport_TweakSettingsSemicolon; //tests semicolon delimited, custom country values
+    procedure TestFixedTextExport;
+    procedure TestJSONExport;
+    procedure TestRTFExport;
+    procedure TestSQLExport;
+    procedure TestTeXExport;
+    procedure TestXMLExport; //tests simple xml export
+    procedure TestXSDExport_Access_NoXSD_DecimalOverride; //tests xmlxsd export
+    procedure TestXSDExport_Access_NoXSD_NoDecimalOverride; //tests xmlxsd export
+    procedure TestXSDExport_Access_XSD_DecimalOverride; //tests xmlxsd export
+    procedure TestXSDExport_Access_XSD_NoDecimalOverride; //tests xmlxsd export
+    procedure TestXSDExport_ADONET_NoXSD; //tests xmlxsd export
+    procedure TestXSDExport_ADONET_XSD; //tests xmlxsd export
+    procedure TestXSDExport_DelphiClientDataset; //tests xmlxsd export
+    procedure TestXSDExport_Excel; //tests xmlxsd export
+  end;
+
+implementation
+
+function TTestDBExport.FieldSupported(const FieldType: TFieldType;
+  const ExportSubFormat: TDetailedExportFormats): boolean;
+const
+  DBaseVIIUnsupported=[ftUnknown,ftCurrency,ftBCD,ftTime,ftBytes,ftVarBytes,ftGraphic,ftFmtMemo,ftParadoxOle,ftTypedBinary,ftCursor,ftADT,ftArray,ftReference,ftDataSet,ftOraBlob,ftOraClob,ftVariant,ftInterface,ftIDispatch,ftGuid,ftTimeStamp,ftFMTBcd];
+  FoxProUnsupported=[ftUnknown,ftTime,ftVarBytes,ftGraphic,ftFmtMemo,ftParadoxOle,ftTypedBinary,ftCursor,ftADT,ftArray,ftReference,ftDataSet,ftOraBlob,ftOraClob,ftVariant,ftInterface,ftIDispatch,ftGuid,ftTimeStamp,ftFMTBcd];
+begin
+  result:=true;
+  case ExportSubFormat of
+    efDBaseIII: if FieldType in DBaseVIIUnsupported+[ftAutoInc] then result:=false;
+    efDBaseIV: if FieldType in DBaseVIIUnsupported+[ftAutoInc] then result:=false;
+    efDBaseVII: if FieldType in DBaseVIIUnsupported then result:=false;
+    efCSV: result:=true;
+    efFixedLengthText: result:=true; //todo: verify if all fields are really supported. Quick glance would indicate so
+    efFoxpro: if FieldType in FoxProUnsupported then result:=false;
+    efJSON: result:=true;
+    efRTF: result:=true;
+    efSQL: result:=true;
+    efTeX: result:=true;
+    efXML: result:=true;
+    efXMLXSDAccess, efXMLXSDADONet, efXMLXSDClientDataset, efXMLXSDExcel: result:=true;
+    else
+    begin
+      result:=false;
+      Fail('Error in test code itself: FieldSupported unknown ExportSubFormat '+inttostr(ord(ExportSubFormat)));
+    end;
+  end;
+end;
+
+procedure TTestDBExport.GenericExportTest(Exporter: TCustomDatasetExporter; ExportFormat: TDetailedExportFormats);
+var
+  FieldMapping: TExportFields;
+  NumberExported: integer;
+  i: integer;
+begin
+  FieldMapping:=TExportFields.Create(Exporter.ExportFields.ItemClass);
+  try
+    Exporter.Dataset := DBConnector.GetFieldDataset;
+    Exporter.Dataset.Open;
+    Exporter.BuildDefaultFieldMap(FieldMapping);
+    // Remove unsupported data types in export from the mapping.
+    // Cannot use FieldMapping[i].Field.DataType as
+    // the field hasn't been set by BindFields yet... assume the
+    // order of original fields and their mapping match
+    for i:=Exporter.Dataset.Fields.Count-1 downto 0 do
+    begin
+      if not FieldSupported(
+        Exporter.Dataset.Fields[i].DataType,
+        ExportFormat) then
+        FieldMapping.Delete(i);
+    end;
+    for i:=0 to FieldMapping.Count-1 do
+    begin
+      Exporter.ExportFields.Add.Assign(FieldMapping[i]);
+    end;
+    NumberExported := Exporter.Execute;
+    Exporter.Dataset.Last;
+    Exporter.Dataset.First;
+    AssertEquals('Number of records exported', NumberExported,
+      Exporter.Dataset.RecordCount);
+    Exporter.Dataset.Close;
+  finally
+    FieldMapping.Free;
+  end;
+end;
+
+function TTestDBExport.GetFileSize(const FileName: string): integer;
+Var
+  F : file of byte;
+begin
+  result:=0;
+  assign (F,FileName);
+  try
+    reset(F);
+    result:=filesize(F);
+  finally
+    close(F);
+  end;
+end;
+
+procedure TTestDBExport.SetUp;
+begin
+  inherited SetUp;
+  InitialiseDBConnector;
+  //DBConnector.StartTest; //is this needed?
+  FExportTempDir:=IncludeTrailingPathDelimiter(ExpandFileName(''))+'exporttests'+PathDelim; //Store output in subdirectory
+  ForceDirectories(FExportTempDir);
+  FKeepFilesAfterTest:=true; //keep test files; consistent with other units right now
+end;
+
+procedure TTestDBExport.TearDown;
+begin
+  inherited TearDown;
+  //DBConnector.StopTest; //is this needed?
+  FreeDBConnector;
+end;
+
+procedure TTestDBExport.TestDBFExport_DBaseVII;
+var
+  Exporter: TFPDBFExport;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TDBFExportFormatSettings;
+begin
+  Exporter := TFPDBFExport.Create(nil);
+  ExportSettings:=TDBFExportFormatSettings.Create(true);
+  try
+    ExportFormat:=efDBaseVII;
+    ExportSettings.TableFormat:=tfDBaseVII;
+    // Use export subtype position to differentiate output filenames:
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5)) +
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestDBFExport_DBaseIV;
+var
+  Exporter: TFPDBFExport;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TDBFExportFormatSettings;
+begin
+  Exporter := TFPDBFExport.Create(nil);
+  ExportSettings:=TDBFExportFormatSettings.Create(true);
+  try
+    ExportFormat:=efDBaseIV;
+    ExportSettings.TableFormat:=tfDBaseIV;
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5)) +
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestDBFExport_FoxPro;
+var
+  Exporter: TFPDBFExport;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TDBFExportFormatSettings;
+begin
+  Exporter := TFPDBFExport.Create(nil);
+  ExportSettings:=TDBFExportFormatSettings.Create(true);
+  try
+    ExportFormat:=efFoxpro;
+    ExportSettings.TableFormat:=tfFoxPro;
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5)) +
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestXSDExport_Access_NoXSD_DecimalOverride;
+var
+  Exporter: TXMLXSDExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TXMLXSDFormatSettings;
+begin
+  Exporter := TXMLXSDExporter.Create(nil);
+  ExportSettings:=TXMLXSDFormatSettings.Create(true);
+  try
+    ExportSettings.ExportFormat:=AccessCompatible;
+    ExportFormat:=efXMLXSDAccess;
+    ExportSettings.CreateXSD:=false;
+    ExportSettings.DecimalSeparator:='.'; //override
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5)) +
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestXSDExport_Access_NoXSD_NoDecimalOverride;
+var
+  Exporter: TXMLXSDExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TXMLXSDFormatSettings;
+begin
+  Exporter := TXMLXSDExporter.Create(nil);
+  ExportSettings:=TXMLXSDFormatSettings.Create(true);
+  try
+    ExportSettings.ExportFormat:=AccessCompatible;
+    ExportFormat:=efXMLXSDAccess;
+    ExportSettings.CreateXSD:=false;
+    ExportSettings.DecimalSeparator:=char(''); //don't override
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5)) +
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestXSDExport_Access_XSD_DecimalOverride;
+var
+  Exporter: TXMLXSDExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TXMLXSDFormatSettings;
+begin
+  Exporter := TXMLXSDExporter.Create(nil);
+  ExportSettings:=TXMLXSDFormatSettings.Create(true);
+  try
+    ExportSettings.ExportFormat:=AccessCompatible;
+    ExportFormat:=efXMLXSDAccess;
+    ExportSettings.CreateXSD:=true;
+    ExportSettings.DecimalSeparator:='.'; //override
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5)) +
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestXSDExport_Access_XSD_NoDecimalOverride;
+var
+  Exporter: TXMLXSDExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TXMLXSDFormatSettings;
+begin
+  Exporter := TXMLXSDExporter.Create(nil);
+  ExportSettings:=TXMLXSDFormatSettings.Create(true);
+  try
+    ExportSettings.ExportFormat:=AccessCompatible;
+    ExportFormat:=efXMLXSDAccess;
+    ExportSettings.CreateXSD:=true;
+    ExportSettings.DecimalSeparator:=char(''); //don't override
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5)) +
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestXSDExport_ADONET_NoXSD;
+var
+  Exporter: TXMLXSDExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TXMLXSDFormatSettings;
+begin
+  ExportSettings.ExportFormat:=AccessCompatible;
+  Exporter := TXMLXSDExporter.Create(nil);
+  ExportSettings:=TXMLXSDFormatSettings.Create(true);
+  try
+    ExportSettings.ExportFormat:=ADONETCompatible;
+    ExportFormat:=efXMLXSDADONet;
+    ExportSettings.CreateXSD:=false;
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5)) +
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestXSDExport_ADONET_XSD;
+var
+  Exporter: TXMLXSDExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TXMLXSDFormatSettings;
+begin
+  Exporter := TXMLXSDExporter.Create(nil);
+  ExportSettings:=TXMLXSDFormatSettings.Create(true);
+  try
+    ExportSettings.ExportFormat:=ADONETCompatible;
+    ExportFormat:=efXMLXSDADONet;
+    ExportSettings.CreateXSD:=true;
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5)) +
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestCSVExport;
+var
+  Exporter: TCSVExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings: TCSVFormatSettings;
+begin
+  Exporter := TCSVExporter.Create(nil);
+  ExportSettings:=TCSVFormatSettings.Create(true);
+  try
+    ExportFormat:=efCSV;
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5)) +
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestCSVExport_RFC4180WithHeader;
+var
+  Exporter: TCSVExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings: TCSVFormatSettings;
+begin
+  Exporter := TCSVExporter.Create(nil);
+  ExportSettings:=TCSVFormatSettings.Create(true);
+  try
+    ExportSettings.FieldDelimiter:=','; //RFC 4180 specified commas as delimiter
+    ExportSettings.HeaderRow:=true; //...allows an optional header line
+    ExportSettings.StringQuoteChar:='"'; //...requires quoting with " (if quoting)
+    // Fields containing line breaks (CRLF), double quotes,
+    // and commas should be enclosed in double-quotes.
+    // => this probably won't get tested with this test set.
+    ExportFormat:=efCSV;
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5)) +
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestCSVExport_TweakSettingsSemicolon;
+var
+  Exporter: TCSVExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings: TCSVFormatSettings;
+begin
+  Exporter := TCSVExporter.Create(nil);
+  ExportSettings:=TCSVFormatSettings.Create(true);
+  try
+    ExportSettings.FieldDelimiter:=';';
+    ExportSettings.QuoteStrings:=[qsAlways,qsSpace,qsDelimiter]; //quote everything we can
+    ExportSettings.StringQuoteChar:='"'; //try explicit assignment
+    ExportSettings.RowDelimiter:=#10; //Unix/Linux format
+    ExportSettings.BooleanFalse:='onwaar'; //why not a Dutch output format?
+    ExportSettings.BooleanTrue:='waar'; //why not a Dutch output format?
+    ExportSettings.CurrencyDigits:=3;
+    ExportSettings.CurrencySymbol:='€'; //euro sign
+    ExportSettings.DateFormat:='d-mm-yyyy'; //Dutch setting
+    ExportSettings.DateTimeFormat:='d-mm-yyyy hh:nn:ss'; //Dutch setting
+    ExportSettings.DecimalSeparator:=','; //another Dutch setting
+    ExportSettings.TimeFormat:='hh:nn:ss'; //Dutch setting
+    ExportSettings.IntegerFormat:='0000';//Strange but nice ;)
+    ExportFormat:=efCSV;
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5)) +
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestFixedTextExport;
+var
+  Exporter: TFixedLengthExporter;
+  ExportFormat: TDetailedExportFormats;
+begin
+  Exporter := TFixedLengthExporter.Create(nil);
+  try
+    ExportFormat:=efFixedLengthText;
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5)) +
+      TDetailedExportExtensions[ExportFormat];
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestJSONExport;
+var
+  Exporter: TSimpleJSONExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TSimpleJSONFormatSettings;
+begin
+  Exporter := TSimpleJSONExporter.Create(nil);
+  ExportSettings:=TSimpleJSONFormatSettings.Create(true);
+  try
+    ExportFormat:=efJSON;
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) + lowercase(rightstr(TestName,5))+
+     inttostr(ord(ExportFormat))+
+     TDetailedExportExtensions[ExportFormat];    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestRTFExport;
+var
+  Exporter: TRTFExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TRTFExportFormatSettings;
+begin
+  Exporter := TRTFExporter.Create(nil);
+  ExportSettings:=TRTFExportFormatSettings.Create(true);
+  try
+    ExportFormat:=efRTF;
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5))+
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestSQLExport;
+var
+  Exporter: TSQLExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TSQLFormatSettings;
+begin
+  Exporter := TSQLExporter.Create(nil);
+  ExportSettings:=TSQLFormatSettings.Create(true);
+  try
+    ExportSettings.TableName:='ATABLE'; //required for export to succeed
+    ExportFormat:=efSQL;
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5))+
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestTeXExport;
+var
+  Exporter: TTexExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TTeXExportFormatSettings;
+begin
+  Exporter := TTexExporter.Create(nil);
+  ExportSettings:=TTeXExportFormatSettings.Create(true);
+  try
+    ExportFormat:=efTeX;
+    Exporter.FileName := FExportTempDir +
+      inttostr(ord(ExportFormat)) + lowercase(rightstr(TestName,5))+
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestXMLExport;
+var
+  Exporter: TSimpleXMLExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TSimpleXMLFormatSettings;
+begin
+  Exporter := TSimpleXMLExporter.Create(nil);
+  ExportSettings:=TSimpleXMLFormatSettings.Create(true);
+  try
+    ExportFormat:=efXML;
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+     lowercase(rightstr(TestName,5)) +
+     TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestXSDExport_DelphiClientDataset;
+var
+  Exporter: TXMLXSDExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TXMLXSDFormatSettings;
+begin
+  Exporter := TXMLXSDExporter.Create(nil);
+  ExportSettings:=TXMLXSDFormatSettings.Create(true);
+  try
+    ExportSettings.ExportFormat:=DelphiClientDataset;
+    ExportFormat:=efXMLXSDClientDataset;
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5)) +
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+procedure TTestDBExport.TestXSDExport_Excel;
+var
+  Exporter: TXMLXSDExporter;
+  ExportFormat: TDetailedExportFormats;
+  ExportSettings:TXMLXSDFormatSettings;
+begin
+  Exporter := TXMLXSDExporter.Create(nil);
+  ExportSettings:=TXMLXSDFormatSettings.Create(true);
+  try
+    ExportSettings.ExportFormat:=ExcelCompatible;
+    ExportFormat:=efXMLXSDExcel;
+    Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
+      lowercase(rightstr(TestName,5)) +
+      TDetailedExportExtensions[ExportFormat];
+    Exporter.FormatSettings:=ExportSettings;
+    GenericExportTest(Exporter, ExportFormat);
+    AssertTrue('Output file must be created', FileExists(Exporter.FileName));
+    AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
+  finally
+    if (FKeepFilesAfterTest = False) then
+      DeleteFile(Exporter.FileName);
+    ExportSettings.Free;
+    Exporter.Free;
+  end;
+end;
+
+
+initialization
+  RegisterTest(TTestDBExport);
+end.

+ 1 - 1
packages/fcl-db/tests/testfieldtypes.pas

@@ -1316,7 +1316,7 @@ begin
           'EXECUTE BLOCK RETURNS (U VARCHAR(255)) AS BEGIN SELECT rdb$get_context(''SYSTEM'',''CURRENT_USER'') FROM rdb$database INTO U; SUSPEND; END' (*FB 2.0*)
         );
       ssPostgreSQL:
-        statements := TTestStatements.Create(CTE_SELECT);
+        statements := TTestStatements.Create(CTE_SELECT, 'EXPLAIN '+CTE_SELECT);
       ssMSSQL:
         statements := TTestStatements.Create(CTE_SELECT  (*MS SQL 2005*));
       ssMySQL:

+ 0 - 696
packages/fcl-db/tests/xmlxsdexporttestcase1.pas

@@ -1,696 +0,0 @@
-unit XMLXSDExportTestCase1;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
-  Classes, SysUtils, Fpcunit, Testutils, Testregistry, DB, fpXMLXSDExport,
-  BufDataset, dateutils;
-
-type
-
-  { Ttestxmlxsdexport1 }
-
-  Ttestxmlxsdexport1 = class(Ttestcase)
-  const
-    KeepFilesAfterTest = true;
-    //Change if you want to keep export files for further testing
-  private
-    procedure FillTestData;
-  protected
-    FTestDataset: TBufDataset;
-    FExportTempDir: string; //where we store exported files in these tests
-    procedure FillRecord(const RowNumber: integer; const Teststring: string;
-      const TestGUID: string; const TestInteger: integer;
-      const TestExtended: extended; const TestDatetime: Tdatetime;
-      const TestBoolean: boolean);
-    procedure Setup; override;
-    procedure Teardown; override;
-  published
-    procedure TestXSDExport_Access_NoXSD_DecimalOverride;
-    procedure TestXSDExport_Access_NoXSD_NoDecimalOverride;
-    procedure TestXSDExport_Access_XSD_DecimalOverride;
-    procedure TestXSDExport_Access_XSD_NoDecimalOverride;
-    procedure TestXSDExport_ADONET_NoXSD;
-    procedure TestXSDExport_ADONET_XSD;
-    procedure TestXSDExport_DelphiClientDataset;
-    procedure TestXSDExport_Excel;
-  end;
-
-implementation
-
-procedure Ttestxmlxsdexport1.TestXSDExport_Access_NoXSD_NoDecimalOverride;
-
-var
-  Export: TXMLXSDExporter;
-  Settings: TXMLXSDFormatSettings;
-  NumberExported: integer;
-
-begin
-  Export := TXMLXSDExporter.Create(nil);
-  Settings := TXMLXSDFormatSettings.Create(True);
-  try
-    //Don't override decimal separator
-    Settings.CreateXSD := False;
-    Settings.DecimalSeparator := char(''); //Don't override decimalseparator
-    Settings.ExportFormat := AccessCompatible;
-    Export.Dataset := FTestDataset;
-    Export.FormatSettings := Settings;
-    Export.FileName := FExportTempDir + 'Access_NoXSD_NoDecimalOverride.xml';
-    NumberExported := Export.Execute;
-    FTestDataset.Close;
-    AssertEquals('Number of records exported', NumberExported, FTestDataset.RecordCount);
-  finally
-    Settings.Free;
-    if (KeepFilesAfterTest = False) then
-    begin
-      DeleteFile(Export.FileName);
-    end;
-    Export.Free;
-  end;
-end;
-
-procedure Ttestxmlxsdexport1.TestXSDExport_Access_NoXSD_DecimalOverride;
-var
-  Export: TXMLXSDExporter;
-  Settings: TXMLXSDFormatSettings;
-  NumberExported: integer;
-
-begin
-  Export := TXMLXSDExporter.Create(nil);
-  Settings := TXMLXSDFormatSettings.Create(True);
-  try
-    Settings.DecimalSeparator := ',';
-    //Try to override decimal separator specified by fpXMLXSDExport
-    Settings.CreateXSD := False;
-    Settings.ExportFormat := AccessCompatible;
-    Export.Dataset := FTestDataset;
-    Export.FormatSettings := Settings;
-    Export.FileName := FExportTempDir + 'Access_NoXSD_DecimalOverride.xml';
-    NumberExported := Export.Execute;
-    FTestDataset.Close;
-    AssertEquals('Number of records exported', NumberExported, FTestDataset.RecordCount);
-  finally
-    Settings.Free;
-    if (KeepFilesAfterTest = False) then
-    begin
-      DeleteFile(Export.FileName);
-    end;
-    Export.Free;
-  end;
-end;
-
-procedure Ttestxmlxsdexport1.TestXSDExport_Access_XSD_NoDecimalOverride;
-var
-  Export: TXMLXSDExporter;
-  Settings: TXMLXSDFormatSettings;
-  NumberExported: integer;
-
-begin
-  Export := TXMLXSDExporter.Create(nil);
-  Settings := TXMLXSDFormatSettings.Create(True);
-  try
-    //Settings.DecimalSeparator := ','; //Don't override decimal separator
-    Settings.CreateXSD := True;
-    Settings.ExportFormat := AccessCompatible;
-    Export.Dataset := FTestDataset;
-    Export.FormatSettings := Settings;
-    Export.FileName := FExportTempDir + 'Access_XSD_NoDecimalOverride.xml';
-    NumberExported := Export.Execute;
-    FTestDataset.Close;
-    AssertEquals('Number of records exported', NumberExported, FTestDataset.RecordCount);
-  finally
-    Settings.Free;
-    if (KeepFilesAfterTest = False) then
-    begin
-      DeleteFile(Export.FileName);
-    end;
-    Export.Free;
-  end;
-end;
-
-procedure Ttestxmlxsdexport1.TestXSDExport_Access_XSD_DecimalOverride;
-var
-  Export: TXMLXSDExporter;
-  Settings: TXMLXSDFormatSettings;
-  NumberExported: integer;
-
-begin
-  Export := TXMLXSDExporter.Create(nil);
-  Settings := TXMLXSDFormatSettings.Create(True);
-  try
-    Settings.DecimalSeparator := ','; //Try to override decimal separator
-    Settings.CreateXSD := True;
-    Settings.ExportFormat := AccessCompatible;
-    Export.Dataset := FTestDataset;
-    Export.FormatSettings := Settings;
-    Export.FileName := FExportTempDir + 'Access_XSD_DecimalOverride.xml';
-    NumberExported := Export.Execute;
-    FTestDataset.Close;
-    AssertEquals('Number of records exported', NumberExported, FTestDataset.RecordCount);
-  finally
-    Settings.Free;
-    if (KeepFilesAfterTest = False) then
-    begin
-      DeleteFile(Export.FileName);
-    end;
-    Export.Free;
-  end;
-end;
-
-procedure Ttestxmlxsdexport1.TestXSDExport_ADONET_NoXSD;
-var
-  Export: TXMLXSDExporter;
-  Settings: TXMLXSDFormatSettings;
-  NumberExported: integer;
-
-begin
-  Export := TXMLXSDExporter.Create(nil);
-  Settings := TXMLXSDFormatSettings.Create(True);
-  try
-    Settings.CreateXSD := False;
-    Settings.ExportFormat := ADONETCompatible;
-    Export.Dataset := FTestDataset;
-    Export.FormatSettings := Settings;
-    Export.FileName := FExportTempDir + 'ADONET_NoXSD.xml';
-    NumberExported := Export.Execute;
-    FTestDataset.Close;
-    AssertEquals('Number of records exported', NumberExported, FTestDataset.RecordCount);
-  finally
-    Settings.Free;
-    if (KeepFilesAfterTest = False) then
-    begin
-      DeleteFile(Export.FileName);
-    end;
-    Export.Free;
-  end;
-end;
-
-procedure Ttestxmlxsdexport1.TestXSDExport_ADONET_XSD;
-var
-  Export: TXMLXSDExporter;
-  Settings: TXMLXSDFormatSettings;
-  NumberExported: integer;
-
-begin
-  Export := TXMLXSDExporter.Create(nil);
-  Settings := TXMLXSDFormatSettings.Create(True);
-  try
-    Settings.CreateXSD := True;
-    Settings.ExportFormat := ADONETCompatible;
-    Export.Dataset := FTestDataset;
-    Export.FormatSettings := Settings;
-    Export.FileName := FExportTempDir + 'ADONET_XSD.xml';
-    NumberExported := Export.Execute;
-    FTestDataset.Close;
-    AssertEquals('Number of records exported', NumberExported, FTestDataset.RecordCount);
-  finally
-    Settings.Free;
-    if (KeepFilesAfterTest = False) then
-    begin
-      DeleteFile(Export.FileName);
-    end;
-    Export.Free;
-  end;
-end;
-
-procedure Ttestxmlxsdexport1.TestXSDExport_DelphiClientDataset;
-var
-  Export: TXMLXSDExporter;
-  Settings: TXMLXSDFormatSettings;
-  NumberExported: integer;
-
-begin
-  Export := TXMLXSDExporter.Create(nil);
-  Settings := TXMLXSDFormatSettings.Create(True);
-  try
-    Settings.ExportFormat := DelphiClientDataset;
-    Export.Dataset := FTestDataset;
-    Export.FormatSettings := Settings;
-    Export.FileName := FExportTempDir + 'DelphiClientDataset.xml';
-    NumberExported := Export.Execute;
-    FTestDataset.Close;
-    AssertEquals('Number of records exported', NumberExported, FTestDataset.RecordCount);
-    //we should have exported 2 records.
-  finally
-    Settings.Free;
-    if (KeepFilesAfterTest = False) then
-    begin
-      DeleteFile(Export.FileName);
-    end;
-    Export.Free;
-  end;
-end;
-
-procedure Ttestxmlxsdexport1.TestXSDExport_Excel;
-var
-  Export: TXMLXSDExporter;
-  Settings: TXMLXSDFormatSettings;
-  NumberExported: integer;
-
-begin
-  Export := TXMLXSDExporter.Create(nil);
-  Settings := TXMLXSDFormatSettings.Create(True);
-  try
-    Settings.ExportFormat := ExcelCompatible;
-    Export.Dataset := FTestDataset;
-    Export.FormatSettings := Settings;
-    Export.FileName := FExportTempDir + 'Excel.xml';
-    NumberExported := Export.Execute;
-    FTestDataset.Close;
-    AssertEquals('Number of records exported', NumberExported, FTestDataset.RecordCount);
-    //we should have exported 2 records.
-  finally
-    Settings.Free;
-    if (KeepFilesAfterTest = False) then
-    begin
-      DeleteFile(Export.FileName);
-    end;
-    Export.Free;
-  end;
-end;
-
-
-procedure Ttestxmlxsdexport1.FillTestData;
-var
-  RowNumber: integer; //Keep track of how many rows we inserted
-  TestBoolean: boolean;
-  TestDateTime: TDateTime;
-  TestExtended: extended;
-  //yes, a lot of precision; we can convert to single/double if required
-  TestInteger: integer;
-  TestGuid: string;
-  TestString: string;
-begin
-  FTestDataset.Close;
-  RowNumber := 0;
-  //for memds:
-  //FTestDataset.Clear(False); //memds: clear out any data
-  //FTestDataset.Fields.Clear; //bufds: clear out any data, but also FIELDDEFS: don't use
-  FTestDataset.Open;
-
-  // Fill some test data
-  // First row: positive numerical values, late dates/times, strings with special chars (tab, linefeed, ; > <)
-  FTestDataset.Append;
-  TestBoolean := True;
-  TestDateTime := EncodeDate(9999, 12, 31) + EncodeTime(23, 59, 59, 999);
-  TestExtended := 42.424242424242424242424242424242;
-  TestInteger := Round(TestExtended);
-  TestGuid := '{21EC2020-3AEA-1069-A2DD-08002B30309D}';
-  TestString := 'Douglas Adams less than: < greater than > tab:' +
-    #9 + 'crlf:' + #13 + #10 +
-    '國缺界广欠廣界界东缺. Haddock drinks rosé (ros, e accent aigu), водка (wodka cyrillic) and ούζο (ouzo Greek) but prefers Loch Lomond whiskey.';
-  RowNumber := RowNumber + 1;
-  FillRecord(RowNumber, Teststring, TestGUID, Testinteger, Testextended,
-    Testdatetime, Testboolean);
-  FTestDataset.Post;
-
-  // Second row: negative numerical values, early dates/times, strings with maximum field width and Greek, east asian (multibyte) characters
-  FTestDataset.Append;
-  TestBoolean := False;
-  TestDateTime := EncodeDate(1, 1, 1) + EncodeTime(0, 0, 0, 1);
-  TestExtended := -42.424242424242424242424242424242;
-  TestInteger := Round(TestExtended);
-  TestGuid := '{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}';
-  TestString := 'ARMA virumque cano, Troiae qui primus ab oris' +
-    #13 + #10 + 'Italiam, fato profugus, Laviniaque venit' + #13 +
-    #10 + 'litora, multum ille et terris iactatus et alto' + #13 +
-    #10 + 'vi superum saevae memorem Iunonis ob iram;' + #13 + #10 +
-    'multa quoque et bello passus, dum conderet urbem,' + #13 + #10 +
-    'inferretque deos Latio, genus unde Latinum,' + #13 + #10 +
-    'Albanique patres, atque altae moenia Romae.' + #13 + #10 + #13 +
-    #10 + 'Musa, mihi causas memora, quo numine laeso,' + #13 + #10 +
-    'quidve dolens, regina deum tot volvere casus' + #13 + #10 +
-    'insignem pietate virum, tot adire labores' + #13 + #10 +
-    'impulerit.  Tantaene animis caelestibus irae?' + #13 + #10 +
-    #13 + #10 + 'Urbs antiqua fuit, Tyrii tenuere coloni,' + #13 +
-    #10 + 'Karthago, Italiam contra Tiberinaque longe' + #13 + #10 +
-    'ostia, dives opum studiisque asperrima belli;' + #13 + #10 +
-    'quam Iuno fertur terris magis omnibus unam' + #13 + #10 +
-    'posthabita coluisse Samo; hic illius arma,' + #13 + #10 +
-    'hic currus fuit; hoc regnum dea gentibus esse,' + #13 + #10 +
-    'si qua fata sinant, iam tum tenditque fovetque.' + #13 + #10 +
-    'Progeniem sed enim Troiano a sanguine duci' + #13 + #10 +
-    'audierat, Tyrias olim quae verteret arces;' + #13 + #10 +
-    'hinc populum late regem belloque superbum' + #13 + #10 +
-    'venturum excidio Libyae:  sic volvere Parcas.' + #13 + #10 +
-    'Id metuens, veterisque memor Saturnia belli,' + #13 + #10 +
-    'prima quod ad Troiam pro caris gesserat Argis---' + #13 + #10 +
-    'necdum etiam causae irarum saevique dolores' + #13 + #10 +
-    'exciderant animo:  manet alta mente repostum' + #13 + #10 +
-    'iudicium Paridis spretaeque iniuria formae,' + #13 + #10 +
-    'et genus invisum, et rapti Ganymedis honores.' + #13 + #10 +
-    'His accensa super, iactatos aequore toto' + #13 + #10 +
-    'Troas, reliquias Danaum atque immitis Achilli,' + #13 + #10 +
-    'arcebat longe Latio, multosque per annos' + #13 + #10 +
-    'errabant, acti fatis, maria omnia circum.' + #13 + #10 +
-    'Tantae molis erat Romanam condere gentem!';
-  RowNumber := RowNumber + 1;
-  FillRecord(RowNumber, Teststring, TestGUID, Testinteger, Testextended,
-    Testdatetime, Testboolean);
-  FTestDataset.Post;
-
-  // Third row: empty/zero numerical values, dates/times, strings
-  FTestDataset.Append;
-  TestBoolean := False;
-  TestDateTime := EncodeDate(1, 1, 1) + EncodeTime(0, 0, 0, 0);
-  TestExtended := 0;
-  TestInteger := Round(TestExtended);
-  TestGuid := '{3F2504E0-4F89-11D3-9A0C-0305E82C3301}';
-  TestString := '';
-  RowNumber := RowNumber + 1;
-  FillRecord(RowNumber, Teststring, TestGUID, Testinteger, Testextended,
-    Testdatetime, Testboolean);
-  FTestDataset.Post;
-
-  // Fourth row: plausible data
-  FTestDataset.Append;
-  TestBoolean := True;
-  TestDateTime := EncodeDate(2005, 9, 10) + EncodeTime(13, 52, 18, 0);
-  TestExtended := 42;
-  TestInteger := Round(TestExtended);
-  TestString := 'The answer to life, the universe, and everything';
-  RowNumber := RowNumber + 1;
-  FillRecord(RowNumber, Teststring, TestGUID, Testinteger, Testextended,
-    Testdatetime, Testboolean);
-  FTestDataset.Post;
-
-  // Make sure recordcount is correct:
-  FTestDataset.Last;
-  FTestDataset.First;
-  AssertEquals('Number of records in test dataset', RowNumber, FTestDataset.RecordCount);
-end;
-
-procedure Ttestxmlxsdexport1.Setup;
-const
-  NumberOfDecimals = 2;
-  NumberOfBytes = 10;
-var
-  FieldDef: TFieldDef;
-begin
-  FExportTempDir := GetTempDir(False);
-  FTestDataset := TBufDataset.Create(nil);
-
-  {We should cover all data types defined in FPC:
-
-  FPC maps "external" types such as ftOracleBlob to
-  internal types, but that can be overridden, which is done
-  by e.g. IBX and mseide.
-  So it makes sense to keep as many datatypes in the exporter code as possible: it documents the mappings and allows other people to use these types without the exporter breaking.
-  }
-  {Sorted by datatype; commented out what doesn't work at the moment in bufdataset
-  See http://docwiki.embarcadero.com/VCL/en/DB.TField.Size for overview of field sizes in the competition product ;)
-  Apparently ftGuid also needs size...
-  }
-
-  {
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftADT';
-  FieldDef.DataType := ftADT;
-  FieldDef.Size := 4096;//large but hopefully not too large for memory.
-  }
-
-  {
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftArray';
-  FieldDef.DataType := ftArray;
-  FieldDef.Size := 10;//the number of elements in the array
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftAutoInc';
-  FieldDef.DataType := ftAutoInc;
-  }
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftBCD';
-  FieldDef.DataType := ftBCD;
-  FieldDef.Size := NumberOfDecimals;
-  //Size is the number of digits after the decimal place
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftBlob_4096';
-  FieldDef.DataType := ftBlob;
-  FieldDef.Size := 4096;//large but hopefully not too large for memory.
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftBoolean';
-  FieldDef.DataType := ftBoolean;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftBytes';
-  FieldDef.DataType := ftBytes;
-  FieldDef.Size := NumberOfBytes;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftCurrency';
-  FieldDef.DataType := ftCurrency;
-
-  {
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftCursor';
-  FieldDef.DataType := ftCursor;
-  }
-
-  {
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftDataSet';
-  FieldDef.DataType := ftDataSet;
-  }
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftDate';
-  FieldDef.DataType := ftDate;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftDateTime';
-  FieldDef.DataType := ftDateTime;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftDBaseOle';
-  FieldDef.DataType := ftDBaseOle;
-  FieldDef.Size := 4096;//large but hopefully not too large for memory.
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftFixedChar_2';
-  FieldDef.DataType := ftFixedChar;
-  FieldDef.Size := NumberOfDecimals;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftFixedWideChar_2';
-  FieldDef.DataType := ftFixedWideChar;
-  FieldDef.Size := NumberOfBytes;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftFloat';
-  FieldDef.DataType := ftFloat;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftFMTBcd';
-  FieldDef.DataType := ftFMTBcd;
-  FieldDef.Size := NumberOfDecimals; //the number of digits after the decimal place.
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftFmtMemo';
-  FieldDef.DataType := ftFmtMemo;
-  FieldDef.Size := 4096;//large but hopefully not too large for memory.
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftGraphic';
-  FieldDef.DataType := ftGraphic;
-  FieldDef.Size := 4096;//large but hopefully not too large for memory.
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftGuid';
-  FieldDef.DataType := ftGuid;
-  FieldDef.Size := 38;
-  //Apparently right answer is not 42; had to look up 38 in source code.
-
-  {
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftIDispatch';
-  FieldDef.DataType := ftIDispatch;
-  }
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftInteger';
-  FieldDef.DataType := ftInteger;
-
-  {
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftInterface';
-  FieldDef.DataType := ftInterface;
-  }
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftLargeint';
-  FieldDef.DataType := ftLargeint;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftMemo';
-  FieldDef.DataType := ftMemo;
-  FieldDef.Size := 4096;//large but hopefully not too large for memory.
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftOraBlob';
-  FieldDef.DataType := ftOraBlob;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftOraClob';
-  FieldDef.DataType := ftOraClob;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftParadoxOle';
-  FieldDef.DataType := ftParadoxOle;
-  FieldDef.Size := 4096;//large but hopefully not too large for memory.
-
-  {
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftReference';
-  FieldDef.DataType := ftReference;
-  }
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftSmallInt';
-  FieldDef.DataType := ftInteger;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftString_1';
-  FieldDef.DataType := ftString;
-  FieldDef.Size := 1;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftString_256'; //1 character more than many db string types support
-  FieldDef.DataType := ftString;
-  FieldDef.Size := 256;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftTime';
-  FieldDef.DataType := ftTime;
-
-  {
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftTimeStamp';
-  FieldDef.DataType := ftTimeStamp;
-  }
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftTypedBinary';
-  FieldDef.DataType := ftTypedBinary;
-  FieldDef.Size := 4096;//large but hopefully not too large for memory.
-
-  { ftVariant and ftVarBytes don't work; see bug 19930
-  However, there's more wront in bufdataset; if I don't
-  include these field definitions, I get access violations later on.}
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftVariant';
-  FieldDef.DataType := ftVariant;
-  FieldDef.Size := NumberOfBytes;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftVarBytes';
-  FieldDef.DataType := ftVarBytes;
-  FieldDef.Size := NumberOfBytes;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftWideMemo';
-  FieldDef.DataType := ftWideMemo;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftWideString256';
-  FieldDef.DataType := ftWideString;
-  FieldDef.Size := 256;
-
-  FieldDef := FTestDataset.FieldDefs.AddFieldDef;
-  FieldDef.Name := 'ftWord';
-  FieldDef.DataType := ftWord;
-
-  //Createtable is needed if you use a memds
-  //FTestDataset.CreateTable;
-  //CreateDataset is needed if you use a bufdataset
-  FTestDataset.CreateDataSet;
-
-  // Fill dataset with test data
-  FillTestData;
-end;
-
-procedure Ttestxmlxsdexport1.FillRecord(const RowNumber: integer;
-  const TestString: string; const TestGUID: string; const TestInteger: integer;
-  const TestExtended: extended; const TestDatetime: Tdatetime;
-  const TestBoolean: boolean);
-var
-  FieldCounter: integer;
-begin
-  writeln('*** Starting to fill row ' + IntToStr(RowNumber));
-  {As our bufdataset doesn't support these datatypes, don't use them:
-ftAutoInc -> exists but doesn't seem to return any data.
-ftCursor
-ftDataSet
-ftInterface
-ftReference
-ftTimeStamp}
-
-  FTestDataset.FieldByName('ftBCD').AsFloat := Testextended;
-  FTestDataset.FieldByName('ftBlob_4096').AsString := Teststring;
-  FTestDataset.FieldByName('ftBoolean').AsBoolean := Testboolean;
-  FTestDataset.FieldByName('ftBytes').AsString := Teststring;
-  FTestDataset.FieldByName('ftCurrency').Ascurrency := Testextended;
-  FTestDataset.FieldByName('ftDate').AsDateTime := Testdatetime;
-  FTestDataset.FieldByName('ftDateTime').AsDateTime := Testdatetime;
-  FTestDataset.FieldByName('ftDBaseOle').AsString := Teststring;
-  FTestDataset.FieldByName('ftFixedChar_2').AsString := Teststring;
-  FTestDataset.FieldByName('ftFixedWideChar_2').AsString := Teststring;
-  FTestDataset.FieldByName('ftFloat').AsFloat := Testextended;
-  FTestDataset.FieldByName('ftFMTBcd').AsFloat := Testextended;
-  FTestDataset.FieldByName('ftFmtMemo').AsString := Teststring;
-  FTestDataset.FieldByName('ftGraphic').AsString := Teststring;
-  FTestDataset.FieldByName('ftGuid').AsString := TestGUID;
-  FTestDataset.FieldByName('ftInteger').AsInteger := Testinteger;
-  FTestDataset.FieldByName('ftLargeint').AsInteger := Testinteger;
-  FTestDataset.FieldByName('ftMemo').AsString := Teststring;
-  FTestDataset.FieldByName('ftOraBlob').AsString := Teststring;
-  FTestDataset.FieldByName('ftOraClob').AsString := Teststring;
-  FTestDataset.FieldByName('ftParadoxOle').AsString := Teststring;
-  FTestDataset.FieldByName('ftSmallInt').AsInteger := Testinteger;
-  FTestDataset.FieldByName('ftString_1').AsString := Teststring;
-  FTestDataset.FieldByName('ftString_256').AsString := Teststring;
-  FTestDataset.FieldByName('ftTime').AsDateTime := Testdatetime;
-  FTestDataset.FieldByName('ftTypedBinary').AsString := Teststring;
-  { ftVarBytes and ftVariant don't work; see bug 19930}
-  {
-  FTestDataSet.FieldByName('ftVarBytes').AsString := TestString;
-  FTestDataSet.FieldByName('ftVariant').AsString := TestString;
-  }
-  FTestDataset.FieldByName('ftWideMemo').AsString := Teststring;
-  FTestDataset.FieldByName('ftWideString256').AsString := Teststring;
-  FTestDataset.FieldByName('ftWord').AsInteger := Abs(Testinteger);
-  //If I keep the output code below on Win32, I don't get an access violation.
-  //If I remove it, I do. Probably bug 19930 again?
-  for Fieldcounter := 0 to FTestDataset.Fields.Count - 1 do
-  begin
-    try
-      writeln('Field: ' + FTestDataset.Fields[FieldCounter].FieldName +
-        ' has value ' + FTestDataset.Fields[FieldCounter].AsString);
-      {writeln('Field: ' + FTestDataset.Fields[FieldCounter].FieldName +
-        ' has displaytext ' + FTestDataset.Fields[FieldCounter].DisplayText);}
-    except
-      on E: Exception do
-      begin
-        writeln('Field: ' + FTestDataset.Fields[FieldCounter].FieldName +
-          ': error retrieving value: ');
-        writeln(E.ClassName, '; detailed error message: ', E.message);
-      end;
-    end;
-  end;
-  writeln('*** Finished filling row ' + IntToStr(RowNumber));
-end;
-
-procedure Ttestxmlxsdexport1.Teardown;
-begin
-  FTestDataset.Free;
-end;
-
-initialization
-  Registertest(Ttestxmlxsdexport1);
-end.
-