Skip to content
caox edited this page Jan 28, 2013 · 9 revisions

db_driver

Copyright © 2009-2010 Beijing RYTong Information Technologies, Ltd.

Version: 1.0.0

Authors: cao.xu (cao.xu@rytong.com), deng.lifen (deng.lifen@rytong.com), wang.meigong (wang.meigong@rytong.com).

Introduction
Design Purpose
Download
Installation
Documentation
Configuration
Getting Started
Tests
Data Type
Notices

The db_driver is a high performance database driver based on the Erlang linked-in driver. It uses asynchronous threads to avoid IO block during the database access, the same way in which Erlang asynchronous drivers were implemented. We followed the syntax of Erlydb (erlang_mysql_driver) to design the APIs. For one database access request, the parameters will be passed to driver and processed in asynchronous threads. Then the request will be translated to respective SQL statements for different database types. After that, the work threads will call vendors' C/C++ APIs to execute these SQL statements and return the responses with ei.

Now the driver supports MySQL, Oracle and Sybase. DB2 is under test.

We want to support most typical database systems, such as Mysql, Oracle, Sybase, DB2, but we don't choose ODBC because of its poor performance.

See download link

In the db_driver directory, execute

./configure
make
sudo make install

In the db_driver directory, execute

make doc

to generate document of Erlang APIs.

The Database-Driven Documentation is generated by doxygen. If you installed doxygen, you can execute

make libdoc

to generate document of C APIs.

See Database-Driven Documentation

To use db_driver, you need to configure db_driver to set default database connection for db_driver to start-up by editing the following Erlang term in your db.conf file:

{connect_name, [{driver, mysql},
                {database, "test"},
                {host, "localhost"}, 
                {user, "root"},
                {password, ""},
                {threadlength, 10},
                {poolsize, 8}]}.

connect_name is the name of your connection instance and its type is atom.

The followings are required parameters.

driver::atom()          Database type. Supporting mysql, oracle and sybase.
database::string()      Database name.
host::string()          Database host name or IP address.
user:string()           Database user.
password:string()       Database password.
poolsize::integer()     Connection pool size.
threadlength::integer() Thread length.

The followings are optional parameters.

port::integer()             Database port. Default value is 3306.
maxthreadlength::integer()  Max thread length. Default value is 1000.
maxqueue::integer()         Max message queue size. Default value is 1000.

You can set many connections in the configuration file and you can get connection parameters by calling db_server:get_db_config(ConfigName, ConfigPath). The value of ConfigName is connect_name which is a connection name in the configuration file, and ConfigPath is the path configuration file. db_server:get_db_config(ConfigName) uses the default configuration file path (config/db.conf).

1.Starts by normal mode.

%% Start db driver.
Pid = db_driver:start().

%% Connection args.
ConnArg = db_server:get_db_config(ConnectName).
%% Or
ConnArg = [{driver, mysql},
           {database, "test"},
           {host, "localhost"}, 
           {user, "root"},
           {password, ""},
           {threadlength, 10},
           {poolsize, 8}].

%% Create a connection.
{ok, ConnPool} = db_driver:connect(ConnArg).

%% Execute sql string.
db_driver:execute_sql(ConnPool, "select version()").

%% Destroy a connect.
db_driver:disconnect(ConnPool),
    
%% Stop db driver.
db_driver:stop(Pid).

2.Starts by server mode.

Started by the server mode, the connection information and fields information will be storaged in ets table. you may use the default connection or the connection has been created to execute the database operation.

%% Start db server and db driver.
db_server:start().

%% Initialize default connection, the ConnectName is configured in db.conf.
db_server:init_default(ConnectName).

%% You can use the functions in module db_api to execute the database 
%% operation after starting db server and creating default connection.
db_api:execute_sql("select version()").

%% ConnectName is configured in db.conf.
ConnectArgs = db_server:get_db_config(ConnectName).

%% Create a new connection.
db_server:connect(ConnectName, ConnectArgs).

%% Operate database using the connection just created.
db_api:execute_sql("select version()", [{db_name, ConnectName}]).

%% Stop the db server when you do not need to operate database any more.
db_server:stop().

See test cases in module db_sample and module db_driver_test.

The followings are the mapping of database data type and Erlang data type.

  1. MySQL data type.
BIT             integer()
TINYINT         integer()
BOOL, BOOLEAN   integer()
SMALLINT        integer()
MEDIUMINT       integer()
INT             integer()
INTEGER         integer()
BIGINT          integer()
FLOAT           float()
DOUBLE          float()
FLOAT           float()
DECIMAL         float()
DATE            {date, {Year::integer(), Month::integer(), Day::integer()}}
DATETIME        {datetime,
                    {{Year::integer(), Month::integer(), Day::integer()},
                     {Hour::integer(), Minute::integer(), Second::integer()}}}
TIMESTAMP       {datetime,
                    {{Year::integer(), Month::integer(), Day::integer()},
                     {Hour::integer(), Minute::integer(), Second::integer()}}}
TIME            {time, 
                    {Hour::integer(), Minute::integer(), Second::integer()}}
YEAR            integer()
CHAR            integer()
VARCHAR         string()
BINARY          string()
VARBINARY       string()
TINYBLOB        binary()
TINYTEXT        string()
BLOB            binary()
TEXT            string()
MEDIUMBLOB      binary()
MEDIUMTEXT      string()
LONGBLOB        binary()
LONGTEXT        string()
  1. Oracle data type.
STRING          string()
NUMBER          number()
DATE            {datetime,
                    {{Year::integer(), Month::integer(), Day::integer()},
                     {Hour::integer(), Minute::integer(), Second::integer()}}}
TIMESTAMP       {timestamp, 
                    {{Year::integer(), Month::integer(), Day::integer()},
                     {Hour::integer(),
                      Minute::integer(),
                      Second::integer(),
                      Microseconds::integer()},      
                     {TimeZoneOffsetInHours::integer(), 
                      TimeZoneOffsetInMinutes::integer()}}}
TIMESTAMP_Z     {timestamp,
                    {{Year::integer(), Month::integer(), Day::integer()},
                     {Hour::integer(),
                      Minute::integer(),
                      Second::integer(),
                      Microseconds::integer()},
                     {TimeZoneOffsetInHours::integer(), 
                      TimeZoneOffsetInMinutes::integer()}}}
TIMESTAMP_LZ    {timestamp,
                    {{Year::integer(), Month::integer(), Day::integer()},
                     {Hour::integer(),
                      Minute::integer(),
                      Second::integer(), 
                      Microseconds::integer()},
                     {TimeZoneOffsetInHours::integer(), 
                      TimeZoneOffsetInMinutes::integer()}}}
BINARY          binary()
CLOB            string()
NCLOB           string()
BLOB            binary()
INTERVAL_YM     {interval_ym, {Year::integer(), Month::integer()}}}  
INTERVAL_DS     {interval_ds, 
                    {Day::integer(),
                     Hour::integer(),
                     Minute::integer(),
                     Second::integer(),
                     FractionalSecondComponent::integer()}}
  1. Sybase data type.
VARBINARY       binary()
BIT             integer()
CHAR            string()
VARCHAR         string()
UNICHAR         list()
UNIVARCHAR      list()
DATE            {date, {Year::integer(), Month::integer(), Day::integer()}}
TIME            {time,
                    {Hour::integer(),
                     Minute::integer(),
                     Second::integer(),
                     Millisecond::integer()}}
DATETIME        {datetime,
                    {{Year::integer(), Month::integer(), Day::integer()},
                     {Hour::integer(),
                      Minute::integer(),
                      Second::integer(),
                      Millisecond::integer()}}}
SMALLDATETIME   {smalldatetime,         
                    {{Year::integer(), Month::integer(), Day::integer()},
                     {Hour::integer(), Minute::integer()}}}
TINYINT         integer()
SMALLINT        integer()
INT             integer()
BIGINT          integer()
DECIMAL         {number, string()}
NUMERIC         {number, string()}
FLOAT           float()
REAL            float()
MONEY           {number, string()}
SMALLMONEY      float()

1. Oracle prepare statement.

The sql of prepare is like "select ?,? from user", but the sql in Oracle is like "select :1,:2 from user". You can consistently use two methods in module db_api, but you can only use the second method in module db_driver.