- GUI
- Windows API tutorial
- Introduction to Windows API
- Windows API main functions
- System functions in Windows API
- Strings in Windows API
- Date & time in Windows API
- A window in Windows API
- First steps in UI
- Windows API menus
- Windows API dialogs
- Windows API controls I
- Windows API controls II
- Windows API controls III
- Advanced controls in Windows API
- Custom controls in Windows API
- The GDI in Windows API
- PyQt4 tutorial
- PyQt5 tutorial
- Qt4 tutorial
- Introduction to Qt4 toolkit
- Qt4 utility classes
- Strings in Qt4
- Date and time in Qt4
- Working with files and directories in Qt4
- First programs in Qt4
- Menus and toolbars in Qt4
- Layout management in Qt4
- Events and signals in Qt4
- Qt4 Widgets
- Qt4 Widgets II
- Painting in Qt4
- Custom widget in Qt4
- The Breakout game in Qt4
- Qt5 tutorial
- Introduction to Qt5 toolkit
- Strings in Qt5
- Date and time in Qt5
- Containers in Qt5
- Working with files and directories in Qt5
- First programs in Qt5
- Menus and toolbars in Qt5
- Layout management in Qt5
- Events and signals in Qt5
- Qt5 Widgets
- Qt5 Widgets II
- Painting in Qt5
- Custom widget in Qt5
- Snake in Qt5
- The Breakout game in Qt5
- PySide tutorial
- Tkinter tutorial
- Tcl/Tk tutorial
- Qt Quick tutorial
- Java Swing tutorial
- JavaFX tutorial
- Java SWT tutorial
- wxWidgets tutorial
- Introduction to wxWidgets
- wxWidgets helper classes
- First programs in wxWidgets
- Menus and toolbars in wxWidgets
- Layout management in wxWidgets
- Events in wxWidgets
- Dialogs in wxWidgets
- wxWidgets widgets
- wxWidgets widgets II
- Drag and Drop in wxWidgets
- Device Contexts in wxWidgets
- Custom widgets in wxWidgets
- The Tetris game in wxWidgets
- wxPython tutorial
- Introduction to wxPython
- First Steps
- Menus and toolbars
- Layout management in wxPython
- Events in wxPython
- wxPython dialogs
- Widgets
- Advanced widgets in wxPython
- Drag and drop in wxPython
- Internationalisation
- Application skeletons in wxPython
- The GDI
- Mapping modes
- Creating custom widgets
- Tips and Tricks
- wxPython Gripts
- The Tetris game in wxPython
- C# Winforms Mono tutorial
- Java Gnome tutorial
- Introduction to Java Gnome
- First steps in Java Gnome
- Layout management in Java Gnome
- Layout management II in Java Gnome
- Menus in Java Gnome
- Toolbars in Java Gnome
- Events in Java Gnome
- Widgets in Java Gnome
- Widgets II in Java Gnome
- Advanced widgets in Java Gnome
- Dialogs in Java Gnome
- Pango in Java Gnome
- Drawing with Cairo in Java Gnome
- Drawing with Cairo II
- Nibbles in Java Gnome
- QtJambi tutorial
- GTK+ tutorial
- Ruby GTK tutorial
- GTK# tutorial
- Visual Basic GTK# tutorial
- PyGTK tutorial
- Introduction to PyGTK
- First steps in PyGTK
- Layout management in PyGTK
- Menus in PyGTK
- Toolbars in PyGTK
- Signals & events in PyGTK
- Widgets in PyGTK
- Widgets II in PyGTK
- Advanced widgets in PyGTK
- Dialogs in PyGTK
- Pango
- Pango II
- Drawing with Cairo in PyGTK
- Drawing with Cairo II
- Snake game in PyGTK
- Custom widget in PyGTK
- PHP GTK tutorial
- C# Qyoto tutorial
- Ruby Qt tutorial
- Visual Basic Qyoto tutorial
- Mono IronPython Winforms tutorial
- Introduction
- First steps in IronPython Mono Winforms
- Layout management
- Menus and toolbars
- Basic Controls in Mono Winforms
- Basic Controls II in Mono Winforms
- Advanced Controls in Mono Winforms
- Dialogs
- Drag & drop in Mono Winforms
- Painting
- Painting II in IronPython Mono Winforms
- Snake in IronPython Mono Winforms
- The Tetris game in IronPython Mono Winforms
- FreeBASIC GTK tutorial
- Jython Swing tutorial
- JRuby Swing tutorial
- Visual Basic Winforms tutorial
- JavaScript GTK tutorial
- Ruby HTTPClient tutorial
- Ruby Faraday tutorial
- Ruby Net::HTTP tutorial
- Java 2D games tutorial
- Java 2D tutorial
- Cairo graphics tutorial
- PyCairo tutorial
- HTML5 canvas tutorial
- Python tutorial
- Python language
- Interactive Python
- Python lexical structure
- Python data types
- Strings in Python
- Python lists
- Python dictionaries
- Python operators
- Keywords in Python
- Functions in Python
- Files in Python
- Object-oriented programming in Python
- Modules
- Packages in Python
- Exceptions in Python
- Iterators and Generators
- Introspection in Python
- Ruby tutorial
- PHP tutorial
- Visual Basic tutorial
- Visual Basic
- Visual Basic lexical structure
- Basics
- Visual Basic data types
- Strings in Visual Basic
- Operators
- Flow control
- Visual Basic arrays
- Procedures & functions in Visual Basic
- Organizing code in Visual Basic
- Object-oriented programming
- Object-oriented programming II in Visual Basic
- Collections in Visual Basic
- Input & output
- Tcl tutorial
- C# tutorial
- Java tutorial
- AWK tutorial
- Jetty tutorial
- Tomcat Derby tutorial
- Jtwig tutorial
- Android tutorial
- Introduction to Android development
- First Android application
- Android Button widgets
- Android Intents
- Layout management in Android
- Android Spinner widget
- SeekBar widget
- Android ProgressBar widget
- Android ListView widget
- Android Pickers
- Android menus
- Dialogs
- Drawing in Android
- Java EE 5 tutorials
- Introduction
- Installing Java
- Installing NetBeans 6
- Java Application Servers
- Resin CGIServlet
- JavaServer Pages, (JSPs)
- Implicit objects in JSPs
- Shopping cart
- JSP & MySQL Database
- Java Servlets
- Sending email in a Servlet
- Creating a captcha in a Servlet
- DataSource & DriverManager
- Java Beans
- Custom JSP tags
- Object relational mapping with iBATIS
- Jsoup tutorial
- MySQL tutorial
- MySQL quick tutorial
- MySQL storage engines
- MySQL data types
- Creating, altering and dropping tables in MySQL
- MySQL expressions
- Inserting, updating, and deleting data in MySQL
- The SELECT statement in MySQL
- MySQL subqueries
- MySQL constraints
- Exporting and importing data in MySQL
- Joining tables in MySQL
- MySQL functions
- Views in MySQL
- Transactions in MySQL
- MySQL stored routines
- MySQL Python tutorial
- MySQL Perl tutorial
- MySQL C API programming tutorial
- MySQL Visual Basic tutorial
- MySQL PHP tutorial
- MySQL Java tutorial
- MySQL Ruby tutorial
- MySQL C# tutorial
- SQLite tutorial
- SQLite C tutorial
- SQLite PHP tutorial
- SQLite Python tutorial
- SQLite Perl tutorial
- SQLite Ruby tutorial
- SQLite C# tutorial
- SQLite Visual Basic tutorial
- PostgreSQL C tutorial
- PostgreSQL Python tutorial
- PostgreSQL Ruby tutorial
- PostgreSQL PHP tutorial
- PostgreSQL Java tutorial
- Apache Derby tutorial
- SQLAlchemy tutorial
- MongoDB PHP tutorial
- MongoDB Java tutorial
- MongoDB JavaScript tutorial
- MongoDB Ruby tutorial
- Spring JdbcTemplate tutorial
- JDBI tutorial
MySQL Ruby tutorial
This is a Ruby programming tutorial for the MySQL database. It covers the basics of MySQL programming with Ruby. It uses the mysql
module. The examples were created and tested on Ubuntu Linux.
There is a similar MySQL C API tutorial , MySQL Visual Basic tutorial , or MySQL Python tutorial on ZetCode.
You may also consider to look at the MySQL tutorial , too.
MySQL & Ruby
MySQL is a leading open source database management system. It is a multi user, multithreaded database management system. MySQL is especially popular on the web. It is on part of the very popular LAMP platform consisting of Linux, Apache, MySQL, and PHP. Currently MySQL is owned by Oracle. MySQL database is available on most important OS platforms. Ruby is a dynamic, reflective, general-purpose object-oriented programming language. Recently it became very popular in web programming, mainly due to the successful Ruby on Rails framework.
mysql module
The mysql
module is a Ruby interface to the MySQL server. It provides the same functions for Ruby programs that the MySQL C API provides for C programs.
$ sudo gem1.9 install mysql
Here we install the Ruby module for the MySQL database.
Before we start
We are going to create a new database user and a new database. To do this, we use the mysql
client program.
$ mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 30 Server version: 5.0.67-0ubuntu6 (Ubuntu) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | +--------------------+ 2 rows in set (0.00 sec)
We connect to the MySQL server using the root account. We show all available databases with the SHOW DATABASES
statement.
mysql> CREATE DATABASE mydb; Query OK, 1 row affected (0.02 sec)
We create a new mydb
database. We will use this database throughout the tutorial.
mysql> CREATE USER user12@localhost IDENTIFIED BY '34klq*'; Query OK, 0 rows affected (0.00 sec) mysql> USE mydb; Database changed mysql> GRANT ALL ON mydb.* to user12@localhost; Query OK, 0 rows affected (0.00 sec) mysql> quit; Bye
We create a new database user. We grant all privileges to this user for all tables of the mydb
database.
MySQL server version
In the first example, we will get the version of the MySQL database.
#!/usr/bin/ruby require 'mysql' begin con = Mysql.new 'localhost', 'user12', '34klq*' puts con.get_server_info rs = con.query 'SELECT VERSION()' puts rs.fetch_row rescue Mysql::Error => e puts e.errno puts e.error ensure con.close if con end
In this script, we get the server version. We do it in two different ways.
require 'mysql'
We import the mysql
module. The module has the classes and methods to work with the MySQL database.
con = Mysql.new 'localhost', 'user12', '34klq*'
We create the connection object. The parameters include the host name, user name and password. In our case the host name is localhost, e.g. our computer.
puts con.get_server_info
The Mysql object that we have created has a get_server_info
method. It returns the version of the MySQL server installed.
rs = con.query 'SELECT VERSION()' puts rs.fetch_row
Another way to get the version is to execute the SELECT VERSION()
SQL statement. We fetch the data. Since we retrieve only one record, we call the fetch_row
method.
rescue Mysql::Error => e puts e.errno puts e.error
We check for errors. This is important, since working with databases is error prone.
ensure con.close if con end
In the end, we release the resources.
$ ./version.rb 5.5.9 5.5.9
The output might look like the above.
Listing databases
The MySQL Ruby module has a list_dbs
method, which returns available databases.
#!/usr/bin/ruby require 'mysql' begin con = Mysql.new 'localhost', 'user12', '34klq*' con.list_dbs.each do |db| puts db end rescue Mysql::Error => e puts e.errno puts e.error ensure con.close if con end
In this script, we print all available databases on our MySQL server.
con.list_dbs.each do |db| puts db end
The list_dbs
method returns an array of available database names. Using the each method of the array, we print each item of the array to the console.
$ ./listdb.rb information_schema mydb test world
On my system, I had the above databases created.
Creating and populating a table
We create a table and populate it with some data.
#!/usr/bin/ruby require 'mysql' begin con = Mysql.new 'localhost', 'user12', '34klq*', 'mydb' con.query("CREATE TABLE IF NOT EXISTS \ Writers(Id INT PRIMARY KEY AUTO_INCREMENT, Name VARCHAR(25))") con.query("INSERT INTO Writers(Name) VALUES('Jack London')") con.query("INSERT INTO Writers(Name) VALUES('Honore de Balzac')") con.query("INSERT INTO Writers(Name) VALUES('Lion Feuchtwanger')") con.query("INSERT INTO Writers(Name) VALUES('Emile Zola')") con.query("INSERT INTO Writers(Name) VALUES('Truman Capote')") rescue Mysql::Error => e puts e.errno puts e.error ensure con.close if con end
We create a Writers table and add five authors to it.
con.query("CREATE TABLE IF NOT EXISTS \ Writers(Id INT PRIMARY KEY AUTO_INCREMENT, Name VARCHAR(25))")
To execute an SQL statement, we use the query
method. This SQL statement creates a new database table called Writers. It has two columns. Id and Name.
con.query("INSERT INTO Writers(Name) VALUES('Jack London')") con.query("INSERT INTO Writers(Name) VALUES('Honore de Balzac')") ...
We use the INSERT
statement to insert authors to the table. Here we add two rows.
mysql> SELECT * FROM Writers; +----+-------------------+ | Id | Name | +----+-------------------+ | 1 | Jack London | | 2 | Honore de Balzac | | 3 | Lion Feuchtwanger | | 4 | Emile Zola | | 5 | Truman Capote | +----+-------------------+ 5 rows in set (0.00 sec)
After executing the script, we use the mysql
client tool to select all data from the Writers table.
Retrieving data
Now that we have inserted some data into the database, we can retrieve it back.
#!/usr/bin/ruby require "mysql" begin con = Mysql.new 'localhost', 'user12', '34klq*', 'mydb' rs = con.query("SELECT * FROM Writers") n_rows = rs.num_rows puts "There are #{n_rows} rows in the result set" n_rows.times do puts rs.fetch_row.join("\s") end rescue Mysql::Error => e puts e.errno puts e.error ensure con.close if con end
In this example, we retrieve all data from the Writers table.
con = Mysql.new 'localhost', 'user12', '34klq*', 'mydb'
The last parameter of the constructor is the database name, to which we connect.
rs = con.query("SELECT * FROM Writers")
This SQL statement selects all data from the Writers
table.
n_rows = rs.num_rows
We get the number of rows in the result set using the num_rows
method of the result set object.
n_rows.times do puts rs.fetch_row.join("\s") end
Here we fetch each row with the fetch_row
method. It returns a row as an array of fields. By default, the fields are separated by new line, when printed. With the join
method, we print each row on one line. The fields are separated by one space.
$ ./retrieve1.rb There are 5 rows in the result set 1 Jack London 2 Honore de Balzac 3 Lion Feuchtwanger 4 Emile Zola 5 Truman Capote
Next we present another way to retrieve data from the table.
#!/usr/bin/ruby require "mysql" begin con = Mysql.new 'localhost', 'user12', '34klq*', 'mydb' rs = con.query("SELECT * FROM Writers") rs.each do |row| puts row.join("\s") end rescue Mysql::Error => e puts e.errno puts e.error ensure con.close if con end
We print all data from the Writers
table. This time we use an each method of the result set to traverse the data.
rs.each do |row| puts row.join("\s") end
We iterate through the result set using the each method.
$ ./retrieve2.rb 1 Jack London 2 Honore de Balzac 3 Lion Feuchtwanger 4 Emile Zola 5 Truman Capote
This is the output of the example.
We can traverse data in form of a Ruby hash.
#!/usr/bin/ruby require 'mysql' begin con = Mysql.new 'localhost', 'user12', '34klq*', 'mydb' rs = con.query "SELECT * FROM Writers WHERE Id IN (1, 2, 3)" puts "We have #{rs.num_rows} row(s)" rs.each_hash do |row| puts row['Id'] + " " + row['Name'] end rescue Mysql::Error => e puts e ensure con.close if con end
In the example, we use the each_hash
iterator. Records from the result set can be retrieved by their column names.
rs.each_hash do |row| puts row['Id'] + " " + row['Name'] end
We go through the result set with the each_hash
method. Each returned row is a Ruby hash; a collection of key-value pairs. The keys are the column names.
$ ./retrieve3.rb We have 3 row(s) 1 Jack London 2 Honore de Balzac 3 Lion Feuchtwanger
Ouput of the example.
Multiple statements
MySQL supports multiple statement execution. This must be enabled by a special option.
#!/usr/bin/ruby require 'mysql' begin con = Mysql.new 'localhost', 'user12', '34klq*', 'mydb' con.set_server_option Mysql::OPTION_MULTI_STATEMENTS_ON rs = con.query "SELECT Name FROM Writers WHERE Id=1; SELECT Name FROM Writers WHERE Id=2; SELECT Name FROM Writers WHERE Id=3" puts rs.fetch_row while con.next_result rs = con.store_result puts rs.fetch_row end rescue Mysql::Error => e puts e.errno puts e.error ensure con.close if con end
In this example, we have three SELECT
statements in one query.
con.set_server_option Mysql::OPTION_MULTI_STATEMENTS_ON
First we need to enable the multiple statements processing with the Mysql::OPTION_MULTI_STATEMENTS_ON
.
rs = con.query "SELECT Name FROM Writers WHERE Id=1; SELECT Name FROM Writers WHERE Id=2; SELECT Name FROM Writers WHERE Id=3"
Here we define three SELECT
statements. They are separated by a semicolon.
puts rs.fetch_row
The query method returns the first result set. We fetch a row from this result set.
while con.next_result rs = con.store_result puts rs.fetch_row end
We get additional result sets until there are no more statements left to process.
$ ./multiplest.rb Jack London Honore de Balzac Lion Feuchtwanger
Running the example.
Metadata
Metadata is information about the data in the database. Metadata in a MySQL system contains information about the tables and columns, in which we store data. Number of rows affected by an SQL statement is a metadata. Number of rows and columns returned in a result set belong to metadata as well.
#!/usr/bin/ruby require 'mysql' begin con = Mysql.new 'localhost', 'user12', '34klq*', 'mydb' rs = con.query "SELECT * FROM Writers WHERE Id IN (1, 2, 3)" puts "We have #{con.field_count} fields" puts "We have #{rs.num_rows} row(s)" puts rs.fetch_row.join("\s") rescue Mysql::Error => e puts e ensure con.close if con end
In this script, we find out the number of rows and columns from an SQL query.
rs = con.query "SELECT * FROM Writers WHERE Id IN (1, 2, 3)"
This SQL statement returns three rows. Each row has two columns.
puts "We have #{con.field_count} fields" puts "We have #{rs.num_rows} row(s)"
These two lines return the number of columns and rows in the result set. Note that here a field is a synonym for a column. The returned data is metadata.
puts rs.fetch_row.join("\s")
Here we return one row from the result set. This is the original data stored in our database table.
For INSERT
, DELETE
and UPDATE
statements there is a method called rows_affected
. This method returns the number of rows affected by these three statements.
#!/usr/bin/ruby require 'mysql' begin con = Mysql.new 'localhost', 'user12', '34klq*', 'mydb' con.query "DELETE FROM Writers WHERE Id IN (1, 2, 3)" puts "The query has affected #{con.affected_rows} rows" rescue Mysql::Error => e puts e ensure con.close if con end
In our example, we delete first three rows from the Writers
table.
con.query "DELETE FROM Writers WHERE Id IN (1, 2, 3)"
An SQL statement, which deletes first three rows of the Writers
table.
puts "The query has affected #{con.affected_rows} rows"
Here we get the number of rows that were affected by the above SQL statement. This number belongs to the metadata.
$ ./affected.rb The query has affected 3 rows mysql> SELECT * FROM Writers; +----+---------------+ | Id | Name | +----+---------------+ | 4 | Emile Zola | | 5 | Truman Capote | +----+---------------+ 2 rows in set (0.00 sec)
We execute the affected.rb script and check for changes in the Writers
table. Three rows have been deleted.
In the next example, we are going to check for metadata about a field.
#!/usr/bin/ruby require 'mysql' begin con = Mysql.new 'localhost', 'user12', '34klq*', 'mydb' rs = con.query "SELECT * FROM Writers WHERE Id=1" field = rs.fetch_field_direct 1 puts "Table name: #{field.table}" puts "Field name: #{field.name}" puts "Field length: #{field.length}" puts "Field type: #{field.type}" rescue Mysql::Error => e puts e ensure con.close if con end
We get one record from the database. We get the field's table name, colum name, length and type.
rs = con.query "SELECT * FROM Writers WHERE Id=1"
This query returns one row. It has two columns.
field = rs.fetch_field_direct 1
Using the fetch_field_direct
method, we get a specific record. More precisely, the record from the intersection of the first row, second column.
puts "Table name: #{field.table}" puts "Field name: #{field.name}" puts "Field length: #{field.length}" puts "Field type: #{field.type}"
We get the metadata using attribute readers of the field object.
$ ./metadata.rb Table name: Writers Field name: Name Field length: 25 Field type: 253
This is the output of the example.
In our last example relating to the metadata, we will print all rows from the table with their column names.
#!/usr/bin/ruby require 'mysql' begin con = Mysql.new 'localhost', 'user12', '34klq*', 'mydb' rs = con.query "SELECT * FROM Writers" fields = rs.fetch_fields puts "%3s %s" % [fields[0].name, fields[1].name] rs.each_hash do |row| puts "%3s %s" % [row['Id'], row['Name']] end rescue Mysql::Error => e puts e ensure con.close if con end
We print the contents of the Writers
table to the console. Now, we include the names of the columns too.
fields = rs.fetch_fields puts "%3s %s" % [fields[0].name, fields[1].name]
In the first step, we get the column names. They are printed using the standard Ruby string formatting abilities.
rs.each_hash do |row| puts "%3s %s" % [row['Id'], row['Name']] end
Now the data is fechted and printed to the console. We do some formatting too.
$ ./columnheaders.rb Id Name 1 Jack London 2 Honore de Balzac 3 Lion Feuchtwanger 4 Emile Zola 5 Truman Capote
Ouput of the script.
Prepared statements
Now we will concern ourselves with prepared statements. When we write prepared statements, we use placeholders instead of directly writing the values into the statements. Prepared statements increase security and performance.
#!/usr/bin/ruby require 'mysql' name = "Stefan Zweig" begin con = Mysql.new 'localhost', 'user12', '34klq*', 'mydb' pst = con.prepare "INSERT INTO Writers(Name) VALUES(?)" pst.execute name rescue Mysql::Error => e puts e ensure con.close if con pst.close if pst end
In the above example, we insert a new row into the Writers
table. We use a prepared statement.
pst = con.prepare "INSERT INTO Writers(Name) VALUES(?)"
The prepare
method is used to create a prepared statement. The ?
character is a placeholder. Later we bind a value to this placeholder.
pst.execute name
We bind a value from the name variable to the placeholder and execute the prepared statement.
pst.close if pst
The prepared statement is closed.
mysql> SELECT * FROM Writers; +----+-------------------+ | Id | Name | +----+-------------------+ | 1 | Jack London | | 2 | Honore de Balzac | | 3 | Lion Feuchtwanger | | 4 | Emile Zola | | 5 | Truman Capote | | 6 | Stefan Zweig | +----+-------------------+ 6 rows in set (0.00 sec)
After the script was successfully run, we see a new author in the Writers table.
Writing images
Some people prefer to put their images into the database, some prefer to keep them on the file system for their applications. Technical difficulties arise when we work with lots of images. Images are binary data. MySQL database has a special data type to store binary data called BLOB
(Binary Large Object).
mysql> CREATE TABLE Images(Id INT PRIMARY KEY AUTO_INCREMENT, Data MEDIUMBLOB); Query OK, 0 rows affected (0.06 sec)
For this example, we create a new table called Images
.
#!/usr/bin/ruby require 'mysql' begin fin = File.open("woman.jpg" , "rb") img = fin.read rescue SystemCallError => e puts e ensure fin.close if fin end begin con = Mysql.new 'localhost', 'user12', '34klq*', 'mydb' pst = con.prepare("INSERT INTO Images SET Data='%s'" % img.unpack('H*')) pst.execute rescue Mysql::Error => e puts e ensure con.close if con pst.close if pst end
In the above script, we read a JPG image and insert it into the Images
table.
fin = File.open("woman.jpg" , "rb") img = fin.read
We open and read an image. The read
method returns the data as string.
pst = con.prepare("INSERT INTO Images SET Data='%s'" % img.unpack('H*'))
This string data is placed into the prepared statement. Before doing so, it is decoded using the unpack
method of the Ruby string object. Decoding is necessary, because the image object has many special characters which cannot be processed normally.
Reading images
In the previous example, we have inserted an image into the database table. Now we are going to read the image back from the table.
#!/usr/bin/ruby require 'mysql' begin con = Mysql.new 'localhost', 'user12', '34klq*', 'mydb' rs = con.query "SELECT Data FROM Images LIMIT 1" f = File.new "woman2.jpg", "wb" f.write rs.fetch_row.pack 'H*' rescue Mysql::Error, SystemCallError => e puts e ensure con.close if con f.close if f end
We read one image from the Images table.
rs = con.query "SELECT Data FROM Images LIMIT 1"
We select one record from the table.
f = File.new "woman2.jpg", "wb"
We create a writable binary file.
f.write rs.fetch_row.pack 'H*'
We fetch the data from the previous SQL statement and write it to the file. The fetch_row
method returns an array object. Before the data is written to the file, it is put back into the original format with the pack
method of the array. For both operations, decoding and reversing, we use the same directive, 'H*'
. It stands for hex string.
Now we should have an image called woman2.jpg
in our current directory. We can check if it is the same image that we have inserted into the table.
Transaction support
A transaction
is an atomic unit of database operations against the data in one or more databases. The effects of all the SQL statements in a transaction can be either all committed to the database or all rolled back.
By default, MySQL runs in the autocommit mode. In this mode, all changes to the tables are immediately effective. To prevent this, we have to turn off the autocommit mode. After disabling autocommit, changes to transaction-aware tables are not permanent immediately. To store the changes, we must call the COMMIT
statement or ROLLBACK
to revert them. The Ruby MySQL has convenience methods for these SQL statements, commit
and rollback
.
The MySQL database has different types of storage engines. The most common are the MyISAM and the InnoDB engines. There is a trade-off between data security and database speed. The MyISAM tables are faster to process and they do not support transactions. The commit
and rollback
methods are not implemented. They do nothing. On the other hand, the InnoDB tables are more safe against the data loss. They support transactions. They are slower to process.
mysql> SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES -> where TABLE_SCHEMA = 'mydb' AND TABLE_NAME='Writers'; +------------+--------+ | TABLE_NAME | ENGINE | +------------+--------+ | Writers | InnoDB | +------------+--------+ 1 row in set (0.00 sec)
The engine of the Writers
table is InnoDB, which supports transactions.
#!/usr/bin/ruby require 'mysql' begin con = Mysql.new 'localhost', 'user12', '34klq*', 'mydb' con.autocommit false pst = con.prepare "UPDATE Writers SET Name = ? WHERE Id = ?" pst.execute "Leo Tolstoy", "1" pst.execute "Boris Pasternak", "2" pst.execute "Leonid Leonov" con.commit rescue Mysql::Error => e puts e con.rollback ensure pst.close if pst con.close if con end
In this script, we try to update three rows.
con.autocommit false
The autocommit mode is disabled.
pst = con.prepare "UPDATE Writers SET Name = ? WHERE Id = ?" pst.execute "Leo Tolstoy", "1" pst.execute "Boris Pasternak", "2" pst.execute "Leonid Leonov"
We execute three UPDATE
statements. The last one is incorrect. The second parameter is missing.
con.commit
If all is OK, changes are committed to the table.
rescue Mysql::Error => e puts e con.rollback
In case of an error, changes are rolled back.
$ ./update.rb execute: param_count(2) != number of argument(1) mysql> SELECT * FROM Writers; +----+-------------------+ | Id | Name | +----+-------------------+ | 1 | Jack London | | 2 | Honore de Balzac | | 3 | Lion Feuchtwanger | | 4 | Emile Zola | | 5 | Truman Capote | | 6 | Stefan Zweig | +----+-------------------+ 6 rows in set (0.00 sec)
Running the script gives an error. However, the transaction was rolled back and the first two rows were not changed.
This was MySQL Ruby tutorial. You may be also interested in PostgreSQL Ruby tutorial , SQLite Ruby tutorial , or MongoDB Ruby tutorial .
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论