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