Hello:

We are going to need to implement the version 11 of the Firebird 
Protocol and review the buffer handling code to make better checks on 
buffer lengths and server resposnses.

Now the Firebird server supports batching of messages ( not available 
for all of them ), so we can send several messages in the same request 
and retrieve all the answers at the same time.

An example will be the statement preparation, in the actual GDS 
implementation we make two calls to the server:

    1. To prepare the statement
    2. To get the statement type

Now we can send them in the same request to the server, something like this:

        public override void Prepare(string commandText)
        {
            // Clear data
            this.Clear();
            this.parameters = null;
            this.fields = null;

            lock (this.db)
            {
                if (this.state == StatementState.Deallocated)
                {
                    // Allocate    statement
                    this.Allocate();
                }

                try
                {
                    // Prepare the statement
                    this.db.Send.Write(IscCodes.op_prepare_statement);
                    this.db.Send.Write(this.transaction.Handle);
                    this.db.Send.Write(this.handle);
                    this.db.Send.Write((int)this.db.Dialect);
                    this.db.Send.Write(commandText);
                    this.db.Send.WriteBuffer(DescribeInfoItems, 
DescribeInfoItems.Length);
                    this.db.Send.Write(IscCodes.MAX_BUFFER_SIZE);

                    // Grab statement type
                    this.db.Send.Write(IscCodes.op_info_sql);
                    this.db.Send.Write(this.handle);
                    this.db.Send.Write(0);
                    this.db.Send.WriteBuffer(StatementTypeInfoItems, 
StatementTypeInfoItems.Length);
                    this.db.Send.Write(IscCodes.STATEMENT_TYPE_BUFFER_SIZE);

                    // Flush data
                    this.db.Send.Flush();

                    // Prepare statement info processing
                    GdsGenericResponse response = 
(GdsGenericResponse)this.db.ReadResponse();

                    this.fields = this.ParseSqlInfo(response.Data, 
DescribeInfoItems);

                    // Statement type information processing
                    GdsGenericResponse stmtmTypeResponse = 
(GdsGenericResponse)this.db.ReadResponse();

                    this.statementType = 
this.ParseStatementTypeInfo(stmtmTypeResponse.Data);

                    this.state = StatementState.Prepared;
                }
                catch (IOException)
                {
                    this.state = StatementState.Error;
                    throw new IscException(IscCodes.isc_net_read_err);
                }
            }
        }


Another example, could be the statement execution method that makes two 
calls ( wehn execution insert, updates, deletes )

    1. To execute the statement
    2. To retrieve the number of rows affected by the statement execution

Now we can send them in the same request to the server, something like this:

        public override void Execute()
        {
            if (this.state == StatementState.Deallocated)
            {
                throw new InvalidOperationException("Statment is not 
correctly created.");
            }

            // Clear data
            this.Clear();

            lock (this.db)
            {
                try
                {
                    byte[] descriptor = null;

                    if (this.parameters != null)
                    {
                        XdrStream xdr = new XdrStream(this.db.Charset);
                        xdr.Write(this.parameters);

                        descriptor = xdr.ToArray();

                        xdr.Close();
                    }

                    if (this.statementType == 
DbStatementType.StoredProcedure)
                    {
                        this.db.Send.Write(IscCodes.op_execute2);
                    }
                    else
                    {
                        this.db.Send.Write(IscCodes.op_execute);
                    }

                    this.db.Send.Write(this.handle);
                    this.db.Send.Write(this.transaction.Handle);

                    if (this.parameters != null)
                    {
                        
this.db.Send.WriteBuffer(this.parameters.ToBlrArray());
                        this.db.Send.Write(0);    // Message number
                        this.db.Send.Write(1);    // Number of messages
                        this.db.Send.Write(descriptor, 0, 
descriptor.Length);
                    }
                    else
                    {
                        this.db.Send.WriteBuffer(null);
                        this.db.Send.Write(0);
                        this.db.Send.Write(0);
                    }

                    if (this.statementType == 
DbStatementType.StoredProcedure)
                    {
                        this.db.Send.WriteBuffer((this.fields == null) ? 
null : this.fields.ToBlrArray());
                        this.db.Send.Write(0);    // Output message number
                    }

                    // Obtain records affected by query execution
                    if (this.ReturnRecordsAffected &&
                        (this.StatementType == DbStatementType.Insert ||
                        this.StatementType == DbStatementType.Delete ||
                        this.StatementType == DbStatementType.Update ||
                        this.StatementType == 
DbStatementType.StoredProcedure ||
                        this.StatementType == DbStatementType.Select))
                    {
                        // Grab statement type
                        this.db.Send.Write(IscCodes.op_info_sql);
                        this.db.Send.Write(this.handle);
                        this.db.Send.Write(0);
                        
this.db.Send.WriteBuffer(RecordsAffectedInfoItems, 
RecordsAffectedInfoItems.Length);
                        
this.db.Send.Write(IscCodes.ROWS_AFFECTED_BUFFER_SIZE);

                        this.recordsAffected = 0;
                    }
                    else
                    {
                        this.recordsAffected = -1;
                    }                   

                    this.db.Send.Flush();

                    if (this.db.NextOperation() == IscCodes.op_sql_response)
                    {
                        // This would be an Execute procedure
                        
this.outputParams.Enqueue(this.ReadStoredProcedureOutput());
                    }

                    this.db.ReadResponse();

                    if (this.recordsAffected == 0)
                    {
                        GdsGenericResponse response = 
(GdsGenericResponse)this.db.ReadResponse();
                        this.ProcessRecordsAffectedBuffer(response.Data);
                    }

                    this.state = StatementState.Executed;
                }
                catch (IOException)
                {
                    this.state = StatementState.Error;
                    throw new IscException(IscCodes.isc_net_read_err);
                }
            }
        }





For the new GDS implementation, my first thought is that we can make all 
the public methods on the current GDS implementation virtual, and 
override ( and rewrite ) them in the new GDS implementation ( i will try 
to check if that approach will be possible or not ... i think it's but 
.. better to be sure XD )









-- 
Carlos Guzmán Álvarez
Vigo-Spain

http://carlosga.wordpress.com


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Firebird-net-provider mailing list
Firebird-net-provider@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/firebird-net-provider

Reply via email to