Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

We have been using dbExpress for years. But too many bugs go unfixed and we are now forced to switch to ADO.

As we have been switching to ADO, we have found things that dbExpress handled differently than ADO. For instance, when pulling calculated fields, or data from a CTE query (which combines data from multiple tables into a single dataset), the TADOQuery flags each field as read-only. dbExpress didn't do that.

Now our client app won't let the read-only records be changed in any way, and all attempts to remove the read-only field attribute have failed.

Here is some contrived code to demonstrate the issue:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, Data.Win.ADODB, Datasnap.DBClient, Data.DB, ActiveX;

var
  con: TADOConnection; cds: TClientDataSet; qry: TADOQuery; i: Integer;

begin
  try
    CoInitialize(nil);
    try
      begin
        con := TADOConnection.Create(nil);
        try
          con.ConnectionString := 'Provider=SQLNCLI10.1;Integrated Security=SSPI;Initial Catalog=tempdb;Data Source=localhost';

          cds := TClientDataSet.Create(nil);
          try
            cds.DisableStringTrim := True;
            cds.ReadOnly := False;

            qry := TADOQuery.Create(nil);
            try
              qry.Connection := con;
              qry.SQL.Text := 'select 1 as ID, ''test'' as aString';
              cds.SetProvider(qry);
              cds.Open;

              { Attempting to change read-only flag -- nothing changes! }
              for i := 0 to cds.FieldDefs.Count - 1 do
                cds.FieldDefs[i].Attributes := cds.FieldDefs[i].Attributes - [faReadonly];

              cds.SaveToFile('c:\test.xml', dfXML);

            finally FreeAndNil(qry); end;
          finally FreeAndNil(cds); end;
        finally FreeAndNil(con); end;
      end;
    except
      on E: Exception do
        Writeln(E.ClassName, ': ', E.Message);
    end;
  finally
    CoUninitialize;
  end;
end.

Which produces this file:

<?xml version="1.0" standalone="yes"?>
<DATAPACKET Version="2.0">
  <METADATA>
    <FIELDS>
      <FIELD attrname="ID" fieldtype="i4" readonly="true"/>
      <FIELD attrname="aString" fieldtype="string" readonly="true" WIDTH="4"/>
    </FIELDS>
    <PARAMS/>
  </METADATA>
  <ROWDATA>
    <ROW ID="1" aString="test"/>
  </ROWDATA>
</DATAPACKET>

Notice the readonly="true" in the field defs.


Question

Our framework uses a generic TADOQuery and TClientDataSet components to pull and transfer the data from the database to the client app. The TADOQuery derives the field definitions from the data that is pulled from the database. So we can't setup the fields in advance, before pulling the data, and the field definitions seem to be static after pulling the data...

We don't save the data from the TClientDataSet to an XML file for real. It's just used here for demonstrative purposes, and it illustrates that the fields are flagged as read-only.

Does anyone know how to tweak the above code so the saved XML will not have the read-only="true" attribute? Our need is to allow users to edit all fields in the TClientDataSet.

share

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.