Subject Re: [IBO] dssEdit
Author Helen Borrie
At 07:22 PM 25/01/2003 +0000, you wrote:
>I am thoroughly confused ! (As usual).
>
>What is he significance of the various dssEdit, dssInsert etc
>as the state of a dataset ?
>How are they caused ?

Does it help to know that dssEdit, etc. in the native IBO dataset are
equivalent to dsEdit in the VCL datasets? dss* are dataset states - and
they apply to datasets.

A dataset is always in one state. A state change occurs as the result of a
sequence of events. That sequence is triggered off by a call to a method.

The neutral state is dssBrowse. So, if you want to think of it
simplistically, a call to the dataset's Edit method causes the dataset to
transit through from dssBrowse to dssEdit - unless the dataset cursor is at
the end of the dataset (EOF), in which case it will transit through to
dssInsert instead.

I use the term "transit" because it isn't like simply flicking a
switch. The dataset has to check various conditions and perform various
actions before the state change can be considered "ready to go". Once all
of those things are done, the state change happens.

>And which comes first.

The SQL statement ---
defines the interchange that you want to happen between the client and the
server. A SELECT statement is a specification for a dataset. An INSERT,
UPDATE or DELETE statement doesn't specify a dataset. No SQL statement
assignment of itself changes the *state* of the dataset.

The Prepare method ---
is not confined to statements that specify datasets (SELECT
statements). Prepare starts a conversation between client and server that
involves sending a statement of any kind to the server for approval. If
the server thinks the statement is OK, it sends back a message to the
client that includes information that your application needs to have in
order to permit its subsequent method calls to work.

Updatable datasets (remember, they are formed from SELECT statements)
comprise several SQL statements. The properties InsertSQL, EditSQL,
DeleteSQL and LockSQL are all SQL statements that we refer to as "DML
statements". DML is a mnemonic for Data Manipulation Language - the subset
of SQL that is capable of changing data.

If a dataset is naturally updatable AND we indicate that we want it to be,
by setting RequestLive true, then the dataset constructs the appropriate
xxxxSQL statement when it discovers it needs to. It uses the data
characteristics of the SELECT query specification to work out what the
statement should be. If it doesn't already know what that statement is, it
will calculate it as part of its activity during the transition from
dssBrowse to whatever DML method has been called.

So, if you call the dataset's INSERT method, and the dataset doesn't
already have something in the InsertSQL property, it will try to calculate one.

If a Prepare on this InsertSQL statement is needed, an internal call to
Prepare *for that statement* will be done when the Post method is called,
i.e. AFTER the user has entered her data.

The IBO datasets provide for you to provide your own statements to be used
for inserts, updates, deletes and pessimistic locking. You typically use
this capability when you want a naturally non-updatable dataset to be
"live", or when you need your dataset's DML operation to perform a series
of statements instead of just one. In this case, you supply your own
xxxxSQL statement, typically a call to a stored procedure with input
parameters derived from the dataset's keys.

Except in Inserts, the relationship between the dataset's keys and the
operation that is to be done by the xxxxSQL statement (your supplied one,
or the one that the dataset constructs) is crucial. That's why a dataset
needs correct KeyLinks in order for edits (updates), deletes and locking to
succeed.

>If I write an SQL "insert into Mytable ...."
>then 'prepare' does this set the dss State at prepare time.
>Or in the case of a TIB_query with a select statment does
>MyQuery.insert change it into an insert SQL statement ??

It will help to understand that state changes in the dataset happen as the
result of other things that happen *within the dataset*. Preparing a
dataset does not change its state; but, by the same token, there are some
things that can't happen unless the statement is prepared; and there are
some state changes that can't happen while the statement in question is
unprepared.

IBO takes care of the required preparing and unpreparing most of the
time. This is always true of the statements encapsulated in a TIB_Dataset
descendant, even a TIB_StoredProc which doesn't return a dataset (is
executed, not selected). Under some conditions, it is a good idea to test
the "raw" TIB_Statement descendant, TIB_DSQL (if not Prepared then Prepare).

IB 6.0 and IB 5.x have a bug which necessitates Unpreparing and Preparing a
stored procedure, whether in an IB_DSQL or an IB_StoredProc, each time
Execute is called. That is because the message returned to the client from
the server after execution contains an invalid structure that prevents the
next execution from getting new input values for the parameters. The bug
was fixed in Firebird and probably IB 6.5 and onward, since Borland took
all of Firebird's bug fixes across to their 6.5 codebase. If you are using
IB, you need to take care of this yourself, because the IBO datasets - as
well as the VCL ones - can't detect whether you are using a database
version that has this bug.

>ANy clarification welcomed. I have read and re-read the GSG but remain
>confused.

There is a diagram in the GSG that models the cycle of dataset state
changes in response to the method calls. It is the same concept that is
implemented in the VCL, except that the native IBO datasets have two extra
states that support their capability for encapsulated searching. The GSG
is not intended to be a Delphi beginner guide - it needs to be used in
conjunction with the Delphi help if you are not already familiar with the
VCL. It sounds as if you'd get some enlightenment by reading the Delphi
help for the State property of datasets...

cheers,
Helen