Staffsite STMIK PPKIA Pradnya Paramita b6f78 gambas3 bab15
Diterjemahkan oleh Agus Rahadian untuk kepentingan pembelajaran, Silahkan anda
perbanyak dan edit terjemahan ini tetapi tidak untuk diperjualbelikan/dikomersilkan.
Penterjemah melakukan ini semampunya tanpa ada dan atau meminta donasi dan hanya
untuk membantu mereka yang kesulitan dalam memahami buku berbahasa Inggris.
Semoga Allah SWT mencerahkan hati dan pikiran kita, Amiin.
(2)
BAB 15
MySQL DAN GAMBAS
Bab ini menjelaskan secara rinci proses menggunakan database MySQL dari dalam lingkungan pemrograman Gambas. Untuk tujuan kita, kita akan mengasumsikan bahwa MySQL sudah terinstal di komputer Anda (atau mesin diakses kepada Anda dari mesin anda) dan bahwa server MySQL tersedia bagi Anda untuk terhubung ke dari dalam program Gambas Anda. Jika hal ini tidak terjadi, maka Anda akan harus merujuk ke manual MySQL dan mencari cara untuk menginstal distribusi database MySQL pada sistem tertentu. Anda juga harus menyadari fakta bahwa Gambas juga akan bekerja sama dengan PostgreSQL dan SQLite. SQLite bukanlah sebuah arsitektur client / server yang benar seperti MySQL dan PostgreSQL. Ini adalah sebuah sistem database yang flat-file dan tidak menggunakan model klien / server database. Untuk tujuan kita dalam bab ini, kita akan tetap ke MySQL karena mungkin yang paling banyak digunakan dari tiga produk database.
Paket database MySQL terdiri dari MySQL Server dan berbagai program client. MySQL Server adalah program yang menyimpan dan mengelola semua database Anda dalam lingkungan MySQL. Program klien yang disertakan dengan MySQL terlalu banyak untuk daftar di sini tetapi penting bagi Anda untuk memahami bahwa setiap aplikasi klien melayani tujuan tertentu yang berkaitan dengan manajemen dan / atau administrasi data atau metadata disimpan pada MySQL Server. Program klien kita akan berhadapan dengan -dalam bab ini- disebut mysql (perhatikan itu dieja dalam huruf kecil). Program client menyediakan antarmuka baris perintah (CLI=Command Line Interface) dapat Anda gunakan untuk mengeluarkan pernyataan SQL interaktif ke MySQL Server dan melihat hasilnya segera ditampilkan. Perbedaan utama antara MySQL dan mysql adalah bahwa MySQL digunakan untuk merujuk pada paket seluruh distribusi MySQL atau merujuk ke MySQL Server sementara mysql mengacu pada program CLI klien.
Apa tujuan melakukannya melayani untuk memiliki kedua klien dan server bukannya satu program? Server dan program client dibagi menjadi entitas yang berbeda sehingga Anda dapat menggunakan program klien (s) pada sistem Anda untuk mengakses data pada server MySQL yang dapat berjalan pada komputer lain. Dengan memisahkan paket menjadi klien server dan n, berfungsi untuk memisahkan data dari antarmuka pengambilan data. Sebelum Anda mulai bekerja pada bab ini, sangat disarankan agar Anda membiasakan diri dengan MySQL dengan men-download panduan terbaru dari situs web resmi MySQL. Minimal, menyelesaikan tutorial dalam Bab 3 dari User Manual MySQL sebelum melanjutkan dengan bab ini. Begitu Anda sudah familiar dengan bagaimana dasar SQL operasi bekerja dalam lingkungan MySQL, Anda siap untuk melanjutkan dengan bab ini, yang lebih berfokus pada bagaimana menyelesaikan jenis yang sama hal yang tutorial MySQL ditunjukkan, melainkan dari dalam program Gambas.
Untuk mengakses database dalam lingkungan Gambas, Anda perlu memastikan proyek Anda menggunakan komponen gb.db. Bila Anda membuat proyek baru, Anda perlu pergi ke dialog proyek properti dan Anda akan menemukan tab untuk komponen. Dari dalam dialog ini tab, Anda dapat memilih komponen yang Anda butuhkan untuk program Anda. Dalam kasus database, Anda akan perlu memeriksa gb.db sebelum Anda dapat menggunakan salah satu kelas yang didefinisikan oleh komponen ini. Seperti yang kita dinyatakan sebelumnya, komponen gb.db memungkinkan Anda untuk mengakses sistem manajemen database berikut: PostgreSQL, MySQL, SQLite2, SQLite3, Firebird, dan ODBC. Karena PostgreSQL dan MySql adalah klien / server database, itu berarti program Anda akan perlu untuk membuat sambungan ke server database. SQLite adalah database berbasis flatfile sehingga tidak ada proses server untuk program Anda untuk terhubung dengannya. Namun, ini juga berarti bahwa program Anda mungkin perlu menggunakan nama path yang memenuhi syarat untuk menggunakan setiap file database
(3)
jika jalan default (yaitu, application path) tidak digunakan.
Komponen gb.db telah dirancang untuk menciptakan perantara (diabstraksikan) lapisan antara server database dan program anda. Hal ini memungkinkan Anda untuk menggunakan kode yang sama terlepas dari backend database Anda memutuskan untuk menggunakan. Ada beberapa peringatan, tentu saja. Pendekatan ini disarikan hanya bekerja jika Anda telah membuat database Anda dengan menggunakan database manager atau dengan menggunakan komponen gb.db. Furtherrmore, Anda harus menggunakan metode Find, Create dan Edit dilengkapi dengan komponen gb.db. Anda tidak dapat menempatkan nilai-nilai SQL secara langsung dalam permintaan - Anda harus menggunakan fitur metode substitusi tersebut untuk mencapai itu. Akhirnya, Anda tidak dapat menggunakan metode Exec untuk mengirim permintaan SQL langsung ke server untuk mengakses server-fitur khusus. Sementara ini terdengar cukup ketat, pada kenyataannya itu bukan halangan untuk program anda. Mengingat beberapa peringatan, Anda dapat menyelesaikan hampir semua operasi database yang diperlukan dari dalam lingkungan Gambas. Kelas-kelas yang didukung dalam komponen gb.db adalah Blob, Connection, DB, Database, DatabaseUser, Field, Index, Hasil, ResultField, Tabel.
Catatan: Gambas 3 memperkenalkan kelas baru yang disebut Connections.
Blob Class
Kelas Blob adalah obyek dikembalikan oleh field Blob, yang merupakan jenis data yang digunakan dalam SQLite3 mengandung data format yang tak tentu, seperti data type Varian dalam Gambas. Hal ini memungkinkan kita untuk membaca atau menulis data bila tipe data yang akan menerima variabel tidak diketahui. Blob memiliki dua sifat: Data, yang menetapkan atau mengembalikan isi blob, dan Length, yang mengembalikan panjang isi Blob dalam bytes.
Connection Class
Kelas Connection menetapkan koneksi ke database. Agar berhasil terhubung ke database, Anda harus terlebih dahulu membuat objek koneksi dan mengatur sifat yang diperlukan yang akan digunakan oleh database. Selanjutnya Anda harus memanggil method Open. Jika Anda tersambung ke database SQLite dan properti Name adalah null, database dibuka dalam memori. Jika Name ditentukan adalah path absolut, pathname digunakan. Jika Name yang ditetapkan adalah path relatif dan properti Host nol, database terletak dalam aplikasi sementara direktori / tmp / gambas. $UID / sqlite. Jika tidak, Host akan berisi nama direktori database dan path file database adalah hasil dari concatenating Host dan nilai Name properti. Kelas ini creatable dan konvensi pemanggilan adalah:
DIM hConnection AS Connection hConnection = NEW Connection()
1. Properti Connection
Ketika objek hConnection diberi contoh, itu menciptakan objek kekosongan koneksi baru. Anda kemudian akan perlu mengatur properti untuk objek ini. Properti yang dapat Anda gunakan dengan objek koneksi meliputi:
• Charset
Charset adalah properti read-only yang mengembalikan charset yang digunakan oleh database. Hal ini mungkin bagi Anda untuk menyimpan string Anda dalam database secara langsung dalam format UTF-8. Namun, Anda juga bisa dapat
(4)
menggunakan properti dikombinasikan dengan Conv$() subroutine untuk mengkonversi dari format UTF-8 ke format charset database. Namun Menggunakan charset database yang datang pada biaya dalam kinerja. Hal ini karena Anda harus menggunakan Conv$ () subroutine setiap kali Anda membaca atau menulis data string untuk field pada database. Untuk saat ini, ini adalah satu-satunya cara Anda dapat melakukan ini jika Anda ingin menggunakan string berbasis fungsi SQL dan built-in rutinitas semacam sistem manajemen database (MySQL, PostgreSQL, atau SQLite). Versi mendatang dari Gambas otomatis dapat membuat konversi antara string Gambas dan charset database.
• Databases
Properti Database dapat diperiksa untuk mendapatkan obyek koleksi yang akan berisi nama dari semua database yang dikelola oleh server database. Sintaks adalah:
PROPERTY Databases AS .ConnectionDatabases
Pengumpulan data yang dihasilkan (yang enumerable menggunakan
pernyataan FOR EACH) akan sama seperti jika Anda mengetik SHOW
DATABASES dari CLI mysql client.
• Error
Properti ini mengembalikan kode kesalahan terakhir yang diajukan oleh driver database.
• Host
Anda dapat menggunakan properti host untuk mengatur atau mendapatkan nama host dari mana server database berada. Nama host dapat berupa nama mesin atau alamat IP. Host default bernama localhost. Dalam SQLite, nama host tidak relevan karena SQLite bukanlah sytstem database klien / server. Namun, dari versi 0.95 ke depan, adalah mungkin bagi Anda untuk mengatur jalur path database SQLite dengan menggunakan properti ini. Sintaks untuk menggunakan properti Host:
PROPERTY Host AS String
• Login
Properti Login digunakan untuk mengatur atau mendapatkan data login pengguna yang digunakan untuk membangun koneksi ke database. Sekali lagi, ini berlaku untuk MySQL dan PostgreSQL, bukan SQLite. Karena SQLite tidak memiliki konsep pengguna, akses ke database SQLite dikendalikan oleh pengaturan file izin dari file database itu sendiri. Ini berarti bahwa properti Login selalu akan diatur ke user id dari user yang menjalankan program Gambas yang menggunakan database SQLite. Sintaks adalah:
(5)
• Name
Properti Name set atau mendapatkan nama database yang Anda ingin terhubung ke. Jika Anda tidak menentukan nama, database sistem default digunakan. Untuk PostgreSQL database default bernama template1 dan mySQL itu bernama mysql. Untuk SQLite, nama default adalah / tmp / sqlite.db. Untuk setiap akses database, Namun, pengguna harus memiliki setidaknya membaca dan menghubungkan hak akses untuk menggunakan database ini. Sqlite akan mencari database pertama dengan mencoba untuk menggunakan nama path lengkap jika telah diberikan. Jika tidak, itu akan memeriksa untuk melihat apakah variabel host telah ditetapkan. Jika itu terjadi, SQLite akan melihat nama jalan yang ditetapkan dalam variabel. Jika GAMBAS_SQLITE_DBHOME variabel lingkungan telah ditetapkan, maka SQLite akan menggunakannya sebagai direktori kerja saat ini. Hal ini juga memungkinkan untuk membuat dan menggunakan database di memori dengan menyetel properti Name untuk ": memori:" daripada "mysql" atau "postgresql" atau "sqlite". Sintaks adalah:
PROPERTY Name AS String
• Opened
Properti Boolean mengembalikan TRUE jika koneksi dibuka. Sintaks adalah:
PROPERTY READ Opened AS Boolean
• Password
Properti Password akan mengembalikan atau mengatur sandi yang digunakan untuk membangun koneksi ke database. Konvensi pemanggilan adalah:
PROPERTY Password AS String
• Port
Properti Port digunakan untuk mendapatkan atau mengatur port TCP / IP yang digunakan untuk membangun koneksi ke database. Port default tergantung pada Tipe koneksi. Sintaks adalah:
PROPERTY Port AS String
• Tables
Properti Tabel digunakan untuk memperoleh koleksi virtual yang dapat digunakan untuk mengelola semua tabel dari database. Sintaks adalah:
PROPERTY Tables AS .ConnectionTables
• Type
Properti Type merupakan tipe server database Anda ingin terhubung ke. Pada Gambas, tipe database saat ini didukung adalah: "postgresql", "mysql", dan "sqlite". Properti tipe menggunakan sintaks ini:
(6)
PROPERTY Type AS String
• User
Ini sinonim dengan Properti Password. Sintak adalah :
PROPERTY User AS String
Properti Users mengembalikan koleksi semua pengguna terdaftar di database server. Seperti benda koleksi lainnya, dapat disebutkan dengan FOR EACH. Sintaks adalah:
PROPERTY Users AS .ConnectionUsers
• Version
Properti Version adalah nilai read-only yang mengembalikan versi database bahwa driver terhubung dengan. Sintaks adalah:
PROPERTY READ Version AS Integer
2. Konsep Transaksi
Ada kalanya urutan yang database tindakan (atau query) yang dieksekusi adalah penting. Kadang-kadang, sebuah program harus memastikan semua permintaan dalam kelompok dijalankan dengan sukses dan dalam rangka atau proses tidak satupun dari mereka sama sekali. Sebuah contoh klasik yang diambil dari lingkungan perbankan. Jika jumlah uang yang diberikan (misalnya, 100 dolar) yang diambil dari satu account dan diposting ke akun yang lain, kita akan mengharapkan tindakan berikut terjadi:
UPDATE account1 SET balance = balance - 100; UPDATE account2 SET balance = balance + 100;
Kedua pertanyaan harus mengeksekusi berhasil atau tidak harus mengeksekusi. Uang tidak dapat ditransfer dari satu account dan gagal yang akan diposting ke akun lainnya. Kedua pertanyaan membentuk satu transaksi yang terdiri dari dua tindakan yang terpisah (debit 100 dari account1 dan kredit 100 sampai account2). Sebuah transaksi hanya satu atau lebih query database individu dikelompokkan bersama antara BEGIN dan COMMIT pernyataan. Tanpa pernyataan COMMIT, transaksi tidak permanen dan dapat dibalik dengan pernyataan ROLLBACK.
MySQL otomatis melakukan pernyataan yang bukan merupakan bagian dari proses transaksi. Hasil dari pernyataan UPDATE atau INSERT SQL yang tidak didahului dengan BEGIN akan segera dapat dilihat oleh semua koneksi ke database karena komit secara otomatis dilakukan. Kebanyakan database yang mampu mencapai hal ini dikatakan ACID-compliant. Model ACID merupakan salah satu konsep tertua dan paling penting dari teori database. Empat tujuan yang harus dipenuhi untuk setiap database yang akan dipertimbangkan handal adalah Atomicity, Consistency, Isolation dan Durability (ACID). Mari kita periksa masing-masing empat karakteristik secara rinci.
Atomicity
Atomicity berarti modifikasi database harus mengikuti aturan "semua atau tidak sama sekali". Setiap transaksi dianggap sebagai unit "atom". Jika ada bagian dari transaksi gagal, seluruh transaksi gagal. Hal ini penting DBMS memelihara sifat atom dari transaksi
(7)
dalam keadaan apapun. Consistency
Consistency menyatakan hanya data yang valid akan ditulis ke database. Apabila suatu transaksi dieksekusi yang melanggar aturan konsistensi database, seluruh transaksi akan digulung kembali dan database akan dikembalikan ke keadaan konsisten dengan aturan. Sebaliknya, jika transaksi mengeksekusi berhasil, ia akan mempertahankan keadaan konsistensi.
Isolation
Isolasi memerlukan beberapa transaksi yang terjadi secara bersamaan tidak mempengaruhi satu sama lain. Misalnya, jika Pengguna A melakukan transaksi dalam waktu bersamaan dengan transaksi PenggunaB, kedua transaksi harus beroperasi pada database dalam isolasi “kebahagiaan”. Database harus melakukan satu transaksi sebelum yang lain. Ini mencegah transaksi dari membaca data menengah dihasilkan sebagai efek samping dari transaksi lain. Isolasi tidak menjamin transaksi baik akan mengeksekusi pertama, hanya saja mereka tidak akan saling mengganggu.
Durability
Durabilitas memastikan setiap transaksi berkomitmen untuk database tidak akan hilang. Hal ini dilakukan melalui backup database dan log transaksi yang memfasilitasi pemulihan transaksi yang dilakukan meskipun ada kegagalan berikutnya. Sekarang, mari kita lihat metode kelas Koneksi Gambas tersedia bagi Anda dalam program Anda.
3. Metode Koneksi Kelas
Kelas Connection menyediakan sebagian besar metode Anda akan perlu untuk membuat koneksi ke database dan mengeksekusi satu atau lebih transaksi untuk mencari, menambah, mengubah, atau menghapus data.
Open/Close
Metode Open digunakan untuk membuka koneksi ke database. Sebelum membuat panggilan ke Open, Anda harus mengatur properti koneksi dengan data yang diperlukan untuk menggunakan database. Umumnya, minimal Anda akan perlu untuk menentukan jenis database, host, login ID dan password, dan nama database yang ingin Anda gunakan. Sintaks untuk terbuka adalah:
FUNCTION Open ( ) AS Boolean
Contoh kode di bawah ini menunjukkan bagaimana menggunakan method Open untuk menghubungkan jrittinghouse pengguna ke database MySQL bernama "GambasBugs" yang disimpan di Host localhost :
DIM $hConn As NEW Connection WITH $hConn
.Type = "mysql" .Host = "localhost" .Login = "jrittinghouse" .Password = "ab32e44" .Name = "GambasBugs" END WITH
(8)
TRY $hConn.Open
IF Error THEN PRINT "Database cannot be opened. Error = "; Error.Text
Untuk menutup koneksi, cukup memanggil metode Close. Dalam contoh kita di atas, Anda bisa menggunakan kode ini:
$hConn.Close
dan koneksi akan ditutup. Untuk selanjutnya menggunakan data yang disimpan dalam database, Anda akan perlu untuk membuka kembali database dengan menggunakan method Open.
Beggin/Commit/Rollback
Seperti yang kita dinyatakan sebelumnya, transaksi adalah satu atau lebih query database individu yang dikelompokkan bersama-sama antara pernyataan BEGIN dan COMMIT. Tanpa pernyataan COMMIT, transaksi tidak permanen dan dapat dibalik dengan pernyataan ROLLBACK. Ingat bahwa MySQL otomatis melakukan pernyataan yang bukan merupakan bagian dari proses transaksi (didefinisikan oleh BEGIN dan COMMIT). Pada Gambas, disarankan agar Anda menggunakan metode Cari, Buat, dan Edit untuk membuat perubahan ke database. Hal ini membantu untuk menjaga independensi kode dan memungkinkan Anda untuk menulis satu bagian dari kode yang akan bekerja dengan database yang didukung oleh Gambas. Gambas menggunakan objek hasil untuk mengembalikan hasil query SQL.
Find
Tersebut metode Find mengembalikan sebuah objek read-only Result digunakan untuk query catatan dalam tabel tertentu. Konvensi menghubungi Find adalah:
FUNCTION Find (Table AS String [, Request AS String, Arguments AS , ... ] ) AS Result
Request merupakan pernyataan WHERE SQL yang digunakan untuk query tabel. Argumen yang dikutip seperlunya (ditentukan oleh sintaks SQL), dan diganti dalam string Request. Ia bekerja seperti fungsi Subst () dalam kasus ini. Dengan menggunakan metode Find memungkinkan Anda untuk menulis permintaan yang independen dari database, yang berarti ia akan bekerja dengan PostgreSQL atau MySQL tanpa perubahan kode yang diperlukan.
Create
Metode Create digunakan untuk membangun baca / tulis objek Result yang dapat digunakan untuk membuat catatan dalam sebuah tabel. Standar konvensi pemanggilan adalah:
FUNCTION Create ( Table AS String ) AS Result Edit
Metode Edit mengembalikan sebuah objek baca / tulis Result digunakan untuk mengedit catatan dalam tabel yang ditentukan. Request adalah SQL WHERE Clause digunakan untuk menyaring tabel, dan Argumen yang dikutip dibutuhkan oleh sintaks SQL dan diganti dalam string Request sebagaimana telah dijelaskan sebelumnya. Standar konvensi
(9)
pemanggilan adalah:
FUNCTION Edit ( Table AS String [ , Request AS String, Arguments AS , ... ] ) AS Result
Berikut adalah contoh kode untuk menunjukkan bagaimana Edit () bekerja:
DIM MyResult AS Result DIM sQuery AS String DIM iParm AS Integer
sQuery = "Select * from tblDEFAULT where id = "
' we will insert a parameter value (12) at the end of the query string
iParm = 12 $hConn.Begin
MyResult=$hConn.Edit("tblDEFAULT", sQuery, iParm) MyResult!Name = "Mr Rittinghouse" ' Set a field value
$hConn.Update ' Update with the new value
$hConn.Commit ' make the changes permanent
$hConn.Close ' close the database connection
Exec
Metode Exec mengeksekusi permintaan SQL dan mengembalikan sebuah objek read-only Result yang berisi hasil dari permintaan. Standar konvensi pemanggilan adalah:
FUNCTION Exec ( Request AS String, Arguments AS , ... ) AS Result
Request adalah SQL WHERE Clause dan Argumen harus dikutip seperti yang dipersyaratkan oleh sintaks SQL.
Limit
Metode ini membatasi jumlah record yang dikembalikan oleh permintaan berikutnya. Setelah query dijalankan, jumlah record yang dikembalikan ulang ke terbatas. Metode ini mengembalikan sambungan itu berlaku untuk, sehingga Anda dapat menulis sesuatu seperti itu:
DB.Limit(X).Exec(...) Quote
Metode Quote mengembalikan sebuah identifier quote dapat Anda gunakan untuk
menyisipkan dalam query SQL. Pengenal ini dapat menjadi tabel atau nama field.
Sintaks adalah:
FUNCTION Quote ( Name AS String ) AS String
Mekanisme mengutip tergantung pada driver database server tertentu yang membuat metode ini diperlukan jika Anda perlu untuk menulis database-independen kode. Berikut adalah contoh bagaimana menggunakan Quote:
' Returns number of records in a querys DBTable
' is the name of the table. Since the name can include reserved 'characters it needs to be surrounded by quote marks
rResult = $hConn.Exec("SELECT COUNT(*) AS iNumRecs FROM " & DB.Quote(sDBTable)) PRINT rResult!iNumRecs
(10)
Subst
Metode Subst menciptakan sebuah kalimat SQL dengan menggantikan argumen dalam format string. Sintaks adalah:
FUNCTION Subst ( Format AS String, Arguments AS, ... ) AS String
Format adalah kalimat SQL, dan Argumen adalah argumen untuk menggantikan. Tersebut & 1, 2 & ... pola dalam string Format digantikan oleh masing-masing representasi SQL dari argumen ke-1, ke-2 .... Argumen-argumen ini quote sesuai dengan sintaks SQL database. Argumen yang digunakan dalam cara yang sama bahwa mereka digunakan dalam fungsi Subst$, dibahas dalam Bab 7.
Untuk contoh :
PRINT DB.Subst(“WHERE Name = &1 AND Date = &2”, “Benoit”, Now)
mengembalikan output ini :
WHERE Name = 'Benoit' AND Date = '2011-02-15 11:51:33.043'
4. Hasil Obyek
Obyek Hasilnya adalah kelas yang digunakan untuk mengembalikan hasil dari permintaan SQL. Kelas ini tidak creatable dan bertindak seperti array read-only. Hal ini enumerable menggunakan pernyataan FOR EACH. Mendeklarasikan dan iterate objek hasil sebagai berikut:
DIM hResult AS Result FOR EACH hResult
'do something with the data
NEXT
Kode snippet di bawah ini menunjukkan bagaimana Anda bisa mendapatkan nilai dari field dalam rekor saat objek Result:
DIM MyResult AS Result DIM MyVariant AS Variant
MyVariant = MyResult [Field AS String]
Kelas ResultField merupakan salah satu bidang objek Result. Anda dapat menggunakan metode Find untuk memilih bidang tertentu sebelum menggunakannya. Sifat kelas ini adalah mendukung Length, Name, Resultl dan Type. Hal ini juga memungkinkan untuk menghitung data yang ResultField dengan kata kunci FOR EACH. Kelas ini tidak creatable. Kode di bawah ini menunjukkan Anda bagaimana untuk mengubah nilai dari field dalam rekor saat objek Result:
DIM MyResult AS Result DIM MyVariant AS Variant
MyResult [Field AS String] = MyVariant
Properti yang dapat Anda gunakan dengan objek hasil meliputi Available, Connection, Count, Fields, Indeks, Length dan Max. Available akan mengembalikan nilai TRUE jika
(11)
hasilnya menunjuk ke catatan database yang sudah ada. Connection mengembalikan objek Connection orangtua. Count memberitahu Anda jumlah record (baris) kembali dengan obyek hasil. Fields mengembalikan koleksi field dalam tabel database dikembalikan dengan objek hasil. Indeks mengembalikan indeks (baris pointer atau kursor saat ini) dari catatan saat ini, dimulai dari nol. Length adalah sama dengan jumlah dan digunakan secara bergantian. Max kembali Result.Count-1.
Metode didukung oleh kelas objek hasil termasuk Delete, MoveFirst, MoveLast, MoveNext, MovePrevious, MoveTo, dan Update. Sebagian besar yang cukup jelas, tetapi metode Update digunakan untuk menulis ulang catatan saat ini untuk database dengan perubahan data yang ditentukan. Jika Anda menggunakan MoveTo dan menentukan indeks yang batal atau tidak sah, maka akan mengembalikan nilai TRUE menunjukkan kesalahan. Sekarang bahwa kita memiliki pemahaman dasar tentang apa objek hasil dan bagaimana menggunakannya, mari kita lihat bagaimana Gambas memungkinkan Anda untuk menemukan data dalam database dengan metode Find.
DB Class
Kelas ini merupakan koneksi database saat ini. Kelas ini bersifat statis dan semua anggotanya juga statis. Sebagian besar sifat dari kelas ini adalah sama dengan kelas Connection jadi kami hanya akan mencakup mereka yang berbeda, yaitu Current, Database, dan Debug. Current mengembalikan atau menetapkan sambungan saat ini. Database mengembalikan koleksi semua database yang dikelola oleh server database. Debug set atau mengembalikan TRUE jika komponen database dalam modus debug. Ketika bendera debug diatur, setiap query dikirim ke setiap driver database yang dicetak pada output standard error (umumnya, konsol). Metode yang digunakan dalam kelas DB adalah sama dengan yang digunakan di kelas Connection (Begin, Close, Commit, Create, Delete, Edit, Exec, Find, Limit, Open, Quote dan Rollback. Subst) jadi kita tidak akan mengulangi informasi di sini.
Database
Kelas Database digunakan untuk mewakili informasi yang berkaitan dengan database. Kelas ini tidak creatable. Sifat-sifat yang dapat Anda gunakan dengan kelas ini termasuk Connection, Name, dan Sistem. Connection dapat digunakan untuk mendapatkan obyek Connection parent. Name akan mengembalikan nama database dan Sistem akan mengembalikan nilai TRUE jika database adalah sistem database. Kelas database hanya memiliki satu metode, Delete, yang akan menghapus database.
DatabaseUser
Kelas DatabaseUser digunakan untuk mewakili pengguna database. Kelas ini tidak creatable. Tersebut mendukung User properti kelas adalah Administrator, Connection, Name dan Password. Administrator adalah properti read-only yang mengembalikan TRUE jika pengguna adalah administrator database. Connection mengembalikan objek induk koneksi pengguna. Name akan mengembalikan nama pengguna dan Password akan mendapatkan atau menetapkan sandi yang terkait dengan pengguna. Ketika Anda membaca properti, Anda harus mendapatkan password dalam bentuk terenkripsi. Kelas DatabaseUser memiliki metode tunggal, Delete yang digunakan untuk menghapus pengguna dari database.
(12)
Field
Kelas Field digunakan untuk merepresentasikan data untuk table field. Kelas ini tidak creatable. Properti yang mendukung hal ini adalah kelas Default, Length, Name, Tabel, dan Type. Standar mengembalikan nilai default dari field. Lentgh akan mengembalikan panjang maksimum kolom teks. Jika ruas teks yang diperiksa tidak memiliki batas yang ditentukan, nilai nol dikembalikan. Name akan mengembalikan nama field dan Tabel mengembalikan objek tabel di mana field diciptakan. Type mengembalikan datatype bahwa field mewakili. Gambas akan mengembalikan salah satu dari konstanta berikut:
gb.Boolean, gb.Integer, gb.Float, gb.Date or gb.String
Index
Kelas Index merupakan indeks tabel. Kelas ini tidak creatable. Sifat kelas ini mendukung adalah Fields, Name, Primer, Tabel, dan unik. Fields mengembalikan daftar commaseparated string yang mewakili bidang yang membentuk indeks. Name mengembalikan nama indeks sementara Primer akan mengembalikan nilai TRUE jika indeks adalah indeks utama dari tabel. Tabel akan mengembalikan objek tabel yang memiliki indeks ini. Unik mengembalikan TRUE jika indeks unik.
Table
Kelas Table merupakan definisi dari tabel database. Kelas ini tidak creatable. Sifat-sifat yang didukung oleh kelas Table termasuk Connection, Fields, Indeks, Name, primaryKey, Sistem dan Type. Connection dapat digunakan untuk mendapatkan obyek Connection parent. Fields akan mengembalikan koleksi field table sementara Indeks akan mengembalikan koleksi indeks tabel. Name akan mengembalikan nama tabel. PrimaryKey akan mengembalikan atau mengatur primary key dari tabel. Primary Key adalah sebuah array string yang berisi nama masing-masing field primary key. Sistem akan mengembalikan nilai TRUE jika database adalah sistem database. Type mengembalikan atau menetapkan jenis tabel. Properti ini unik untuk MySQL dan hanya digunakan dengan database MySQL. Kelas ini hanya memiliki satu metode, Update, yang disebut untuk benar-benar membuat tabel dalam database saat ini terhubung.
(13)
Contoh Program Database
Bagian sebelumnya dari bab ini telah dijelaskan tentang komponen database Gambas dan fitur yang disediakan di dalamnya. Namun, tidak ada pengganti bekerja dengan kode nyata dalam aplikasi nyata. Kapal gambas dengan program database contoh yang ditulis oleh pendiri Gambas Benoit Minisini, dan program ini merupakan contoh yang sangat baik bagaimana kode program anda untuk menggunakan database dalam lingkungan Gambas.
Kita akan bekerja dengan versi modifikasi dari program ini bernama "database1", ditemukan pada DVD yang menyertai buku ini. Untuk memulai, mulailah Gambas dan memilih program database1 dari DVD. Ketika IDE muncul, Anda akan melihat bahwa program ini mengandung dua bentuk, FMain dan frequest. FMain akan terlihat seperti ini:
Gambar 108: The FMain form dalam mode desain.
Program ini akan memungkinkan Anda untuk memilih apa platform database untuk menggunakan (yaitu, PostgreSQL, MySQL, atau SQLite) dan tentukan nama host, nama database, user ID dan password. Sebuah opsi untuk secara otomatis membuat database ada dan diaktifkan setiap kali kotak centang dicentang. Setelah Anda telah berhasil terhubung ke database, Anda memiliki pilihan untuk membuat tabel, menghapus, atau mengisinya dengan beberapa data uji. Permintaan SQL kotak di bagian bawah formulir akan memungkinkan Anda untuk melakukan query terhadap database SQL. Semua dalam semua, program ini menunjukkan hampir semua yang anda perlu tahu untuk koneksi ke database menggunakan Gambas. Bentuk FRequest jauh lebih sederhana
(14)
untuk membangun. Hal ini ditunjukkan pada gambar di bawah ini:
Gambar 109: FRequest Form dalam mode desain
Bentuk FRequest berisi kendali tunggal, yang kita belum pernah diperkenalkan, kontrol TableView. Kontrol ini ditemukan dalam toolset QT kita bahas sebelumnya. Kami akan menunjukkan kepada Anda bagaimana menggunakan kontrol ini ketika kita membahas kode bentuk FRrequest bawah. Untuk saat ini, mari kita melompat ke kode untuk bentuk FMain dan melihat bagaimana segalanya berjalan
' Gambas class file
$ hConn dinyatakan sebagai variabel pribadi dan akan digunakan oleh semua subrutin dalam file kelas. Perhatikan bahwa variabel diawali dengan simbol $ untuk menunjukkan itu adalah variabel kelas privat. Meskipun tidak diperlukan, itu adalah konvensi pemrograman yang baik untuk diikuti.
PRIVATE $hConn AS Connection
Setiap kali pengguna telah mengisi data pada bagian atas formulir dengan nama pengguna mereka, host, password, dll, dan klik tombol connect, program ini akan datang ke subroutine ini dan mencoba untuk menggunakan data tersebut untuk membuat koneksi ke database.
PUBLIC SUB btnConnect_Click()
'we need to have a string to work with so declare sName as local
DIM sName AS String
'now we get a little tricky. if a database was previously opened 'and is still open, this next line would close it. Using TRY
(15)
'would allow any error to be caught (see CATCH below). 'If there is not an open database to close, no harm was done 'and the code execution proceeds.
TRY $hConn.Close
'we assign the data in the Textbox txtName to our string var sName 'and set the database connection properties to the values provided 'by the user by using the WITH/END WITH construct.
sName = txtName.Text WITH $hConn
.Type = cmbType.Text 'the type of database platform to use
.Host = txtHost.Text 'host name of the database
.Login = txtUser.Text 'USER ID
.Password = txtPassword.Text 'USER password
END WITH
'at this point, all the connection properties are set but 'we have not opened the connection yet. The following code 'segment will see if a database with the name specified by 'sName exists and, if not, it will create it if the checkbox to 'create database is checked.
IF chkCreate.Value THEN
$hConn.Open 'open the connection
'see if a database sName exists and if not, add it to the server
IF NOT $hConn.Databases.Exist(sName) THEN $hConn.Databases.Add(sName)
ENDIF
'now close the connection
$hConn.Close ENDIF
'now, we are ready to open the database. Either it already existed 'and we open that database or we will open the new one we created 'if the checkbox was checked. First, set the Name property for the 'connection to sName and then call the Open method:
$hConn.Name = sName $hConn.Open
'we set the enabled properties for both program forms to TRUE 'and place some default text in the SQL request box at the 'bottom of the FMain form:
frmDatabase.Enabled = TRUE frmRequest.Enabled = TRUE txtRequest.Text = "SHOW TABLES"
'if our TRY failed or if any error occurred during this subroutine, 'the CATCH statement would display an ERROR dialog with the text of 'the error message. DConv will convert the system charset to UTF-8.
CATCH
Message.Error(DConvError.Text)) END 'of connectBtn_Click subroutine
Jika, setelah koneksi database didirikan, pengguna akan mengklik tabel Create "test" tombol, subrutin ini akan dieksekusi.
(16)
PUBLIC SUB btnCreate_Click()
'declare a local Table variable
DIM hTable AS Table
'add the table to the database using the Add method
hTable = $hConn.Tables.Add(txtName.text)
'now add the fields of the table to the table we just added 'note that we specify the field name and data type for each 'of the fields we insert into the table. For string data, 'we also specify the maximum length of the string field.
hTable.Fields.Add("id", gb.Integer)
hTable.Fields.Add("firstname", gb.String, 16) hTable.Fields.Add("name", gb.String, 32) hTable.Fields.Add("birth", gb.Date) hTable.Fields.Add("active", gb.Boolean) hTable.Fields.Add("salary", gb.Float)
'we can specify a primary key for the database table. In this 'case, the id field is used as we can create unique integer index 'data
hTable.PrimaryKey = ["id"]
'the call to the Update method commits the changes to the database 'and makes them permanent.
hTable.Update
'now we put up a simple dialog to inform the user we have 'successfully completed the creation task.
Message.Info("Table " & txtName.Text & " has been created.")
'this code enables or disables the
'buttons depending on the state of the database. For example, 'if there is data already in the database table, it does not make 'sense to fill that table again, so that button would be disabled. 'however, the delete button would be enabled so the data could be 'removed. If the database table is deleted, then it would be
're-enabled and if the table is created and no data exists,
'the fill button would again be enabled, etc. This prevents errors 'from clicking on a button where an action could not be performed 'successfully.
btnFill.Enabled = TRUE btnDelete.Enabled = TRUE btnCreate.Enabled = FALSE
'next, we add some default text to the SQL query box
txtRequest.Text = "Show TABLES"
'the CATCH statement would display an ERROR dialog with the text of 'the error message if any error occurs in this subroutine.
CATCH
Message.Error(DConv(Error.Text)) END 'of the create button subroutine
Jika, setelah koneksi database didirikan, pengguna akan mengklik Menghapus tabel "test" tombol, subrutin ini akan dieksekusi.
PUBLIC SUB btnDelete_Click()
'remove the table
TRY $hConn.Tables.Remove(txtName.Text)
'put up a message to inform the user the table is gone
Message.Info("Table "& txtName.Text & " has been removed")
(17)
'has been removed, it cannot be deleted again and it cannot 'be filled since it does not exist. All that is left is to
'recreate it and that button is enabled.
btnDelete.Enabled = FALSE btnFill.Enabled = FALSE btnCreate.Enabled = TRUE
'no table exists to query so blank out the SQL query text.
txtRequest.Text = ""
'if an error occurs in the subroutine catch it here and show a dialog 'message to the user.
CATCH
Message.Error(Error.Text) END 'the delete button subroutine
Jika koneksi database telah ditetapkan dan pengguna telah menciptakan tabel, perlu ada beberapa data tambahan untuk membuatnya berguna. Subroutine ini dijalankan dan akan menambah semi-arbitrary data ke tabel. Ini akan secara acak memilih nama pertama dari array lima nama yang diberikan dan menggabungkan nomor berlawanan dengan "Name #" string untuk melayani sebagai nama belakang. Tanggal lahir dibuat secara acak dengan memilih nilai yang menambahkan nomor acak dari 1-10,000 ke tanggal dasar 1 Januari 1970. Rekor memiliki bendera yang aktif, secara acak ditetapkan juga. Angka gaji yang dipilih secara acak dalam kisaran 1.000 hingga 10.000. Akhirnya, metode Update akan menaruh semua data dalam tabel dan membuat COMMIT ke database. Mari kita lihat setiap baris kode untuk melihat betapa mudahnya hal ini dilakukan di Gambas:
PUBLIC SUB btnFill_Click()
'we need an integer counter iInd to be our index and we 'need a Result object to store our results
DIM iInd AS Integer DIM rTest AS Result
'set the Busy flag to prevent interruptions to our process
INC Application.Busy
'we are going to start the database transaction process with BEGIN
$hConn.Begin
'create the database table first 'rTest = $hConn.Create("test")
rTest = $hConn.Create(txtName.Text)
'now, set up a loop to create 100 records
FOR iInd = 1 TO 100
'make the record id be the counter variable value
rTest!id = iInd
'randomly set the first name to be one of the five in the array
rTest!firstname = ["Paul","Pierre","Jacques","Antoine","Mathieu"][Int(Rnd(5))]
'make the last name a catenated value with the integer index value
rTest!name = "Name #" & iInd
'randomly choose a date by adding a value from 1 – 10,000 to the 'base date of Jan 1, 1970
rTest!birth = CDate("01/01/1970") + Int(Rnd(10000))
'set the active flag to either 0 or 1 (TRUE or FALSE)
rTest!active = Int(Rnd(2))
'randomly choose a salary figure from 1,000 to 10,000
rTest!salary = Int(Rnd(1000, 10000))
'update this record with the data semi-arbitrary data values
rTest.Update
(18)
'commit all added records to the database
$hConn.Commit
'last thing to execute before leaving the subroutine
FINALLY
'decrement the busy flag
DEC Application.Busy
'pop up a message to inform the user what we did
Message.Info(txtName.Text & " has been filled.")
'put a default SQL query in the SQL Query textbox
txtRequest.Text = "select * from " & txtName.Text
'fix our buttons to make sense
btnFill.Enabled = FALSE btnDelete.Enabled = TRUE btnCreate.Enabled = FALSE
'if something goes wrong, abort all changes with the Rollback and 'show the error message to the user
CATCH
$hConn.Rollback
Message.Error(Error.Text) END 'of the fill data subroutine
Jika pengguna memasukkan permintaan SQL apapun dalam kotak query SQL di bagian bawah formulir, kita akan menggunakan metode Exec untuk melakukan query dan tampilan hasil dari permintaan menggunakan formulir FRrequest. Berikut adalah cara yang dilakukan:
PUBLIC SUB btnRun_Click()
'declare a result object to hold the results of the query
DIM rData AS Result
'declare a form variable so we can show the FRequest form
DIM hForm AS FRequest
'execute the query using the Exec method and assign the results to 'the result object rData
rData = $hConn.Exec(txtRequest.Text)
'pass the database connection handle and the result data to the 'FRequest form when it is instantiated
hForm = NEW FRequest($hConn, rData)
'now display the form to the user with the result data
hForm.Show
'come here if there is a problem in the subroutine and display a msg
CATCH
Message.Error(Error.Text) END 'of sql query subroutine
Setiap kali program kami berjalan dan bentuk FMain terbuka, kita perlu instantiate Connection variabel kita $ hConn. Setiap kali formulir ditutup, kami akan menutup koneksi.
PUBLIC SUB Form_Open() $hConn = NEW Connection END
PUBLIC SUB Form_Close() $hConn.Close
END
Selanjutnya, kita perlu melihat bentuk FRrequest dan melihat bagaimana kode yang menampilkan data hasil objek bila dipanggil. Berikut adalah kode untuk itu:
(19)
' Gambas class file
' fRequest.class declares two private variables to use in this class ' one for the connection, one for the result data.
PRIVATE $hConn AS Connection PRIVATE $rData AS Result
'a constructor routine will be used to receive the connection handle 'and the results of a query as parameters when
FRequest is called by 'the FMain form.
PUBLIC SUB _new(hConn AS Connection, rData AS Result)
'assign the hConn parameter to our private $hConn variable
$hConn = hConn
'assign the rData parameter to our $rData private variable 'these assignments are made so the $ prefixed variables are 'visible to the entire class, not just the constructor routine.
$rData = rData
'call our little subroutine to display the title in the form window
RefreshTitle
'the ReadData subroutine is used to populate our TableView control
ReadData
'resize the window to center on the desktop
ME.Move(Int(Rnd(Desktop.W - ME.W)), Int(Rnd((Desktop.H - ME.H)))) END 'of the constructor
'this subroutine simply updates the window caption
PRIVATE SUB RefreshTitle()
'we need a local string variable
DIM sTitle AS String
'we will concatenate the connection name to the text for the caption
sTitle = ("SQL Query Results ") & " - " & $hConn.Name
'and set the title property to be the string variable value
ME.Title = sTitle END
Subrutin readdata () digunakan untuk mendefinisikan struktur data yang diberikan dalam dari objek hasil untuk kontrol TableView. Hal ini menentukan jumlah field dari obyek hasil dan menyiapkan kolom dalam tabel, menempatkan nama kolom (field) yang tepat dan tipe data. Tipe data ditentukan dengan memanggil subrutin lain, WidthFromType () untuk mendapatkan informasi tersebut.
Basis QT Library Kontrol TableView sudah usang di Qt Library, yang telah digantikan dengan kontrol QTable. Namun, Gambas telah menambahkan kontrol TableView sendiri, sehingga masih dapat digunakan dan kami akan menunjukkan kepada Anda bagaimana hal itu dilakukan.
PRIVATE SUB ReadData()
'this variable is declared but never used, you can comment it out
DIM hTable AS Table DIM hField AS ResultField DIM iInd AS Integer
'set the application busy flag to avoid interruptions
INC Application.Busy
'reset row count of the TableView control to zero
tbvData.Rows.Count = 0
'set the number of columns to be the same number ' as the number of fields in the result object
tbvData.Columns.Count = $rData.Fields.Count
(20)
'get the name of the field and the data type and set the TableView 'column headings and field type/size as appropriate
FOR EACH hField IN $rData.Fields WITH hField
'this is a debug line that was commented out
'PRINT .Name; ": "; .Type; " "; .Length
'this next line sets the column name to be the field name
tbvData.Columns[iInd].Text = .Name
'here, the call to WidthFromType is used to determine what data 'type the field is and what the appropriate width should be
tbvData.Columns[iInd].Width = WidthFromType(tbvData, .Type, .Length, .Name) END WITH
'increment our index counter
INC iInd
NEXT 'iteration of result data
'set the number of TableView rows to be the same as the number 'of rows of data in the result object
tbvData.Rows.Count = $rData.Count
'last thing we do in this subroutine is decrement the busy flag
FINALLY
DEC Application.Busy
'if there were any errors in this subroutine we would show a message
CATCH
Message.Error("Cannot exec request." & "\n\n" & Error.Text) END 'of ReadData subroutine
Bit berikutnya kode diaktifkan setiap kali data yang hadir. Event data dari kontrol TableView digunakan sebagai driver untuk aktivasi subrutin ini. Ini menyisipkan baris data dari objek hasil ke baris saat ini dan kolom kontrol TableView. Ingatlah bahwa Anda tidak pernah memanggil event data secara langsung. Ada dokumentasi yang sangat sedikit tersedia untuk kontrol TableView sehingga tidak dinyatakan di sini harus dianggap sebagai jawaban definitif untuk menggunakannya. Namun, pendekatan umum untuk menggunakan kontrol TableView adalah untuk pertama memuat semua data yang akan ditampilkan ke dalam array dan mempersiapkan kontrol TableView dengan baris dan kolom seperti yang dilakukan dalam subrutin readdata atas. Proses sangat mengisi array dan mendefinisikan kolom dengan cara ini memaksa widget yang digunakan dalam kontrol TableView untuk membuat panggilan internal untuk event data yang benar-benar yang mengisi sel dengan data dari array Anda. Terserah Anda untuk kode pernyataan penugasan (s) yang memindahkan data dari objek hasil ke baris dan kolom TableView di mana Anda ingin data yang ditampilkan. Hal penting untuk diingat adalah bahwa Anda harus memiliki event handler, tbvControl_Data (...) di suatu tempat di file kelas Anda untuk melakukan hal ini. Dalam kontrol TableView, data yang segar hanya apa yang terlihat di kontrol. Kontrol dapat menampilkan sejumlah besar data tanpa memegang salah satu nilai data secara langsung dalam penyimpanan itu sendiri. Itulah array yang digunakan untuk program anda. Meskipun terdengar agak canggung, itu adalah solusi pragmatis yang memungkinkan Gambas untuk menampilkan data dari database dengan cara yang cukup efisien.
PUBLIC SUB tbvData_Data(Row AS Integer, Column AS Integer)
'this gets to the correct row
$rData.MoveTo(Row)
'this actually assigns data from the results object to the tableview
tbvData.Data.Text = Str($rData[tbvData.Columns[Column].Text]) END
Jika formulir tersebut diubah ukurannya oleh pengguna, kita perlu mengubah ukuran kontrol. Subroutine ini akan melakukan trik.
(21)
PUBLIC SUB Form_Resize()
tbvData.Resize(ME.ClientW, ME.ClientH) END
Ketika data sedang dibaca dari obyek hasil, subrutin ini disebut untuk menentukan apa jenis data untuk setiap bidang berturut-turut. Sifat dari kelas Field dikirimkan sebagai parameter ke fungsi ini dan digunakan dalam statemen SELECT. Hal ini memastikan data yang ditempatkan di sel-sel individual dari kontrol TableView tidak disingkat dan akan ditampilkan dengan benar, terlepas dari pengaturan font properti yang didirikan oleh kontrol TableView sendiri.
PRIVATE FUNCTION WidthFromType(hCtrl AS control, iType AS Integer, iLength AS Integer, sTitle AS String) AS Integer
DIM iWidth AS Integer SELECT CASE iType CASE gb.Boolean
iWidth = hCtrl.Font.Width(Str(FALSE)) + 32 CASE gb.Integer
iWidth = hCtrl.Font.Width("1234567890") + 16 CASE gb.Float
iWidth = hCtrl.Font.Width(CStr(Pi) & "E+999") + 16 CASE gb.Date
iWidth = hCtrl.Font.Width(Str(Now)) + 16 CASE gb.String
IF iLength = 0 THEN iLength = 255 iLength = Min(32, iLength)
iWidth = hCtrl.Font.Width("X") * iLength + 16 END SELECT
iWidth = Max(iWidth, hCtrl.Font.Width(sTitle) + 8) RETURN iWidth
END
Akhirnya, jika pengguna mengklik pada "x" di sudut kanan atas jendela untuk menutup program, kami datang ke rutinitas, dan hal dekat ke bawah.
PUBLIC SUB Form_Close() ME.Close
END
Ketika Anda menjalankan program Contoh database, hal itu mewajibkan anda memiliki sistem database seperti PostgreSQL atau MySQL diinstal pada sistem Anda. Anda harus memiliki account pengguna dan password untuk menggunakan sistem database. Mengingat peringatan tersebut, jalankan program dan login ke dalam database. Anda dapat bermain-main, membuat dan mengisi tabel percobaan, dan membuat pertanyaan dengan program. Pada titik ini, Anda telah belajar semua dasar-dasar untuk menghubungkan dan menggunakan database di Gambas. Dalam bab berikutnya, kita akan membahas hal-hal penting untuk membuat program anda tersedia bagi pengguna secara global, proses yang disebut internasionalisasi (I18N).
(1)
PUBLIC SUB btnCreate_Click() 'declare a local Table variable DIM hTable AS Table
'add the table to the database using the Add method hTable = $hConn.Tables.Add(txtName.text)
'now add the fields of the table to the table we just added 'note that we specify the field name and data type for each 'of the fields we insert into the table. For string data, 'we also specify the maximum length of the string field. hTable.Fields.Add("id", gb.Integer)
hTable.Fields.Add("firstname", gb.String, 16) hTable.Fields.Add("name", gb.String, 32) hTable.Fields.Add("birth", gb.Date) hTable.Fields.Add("active", gb.Boolean) hTable.Fields.Add("salary", gb.Float)
'we can specify a primary key for the database table. In this 'case, the id field is used as we can create unique integer index 'data
hTable.PrimaryKey = ["id"]
'the call to the Update method commits the changes to the database 'and makes them permanent.
hTable.Update
'now we put up a simple dialog to inform the user we have 'successfully completed the creation task.
Message.Info("Table " & txtName.Text & " has been created.") 'this code enables or disables the
'buttons depending on the state of the database. For example, 'if there is data already in the database table, it does not make 'sense to fill that table again, so that button would be disabled. 'however, the delete button would be enabled so the data could be 'removed. If the database table is deleted, then it would be
're-enabled and if the table is created and no data exists,
'the fill button would again be enabled, etc. This prevents errors 'from clicking on a button where an action could not be performed 'successfully.
btnFill.Enabled = TRUE btnDelete.Enabled = TRUE btnCreate.Enabled = FALSE
'next, we add some default text to the SQL query box txtRequest.Text = "Show TABLES"
'the CATCH statement would display an ERROR dialog with the text of 'the error message if any error occurs in this subroutine.
CATCH
Message.Error(DConv(Error.Text)) END 'of the create button subroutine
Jika, setelah koneksi database didirikan, pengguna akan mengklik
Menghapus tabel "test" tombol, subrutin ini akan dieksekusi. PUBLIC SUB btnDelete_Click()
'remove the table
TRY $hConn.Tables.Remove(txtName.Text)
'put up a message to inform the user the table is gone
Message.Info("Table "& txtName.Text & " has been removed") 'enable or disable the buttons to make sense. If the table
(2)
'has been removed, it cannot be deleted again and it cannot 'be filled since it does not exist. All that is left is to
'recreate it and that button is enabled. btnDelete.Enabled = FALSE
btnFill.Enabled = FALSE btnCreate.Enabled = TRUE
'no table exists to query so blank out the SQL query text. txtRequest.Text = ""
'if an error occurs in the subroutine catch it here and show a dialog 'message to the user.
CATCH
Message.Error(Error.Text) END 'the delete button subroutine
Jika koneksi database telah ditetapkan dan pengguna telah menciptakan tabel, perlu ada beberapa data tambahan untuk membuatnya berguna. Subroutine ini dijalankan dan akan menambah semi-arbitrary data ke tabel. Ini akan secara acak memilih nama pertama dari array lima nama yang diberikan dan menggabungkan nomor berlawanan dengan "Name #" string untuk melayani sebagai nama belakang. Tanggal lahir dibuat secara acak dengan memilih nilai yang menambahkan nomor acak dari 1-10,000 ke tanggal dasar 1 Januari 1970. Rekor memiliki bendera yang aktif, secara acak ditetapkan juga. Angka gaji yang dipilih secara acak dalam kisaran 1.000 hingga 10.000. Akhirnya, metode Update akan menaruh semua data dalam tabel dan membuat COMMIT ke database. Mari kita lihat setiap baris kode untuk melihat betapa mudahnya hal ini dilakukan di Gambas:
PUBLIC SUB btnFill_Click()
'we need an integer counter iInd to be our index and we 'need a Result object to store our results
DIM iInd AS Integer DIM rTest AS Result
'set the Busy flag to prevent interruptions to our process INC Application.Busy
'we are going to start the database transaction process with BEGIN $hConn.Begin
'create the database table first 'rTest = $hConn.Create("test") rTest = $hConn.Create(txtName.Text) 'now, set up a loop to create 100 records FOR iInd = 1 TO 100
'make the record id be the counter variable value rTest!id = iInd
'randomly set the first name to be one of the five in the array
rTest!firstname = ["Paul","Pierre","Jacques","Antoine","Mathieu"][Int(Rnd(5))] 'make the last name a catenated value with the integer index value
rTest!name = "Name #" & iInd
'randomly choose a date by adding a value from 1 – 10,000 to the 'base date of Jan 1, 1970
rTest!birth = CDate("01/01/1970") + Int(Rnd(10000)) 'set the active flag to either 0 or 1 (TRUE or FALSE) rTest!active = Int(Rnd(2))
'randomly choose a salary figure from 1,000 to 10,000 rTest!salary = Int(Rnd(1000, 10000))
'update this record with the data semi-arbitrary data values rTest.Update
(3)
'commit all added records to the database $hConn.Commit
'last thing to execute before leaving the subroutine FINALLY
'decrement the busy flag DEC Application.Busy
'pop up a message to inform the user what we did Message.Info(txtName.Text & " has been filled.") 'put a default SQL query in the SQL Query textbox txtRequest.Text = "select * from " & txtName.Text 'fix our buttons to make sense
btnFill.Enabled = FALSE btnDelete.Enabled = TRUE btnCreate.Enabled = FALSE
'if something goes wrong, abort all changes with the Rollback and 'show the error message to the user
CATCH
$hConn.Rollback
Message.Error(Error.Text) END 'of the fill data subroutine
Jika pengguna memasukkan permintaan SQL apapun dalam kotak query SQL di bagian bawah formulir, kita akan menggunakan metode Exec untuk melakukan query dan tampilan hasil dari permintaan menggunakan formulir FRrequest. Berikut adalah cara yang dilakukan:
PUBLIC SUB btnRun_Click()
'declare a result object to hold the results of the query DIM rData AS Result
'declare a form variable so we can show the FRequest form DIM hForm AS FRequest
'execute the query using the Exec method and assign the results to 'the result object rData
rData = $hConn.Exec(txtRequest.Text)
'pass the database connection handle and the result data to the 'FRequest form when it is instantiated
hForm = NEW FRequest($hConn, rData)
'now display the form to the user with the result data hForm.Show
'come here if there is a problem in the subroutine and display a msg CATCH
Message.Error(Error.Text) END 'of sql query subroutine
Setiap kali program kami berjalan dan bentuk FMain terbuka, kita perlu instantiate Connection variabel kita $ hConn. Setiap kali formulir ditutup, kami akan menutup koneksi.
PUBLIC SUB Form_Open() $hConn = NEW Connection END
PUBLIC SUB Form_Close() $hConn.Close
END
Selanjutnya, kita perlu melihat bentuk FRrequest dan melihat bagaimana kode yang menampilkan data hasil objek bila dipanggil. Berikut adalah kode untuk itu:
(4)
' Gambas class file
' fRequest.class declares two private variables to use in this class ' one for the connection, one for the result data.
PRIVATE $hConn AS Connection PRIVATE $rData AS Result
'a constructor routine will be used to receive the connection handle 'and the results of a query as parameters when
FRequest is called by 'the FMain form.
PUBLIC SUB _new(hConn AS Connection, rData AS Result) 'assign the hConn parameter to our private $hConn variable $hConn = hConn
'assign the rData parameter to our $rData private variable 'these assignments are made so the $ prefixed variables are 'visible to the entire class, not just the constructor routine. $rData = rData
'call our little subroutine to display the title in the form window RefreshTitle
'the ReadData subroutine is used to populate our TableView control ReadData
'resize the window to center on the desktop
ME.Move(Int(Rnd(Desktop.W - ME.W)), Int(Rnd((Desktop.H - ME.H)))) END 'of the constructor
'this subroutine simply updates the window caption PRIVATE SUB RefreshTitle()
'we need a local string variable DIM sTitle AS String
'we will concatenate the connection name to the text for the caption sTitle = ("SQL Query Results ") & " - " & $hConn.Name
'and set the title property to be the string variable value ME.Title = sTitle
END
Subrutin readdata () digunakan untuk mendefinisikan struktur data yang diberikan dalam dari objek hasil untuk kontrol TableView. Hal ini menentukan jumlah field dari obyek hasil dan menyiapkan kolom dalam tabel, menempatkan nama kolom (field) yang tepat dan tipe data. Tipe data ditentukan dengan memanggil subrutin lain, WidthFromType () untuk mendapatkan informasi tersebut.
Basis QT Library Kontrol TableView sudah usang di Qt Library, yang telah digantikan dengan kontrol QTable. Namun, Gambas telah menambahkan kontrol TableView sendiri, sehingga masih dapat digunakan dan kami akan menunjukkan kepada Anda bagaimana hal itu dilakukan.
PRIVATE SUB ReadData()
'this variable is declared but never used, you can comment it out DIM hTable AS Table
DIM hField AS ResultField DIM iInd AS Integer
'set the application busy flag to avoid interruptions INC Application.Busy
'reset row count of the TableView control to zero tbvData.Rows.Count = 0
'set the number of columns to be the same number ' as the number of fields in the result object
tbvData.Columns.Count = $rData.Fields.Count
(5)
'get the name of the field and the data type and set the TableView 'column headings and field type/size as appropriate
FOR EACH hField IN $rData.Fields WITH hField
'this is a debug line that was commented out 'PRINT .Name; ": "; .Type; " "; .Length
'this next line sets the column name to be the field name tbvData.Columns[iInd].Text = .Name
'here, the call to WidthFromType is used to determine what data 'type the field is and what the appropriate width should be
tbvData.Columns[iInd].Width = WidthFromType(tbvData, .Type, .Length, .Name) END WITH
'increment our index counter INC iInd
NEXT 'iteration of result data
'set the number of TableView rows to be the same as the number 'of rows of data in the result object
tbvData.Rows.Count = $rData.Count
'last thing we do in this subroutine is decrement the busy flag FINALLY
DEC Application.Busy
'if there were any errors in this subroutine we would show a message CATCH
Message.Error("Cannot exec request." & "\n\n" & Error.Text) END 'of ReadData subroutine
Bit berikutnya kode diaktifkan setiap kali data yang hadir. Event data dari kontrol TableView digunakan sebagai driver untuk aktivasi subrutin ini. Ini menyisipkan baris data dari objek hasil ke baris saat ini dan kolom kontrol TableView. Ingatlah bahwa Anda tidak pernah memanggil event data secara langsung. Ada dokumentasi yang sangat sedikit tersedia untuk kontrol TableView sehingga tidak dinyatakan di sini harus dianggap sebagai jawaban definitif untuk menggunakannya. Namun, pendekatan umum untuk menggunakan kontrol TableView adalah untuk pertama memuat semua data yang akan ditampilkan ke dalam array dan mempersiapkan kontrol TableView dengan baris dan kolom seperti yang dilakukan dalam subrutin readdata atas. Proses sangat mengisi array dan mendefinisikan kolom dengan cara ini memaksa widget yang digunakan dalam kontrol TableView untuk membuat panggilan internal untuk event data yang benar-benar yang mengisi sel dengan data dari array Anda. Terserah Anda untuk kode pernyataan penugasan (s) yang memindahkan data dari objek hasil ke baris dan kolom TableView di mana Anda ingin data yang ditampilkan. Hal penting untuk diingat adalah bahwa Anda harus memiliki event handler, tbvControl_Data (...) di suatu tempat di file kelas Anda untuk melakukan hal ini. Dalam kontrol TableView, data yang segar hanya apa yang terlihat di kontrol. Kontrol dapat menampilkan sejumlah besar data tanpa memegang salah satu nilai data secara langsung dalam penyimpanan itu sendiri. Itulah array yang digunakan untuk program anda. Meskipun terdengar agak canggung, itu adalah solusi pragmatis yang memungkinkan Gambas untuk menampilkan data dari database dengan cara yang cukup efisien.
PUBLIC SUB tbvData_Data(Row AS Integer, Column AS Integer) 'this gets to the correct row
$rData.MoveTo(Row)
'this actually assigns data from the results object to the tableview tbvData.Data.Text = Str($rData[tbvData.Columns[Column].Text]) END
Jika formulir tersebut diubah ukurannya oleh pengguna, kita perlu mengubah ukuran kontrol. Subroutine ini akan melakukan trik.
(6)
PUBLIC SUB Form_Resize()
tbvData.Resize(ME.ClientW, ME.ClientH) END
Ketika data sedang dibaca dari obyek hasil, subrutin ini disebut untuk menentukan apa jenis data untuk setiap bidang berturut-turut. Sifat dari kelas Field dikirimkan sebagai parameter ke fungsi ini dan digunakan dalam statemen SELECT. Hal ini memastikan data yang ditempatkan di sel-sel individual dari kontrol TableView tidak disingkat dan akan ditampilkan dengan benar, terlepas dari pengaturan font properti yang didirikan oleh kontrol TableView sendiri.
PRIVATE FUNCTION WidthFromType(hCtrl AS control, iType AS Integer, iLength AS Integer, sTitle AS String) AS Integer
DIM iWidth AS Integer SELECT CASE iType CASE gb.Boolean
iWidth = hCtrl.Font.Width(Str(FALSE)) + 32 CASE gb.Integer
iWidth = hCtrl.Font.Width("1234567890") + 16 CASE gb.Float
iWidth = hCtrl.Font.Width(CStr(Pi) & "E+999") + 16 CASE gb.Date
iWidth = hCtrl.Font.Width(Str(Now)) + 16 CASE gb.String
IF iLength = 0 THEN iLength = 255 iLength = Min(32, iLength)
iWidth = hCtrl.Font.Width("X") * iLength + 16 END SELECT
iWidth = Max(iWidth, hCtrl.Font.Width(sTitle) + 8) RETURN iWidth
END
Akhirnya, jika pengguna mengklik pada "x" di sudut kanan atas jendela untuk menutup program, kami datang ke rutinitas, dan hal dekat ke bawah.
PUBLIC SUB Form_Close() ME.Close
END
Ketika Anda menjalankan program Contoh database, hal itu mewajibkan anda memiliki sistem database seperti PostgreSQL atau MySQL diinstal pada sistem Anda. Anda harus memiliki account pengguna dan password untuk menggunakan sistem database. Mengingat peringatan tersebut, jalankan program dan login ke dalam database. Anda dapat bermain-main, membuat dan mengisi tabel percobaan, dan membuat pertanyaan dengan program. Pada titik ini, Anda telah belajar semua dasar-dasar untuk menghubungkan dan menggunakan database di Gambas. Dalam bab berikutnya, kita akan membahas hal-hal penting untuk membuat program anda tersedia bagi pengguna secara global, proses yang disebut internasionalisasi (I18N).