This section is a step-by-step guide to get you started using BetaDBC.
The first time you connect to a database from a Beta program, it is a 3 step process:
Step 1 is necessary once per platform, step 2 is necessary once per database/user and step 3 is always necessary :)
First: Install your database manager according to the installation guidelines that came with it.
Then: mysql\lib\opt\libmySQL.lib
beta\lib\nti_ms\
First: Install your database manager according to the installation guidelines that came with it.
Then:/usr/local/lib/libcliPG.so
. If you want to connect to the database 'mydb' on the database server 'delirium' insert the following in your .odbc.ini
file ('ReadOnly = 0' tells the driver that you want to manipulate the 'mydb' database)
[mydatasource] # data source containing the 'mydb' db on delirium Driver = /usr/local/lib/libcliPG.so Database = mydb Servername = delirium ReadOnly = 0
This defines a data source named 'mydatasource', that you may use BetaDBC to connect to. In the example 'ReadOnly' is a driver specific attribute of the data source 'mydatasource'. See the documentation for the drivers used for definitions of driver specific attributes.
FrontBase/bin/sql92
A small example:
start sql92 and type the following:
create database firstdb; connect to firstdb user _system; create user firstuser; disconnect current; connect to firstdb user firstuser; disconnect current;
When the MySQL database manager is up and running it has by default only one user called 'root' whose password is empty. New users are created using eg. GRANT statements as follows:
Start MySQL as user 'root' on the database 'mysql':Create a user called 'firstusr' whose password is 'firstpswd':
./bin/mysql -u root mysql
Additional users can be created in a similar fashion. Now create a database for the user 'firstusr':
mysql> GRANT ALL PRIVILEGES ON *.* TO firstusr@localhost IDENTIFIED BY 'firstpswd' WITH GRANT OPTION; mysql> GRANT ALL PRIVILEGES ON *.* TO firstusr@"%" IDENTIFIED BY 'firstpswd' WITH GRANT OPTION;
This creates a database 'firstdb' after prompting for the password. The user 'firstusr' can now log on to the database 'firstdb':
./bin/mysqladmin -u firstusr -p create firstdb
Tables can now be created using standard SQL statements:
./bin/mysql -u firstusr -p firstdb
mysql> CREATE TABLE test (name CHAR(200) NOT NULL, KEY index_name (name(10)));
You must always INCLUDE the relevant interface
If you use ODBC: | INCLUDE '~beta/betadbc/betadbc_odbc' |
If you use native Oracle: | INCLUDE '~beta/betadbc/betadbc_oracle' |
If you use native Frontbase: | INCLUDE '~beta/betadbc/betadbc_frontbase' |
If you use native MySql: | INCLUDE '~beta/betadbc/betadbc_mysql' |
You must first create an instance of the connection pattern.
sqlCon: @Connection; stmt: @sqlCon.directSqlStatement;
Calling the open method on a connection...
('access','marius',none)->sqlCon.open
...then makes it possible to communicate with the data source. The statement opens a connection to the data source name "access" for the user "marius" without specifying a password.
Data manipulation and definition is done using the SQL statement pattern directSQLStatement. To use a directSQLStatement stmt
, one must first open it and then associate it with an SQL statement as in
or, equivalently
stmt.open; 'SELECT title, length FROM Movie WHERE studioName = \'Disney\''->stmt;
'SELECT title, length FROM Movie WHERE studioName = \'Disney\''->stmt.open;
Invoking stmt.execute
will then cause the SQL statement to be executed at the database. A statement should be closed after use: stmt.close
Definition of shared variables are done via the "declare..." methods. E.g. to declare a text studioName as a shared variable named "studioName" use
studioName: @text; ... do 'studioName'->declareText (# set::(# do value->studioName #); get::(# do studioName[]->value[] #) #)
The contents of a directSQLStatement can be any SQL statement with embedded shared variables and/or markers, i.e. a directSQLStatement stmt may be initialized as in
'SELECT title,length FROM Movie WHERE studioName = :studioName AND year = %i'->stmt;
Here "studioName" is the name of a shared variable declared as shown above. The value of the %i marker may be set using the i pattern in directSQLStatement. Now suppose that the following statements have been executed
'Disney'->studioName; 1990->stmt.i;
When executing the SQL statement the SQL contents of the statement will then conceptually be
SELECT title,length FROM Movie WHERE studioName = 'Disney' AND year = 1990
i.e., before sending an SQL statement to a database the embedded shared variables and the markers are, conceptually, substituted for their current values. After execution the contents of the statement can be changed, the markers can be reset or the statement can be closed.
Also, embedded shared variables and markers can be named as inIn this case, the %i marker is named "theYear" and the statement may be used as
'SELECT title,length FROM Movie WHERE studioName = :studioName AND year = theYear%i'->stmt;
'Disney'->studioName; ('theYear',1990)->stmt.setIntegerByName
Please note that the use of shared variables is only supported in the ODBC interface. Suggested workaround for the other interfaces: build your SQL statements dynamically using append
or putformat
.
Executing an SQL statement stmt will yield an instance of resultSet (in the following rs is a reference to a resultSet):
rs: ^connection.resultSet ... do stmt.execute->rs[]
Given a resultSet, the scan method iterates over the tuples in the resultSet. There are three distinct ways to control the scan. First, one may simply execute
rs.scan(# do ... #)
In the do-part of the scan one may then refer to the values of the columns in the result. This is done sequentially by referring to the markers of the current result. If, e.g., rs was retrieved as shown above,
rs.scan(# do current.s -> putline; current.i->putint; newline #)
will scan over the results in the resultSet and print the values of their columns on the screen.
Second, one may enter a string when evaluating a scan pattern as in:
':title %i'->rs.scan(# do title->putline; current.i->putint; newline #)
Here title is a shared variable named "title". This statement prints the same as above but by providing an input string it is here specified that the first column of each result should be assigned to the shared variable "title" and that the second column of each result is an integer that will be fetched via the i marker. In general one may in this way specify how each column of a result should be treated.
The two ways of scanning shown above may, in some circumstances, be problematic in that they assume a specific ordering of columns in the results. Therefore, the third way of doing a scan names the columns in the resultSet, as in e.g.:
'length%i title:title'->rs.scan (# do title->putline; current.i->putint; newline #)
In this way the order of the columns in the result may be changed from "title, length" to "length, title" without any problems for the last way of scanning.
Please note that the use of shared variables is only supported in the ODBC interface. Suggested workaround for the other interfaces: build your SQL statements dynamically using append
or putformat
.
For obscure reasons the datatype boolean
is not supported by Oracle. Furthermore, the use of time/date datatypes is discouraged, and therefore sparingly suppported by the Oracle interface. Oracle recommends storing dates as text.
A small example using Oracle:
The user scott
with password tiger
wants to connect to the default server (hence the empty text in the opening of the connection):
ORIGIN '~beta/betadbc/betadbc-oracle'; -- program: Descriptor -- (# oraCon: @Connection; stmt: @oraCon.DirectSQLStatement; do ('','scott','tiger')->oraCon.open; 'create table Students("Name" varchar(100), "Age" integer);'->stmt.open; stmt.execute; stmt.close; 'commit;'->stmt.open; stmt.execute; stmt.close; oraCon.close; #)
Please note that the use of shared variables is only supported in the ODBC interface. Suggested workaround for the other interfaces: build your SQL statements dynamically using append
or putformat
.
Selecting a host:
The Beta program must select the host on which the FrontBase server is running before opening a connection. Selecting the host is done by using selecthost
A small example using Frontbase:
ORIGIN '~beta/betadbc/betadbc-frontbase'; -- program: Descriptor -- (# frontbaseCon: @Connection; stmt: @frontbaseCon.DirectSQLStatement; do 'brage.mjolner.dk' -> frontbaseCon.selecthost; ('firstdb','firstuser','')->frontbaseCon.open; 'create table Students("Name" varchar(100), "Age" integer);'->stmt.open; stmt.execute; stmt.close; frontbaseCon.close; #)
Please note that the use of shared variables is only supported in the ODBC interface. Suggested workaround for the other interfaces: build your SQL statements dynamically using append
or putformat
.
Selecting a database:
To utilize the MySQL interface in Beta you must select a database by using selectdb
after opening a connection, as shown in this excerpt from the adhoc.bet demo:
adhoc is then invoked as follows:
ORIGIN '~beta/betadbc/betadbc-mysql'; INCLUDE '~beta/basiclib/formatio' '~beta/basiclib/numberio' '~beta/basiclib/file'; -- program: Descriptor -- (# sqlCon: @Connection; stmt: @sqlCon.DirectSQLStatement; res: ^sqlCon.resultSet do 'hi there'->putline; (2->arguments,3->arguments,4->arguments)->sqlCon.open; 'firstdb'->sqlCon.selectdb; ...
./adhoc vertigo firstusr firstpswd
Where vertigo is the host on which the MySQL server is running. It is possible to use 'localhost'.
The BetaDBC Library - Reference Manual and Tutorial | © 1999-2004 Mjølner Informatics |
[Modified: Friday September 7th 2001 at 12:45]
|