unit uDbParamsHelper;

interface

uses
  Data.DB, FireDAC.Stan.Param, FireDAC.Comp.Client, System.SysUtils, System.Math;

/// <summary>
/// Asigna un parámetro de cadena garantizando codificación Unicode (ftWideString)
/// y evitando desbordamientos de buffer o caracteres extraños en MariaDB/MySQL.
/// </summary>
procedure SetParamString(AParam: TFDParam; const AValue: string); overload;
procedure SetParamString(AQuery: TFDQuery; const AParamName, AValue: string); overload;

/// <summary>
/// Asigna un parámetro de texto largo / enriquecido (ftWideMemo) garantizando
/// UTF-16 Unicode nativo sin truncado ni corrupción de memoria en MariaDB/MySQL.
/// </summary>
procedure SetParamMemo(AParam: TFDParam; const AValue: string); overload;
procedure SetParamMemo(AQuery: TFDQuery; const AParamName, AValue: string); overload;

/// <summary>
/// Asigna inteligentemente texto corto o largo según longitud y contenido.
/// </summary>
procedure SetParamText(AParam: TFDParam; const AValue: string); overload;
procedure SetParamText(AQuery: TFDQuery; const AParamName, AValue: string); overload;

/// <summary>
/// Asigna un parámetro entero de forma segura.
/// </summary>
procedure SetParamInt(AParam: TFDParam; const AValue: Integer); overload;
procedure SetParamInt(AQuery: TFDQuery; const AParamName: string; const AValue: Integer); overload;

/// <summary>
/// Asigna un parámetro booleano de forma segura como 1/0 en MariaDB (tinyint).
/// </summary>
procedure SetParamBool(AParam: TFDParam; const AValue: Boolean); overload;
procedure SetParamBool(AQuery: TFDQuery; const AParamName: string; const AValue: Boolean); overload;

implementation

procedure SetParamString(AParam: TFDParam; const AValue: string);
begin
  if AParam = nil then Exit;
  AParam.DataType := ftWideString;
  AParam.Size := Max(100, (Length(AValue) * 4) + 64);
  AParam.AsWideString := AValue;
end;

procedure SetParamString(AQuery: TFDQuery; const AParamName, AValue: string);
var
  LP: TFDParam;
begin
  if AQuery = nil then Exit;
  LP := AQuery.FindParam(AParamName);
  if LP <> nil then
    SetParamString(LP, AValue);
end;

procedure SetParamMemo(AParam: TFDParam; const AValue: string);
begin
  if AParam = nil then Exit;
  AParam.DataType := ftWideMemo;
  AParam.AsWideMemo := AValue;
end;

procedure SetParamMemo(AQuery: TFDQuery; const AParamName, AValue: string);
var
  LP: TFDParam;
begin
  if AQuery = nil then Exit;
  LP := AQuery.FindParam(AParamName);
  if LP <> nil then
    SetParamMemo(LP, AValue);
end;

procedure SetParamText(AParam: TFDParam; const AValue: string);
begin
  if AParam = nil then Exit;
  // Si el texto supera 200 caracteres o contiene etiquetas HTML, usar ftWideMemo
  if (Length(AValue) > 200) or (Pos('<', AValue) > 0) then
    SetParamMemo(AParam, AValue)
  else
    SetParamString(AParam, AValue);
end;

procedure SetParamText(AQuery: TFDQuery; const AParamName, AValue: string);
var
  LP: TFDParam;
begin
  if AQuery = nil then Exit;
  LP := AQuery.FindParam(AParamName);
  if LP <> nil then
    SetParamText(LP, AValue);
end;

procedure SetParamInt(AParam: TFDParam; const AValue: Integer);
begin
  if AParam = nil then Exit;
  AParam.DataType := ftInteger;
  AParam.AsInteger := AValue;
end;

procedure SetParamInt(AQuery: TFDQuery; const AParamName: string; const AValue: Integer);
var
  LP: TFDParam;
begin
  if AQuery = nil then Exit;
  LP := AQuery.FindParam(AParamName);
  if LP <> nil then
    SetParamInt(LP, AValue);
end;

procedure SetParamBool(AParam: TFDParam; const AValue: Boolean);
begin
  if AParam = nil then Exit;
  AParam.DataType := ftSmallint;
  if AValue then
    AParam.AsSmallInt := 1
  else
    AParam.AsSmallInt := 0;
end;

procedure SetParamBool(AQuery: TFDQuery; const AParamName: string; const AValue: Boolean);
var
  LP: TFDParam;
begin
  if AQuery = nil then Exit;
  LP := AQuery.FindParam(AParamName);
  if LP <> nil then
    SetParamBool(LP, AValue);
end;

end.
