Merhaba Arkadaşlar,
"Evrensel Veri Adaptörü" ismini verdiğim proje aşağıdaki gibidir.
Her yazılımcı bir gün PHP tadacak mıdır ? konusunda aşağıdaki paylaşımım olmuştu.
Kısaca bahsedecek olursak bu yapı, aynı zamanda veri tabanını dışarıya açmadan güvenli bir şekilde iletişim kurmanızı sağlayan, aynı networkte çalışan tüm veri tabanlarınıza aynı port üzerinden erişim sağlayan bir yapıdır. Şimdilik şemada belirtilen 5 veri tabanı (PostgreSQL, Oracle, MsSQL, MySQL, Firebird) eklenmiştir. Siz çoğaltabilirsiniz. Ben çoklu db desteği olan UniDac' ı tercih ettim. Siz FireDac ya da başka bir Dac tercih edebilirsiniz.
İstemci tarafından tek JSON objesi içerisinde bağlantı bilgileri ve sorgu bilgileri (sorgu + parametreler) beklenmektedir.
Örn JSON :
Çalışma şeması basitçe aşağıdaki gibidir;
UServerMethods içeriği;
UMadDB içeriği;
UWebModule içeriği;
Proje ekte yer almaktadır.
Konunun 2. aşamasında PHP client tarafından bahsedeceğim.
Umarım faydası olur...
"Evrensel Veri Adaptörü" ismini verdiğim proje aşağıdaki gibidir.
Her yazılımcı bir gün PHP tadacak mıdır ? konusunda aşağıdaki paylaşımım olmuştu.
Alıntı:Firebird, MSSQL gibi veri tabanlarında istemci sürücülerinde linux tarafında sorunlar yaşanabileceği için, windowsta çalışan dinamik bir Datasnap+Rest Server yazdım (Standalone web server tipinde). Bağlantı bilgilerini, sorguyu ve parametreleri json olarak alıp, işleyip, dataseti json olarak döndüren ve sonucu bildiren, execute işleminde sonucu bildiren bir yapı oldu. Bu şekilde PHP ile tüm veri tabanlarına çok rahat ve hızlı bir şekilde bağlanabiliyorum. Talep eden arkadaşlarla paylaşabilirim.
Kısaca bahsedecek olursak bu yapı, aynı zamanda veri tabanını dışarıya açmadan güvenli bir şekilde iletişim kurmanızı sağlayan, aynı networkte çalışan tüm veri tabanlarınıza aynı port üzerinden erişim sağlayan bir yapıdır. Şimdilik şemada belirtilen 5 veri tabanı (PostgreSQL, Oracle, MsSQL, MySQL, Firebird) eklenmiştir. Siz çoğaltabilirsiniz. Ben çoklu db desteği olan UniDac' ı tercih ettim. Siz FireDac ya da başka bir Dac tercih edebilirsiniz.
İstemci tarafından tek JSON objesi içerisinde bağlantı bilgileri ve sorgu bilgileri (sorgu + parametreler) beklenmektedir.
Örn JSON :
{
"connection_info": {
"db_type": "SQLServer",
"host": "x.y.z.t",
"port": 1433,
"database": "ABC",
"user": "aaa",
"password": "bbb",
"additional_specs": ""
},
"query_info": {
"query": "SELECT * FROM xyz where a=:a and b=:b",
"params": {
"a": "5",
"b": "x"
}
},
"type": "Q"
}
Çalışma şeması basitçe aşağıdaki gibidir;
UServerMethods içeriği;
unit UServerMethods;
interface
uses System.SysUtils, System.Classes, System.Json,
Datasnap.DSServer, Datasnap.DSAuth, DataSnap.DSProviderDataModuleAdapter,
Data.DB, MemDS, DBAccess, Uni, UniProvider, UMadDB, InterBaseUniProvider,
Data.FireDACJSONReflect, dialogs, forms,
Data.DBXCommon, Data.DBXPlatform, inifiles;
type
{$METHODINFO ON}
TServerMethods = class(TDataModule)
function Query(Params : TJSONObject) : TJSONArray;
function Execute(Params : TJSONObject) : Boolean;
private
{ Private declarations }
public
{ Public declarations }
end;
{$METHODINFO OFF}
implementation
uses DataSetConverter4D, DataSetConverter4D.Impl, UMain;
{$R *.dfm}
function TServerMethods.Query(Params : TJSONObject) : TJSONArray;
var
ConnectionInfo : TConnectionInfo;
Con : TUniConnection;
Qry : TUniQuery;
db_info : TJSONObject;
query_info : TJSONObject;
process_type : String;
query_params : TJSONObject;
i : integer;
begin
ConnectionInfo := TConnectionInfo.Create;
db_info := TJSONObject(Params.Get('connection_info').JsonValue);
query_info := TJSONObject(Params.Get('query_info').JsonValue);
process_type := Params.Get('type').JsonValue.Value;
if db_info.Get('db_type').JsonValue.Value = 'SQLServer'
then begin
ConnectionInfo.DBType := SQLServer;
end else if db_info.Get('db_type').JsonValue.Value = 'FireBird'
then begin
ConnectionInfo.DBType := FireBird;
end else if db_info.Get('db_type').JsonValue.Value = 'MySQL'
then begin
ConnectionInfo.DBType := MySQL;
end else if db_info.Get('db_type').JsonValue.Value = 'Oracle'
then begin
ConnectionInfo.DBType := Oracle;
end else if db_info.Get('db_type').JsonValue.Value = 'PostgreSQL'
then begin
ConnectionInfo.DBType := PostgreSQL;
end;
ConnectionInfo.Host := db_info.Get('host').JsonValue.Value;
ConnectionInfo.Port := db_info.Get('port').JsonValue.Value.ToInteger;
ConnectionInfo.Database := db_info.Get('database').JsonValue.Value;
ConnectionInfo.User := db_info.Get('user').JsonValue.Value;
ConnectionInfo.Password := db_info.Get('password').JsonValue.Value;
ConnectionInfo.AdditionalSpecs := db_info.Get('additional_specs').JsonValue.Value;
Con := MadDB.getConnection(ConnectionInfo);
Qry := TUniQuery.Create(nil);
Qry.Connection := Con;
Qry.SQL.Add(query_info.Get('query').JsonValue.Value);
if frmMain.chkLogging.Checked then
begin
//frmmain.Memo1.Lines.Clear;
frmMain.memo1.Lines.Add('----- Sorgu -----');
frmmain.Memo1.Lines.Add(Qry.SQL.Text);
end;
query_params := TJSONObject(query_info.Get('params').JsonValue);
if query_params.Count > 0 then
begin
if frmMain.chkLogging.Checked then
begin
frmMain.memo1.Lines.Add('----- Parametreler -----');
end;
end;
for i := 0 to query_params.Count - 1 do
begin
if frmMain.chkLogging.Checked then
begin
frmMain.memo1.Lines.Add(TJSONObject(query_params).Pairs[i].JsonString.Value + ' : ' + TJSONObject(query_params).Pairs[i].JsonValue.Value);
end;
Qry.ParamByName(TJSONObject(query_params).Pairs[i].JsonString.Value).Value := TJSONObject(query_params).Pairs[i].JsonValue.Value;
end;
try
Qry.Open;
Result := TConverter.New.DataSet(Qry).AsJSONArray;
except on E : Exception do
begin
frmMain.memo1.Lines.Add('----- Hata -----');
frmmain.Memo1.Lines.Add(E.Message);
frmMain.memo1.Lines.Add('-----');
Result := TJSONArray(E.Message);
end;
end;
Qry.Close;
Con.Disconnect;
FreeAndNil(Qry);
FreeAndNil(Con);
FreeAndNil(ConnectionInfo);
db_info := nil;
query_info := nil;
query_params := nil;
end;
function TServerMethods.Execute(Params : TJSONObject) : Boolean;
var
ConnectionInfo : TConnectionInfo;
Con : TUniConnection;
Qry : TUniQuery;
db_info : TJSONObject;
query_info : TJSONObject;
process_type : String;
query_params : TJSONObject;
i : integer;
begin
ConnectionInfo := TConnectionInfo.Create;
db_info := TJSONObject(Params.Get('connection_info').JsonValue);
query_info := TJSONObject(Params.Get('query_info').JsonValue);
process_type := Params.Get('type').JsonValue.Value;
if db_info.Get('db_type').JsonValue.Value = 'SQLServer'
then begin
ConnectionInfo.DBType := SQLServer;
end else if db_info.Get('db_type').JsonValue.Value = 'FireBird'
then begin
ConnectionInfo.DBType := FireBird;
end else if db_info.Get('db_type').JsonValue.Value = 'MySQL'
then begin
ConnectionInfo.DBType := MySQL;
end else if db_info.Get('db_type').JsonValue.Value = 'Oracle'
then begin
ConnectionInfo.DBType := Oracle;
end else if db_info.Get('db_type').JsonValue.Value = 'PostgreSQL'
then begin
ConnectionInfo.DBType := PostgreSQL;
end;
ConnectionInfo.Host := db_info.Get('host').JsonValue.Value;
ConnectionInfo.Port := db_info.Get('port').JsonValue.Value.ToInteger;
ConnectionInfo.Database := db_info.Get('database').JsonValue.Value;
ConnectionInfo.User := db_info.Get('user').JsonValue.Value;
ConnectionInfo.Password := db_info.Get('password').JsonValue.Value;
ConnectionInfo.AdditionalSpecs := db_info.Get('additional_specs').JsonValue.Value;
Con := MadDB.getConnection(ConnectionInfo);
Qry := TUniQuery.Create(nil);
Qry.Connection := Con;
Qry.SQL.Add(query_info.Get('query').JsonValue.Value);
if frmMain.chkLogging.Checked then
begin
frmMain.memo1.Lines.Add('----- Sorgu (E) -----');
frmmain.Memo1.Lines.Add(Qry.SQL.Text);
end;
query_params := TJSONObject(query_info.Get('params').JsonValue);
for i := 0 to query_params.Count - 1 do
begin
Qry.ParamByName(TJSONObject(query_params).Pairs[i].JsonString.Value).Value := TJSONObject(query_params).Pairs[i].JsonValue.Value;
end;
try
Qry.ExecSQL;
Result := true;
except
Result := false;
end;
Qry.Close;
Con.Disconnect;
FreeAndNil(Qry);
FreeAndNil(Con);
FreeAndNil(ConnectionInfo);
db_info := nil;
query_info := nil;
query_params := nil;
end;
end.
UMadDB içeriği;
unit UMadDB;
interface
uses
System.SysUtils, System.Classes, Data.DB, DBAccess, Uni, InterBaseUniProvider,
UniProvider, SQLServerUniProvider, PostgreSQLUniProvider, OracleUniProvider,
MySQLUniProvider;
type
TDBType = (SQLServer, FireBird, MySQL, Oracle, PostgreSQL);
TConnectionInfo = Class
private
FDBType : TDBType;
FHost : String;
FPort : Integer;
FDatabase : String;
FUser : String;
FPassword : String;
FAdditionalSpecs : String;
public
property DBType : TDBType read FDBType write FDBType;
property Host : String read FHost write FHost;
property Port : Integer read FPort write FPort;
property Database : String read FDatabase write FDatabase;
property User : String read FUser write FUser;
property Password : String read FPassword write FPassword;
property AdditionalSpecs : String read FAdditionalSpecs write FAdditionalSpecs;
end;
TMadDB = class(TDataModule)
SQLServerUniProvider1: TSQLServerUniProvider;
InterBaseUniProvider1: TInterBaseUniProvider;
MySQLUniProvider1: TMySQLUniProvider;
OracleUniProvider1: TOracleUniProvider;
PostgreSQLUniProvider1: TPostgreSQLUniProvider;
function getConnection(dbInfo : TConnectionInfo) : TUniConnection;
private
{ Private declarations }
public
{ Public declarations }
end;
var
MadDB: TMadDB;
implementation
function TMadDB.getConnection(dbInfo : TConnectionInfo) : TUniConnection;
var
conn : TUniConnection;
begin
conn := TUniConnection.Create(nil);
case dbInfo.DBType of
SQLServer : begin
conn.ProviderName := 'SQL Server';
end;
FireBird : begin
conn.ProviderName := 'InterBase';
end;
MySQL : begin
conn.ProviderName := 'MySQL';
end;
Oracle : begin
conn.ProviderName := 'Oracle';
end;
PostgreSQL : begin
conn.ProviderName := 'PostgreSQL';
end;
end;
if dbInfo.DBType = Oracle then
begin
conn.SpecificOptions.Add('Oracle.Direct=True');
conn.Server := dbInfo.Host + ':' + inttostr(dbInfo.Port) + ':' + dbInfo.Database;
end else begin
conn.Server := dbInfo.Host;
conn.Port := dbInfo.Port;
conn.Database := dbInfo.Database;
end;
conn.Username := dbInfo.User;
conn.Password := dbInfo.Password;
conn.SpecificOptions.Add(dbInfo.AdditionalSpecs);
// conn.SpecificOptions.Values['Direct'] := true;
conn.LoginPrompt := false;
result := conn;
end;
{%CLASSGROUP 'Vcl.Controls.TControl'}
{$R *.dfm}
end.
UWebModule içeriği;
unit UWebModule;
interface
uses
System.SysUtils, System.Classes, Web.HTTPApp, Datasnap.DSHTTPCommon,
Datasnap.DSHTTPWebBroker, Datasnap.DSServer,
Web.WebFileDispatcher, Web.HTTPProd,
DataSnap.DSAuth,
Datasnap.DSProxyJavaScript, IPPeerServer, Datasnap.DSMetadata,
Datasnap.DSServerMetadata, Datasnap.DSCommonServer, Datasnap.DSHTTP,
Forms, Dialogs, System.JSON, Data.DBXCommon, Data.DBXPlatform,
Generics.Collections;
type
TfrmWebModule = class(TWebModule)
DSRESTWebDispatcher1: TDSRESTWebDispatcher;
WebFileDispatcher1: TWebFileDispatcher;
DSServerMetaDataProvider1: TDSServerMetaDataProvider;
procedure WebModuleCreate(Sender: TObject);
procedure DSRESTWebDispatcher1FormatResult(Sender: TObject;
var ResultVal: TJSONValue; const Command: TDBXCommand;
var Handled: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;
var
WebModuleClass: TComponentClass = TfrmWebModule;
implementation
{$R *.dfm}
uses UServerMethods, UServerContainer, Web.WebReq, UMain;
procedure TfrmWebModule.DSRESTWebDispatcher1FormatResult(Sender: TObject;
var ResultVal: TJSONValue; const Command: TDBXCommand; var Handled: Boolean);
var
Aux: TJSONValue;
Aux2 : TJSONArray;
Aux3 : TJSONArray;
jso : TJsonObject;
jsp_data, jsp_res : TJSONPair;
res : TJSONObject;
begin
jso := TJsonObject.Create();
//add object pairs
jso.AddPair(TJsonPair.Create('code', '0000'));
jso.AddPair(TJsonPair.Create('message', 'Success'));
jsp_res := TJsonPair.Create('result', jso);
jsp_data := TJsonPair.Create('data', TJSONArray(ResultVal).Get(0));
res := TJSONObject.Create();
res.AddPair(jsp_data);
res.AddPair(jsp_res);
GetInvocationMetadata().ResponseContentType := 'application/json';
ResultVal := res;
Handled := true; // -> bu baştaki result objesini kaldırıyor...
if frmMain.chkLogging.Checked then
begin
frmMain.memo1.Lines.Add('----- Sonuç -----');
frmmain.Memo1.Lines.Add(ResultVal.ToString);
frmMain.memo1.Lines.Add('-----');
end;
end;
procedure TfrmWebModule.WebModuleCreate(Sender: TObject);
begin
DSRESTWebDispatcher1.Server := DSServer;
if DSServer.Started then
begin
DSRESTWebDispatcher1.DbxContext := DSServer.DbxContext;
DSRESTWebDispatcher1.Start;
end;
DSRESTWebDispatcher1.AuthenticationManager := DSAuthenticationManager;
end;
initialization
finalization
Web.WebReq.FreeWebModules;
end.
Proje ekte yer almaktadır.
Konunun 2. aşamasında PHP client tarafından bahsedeceğim.
Umarım faydası olur...

