Mostrando entradas con la etiqueta TDataSource. Mostrar todas las entradas
Mostrando entradas con la etiqueta TDataSource. Mostrar todas las entradas

miércoles, 23 de octubre de 2019

Editor simple de SQLite.

Son tan solo 200 líneas de código y desde ya, la librería de SQLite. Desde ya hay programas potentes y también portables como SQLite Studio, el cual uso y recomiendo. Volviendo al editor simple, lo hice para un uso muy específico y limitado, conecta a la base de datos que le indiquemos, muestra las tablas, permite ejecutar consultar cuyo resultado se muestra en un TDBGrid el cual cuenta con un par de opciones y ejecutar sentencias de actualizaciones que realiza mediante TZConnection.ExecuteDirect.
También tiene una opción para leer de un archivo un script SQL y luego ejecutarlo.
Creo que puede ser útil para quienes comiencen con SQLite, Lazarus y ZeosLib.


El código: descargar

unit principal;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils, db, FileUtil, Forms, Controls, Graphics, Dialogs,
StdCtrls, Buttons, DBGrids, DbCtrls, ZConnection, ZDataset;

type
  TConexion=(Conectado, NoConectado);

type

{ TForm1 }

TForm1 = class(TForm)
  BBorrarMemo: TBitBtn;
  BCerrarConsulta: TBitBtn;
  btnSelBD: TBitBtn;
  btnConectar: TBitBtn;
  BCerrar: TBitBtn;
  btnDesconectar: TBitBtn;
  BExecute: TBitBtn;
  BConsulta: TBitBtn;
  btnLeerArchivo: TBitBtn;
  cbAutoCommit: TCheckBox;
  cbAutoSizeCol: TCheckBox;
  DataSource1: TDataSource;
  DBGrid1: TDBGrid;
  DBNavigator1: TDBNavigator;
  edBaseDeDatos: TEdit;
  edConexion: TEdit;
  Label1: TLabel;
  lbTablas: TListBox;
  Memo1: TMemo;
  OpenDialog1: TOpenDialog;
  ZConnection1: TZConnection;
  ZQuery1: TZQuery;
  procedure BBorrarMemoClick(Sender: TObject);
  procedure BCerrarConsultaClick(Sender: TObject);
  procedure BConsultaClick(Sender: TObject);
  procedure BExecuteClick(Sender: TObject);
  procedure btnLeerArchivoClick(Sender: TObject);
  procedure btnSelBDClick(Sender: TObject);
  procedure btnConectarClick(Sender: TObject);
  procedure BCerrarClick(Sender: TObject);
  procedure btnDesconectarClick(Sender: TObject);
  procedure cbAutoSizeColChange(Sender: TObject);
  procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  procedure FormCreate(Sender: TObject);
  procedure lbTablasDblClick(Sender: TObject);
private
  Conexion:TConexion;
  procedure MuestroTablas;
  function HayConexion:Boolean;
{ private declarations }
public
{ public declarations }
end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  Conexion:=NoConectado;
end;

procedure TForm1.btnSelBDClick(Sender: TObject);
begin
  if OpenDialog1.Execute then edBaseDeDatos.Text:= OpenDialog1.FileName;
end;

procedure TForm1.btnLeerArchivoClick(Sender: TObject);
begin
 if OpenDialog1.Execute then Memo1.Lines.LoadFromFile(OpenDialog1.FileName);
end;

procedure TForm1.BBorrarMemoClick(Sender: TObject);
begin
  Memo1.Clear;
end;

procedure TForm1.BCerrarConsultaClick(Sender: TObject);
begin
  ZQuery1.Close;
end;

procedure TForm1.BConsultaClick(Sender: TObject);
begin
  if not(HayConexion) then Exit;
  ZQuery1.Close;
  ZQuery1.SQL.Text:=Memo1.Text;
  ZQuery1.Open;
end;

procedure TForm1.BExecuteClick(Sender: TObject);
var
  n:Integer;
begin
  if not(HayConexion) then Exit;
  if ZConnection1.ExecuteDirect(Memo1.Text, n) then Memo1.Lines.Add('OK! '+IntToStr(n)+'      filas.');
end;

procedure TForm1.btnConectarClick(Sender: TObject);
begin
  if Conexion=Conectado then
  begin
    ShowMessage('Hay una conexión establecida, primero desconecte dicha conexión.');
    Exit;
  end;
  if not (FileExists(edBaseDeDatos.Text)) then exit;
  ZConnection1.Database:=edBaseDeDatos.Text;
  if not(cbAutoCommit.Checked) then ZConnection1.AutoCommit:=False;
  ZConnection1.Connect;
  if ZConnection1.Connected then
  begin
    edConexion.Text:='Conectado';
    edConexion.Font.Color:=clGreen;
    Conexion:=Conectado;
    MuestroTablas;
  end;
end;

procedure TForm1.BCerrarClick(Sender: TObject);
begin
  Close;
end;

procedure TForm1.btnDesconectarClick(Sender: TObject);
begin
  ZConnection1.Disconnect;
  edConexion.Text:='Desconectado';
  edConexion.Font.Color:=clRed;
  Conexion:=NoConectado;
  lbTablas.Clear;
end;

procedure TForm1.cbAutoSizeColChange(Sender: TObject);
begin
  if cbAutoSizeCol.Checked then DBGrid1.AutoFillColumns:=False else DBGrid1.AutoFillColumns:=True;
end;

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  ZConnection1.Disconnect;
  CloseAction:=caFree;
end;

procedure TForm1.lbTablasDblClick(Sender: TObject);
begin
  if not(HayConexion) then Exit;
  Memo1.Clear;
  Memo1.Lines.Add('SELECT * FROM '+lbTablas.Items[lbTablas.ItemIndex]+';');
  ZQuery1.Close;
  ZQuery1.SQL.Text:=Memo1.Text;
  ZQuery1.Open;
end;

procedure TForm1.MuestroTablas;
var
  ZQTablas:TZQuery;
begin
  lbTablas.Clear;
  ZQTablas:=TZQuery.Create(nil);
  ZQTablas.Connection:=ZConnection1;
  ZQTablas.SQL.Text:='SELECT name FROM sqlite_master WHERE type='+
  QuotedStr('table')+' and name <>'+QuotedStr('sqlite_sequence');
  ZQTablas.Open;
  if ZQTablas.RecordCount <1 then Exit;
  ZQTablas.First;
  while not(ZQTablas.EOF) do
  begin
    lbTablas.AddItem(ZQTablas.FieldByName('name').AsString,lbTablas);
    ZQTablas.Next;
  end;
  ZQTablas.Close;
  FreeAndNil(ZQTablas);
end;

function TForm1.HayConexion: Boolean;
begin
  if not(ZConnection1.Connected) then
  begin
    Memo1.Lines.Add('No hay establecida ninguna conexión.');
    Exit(False);
  end;
  Result:=True;
end;

end.


miércoles, 23 de mayo de 2018

TDataSource cuándo usarlo?

Lazarus, Free Pascal y muchos de sus componentes son sencillamente espectaculares, más aún teniendo en cuenta que es un proyecto de código abierto que comenzó hace muchos años (2001 creo), con pocos programadores para tamaño proyecto, actualmente entre Free Pascal y Lazarus, son unos 20.
El problema, lo dije desde un principio cuando retomé la programación, motivado por la existencia del IDE Lazarus, es la documentación, muchas veces inexistente y otras veces hay que dedicar mucho tiempo para dar con ella.
Los tutoriales para trabajar con bases de datos son pocos, algunos desactualizados y casi siempre los mismo ejemplos.
Es así como aprendí que para conectar y trabajar con una BD se necesitan 3 componentes: el conector (TZConnection), la consulta (TZQuery) y la fuente de datos (TDataSource). Pues no es así. Me di cuenta leyendo y participando del foro, cuando un usuario planteó una duda y detecté que en su código no utilizaba ningún TDataSource, le pregunté y me respondió si era necesario. Me sembró la duda y de hecho la respuesta es: No. Eso es cambia mucho mi panorama, para empezar no necesitaré tantos data modules si solo tengo un para de consultas, puedo declarar las conexiones y consultas sin necesidad de utilizar el data aware y que no molesten en el Form. Ahora entiendo por qué una vez me dijeron que cuando comienzas con esto, usas todo data aware y luego vas directamente por el código, y así es.

El data aware TDataSource solo es necesario cuando necesitamos enlazar los datos con un componente como puede ser un DBGrid, DBComboBox, etc. caso contrario no es necesario.

El ícono es muy claro, el componente envía los datos de un TDataSet hacia otros componentes, es indispensable para un TDBGrid por ejemplo, por eso es que el DataSource se debe vincular con un DataSet (y éste con un conector) y lo que alimenta al DBGrid es el DataSource. Ahora si no necesitamos alimentar ningún control, entonces no es necesario utilizar ningún DataSource.