Ayant cherché longtemps de la documentation , en Oxygène ou même C#, sur le sujet sans succès, je vous partage une solution que j'utilise dans un Web Service avec FirebirdSQL 3.0 et de la compression.
Le WS plafonnait à +- 1k interactions seconde et FirebirdSQL semblait s'ennuyer.
Il y avait deux goulets dans ce processus, la requête SQL et la compression/base64 du dataset résultant.
namespace eai;
interface
uses
System,
System.Collections.Generic,
System.Linq,
System.Web,
System.Web.Services,
System.Threading,
System.Threading.Tasks,
System.Net,
System.IO,
Newtonsoft.Json,
Newtonsoft.Json.Bson,
System.Web.Script.Services,
System.Web.Script.Serialization,
System.Runtime.Serialization.Formatters.Binary,
System.Web.Script,
System.Data.SqlClient,
System.Data,
System.Configuration,
System.Text,
System.IO.Compression,
FirebirdSql.Data.FirebirdClient;
type
/// <summary>
/// Summary description for Service
/// </summary>
[WebService(&Namespace := 'http://eai.fi/')]
[WebServiceBinding(ConformsTo := WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
//[System.Web.Script.Services.ScriptService()]
Service = public class(System.Web.Services.WebService)
public
[WebMethod()]
//[ScriptMethod(UseHttpGet := true, ResponseFormat := ResponseFormat.Json)]
method GetLogToJson(np_time : System.String);
private
class method GetConnectionString: String;
protected
class method zipbase64string(ds:DataSet):String; async ;
end;
implementation
class method Service.GetConnectionString: String;
begin
exit ConfigurationManager.AppSettings['FirebirdLogConnectionString']
end;
class method Service.zipbase64string(ds:DataSet): String;
begin
var buffer: array of Byte := Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(ds, Formatting.None));
var memoryStream := new MemoryStream();
using gZipStream := new GZipStream(memoryStream, CompressionMode.Compress, true) do begin
gZipStream.Write(buffer, 0, buffer.Length)
end;
memoryStream.Position := 0;
var compressedData := new Byte[memoryStream.Length];
memoryStream.Read(compressedData, 0, compressedData.Length);
var gZipBuffer := new Byte[compressedData.Length + 4];
system.Buffer.BlockCopy(compressedData, 0, gZipBuffer, 4, compressedData.Length);
system.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gZipBuffer, 0, 4);
exit Convert.ToBase64String(gZipBuffer);
end;
method Service.GetLogToJson(np_time : System.String);
begin
if np_time.Trim = '' then exit;
var query := 'SELECT * FROM NP_LOG_VIEW_NOW where NP_TIME > @np_time;';
var arParams: array of FbParameter := new FbParameter[1] ;
arParams[0] := new FbParameter('@np_time', FbDbType.Time);
arParams[0].Direction := ParameterDirection.Input;
arParams[0].Value := Convert.ToDateTime(np_time);
var fawaiter_dataset : System.Threading.Tasks.Task<DataSet> := async FBSqlHelper.ExecuteDatasetaSync(GetConnectionString,query,arParams);
var dt : DataSet := fawaiter_dataset.Result;
var fawaiter_zip : System.Threading.Tasks.Task<String> := async zipbase64string(dt);
var data: String := fawaiter_zip.Result;
Context.Response.Clear();
Context.Response.ContentType := 'application/JsonZ64';
Context.Response.AppendHeader('Content-Length',data.Length.ToString);
Context.Response.Write(data);
Context.Response.Flush();
Context.Response.Close();
dt.Dispose;
end;
end.
En utilisant un awaiter sur chacun d'eux, c'est FirebirdSQL qui semblait ne plus suivre J
Comme vous pouvez le remarquer, c'est beaucoup, mais beaucoup plus simple à utiliser que tous ce que l'on peut lire sur la toile sur le sujet ;-)