Simple task = create database

Discussion of open issues, suggestions and bugs regarding UniDAC (Universal Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
oz8hp
Posts: 151
Joined: Mon 18 Feb 2008 13:28
Location: Denmark
Contact:

Simple task = create database

Post by oz8hp » Fri 20 Apr 2012 12:59

I have been struggling with a function that allows users to create a new db for my apps
It has to be a universal function as some use MS Access, some SQLite and others MySQL

Is there any sample code somewhere in the supplied demo that can do this (I have spend hours looking without finding it) or is there some place where it can be found?

AlexP
Devart Team
Posts: 5530
Joined: Tue 10 Aug 2010 11:35

Post by AlexP » Fri 20 Apr 2012 14:57

Hello,

MS Access and SQLite are local file DBs, i.e. their creating means file creating. MySQL is a server DB, which is created with the help of a DDL operator. Therefore, there is no unified way of creating DBs in our components. However you can implement your method that would be able to create a DB depending on a choosen server type.
SQLite automatically creates a new DB when attempting to connect to a nonexistent DB file. For creating a MS Access DB, methods from the odbccp32.dll library can be used. A MySQL DB can be created with the help of the DDL comand - CREATE DATABASE.

The following simple example demonstrates creating of different DBs.

Code: Select all

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ODBCUniProvider, AccessUniProvider, SQLiteUniProvider,
  UniProvider, MySQLUniProvider, DB, DBAccess, Uni;

type
  TForm1 = class(TForm)
    UniConnection1: TUniConnection;
    MySQLUniProvider1: TMySQLUniProvider;
    SQLiteUniProvider1: TSQLiteUniProvider;
    AccessUniProvider1: TAccessUniProvider;
    Button1: TButton;
  private
    { Private declarations }
    function CreateDataBase(UniConnection: TUniConnection; const DatabaseName:string):boolean;
  public
    { Public declarations }
  end;

TSQLConfigDataSource = function(hwndParent: Integer; fRequest: Integer;
                                lpszDriverString: string;
                                lpszAttributes: string): Smallint; stdcall;

var
  Form1: TForm1;

implementation

{$R *.dfm}

Function SQLConfigDataSource(hwndParent: Integer; fRequest: Integer;
  lpszDriverString: string; lpszAttributes: string): Integer; stdcall;
var
  func : TSQLConfigDataSource;
  ODBCHModule: HMODULE;
begin
  ODBCHModule := LoadLibrary('odbccp32.dll');
  if ODBCHModule = 0 then
    raise Exception.Create(SysErrorMessage(GetLastError));
  func :=  GetProcAddress(ODBCHModule,PChar('SQLConfigDataSource'));
  if @func = nil then
    raise Exception.Create('Error Getting adress for SQLConfigDataSource' + SysErrorMessage(GetLastError));

  Result := func(hwndParent, fRequest, lpszDriverString, lpszAttributes);
  FreeLibrary(ODBCHModule);
end;


function TForm1.CreateDataBase(UniConnection: TUniConnection; const DatabaseName: string): boolean;
var
  oldConnected: Boolean;
begin
  Result:= false;
  if UniConnection.ProviderName = 'Access' then
    Result := SQLConfigDataSource(0, 1, 'Microsoft Access Driver (*.mdb)','CREATE_DB="' + DatabaseName + '"')  1
  else if UniConnection.ProviderName = 'SQLite' then
  begin
    oldConnected := UniConnection.Connected;
    If UniConnection.Connected then
      UniConnection.Disconnect;
    UniConnection.Database := 'DatabaseName';
    try
      UniConnection.Connect;
    except
    end;
    Result:= True;
    if not oldConnected then
      UniConnection.Disconnect;
  end
  else if UniConnection.ProviderName = 'MySQL' then
  begin
    try
      UniConnection.ExecSQL('CREATE DATABASE ' + DatabaseName,[]);
    except
    end;
    REsult := True;
  end;
end;

end.

Post Reply