25 Mei 2009

General Query Log MySQL

General Query Log pada MySQL berisi semua aktivitas pada saat client melakukan koneksi ke server atau pada waktu koneksi terputus dan query dari client yang dikirim ke server. Fasilitas ini sangat berguna untuk merekam segala aktivitas tiap client yang terhubung ke server. Bisa juga untuk mengetahui kesalahan yang mungkin terjadi dari perintah atau query yang dikirim client.
Sama seperti Slow Query Log, sebelum MySQL 5.1.6 tujuan penulisan log selalu ke file. Mulai MySQL 5.1.6 terdapat pilihan untuk menulis log ke file atau tabel atau keduanya.
Tujuan penulisan log ditentukan dengan pilihan --log-output yang bisa berisi nilai TABLE, FILE atau NONE (tidak menulis log). Jika tujuan penulisan ke tabel, maka tabel tujuan adalah mysql.general_log. Misalnya:
--log-output=TABLE
--log-output=FILE
--log-output=TABLE,FILE

Sebelum MySQL 5.1.6, untuk mengaktifkan General Query Log dengan menggunakan pilihan --log[=file_name]. Mulai MySQL 5.1.6 gunakan pilihan --general_log yang bisa memiliki nilai 0 (tidak aktif) atau 1 (aktif). Sedangkan pilihan --general_log_file[=file_name] digunakan untuk menentukan direktori tempat file log, jika tujuan penyimpanan log pada file.
Mulai MySQL 5.1.12 kita dapat mengaktifkan atau non aktifkan General Query Log pada saat MySQL sedang berjalan. Cara ini bisa digunakan misalnya untuk backup file log. Setelah General Query Log non aktif, ganti nama file log dan buat file log baru, kemudian aktifkan lagi General Query Log. Set ‘ON’ untuk mengaktifkan atau ‘OFF’ untuk non aktif.
SET GLOBAL general_log = 'OFF';
SET GLOBAL general_log = 'ON';

Bisa juga mengaktifkan General Query Log dengan melakukan pengaturan file konfigurasi MySQL (my.ini).
[mysqld]
general-log=1
log-output=FILE
general-log-file="C:/Program Files/MySQL/MySQL 5.1/log.log"

Baca selengkapnya...

22 Mei 2009

Slow Query Log MySQL

Slow Query Log pada MySQL berisi semua query SQL yang dijalankan (waktu eksekusi) melebihi selang waktu tertentu. Selang waktu yang dimaksud ditentukan pada variabel sistem server MySQL (mysqld). Saat menjalankan instance MySQL (mysqld.exe), terdapat pilihan long_query_time, yang digunakan untuk pengecekan apakah akan menulis ke log atau tidak. Isi dari pilihan tersebut merupakan nilai dalam detik, jika suatu query yang dikirim dari client dijalankan selama selang waktu lebih dari yang ditentukan dari pilihan long_query_time, maka query yang bersangkutan akan ditulis ke file log. Sebelum MySQL 5.1.21 nilai minimum dari pilihan long_query_time adalah 1 dan harus tipe integer, mulai MySQL 5.1.21 nilai minimum adalah 0 dan dimungkinkan mengisi nilai mikro detik, tapi hanya nilai integer yang diambil dan ditulis ke tabel jika tujuan penulisan log adalah ke tabel.
Sebelum MySQL 5.1.6 log selalu ditulis ke sebuah file. Mulai MySQL 5.1.6 dimungkinkan untuk menulis ke file, tabel atau keduanya. Untuk mengaktifkan Slow Query Log, gunakan parameter --log-slow-queries[=file_name]. Pilihan ini digunakan sebelum MySQL 5.1.29, mulai MySQL 5.1.29 gunakan pilihan --slow-query-log. Nilai dari pilihan ini bisa 0 (tidak aktif) atau 1 (aktif). Jika tujuan penulisan file log adalah ke file, gunakan pilihan --slow-query-log-file[=file_name]. Tujuan penulisan log bisa ditentukan dengan pilihan --log-output yang bisa berisi nilai TABLE, FILE atau NONE (tidak menulis log). Jika tujuan penulisan ke tabel, maka tabel tujuan adalah mysql.slow_log. Misalnya:
--log-output=TABLE
--log-output=FILE
--log-output=TABLE,FILE
Bisa juga dengan melakukan pengaturan file konfigurasi MySQL (my.ini).
[mysqld]
slow-query-log=1
log-output=FILE
slow-query-log-file="C:/Program Files/MySQL/MySQL 5.1/slowlog.log"

Catatan: Penulisan tanda - atau _ pada yang digunakan sebagai penghubung tiap kata (pada parameter maupun file konfigurasi MySQL) dapat digunakan untuk hasil yang sama. Parameter-parameter berikut memiliki arti dan hasil yang sama.
--log-output=TABLE
--log_output=TABLE

Baca selengkapnya...

21 Mei 2009

Error Log MySQL

Error log pada MySQL berisi kesalahan yang terjadi pada saat MySQL dijalankan atau dihentikan. Log ini juga berisi kesalahan yang terjadi saat MySQL sedang berjalan. Kesalahan yang dimaksud adalah kesalahan yang sifatnya kritis, misalnya jika terjadi masalah pada tabel yang memerlukan tindakan perbaikan pada tabel tersebut, MySQL akan menulis pesan ke log. MySQL tidak akan menulis pesan ke log untuk kesalahan seperti duplikasi data pada suatu tabel karena primary key, dan lain-lain.
Menentukan file log ini dapat dilakukan dengan menambahkan entry log-error pada file konfigurasi MySQL (file “my.ini”) pada bagian mysqld. Dari sini dapat kita tentukan nama file log dan direktori tempat penyimpanan file log. Default disimpan pada direktori data MySQL.
[mysqld]
log-error="C:/Program Files/MySQL/MySQL 5.1/errlog.err"

Bisa juga dengan menambahkan parameter --log-error[=file_name] pada saat menjalankan MySQL.

Baca selengkapnya...

20 Mei 2009

MySQL Server Logs

MySQL mempunyai mekanisme untuk mengetahui apa saja yang terjadi pada saat MySQL berjalan. Pada saat terjadi kesalahan atau terjadi masalah saat menjalankan atau menghentikan MySQL, atau saat terjadi penambahan atau pengubahan atau penghapusan data pada tabel, atau pada saat menjalankan query terhadap suatu tabel. Semua kejadian itu bisa kita ketahui dan disimpan pada suatu file log. Dari file log ini bisa kita ketahui apa saja yang terjadi pada MySQL. Pada log tertentu juga bisa menyimpan data pada tabel. Tipe-tipe log yang ada pada MySQL:
  • Error Log. Informasi yang ditulis ke log merupakan masalah yang terjadi saat server MySQL dijalankan, dihentikan atau saat sedang berjalan.
  • General Query Log. Informasi yang ditulis ke log adalah saat client melakukan koneksi ke server dan saat menjalankan query dari client.
  • Binary Log. Informasi yang ditulis ke log adalah saat menjalankan query dari client yang mengubah data. Juga digunakan untuk replikasi.
  • Slow Query Log. Informasi yang ditulis ke log adalah saat menjalankan query selama selang waktu tertentu.
Secara default semua file log dibuat pada direktori data MySQL. Kita dapat memaksa MySQL untuk menutup dan membuka lagi file log (atau berganti ke file log baru) dengan melakukan “flush” terhadap log. Caranya adalah dengan menjalankan perintah FLUSH LOGS atau menjalankan salah satu dari perintah-perintah berikut dari command prompt.
mysqladmin flush-logs
mysqladmin refresh

Pada General Query Log dan Slow Query Log, log dapat disimpan pada tabel (mulai MySQL 5.1.6). Untuk General Query Log disimpan pada tabel mysql.general_log, dan untuk Slow Query Log disimpan pada tabel mysql.slow_log. Tiap file log ditentukan dengan melakukan pengaturan pada file konfigurasi MySQL. Pada sistem operasi Windows, file yang dimaksud adalah file “my.ini” dan biasanya terletak pada direktori instalasi MySQL. Pada posting berikutnya akan dibahas lebih detail mengenai log pada MySQL.

Baca selengkapnya...

19 Mei 2009

Implementasi Run-Time Type Information / RTTI (Bagian 3)

Dengan mengetahui manfaat dari RTTI, kita bisa menggunakan fungsi-fungsi yang ada untuk mengubah properti dari komponen VCL yang ada pada sebuah form. Kita bisa mengubah properti yang mempunyai tipe integer, string, boolean, atau bahkan enumerasi. Contoh skrip ini minimum membutuhkan sebuah form (nama Form1) dan sebuah TEdit (nama Edit1). Parameter yang dibutuhkan adalah nama form, nama obyek/komponen, nama properti dan nilai dari properti.
uses Forms, StrUtils, SysUtils, TypInfo;

procedure SetObjectProperty(const aFormName, aObjectName, aPropName: string; aPropValue: Variant);
var
  frm: TForm;
  obj: TObject;
  i, j: Integer;
begin
  frm := nil;
  for i := 0 to Screen.FormCount - 1 do
    if UpperCase(Screen.Forms[i].Name) = UpperCase(aFormName) then
      frm := Screen.Forms[i];
  if (Assigned(frm)) and (frm.Name = aFormName) then
  begin
    obj := frm.FindComponent(aObjectName);
    j := 1;
    i := PosEx('.', aPropName, j);
    while i > 0 do
    begin
      obj := GetObjectProp(obj, Copy(aPropName, j, i - j));
      j := i + 1;
      i := PosEx('.', aPropName, j);
    end;
    SetPropValue(obj, Copy(aPropName, j, Length(aPropName)), aPropValue);
  end;
end;

Jalankan perintah-perintah berikut dan lihat hasilnya.
SetObjectProperty('Form1', 'Edit1', 'Text', 'Tes 123');
SetObjectProperty('Form1', 'Edit1', 'Enabled', False);
SetObjectProperty('Form1', 'Edit1', 'Color', clRed);
SetObjectProperty('Form1', 'Edit1', 'Font.Size', 12);
SetObjectProperty('Form1', 'Edit1', 'Font.Style', '[fsBold,fsItalic]');

Baca selengkapnya...

18 Mei 2009

Implementasi Run-Time Type Information / RTTI (Bagian 2)

Penggunaan RTTI memungkinkan kita mendapatkan informasi dari sebuah obyek tentang properti dari obyek tersebut. Salah satu fungsi yang berguna untuk kebutuhan ini adalah GetPropList. Fungsi ini menghasilkan daftar properti (termasuk event) yang terdapat pada sebuah obyek. Properti yang dimaksud adalah properti yang di published, seperti yang kita lihat pada Object Inspector. Ada beberapa variasi sintaks fungsi GetPropList seperti yang dapat kita lihat pada unit TypInfo.
function GetPropList(TypeInfo: PTypeInfo; TypeKinds: TTypeKinds; PropList: PPropList; SortList: Boolean = True): Integer;
function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): Integer;
function GetPropList(AObject: TObject; out PropList: PPropList): Integer;

Fungsi GetPropList mengembalikan jumlah properti yang ditemukan dan properti apa saja yang terdapat pada sebuah obyek yang disimpan pada PropList. Fungsi yang pertama membatasi hasil yang dikembalikan hanya berdasarkan TypeKinds dan mempunyai pilihan untuk mengurutkan properti yang ada. Sedangkan dua variasi lainnya menghasilkan semua properti yang ada. Contoh dibawah ini akan menampilkan tiap properti yang ada pada sebuah obyek.
uses TypInfo;

procedure GetProp(aObject: TObject);
var
  i, PropCount: Integer;
  PropInfo: PPropInfo;
  PropList: PPropList;
  PropType: PPTypeInfo;
  s: string;
begin
  PropCount := GetPropList(PTypeInfo(aObject.ClassInfo), PropList);
  for i := 0 to PropCount - 1 do
  begin
    PropInfo := PropList^[i];
    PropType := PropInfo^.PropType;
    s := GetEnumName(TypeInfo(TTypeKind), Ord(PropType^.Kind));
    ShowMessage(PropInfo^.Name + ':' + PropType^.Name + ':' + s);
  end;
end;

Fungsi lain yang juga penting adalah GetPropInfo. Fungsi ini menghasilkan informasi detail dari sebuah obyek dengan properti tertentu. Fungsi ini juga mempunyai beberapa variasi sintaks.
function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds = []): PPropInfo;
function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds = []): PPropInfo;
function GetPropInfo(TypeInfo: PTypeInfo; const PropName: string): PPropInfo;
function GetPropInfo(TypeInfo: PTypeInfo; const PropName: string; AKinds: TTypeKinds): PPropInfo;

Fungsi tersebut mengembalikan nilai berupa pointer dengan tipe PPropInfo yang berisi karakteristik mengenai properti, seperti dapat kita lihat dibawah ini.
type
  PPropInfo = ^TPropInfo;
  TPropInfo = packed record
    PropType: PPTypeInfo;
    GetProc: Pointer;
    SetProc: Pointer;
    StoredProc: Pointer;
    Index: Integer;
    Default: Longint;
    NameIndex: SmallInt;
    Name: ShortString;
  end;

Terdapat puluhan fungsi untuk mengakses properti dari obyek yang dapat dilihat pada unit TypInfo. Beberapa diantara fungsi-fungsi tersebut adalah:
  • GetObjectProp
  • SetObjectProp
  • GetStrProp
  • SetStrProp
  • GetOrdProp
  • SetOrdProp
  • GetPropValue
  • SetPropValue
Contoh dibawah ini mengganti properti dari obyek TButton dengan nama Button1.
var
  PropInfo: PPropInfo;
  Obj: TObject;
begin
  PropInfo := GetPropInfo(Button1.ClassInfo, 'Font');
  Obj := GetObjectProp(Button1, PropInfo);
  SetPropValue(Obj, 'Style', '[fsBold,fsItalic]');
  SetStrProp(Button1, 'Caption', 'Tombol');
SetOrdProp(Button1.Font, 'Size', 10);

end;

Dengan menggunakan fungsi-fungsi yang berhubungan dengan RTTI, memungkinkan kita untuk mengakses properti dari obyek. Hal ini bisa sangat berguna, misalnya untuk menyimpan layout dari sebuah form. Properti dan nilai dari obyek dapat disimpan dalam registry, file INI atau file format buatan sendiri, atau bisa pula database. Kemudian pada saat form di load, layout dari form tersebut dapat dikembalikan dengan menggunakan properti dan nilai obyek yang disimpan sebelumnya.

Baca selengkapnya...

17 Mei 2009

Implementasi Run-Time Type Information / RTTI (Bagian 1)

Dengan mengetahui teknologi RTTI, kita bisa melakukan banyak hal dalam aplikasi yang kita buat. Tiap komponen VCL yang ada pada Delphi diturunkan dari class TObject. Pada class ini terdapat fungsi ClassName yang mengembalikan nama class pada obyek yang bersangkutan. Dengan mengetahui nama class pada saat run-time kita bisa melakukan pengecekan terhadap sebuah obyek yang mempunyai tipe TObject. Misalnya jika kita tahu sebuah obyek mempunyai tipe TEdit atau turunannya maka kita tahu bahwa obyek tersebut mempunyai properti Text yang bisa kita ganti. Akses terhadap obyek dapat kita lakukan dengan menggunakan operator as dan is.
procedure SetText(aObject: TObject; const aText: string);
begin
  if aObject is TEdit then
    (aObject as TEdit).Text := aText;
end;

Operator is melakukan pengecekan tipe secara dinamik terhadap suatu obyek pada saat run-time. Hasil dari pengecekan tersebut akan menghasilkan nilai True bila obyek yang dibandingkan merupakan instance dari class yang dimaksud atau salah satu turunan dari class tersebut, atau nilai False jika sebaliknya. Jika obyek tersebut berisi nilai nil, juga menghasilkan nilai False. Sedangkan operator as digunakan untuk type casting, yang akan mengembalikan referensi dari suatu obyek dengan tipe class yang diberikan.
Contoh lain kegunaan dari RTTI adalah pada tipe enumerasi. Tipe enumerasi merupakan sekumpulan nilai yang di representasikan dengan identifier yang menggambarkan nilainya. Misalnya jika kita sering bekerja dengan form, pada Object Inspector terdapat properti WindowState yang bisa berisi wsNormal, wsMinimized, atau wsMaximized. Tiap identifier tersebut di deklarasikan pada bagian type, seperti dapat kita lihat pada unit Forms dari Delphi.
type
  TWindowState = (wsNormal, wsMinimized, wsMaximized);

Nilai pada tiap identifier tersebut diwakili oleh sebuah nilai Integer yang dimulai dari 0. Jadi nilai wsNormal = 0, wsMinimized = 1, dan wsMaximized = 2. Nilai integer dari properti obyek yang memiliki tipe enumerasi bisa kita dapatkan dengan menggunakan fungsi Ord.
ShowMessage(IntToStr(Ord(Form1.WindowState)));

Sebaliknya untuk mendapatkan identifier dari tipe enumerasi, kita bisa menggunakan fungsi GetEnumName yang disediakan pada unit TypInfo.
uses TypInfo;

var
  i: Integer;
begin
    for i := Ord(Low(TWindowState)) to Ord(High(TWindowState)) do
    ShowMessage(GetEnumName(TypeInfo(TWindowState), i));
end;

Hasil yang sama kita dapatkan dengan skrip sebagai berikut.
uses TypInfo;

var
  ws: TWindowState;
begin
  for ws in [Low(TWindowState)..High(TWindowState)] do
    ShowMessage(GetEnumName(TypeInfo(TWindowState), Integer(ws)));
end;
Fungsi GetEnumName digunakan untuk mendapatkan nama tipe enumerasi berdasarkan nilai integer dan mempunyai sintaks seperti ini.
function GetEnumName(TypeInfo: PTypeInfo; Value: Integer): string;

Parameter TypeInfo merupakan pointer ke sebuah record yang berisi informasi tentang tipe enumerasi, dan parameter Value merupakan nilai integer yang mewakili tipe enumerasi. Deskripsi record tersebut terdapat pada unit TypInfo.
type
  TTypeKind = (tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat, tkString, tkSet, tkClass, tkMethod, tkWChar, tkLString, tkWString, tkVariant, tkArray, tkRecord, tkInterface, tkDynArray);
  PTypeInfo = ^TTypeInfo;
  TTypeInfo = record
    Kind: TTypeKind;
    Name: ShortString;
  end;

Untuk mendapatkan nilai integer dari suatu tipe enumerasi, menggunakan fungsi GetEnumValue dengan sintaks sebagai berikut.
function GetEnumValue(TypeInfo: PTypeInfo; const Name: string): Integer;

Misalnya mendapatkan nilai integer dari wsMaximized:
ShowMessage(IntToStr(GetEnumValue(TypeInfo(TWindowState), 'wsMaximized')));

Baca selengkapnya...

16 Mei 2009

Run-Time Type Information (RTTI)

Run-Time Type Information (RTTI) merupakan satu fitur Delphi yang sangat menarik yang sudah ada sejak versi awal sampai versi terbaru. RTTI merupakan informasi yang disimpan pada file biner aplikasi. Informasi ini dihasilkan pada saat kompilasi program. Informasi yang disimpan ini berhubungan dengan obyek atau kontrol yang dipakai pada aplikasi yang kita buat. Dengan RTTI kita bisa mendapatkan informasi seperti properti apa saja yang dimiliki oleh sebuah komponen.
Informasi yang kita dapatkan dari RTTI merupakan properti dari komponen VCL yang di published. Contoh nyata dari RTTI ini adalah Object Inspector yang sering kita lihat jika kita memakai IDE Delphi pada saat design time. Dengan RTTI kita bisa mendapatkan informasi apa saja properti dari komponen beserta nilainya pada saat run-time. Sesuai dengan pernyataan yang dikutip dari file help Delphi dalam bahasa Inggris:
Published members have the same visibility as public members. The difference is that runtime type information (RTTI) is generated for published members. RTTI allows an application to query the fields and properties of an object dynamically and to locate its methods. RTTI is used to access the values of properties when saving and loading form files, to display properties in the Object Inspector, and to associate specific methods (called event handlers) with specific properties (called events).
Dokumentasi mengenai RTTI sangat minim, tidak bisa yang kita dapatkan dari file help Delphi. Informasi penting yang bisa kita dapatkan mengenai RTTI ada pada unit TypInfo.pas. Pada unit ini bisa kita dapatkan baris-baris kode yang berhubungan dengan RTTI yang mungkin bisa berguna.

Baca selengkapnya...