Tampilkan postingan dengan label programming. Tampilkan semua postingan
Tampilkan postingan dengan label programming. Tampilkan semua postingan

Rabu, Desember 31, 2008

Belajar Ruby

Berawal dari sebuah kebutuhan untuk mengetahui kapan DHCP Client memperbaharui IP Address, saya akhirnya malah belajar Ruby dan jadilah script sederhana berikut ini. FYI, saya menggunakan GNU/Linux Ubuntu Intrepid Ibex. Saya butuh informasi waktu perbaharuan IP berikutnya dari DHCP Client. Dari file /var/log/daemon.log saya bisa mendapatkan informasi berikut ini


$ grep renewal /var/log/daemon.log
Dec 29 10:32:41 hantulab dhclient: bound to 192.168.1.31 -- renewal in 14563182 seconds.
Dec 29 10:39:10 hantulab dhclient: bound to 192.168.1.31 -- renewal in 14168572 seconds.
Dec 29 12:18:45 hantulab dhclient: bound to 192.168.1.31 -- renewal in 13948234 seconds.
Dec 30 08:08:48 hantulab dhclient: bound to 10.2.13.34 -- renewal in 1496 seconds.
Dec 30 08:33:44 hantulab dhclient: bound to 10.2.13.34 -- renewal in 21496 seconds.
Dec 30 14:32:00 hantulab dhclient: bound to 10.2.13.34 -- renewal in 18630 seconds.
Dec 31 08:53:45 hantulab dhclient: bound to 10.2.13.34 -- renewal in 1446 seconds.


Ide awalnya adalah mengubah angka detik menjadi format jam. Dari tiga bahasa scripting yang terinstall di laptop saya, Perl, Python, dan Ruby, saya memutuskan untuk coba menggunakan Ruby sambil belajar. Dengan bekal panduan dari http://pine.fm/LearnToProgram/, sayapun membuat script sederhana berikut ini:

#!/usr/bin/env ruby

hour = ARGV[0].to_i / 3600
reminder = ARGV[0].to_i % 3600
minute = reminder / 60
second = reminder % 60

puts ARGV[0] + ' = ' + hour.to_s + ':' + minute.to_s + ':' + second.to_s


Lalu saya coba jalankan

$ ruby sectomin.rb 1446
1446 = 0:24:6


Hmm, lumayan. Script simple pertamaku pake Ruby. Selanjutnya aku juga perlu penjumlahan jam nih. Cari-cari nama fungsi dengan fungsionalitas sama dengan explode di PHP, nemu method split. Sekalian aku edit scriptnya dengan membuat fungsi.

#!/usr/bin/env ruby

def sectohour sec
hour = sec / 3600
reminder = sec % 3600
minute = reminder / 60
second = reminder % 60

hour.to_s + ':' + minute.to_s + ':' + second.to_s
end

def houradd hour1 hour2
arr_hour1 = hour1.split(':')
arr_hour2 = hour2.split(':')
result = (arr_hour1[0].to_i + arr_hour2[0].to_i) * 3600
+ (arr_hour1[1].to_i + arr_hour2[1].to_i) * 60
+ (arr_hour1[2].to_i + arr_hour2[2].to_i)
sectohour result
end

hour = sectohour ARGV[0].to_i

puts ARGV[0] + ' = ' + hour
puts ARGV[1] + ' + ' + ARGV[0] + ' = ' + houradd ARGV[1] hour


Coba dijalankan:

$ ruby sectomin.rb 1446 08:53:45
sectomin.rb:12: syntax error, unexpected tIDENTIFIER, expecting '\n' or ';'
sectomin.rb:19: syntax error, unexpected kEND, expecting $end


Wah...wah... koq error yah. Sebelum buka manual, coba-coba lagi, kali ini nambah koma sebagai pemisah argumen, ternyata berhasil. Untuk statemen multi baris juga mesti pake backslash, karena ga ada akhir baris pake ' seperti php. Untuk manggil fungsi dua argumen mesti pake tanda kurung. Inilah hasil script yang jalan, plus penyempurnaan sectohour.

#!/usr/bin/env ruby

def sectohour sec
hour = sec / 3600
reminder = sec % 3600
minute = reminder / 60
second = reminder % 60

hour.to_s \
+ ':' + (minute.to_s.length < 2 ? '0' : '') + minute.to_s \
+ ':' + (second.to_s.length < 2 ? '0' : '') + second.to_s
end

def houradd hour1,hour2
arr_hour1 = hour1.split(':')
arr_hour2 = hour2.split(':')
result = (arr_hour1[0].to_i + arr_hour2[0].to_i) * 3600 \
+ (arr_hour1[1].to_i + arr_hour2[1].to_i) * 60 \
+ (arr_hour1[2].to_i + arr_hour2[2].to_i)
sectohour result
end

hour = sectohour ARGV[0].to_i

puts ARGV[0] + ' = ' + hour
puts ARGV[1] + ' + ' + ARGV[0] + ' = ' + (houradd ARGV[1],hour)


Hasil running:

$ ruby sectomin.rb 1446 08:53:45
1446 = 0:24:6
08:53:45 + 1446 = 9:17:51


Setelah ini selesai, selanjutnya perlu otomatisasi dari pembacaan log sampai didapatkan hasil penjumlahannya. Dengan kombinasi grep dan tail, saya bisa dapat info ini:

$ grep renewal /var/log/daemon.log | tail -n 1
Dec 31 08:53:45 hantulab dhclient: bound to 10.2.13.34 -- renewal in 1446 seconds.


Selanjutnya dengan bantuan gawk yang powerfull, saya bisa membentuk string ini

$ grep renewal /var/log/daemon.log \
| tail -n 1 \
| gawk '{print "ruby sectomin.rb " $12 " " $3;}'
ruby sectomin.rb 1446 08:53:45


Lalu saya tambahkan backtick (`) sehingga saya bisa mendapatkan:

$ grep renewal /var/log/daemon.log \
| tail -n 1 \
| `gawk '{print "ruby sectomin.rb " $12 " " $3;}'`
1446 = 0:24:6
08:53:45 + 1446 = 9:17:51


Jreng...jreng... selesailah script sederhana Ruby pertama saya, plus parsing log. Semoga tulisan singkat saya ini bermanfaat. Ruby ternyata asik juga, cuman kadang saya terbawa kebiasaan di php. Belajar bahasa baru memang harus merubah paradigma dan pola pikir. Nantikan tulisan saya selanjutnya di blog ini.

Minggu, Agustus 31, 2008

Menyimpan file ke dalam database dan menampilkannya di halaman web

Hari ini saya membaca artikel yang sangat menarik di asktom tentang keuntungan dan kerugian menyimpan file ke dalam database. Tom menjawab bahwa dia sampai saat ini tidak menemukan keuntungan menyimpan data dari file diluar database. Tom memaparkan keuntungan-keuntungan yang didapatkan kalau data file disimpan ke dalam database, diantaranya:

  1. data akan dikelola dengan profesional oleh DBMS
  2. data akan ikut di-backup
  3. dapat di-rollback / di-recover bersama data-data lainnya
  4. data ikut terlindungi / aman
  5. scalable
  6. locking
  7. konsistensi data
Membaca pembahasan-pembahasan yang ada disana, saya jadi tertarik untuk mencoba menyimpan file ke dalam database. Kebetulan proyek yang sedang saya kerjakan di kantor memilki permasalahan sinkronisasi file. Ada dua website, gambar diupload di salah satu website, dan ditampilkan di kedua website. Keduanya akan berada di mesin yang terpisah, sehingga saya perlu memikirkan cara sinkronisasi file hasil upload. Jika file yang diupload saya simpan ke database, saya tentu tidak akan memiliki masalah sinkronisasi, karena kedua website dapat mengambil data dari database yang sama.

Saya pun mencoba membuat halaman sederhana untuk upload file yang akan disimpan ke database, dan menampilkan file yang tersimpan di database. Saya menggunakan framework codeigniter dan untuk akses database saya menggunakan adodb. Untuk DBMS sendiri saya menggunakan OracleXE.

Berikut ini potongan struktur tabel, dan potongan kode yang saya buat. Silahkan dipelajari dan dikembangkan lebih lanjut.

Tabel

CREATE TABLE "T_BLOB"
("ID" NUMBER NOT NULL ENABLE,
 "TITLE" VARCHAR2(255 CHAR),
 "FILE_DATA" BLOB,
 "CONTENT_TYPE" VARCHAR2(100 CHAR),
 CONSTRAINT "T_BLOB_PK" PRIMARY KEY ("ID"));

Sequence

CREATE SEQUENCE "SEQ_BLOB" INCREMENT BY 1 START WITH 1;

Package

CREATE OR REPLACE PACKAGE "P_PUBLIC_TYPES" AS
  TYPE theCursor IS REF CURSOR;
END P_Public_Types;
/

CREATE OR REPLACE PACKAGE "PG_BLOB" as

  function get_single(v_id in INTEGER) return p_public_types.theCursor;

  function get_all(v_order in VARCHAR2) return p_public_types.theCursor;

  function add_blob(v_title in VARCHAR2
                    ,v_content_type in VARCHAR2) return INTEGER;

  function delete_blob(v_id in integer) return INTEGER;

end pg_blob;
/

CREATE OR REPLACE PACKAGE BODY "PG_BLOB" as

  function get_single(v_id in INTEGER) return p_public_types.theCursor as
    cc p_public_types.thecursor;
  begin

    open cc for '
    SELECT B.*
    FROM T_BLOB B
    WHERE B.ID = ' || v_id || '
    ';

    return cc;
  end get_single;

  function get_all(v_order in VARCHAR2) return p_public_types.theCursor as
    cc      p_public_types.thecursor;
    orderby VARCHAR2(255);
  begin
 
    if v_order is not null then
      orderby := ' ORDER BY ' || orderby;
    end if;

    open cc for '
    SELECT B.*
    FROM T_BLOB B
    ' || orderby || '
    ';

    return cc;
  end get_all;

  function add_blob(v_title in VARCHAR2
                    ,v_content_type in VARCHAR2) return INTEGER as
    new_id  INTEGER;
  BEGIN
    select SEQ_BLOB.nextval into new_id from dual;

    INSERT INTO T_BLOB (ID, TITLE, FILE_DATA, CONTENT_TYPE)
    VALUES (new_id, v_title, empty_blob(), v_content_type);

    if SQL%ROWCOUNT > 0 then
      return new_id;
    else
      return 0;
    end if;
  end add_blob;

  function delete_blob(v_id in integer) return INTEGER as
  begin

    DELETE FROM T_BLOB
    WHERE ID = v_id;

    return SQL%rowcount;
  end delete_blob;

end pg_blob;
/

Controller function index

function index()
{
  echo '<p><a href="'.site_url('/testblob/add').'">Add new data</a></p>';

  $rs =& $this->adodb->db->ExecuteCursor('begin'
                                        .' :result := pg_blob.get_all(:v_order);'
                                        .'end;'
                                        ,'result'
                                        ,array('v_order' => ''));
  if ($rs && $rs->RecordCount() > 0)
  {
    $this->load->library('table');
    $this->table->set_heading('No'
                            , 'Title'
                            , 'Content-Type'
                            , 'File');
    $i = 1;
    foreach ($rs as $row)
    {
      $this->table->add_row($i++
                          , $row['TITLE']
                          , $row['CONTENT_TYPE']
                          , $row['FILE_DATA'] ?
                              '<a href="'.site_url('/testblob/file/'.$row['ID']).'">Download File</a>'
                            : 'No File');
    }
    echo $this->table->generate();
  }
  else
  {
    echo '<p>No Data yet</p>';
  }
}

Controller function add

function add()
{
  if ($this->input->post('submit'))
  {
    $uploaded = false;
    if ($_FILES['file']['name'] != '')
    {
      //upload image
      $conf_upload['upload_path']    = realpath(BASEPATH.'../').'/tmp/';
      $conf_upload['allowed_types']  = 'gif|jpg|png';
      $conf_upload['encrypt_name']   = true;

      $this->upload->initialize($conf_upload);

      if ( ! $this->upload->do_upload('file'))
      {
        //echo '<p>'.$this->upload->display_errors().'</p>';
      }
      else
      {
        $data_upload = $this->upload->data();
        $uploaded = true;
      }
    }
    //insert data
    $sql = 'declare'
          .'  result integer;'
          .'begin'
          .'  :result := pg_blob.add_blob(:v_title'
                                      .', :v_content_type);'
        .'end;';
    $stmt =& $this->adodb->db->PrepareSP($sql);

    $this->adodb->db->InParameter($stmt, $this->input->post('title'), 'v_title', 255);
    $this->adodb->db->InParameter($stmt, $data_upload['file_type'], 'v_content_type', 255);
    $this->adodb->db->OutParameter($stmt, $result, 'result');

    $this->adodb->db->Execute($stmt);

    if ($result > 0)
    {
      if ($uploaded)
      {
        $this->adodb->db->UpdateBlobFile('T_BLOB', 'FILE_DATA', $data_upload['full_path'], 'ID='.$result, 'BLOB');
        unlink ($data_upload['full_path']);
      }
      redirect('/testblob/index');
    }
  }

  echo form_open_multipart('/testblob/add', array('name' => 'form_add', 'id' => 'form_add'));
  echo '<ol>';
  echo '<li>'.form_label('Title', 'title').form_input('title', $this->input->post('title'), 'id="title"').'</li>';
  echo '<li>'.form_label('File', 'file').form_upload('file', '', 'id="file"').'</li>';
  echo '<li>'.form_submit('submit', 'Add');
  echo '</ol>';
  echo form_close();
}

Controller function file

function file()
{
  $id = intval($this->uri->segment(3));
  if (! $id)
  {
    redirect('/testblob/index');
  }

  $rs =& $this->adodb->db->ExecuteCursor('begin'
                                        .' :result := pg_blob.get_single(:v_id);'
                                        .'end;'
                                        ,'result'
                                        ,array('v_id' => $id));
  if ($rs && $rs->RecordCount() > 0)
  {
    if ($rs->fields['FILE_DATA'])
    {
      header('Content-type: '.$rs->fields['CONTENT_TYPE']);
      echo $rs->fields['FILE_DATA'];
    }
    else
    {
      echo '<p>No File</p>';
    }
  }
  else
  {
    echo '<p>Data no longer exist</p>';
  }
}

Semoga tulisan singkat ini dapat memberikan gambaran kepada pembaca yang ingin menyimpan file ke dalam database dan menampilkan data file dari database.

Silahkan juga baca pembahasan dan contoh di link berikut ini:

  1. http://www.devarticles.com/c/a/MySQL/Blobbing-Data-With-PHP-and-MySQL/

  2. http://phplens.com/lens/adodb/docs-oracle.htm

  3. http://forums.oracle.com/forums/thread.jspa?threadID=205149

Penjumlahan jam dan menit di PHP

Beberapa jam yang lalu seorang teman bertanya tentang kode PHP untuk menjumlahkan dua string jam dan menit. Saya coba cari di google tapi tidak ada solusi yang saya temukan. Saya pun menyarankan untuk parsing manual stringnya, di-explode dan dijumlahkan secara terpisah menit dan jamnya. Cara dasar tapi memang bisa dipakai untuk menyelesaikan permasalahan.

Beberapa saat yang lalu tiba-tiba saja terlintas ide untuk menggali lagi kehebatan fungsi strtotime yang ada pada PHP. Hasilnya adalah potongan kode berikut ini

<?php

$time1 = '10:20';
$time2 = '12:40';

$time1_unix = strtotime(date('Y-m-d').' '.$time1.':00');
$time2_unix = strtotime(date('Y-m-d').' '.$time2.':00');

$begin_day_unix = strtotime(date('Y-m-d').' 00:00:00');

$jumlah_time = date('H:i', ($time1_unix + ($time2_unix - $begin_day_unix)));



Dengan kode diatas penjumlahan dua string jam:menit dapat dilakukan dengan mudah. Semoga bermanfaat.


Update: kesalahan ketik diatas sudah diperbaiki :) Maklum ditulisnya malem2 sih...

Jumat, Februari 15, 2008

SQL tools untuk database mySQL

Semenjak saya menggunakan Navicat untuk membantu saya mengakses database di mySQL, saya menjadi tergantung pada aplikasi ini. Ketika saya beralih ke Ubuntu Linux pun, saya berusaha mencari aplikasi pengganti yang memiliki kemampuan yang sama dengan Navicat yang berjalan di Linux. Pencarian ini sia-sia karena aplikasi yang ada memiliki fitur dan gaya tersendiri yang sudah pasti berbeda dengan Navicat. Saya pun akhirnya mencoba menginstall aplikasi ini diatas wine, dan Navicat pun bisa saya gunakan.

Permasalahan utama Navicat yang dijalankan menggunakan wine adalah fitur docking tidak dapat berfungsi dengan baik. Saya pun menonaktifkan fitur ini, sehingga setiap kali melihat isi tabel maupun desain tabel dan membuka jendela-jendela navicat lainnya, saya akan mendapatkan banyak jendela yang terbuka. Hal ini sedikit merepotkan. Untungnya saya tidak terlalu butuh membuka banyak jendela sekaligus. Kelemahan lainnya adalah aplikasi yang berjalan lambat, dan sering terlambat dalam menerima input dari keyboard, sehingga teks yang saya input seringkali diterima dalam urutan yang salah. Kelemahan lainnya adalah di jendela query, ketika saya menghapus isi dari jendela query yang lama, teks yang lama tersebut tetap ditampilkan sehingga cukup mengganggu.

Di kantor saya menggunakan aplikasi TOAD untuk mengakses database Oracle yang digunakan oleh aplikasi yang sedang ditangani oleh kantor. Salah satu ciri khas TOAD adalah penggunaan jendela editor untuk menuliskan query dalam SQL. Hal ini membuat saya jadi terbiasa mengetikkan perintah-perintah SQL sehingga saya ingin menerapkan hal yang sama pada database mySQL.

Aplikasi yang dapat memudahkan penulisan perintah-perintah SQL di database mySQL adalah MySQL Query Browser. Aplikasi ini tersedia gratis di situs web MySQL dan dapat didownload dan digunakan secara cuma-cuma. Aplikasi ini adalah satu dari dua aplikasi yang dibundel menjadi satu bernama MySQL Tools. Aplikasi yang satunya adalah MySQL Administrator, sebuah aplikasi untuk melihat dan memodifikasi parameter dan keadaan server mySQL secara mudah.

Semalam saya menggunakan aplikasi MySQL Query Browser ini dan saya cukup puas dengan kinerja dan fitur yang tersedia. Saya harap aplikasi ini dapat menggantikan peran Navicat untuk mengakses database mySQL.

Kamis, Februari 07, 2008

Editor Teks

Editor teks adalah aplikasi utama yang selalu saya pergunakan
sehari-hari, baik dalam bekerja maupun untuk keperluan lainnya.
Aplikasi editor teks pertama yang masih saya gunakan hingga sekarang
adalah Vi. Aplikasi ini pertama kali saya gunakan di laboratorium dasar
jurusan. Aplikasi lainnya saat itu adalah joe dan pico, tapi saya lebih
jatuh hati dan lebih hapal perintah2 Vi ketimbang editor teks lainnya.
Seperti biasa, saat pertama kali menjalankan Vi, perintah yang perlu
saya tahu adalah perintah untuk keluar dari aplikasi. Maklum saja,
komputer di lab masih menggunakan modus teks, tidak ada icon silang
yang bisa di-klik untuk menutup aplikasi.

Vi terus saya pergunakan, karena aplikasi ini memang tersedia di
berbagai OS. Editor teks ini sangat cocok digunakan untuk menulis kode
program dalam bahasa apa saja. Fitur yang tersedia juga sangat
berlimpah. Pernah suatu kali saya mendapatkan data dalam bentuk file
excel yang harus dimasukkan ke database mysql. Waktu itu, jalan pintas
yang terlintas di pikiran saya adalah menyimpan file excel dalam format
csv, lalu menggunakan Vi saya lakukan search and replace sehingga data
yang ada menjadi perintah insert ke database mysql. Search and replace
di vi memang sangat powerful karena menggunakan regex.

Kedudukan Vi sebagai aplikasi editor teks di komputer saya akhirnya
dikudeta oleh jEdit. Editor ini menawarkan tampilan yang lebih menarik
dan menyediakan fitur-fitur yang lengkap untuk menunjang kebutuhan
saya. Salah satu fiturnya adalah mengedit file langsung di server
menggunakan koneksi ftp dan ssh. Dengan aplikasi ini, saya dengan mudah
dapat melakukan penulisan kode program di server kampus langsung dari
komputer lab yang menggunakan OS Windows. File langsung di-load dari
server dan disimpan kembali ke server. Cukup lama aplikasi ini saya
gunakan sampai akhirnya digantikan oleh aplikasi editor lain.

Setelah cukup lama menggunakan jEdit, satu kelemahan jEdit yaitu
kebutuhan resource komputer yang cukup besar akhirnya membuat saya
mencari aplikasi editor teks yang lain. jEdit ditulis menggunakan java,
sehingga ketika dijalankan aplikasi ini membutuhkan memory dan
kemampuan processor yang cukup banyak. Walaupun saya sudah cukup
bergantung pada plugin-plugin jEdit yang memudahkan pekerjaan, saya
harus 'membuang' aplikasi ini dan menggantinya dengan aplikasi editor
teks lain yang lebih ringan tapi tetap powerfull. Selamat datang
Notepad++, selamat tinggal jEdit.

Notepad++ ditulis menggunakan C++. Aplikasi ini berjalan dengan mulus
dan ringan di OS Windows XP di komputer saya. Fitur yang tersedia cukup
lengkap, ditambah lagi dengan plugin-plugin yang sangat bermanfaat
membuat saya jatuh cinta pada aplikasi ini. Notepad++ benar-benar
memudahkan pekerjaan saya. Fitur2 pada jEdit yang saya butuhkan
tersedia pada Notepad++. Saat ini juga telah ada plugins yang
memungkinkan Notepad++ mampu mengedit file di komputer lain secara
langsung melalui koneksi ftp. Hanya ada satu kekurangan aplikasi ini
yaitu hanya tersedia untuk OS Windows. Seiring dengan migrasi OS saya
dari Windows XP ke Linux Ubuntu, maka sayapun terpaksa kembali harus
mencari aplikasi teks editor untuk menggantikan Notepad++.

Gedit adalah aplikasi teks editor standar pada Linux Ubuntu 7.10.
Aplikasi ini ada sejak pertama kali instalasi dan menawarkan fitur
standar sebuah aplikasi editor teks. Untuk kebutuhan pekerjaan, saya
merasakan banyak hal yang tidak mampu dilakukan oleh gedit. Untuk itu
saya mencoba menjalankan Notepad++ di Ubuntu dengan menggunakan
perantara Wine. Notepad++ akhirnya dapat berjalan walaupun tidak semua
fitur dapat berjalan dengan baik. Beberapa plugin tidak dapat berjalan
baik, sehingga ketika Notepad++ ditutup lalu dijalankan kembali,
tampilan aplikasi menjadi kacau. Akibatnya saya harus menghapus setting
Notepad++. Aplikasi bisa berjalan kembali tetapi kembali ke setting
default.

Setelah mencari2 referensi, ternyata gedit bisa ditambah kemampuannya
dengan plugins. Plugin untuk gedit cukup beragam, tetapi tetap saya
belum merasa puas. Akhirnya saya menemukan artikel yang menyebutkan
sebuah aplikasi editor teks alternatif yaitu Geany. Geany tersedia di
repository Ubuntu sehingga dapat dengan cepat saya install dan gunakan.
Aplikasi ini akhirnya bisa memenuhi kebutuhan aplikasi editor teks
untuk pekerjaan saya. Saya akan membahas Gedit dan Geany lebih dalam
pada tulisan selanjutnya.

Powered by ScribeFire.

Selasa, April 17, 2007

Review SQuirreL SQL Client

Baru saja saya install dan coba2 aplikasi SQuirreL SQL Client, sebuah aplikasi freeware yang dapat didownload dari sourceforge.net

Aplikasi ini dibangun menggunakan Java, sehingga dapat dijalankan di berbagai OS yang telah memiliki JavaVM. Proses instalasi cukup sederhana dan mudah dilakukan.
Tampilan awal aplikasi masih menggunakan theme metal default dari Java. Aplikasi ini langsung mengenali beberapa driver JDBC yang terinstall, tidak seperti DBVisualizer (pembahasan mengenai DBVisualizer menyusul)

Ketika hendak membuat koneksi ke MySQL di localhost, saya cukup kerepotan mencari tombol untuk melakukannya. Di aplikasi ini, task untuk melakukan koneksi disebut dengan istilah Alias. Untuk membuat koneksi ke MySQL, pengguna harus menuliskan string koneksi dalam format JDBC (jdbc:mysql://localhost/). Hal ini dirasa cukup menyulitkan bagi pemula, apalagi yang belum pernah menggunakan JDBC, walaupun aplikasi telah menyediakan template di isian URLnya (jdbc:mysql://<hostname>[,<failoverhost>][<:3306>]/<dbname>[?<param1>=<value1>][&<param2>=<value2>])

Setelah koneksi terjalin, hal yang cukup merepotkan lainnya adalah ketika ingin melihat informasi tabel di sebuah database. Jika di-klik dari panel tree di kiri jendela utama, tidak tampil apapun di bagian kanannya. Ternyata harus dipilih Catalog yang hendak ditampilkan dari dropdown di bagian atas tree. Dropdown ini berisi list schema. Setelah schema dipilih, barulah tampil list tabel pada tree struktur di bagian kanan. Kenapa ga diintegrasikan aja ke dalam tree-nya, biar ga 2 kali kerja kan??

Eksplorasi aplikasi ini baru sampai pada bagian ini. Info tabel yang tampil di bagian kanan cukup lengkap, dibagi dalam tab2. Yang belum ketemu hingga saat ini adalah cara menambah data ke dalam tabel, maupun untuk mengubah struktur tabel. Aplikasi ini memiliki potensi untuk berkembang lebih baik lagi, semoga saja bisa menggantikan peran Navicat (lihat tulisan sebelumnya).

Selasa, April 10, 2007

Weird GNU C++

While programming in C++, I need to transform a string into lower case. I search how to do it, and found a STL algorithm transform:

#include <string>
#include <iostream>
#include <algorithm>
#include <cctype>
using namespace std;
int main() {
  //create a string
  string s("Some STRING with MiXed cASE");
  cout << "original: " << s << endl;
  //lowercase all characters
  transform (s.begin(), s.end(),    //source
             s.begin(),             //destination
             tolower);              //operation
  cout << "lowered: " << s << endl;
  //uppercase all characters
  transform (s.begin(), s.end(),    //source
             s.begin(),             //destination
             toupper);              //operation
  cout << "uppered: " << s << endl;
}


However, when I compile it, I got this error message:
error: no matching function for call to 'transform(__gnu_cxx::__normal_iterator<char*,>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*,>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*,>, std::allocator<char> > >, <unresolved>)'


After googling for it, I've found a tricky solution here. Just made a new function:
char to_lower (const char c) { return tolower(c); }


Then change the transform function calling into:
  //lowercase all characters
  transform (s.begin(), s.end(),    //source
             s.begin(),             //destination
             to_lower);             //operation
  cout << "lowered: " << s << endl;


It's now compiled with error free, and running as expected. Weird isn't it??

Update : I've found another link explaining this phenomena here.
Rewriting the transform calling into this works too.
  //lowercase all characters
  transform (s.begin(), s.end(),    //source
             s.begin(),             //destination
             (int(*)(int))std::tolower);             //operation
  cout << "lowered: " << s << endl;

Powerful non free Programming Tools

Here the list of a powerful but, unfortunately, non free programming tools. I hope I could find a free-version replacement tools for these.

  1. Power Designer.
    To design a complex database, with many relation between entities, this tools is a must. Power Designer could make a CDM, and convert it into PDM, or you could reverse engineering existing database schema into PDM and CDM.
  2. Navicat
    Browsing database scheme, make new databases, grant privileges, build query from many joined tables. These functionalities are the Navicat's killer feature that I couldn't find in another MySQL tools (yet).
  3. Macromedia Dreamweaver MX 2004 + PHAkt
    Web programming with PHP+MySQL+ADOdb will be easier with this deadly combo. But I'm not prefer using Dreamweaver now,cause it mess with the code identation. I prefer using Notepad++ to edit all of my code, it's a powerful text editor. Dreamweaver is good to test a color, cause you could choose the color from color wheel or color diagram.
I hope this list is not get longer than the above item, and I hope I could find the replaement tools for the first 2 item. If you know, tell me, okay ;)

Kamis, April 05, 2007

OCCI Programming

Untuk mengakses database Oracle dari program yang dibuat dengan bahasa C++, Oracle telah menyediakan interface yang disebut OCCI. Pedoman pemrograman OCCI tersedia di website Oracle dan dapat didownload secara gratis di link ini.

Berikut ini sharing pengalaman saya menggunakan OCCI ini di pekerjaan yang sedang saya kerjakan.

Pola umum program:

Environment *env = Environment::createEnvironment(Environment::OBJECT);
try {
  Connection *con = env->createConnection(userName, password, connectString);
  Statement *stmt = con->createStatement(query);
  ResultSet *rs = stmt->executeQuery();
  ...
  stmt->closeResultSet(rs);
  con->terminateStatement(stmt);
  env->terminateConnection(con);
}
catch (SQLException &e) {
    cerr << "ERROR" << endl;
    cerr << e.getErrorCode() << endl;
    cerr << e.getMessage() << endl;
}


Potongan kode diatas merupakan pola umum untuk melakukan query ke database Oracle. userName, password, connectString merupakan variabel bertipe string yang isinya disesuaikan dengan informasi akses pengguna ke database yang hendak diakses. query merupakan variabel string yang berisi query yang hendak dijalankan terhadap database yang sedang diakses.

Untuk mempermudah penggunaan, saya membuat class sendiri untuk membungkus pemanggilan fungsi2 OCCI. Pola class yang saya gunakan :

class myocciclass
{
  private:
    Environment *env;
    Connection *conn;
    Statement *stmt;
    //properties lain
    ...
    //copy konstruktor
    myocciclass(const myocciclass&);
    //assignment
    myocciclass& operator= (const myocciclass&);

  public:
    //konstruktor
    inline myocciclass(const string& user, const string& passwd, const string& db);
    //destruktor
    inline ~myocciclass();
    //method lain
    ...
};

//konstruktor
inline myocciclass::myocciclass(const string& user, const string& passwd, const string& db) {
  this->env = Environment::createEnvironment (Environment::DEFAULT);
  this->conn = env->createConnection (user, passwd, db);
  this->stmt = conn->createStatement();
}
//destruktor
inline myocciclass::~myocciclass() {
  this->conn->terminateStatement (this->stmt);
  this->env->terminateConnection (this->conn);
  Environment::terminateEnvironment (this->env);
}


Class diatas dapat ditambahkan dengan properties dan method lain yang dibutuhkan. Dengan menggunakan class seperti ini, pengaksesan database akan lebih mudah, karena di program utama, cukup melakukan instantiasi object dari class myocciclass :

myocciclass *moc = new myocciclass (userName, password, db);


Selanjutnya tinggal memanggil mothod2 pada object moc yang telah didefinisikan. Program utama tidak perlu melakukan inisialisasi maupun menutup koneksi ke database Oracle, karena hal itu telah ditangani oleh class myocciclass.

Selamat memprogram menggunakan OCCI...

Minggu, April 01, 2007

Database access from PHP

When building application that need coonections to databases, there are two common options. First, to use a programming language's build in feature to access the database. Second, using a wrapper class / library to provide an easy way to connect to the database.

In PHP, a build in feature to connect to databases is available. Take a look at PHP connection to MySQL. In PHP 5, there are two way to connect to MySQL, either using mysql_ command set, or using mysqli_ command set. Both of those command are incompatible. Example, to escape a string, mysql command set had the command and parameter like this format:

string mysql_real_escape_string ( string unescaped_string [, resource link_identifier] );

But, mysqli had the parameter position swapped:
string mysqli_real_escape_string ( mysqli link, string escapestr )


See, you can't savely replace each mysql_ with mysqli_, both command is not compatible. To connect to other database?? Every database build in command had it's own parameter sets, and it's non compatible with the other's command.

The second way to access database was created to overcome those issues. One of the library that has multiple database connection support is ADODB. When using ADODB, the command to execute query in the MySQL and in the MSSQL is the same command. The parameter are in the same order. ADODB's version to above escape_string functions is
$conn->qstr(string);


ADODB wil take care resource identifier passing to actual command. ADODB wraps all needed variables into a single object. ADODB make PHP Programming easier.

Jumat, Maret 30, 2007

Top 6 from Top 10 for programmer - codinghorror

Got this from linux-programming@linux.or.id maillist, posted by fade2blac

Jerry Weinberg: The 10 Commandments of Egoless Programming
1.Understand and accept that you will make mistakes.
2.You are not your code.
3.No matter how much "karate" you know, someone else will always know more.
4.Don't rewrite code without consultation.
5.Treat people who know less than you with respect, deference, and patience.
6.The only constant in the world is change.
7.The only true authority stems from knowledge, not from position.
8.Fight for what you believe, but gracefully accept defeat.
9.Don't be "the guy in the room."
10.Critique code instead of people- be kind to the coder, not to the code.


Dare Obasanjo: Top 10 Signs Your Software Project is Doomed
1.Trying to do too much in the first version.
2.Taking a major dependency on unproven technology.
3.Competing with an existing internal project that is either a cash cow or has powerful backers.
4.The team is understaffed.
5."Complex problems require complex solutions".
6.Schedule Chicken
7.Scope Creep
8.Second System Syndrome
9.No Entrance Strategy.
10.Tackling a problem you don't know how to solve.


Omar Shahine: Top 10 Tips for Working at Microsoft (or Anywhere Else)
1.Process is no substitute for thinking.
2.Get out of your office.
3.Use your product (the one your customers will).
4.Fix things that are broken rather than complain about them being broken. Actions speak better than your complaining.
5.Make hard problem look easy. Don't make easy problems look hard.
6.Use the right communication tool for the job.
7.Learn to make mistakes.
8.Keep things simple.
9.Add value all the time.
10.Use their product.


Michael McDonough: The Top 10 Things They Never Taught Me in Design School
1.Talent is one-third of the success equation.
2.95 percent of any creative profession is shit work.
3.If everything is equally important, then nothing is very important.
4.Don't over-think a problem.
5.Start with what you know; then remove the unknowns.
6.Don't forget your goal.
7.When you throw your weight around, you usually fall off balance.
8.The road to hell is paved with good intentions; or, no good deed goes unpunished.
9.It all comes down to output.
10.The rest of the world counts.


Andres Taylor: Top 10 Things Ten Years of Professional Software Development Has Taught Me
1.Object orientation is much harder than you think.
2.The difficult part of software development is communication.
3.Learn to say no.
4.If everything is equally important, then nothing is important.
5.Don't over-think a problem.
6.Dive really deep into something, but don't get hung up.
7.Learn about the other parts of the software development machine.
8.Your colleagues are your best teachers.
9.It all comes down to working software.
10.Some people are assholes.


Steve Yegge: 10 Great Books
1.The Pragmatic Programmer: From Journeyman to Master
2.Refactoring: Improving the Design of Existing Code
3.Design Patterns
4.Concurrent Programming in Java(TM): Design Principles and Pattern (2nd Edition)
5.Mastering Regular Expressions, 2nd Edition
6.The Algorithm Design Manual
7.The C Programming Language, Second Edition
8.The Little Schemer
9.Compilers
10.WikiWikiWeb