|
TUTORIAL - DATABASE |
Previous | Next | Tutorial Home |
The FGL programming environment contains a tightly integrated internal database that
provides high-performance and scalability with industry-standard relational and object
technology. FGL also interfaces with a number of external database systems (see the
documentation for details).
The internal database includes a highly optimized distributed architecture with a
number of significant optimizations and xBase-like API. This is further enhanced through
the use of FGL object components which provides a powerful method for using, interacting
with, and providing abstraction layers for data.
FGL programs and Active Pages can use the internal database directly through the more
than fifty available database functions, or preferably through the use of database object
wrappers. Either way, FGL makes it easy to integrate advanced database functionality into
your application. For example:
<html>
<head>
<title>Simple database example</title>
</head>
<body text=black bgcolor=white>
<[
// specify the file names
dbname = 'c:\fgl\data\temp\temp.db'
dxname = 'c:\fgl\data\temp\temp.dx'
if ( fileExists( dbname ) )
// open the database, assign an alias, open the index
dbuse( dbname, "mydb" )
mydb->dbOpenIndex( dxname )
else
// define a database structure
aStruct = {
{ "fname", "C", 30, 0 },
{ "lname", "C", 40, 0 },
{ "age", "N", 3, 0 }
}
// create the database
dbcreate( dbname, aStruct )
// open the database and assign an alias
dbuse( dbname, "mydb" )
// create an index file and open it
mydb->dbCreateIndex( dxname, "upper( field->lname + field->fname )", 0 )
mydb->dbOpenIndex( dxname )
// add some records
mydb->dbAppend( )
mydb->fname = "Steve", mydb->lname = "Repetti", mydb->age = 45
mydb->dbAppend( )
mydb->fname = "Angela", mydb->lname = "Repetti", mydb->age = 48
mydb->dbAppend( )
mydb->fname = "Frank", mydb->lname = "Aiello", mydb->age = 38
mydb->dbAppend( )
mydb->fname = "Mark", mydb->lname = "Lustig", mydb->age = 47
mydb->dbAppend( )
mydb->fname = "Alex", mydb->lname = "Wexler", mydb->age = 29
mydb->dbAppend( )
mydb->fname = "Naira", mydb->lname = "Aiello", mydb->age = 28
mydb->dbAppend( )
mydb->fname = "Stephen", mydb->lname = "Muccione", mydb->age = 38
end
// list the records
mydb->dbGoTop( )
while ( ! mydb->dbEOF( ) )
! mydb->lname + ", " + mydb->fname + " (age " + mydb->age + ") "
! "[rec #" + mydb->dbRecNo( ) + "]<br>"
mydb->dbSkip( )
end
mydb->dbClose( )
]>
</body>
</html>
|
The previous examples makes use of the alias operator to reference all open database
transactions. Alternatively, FGL supports the concept of workareas which can be use instead
of aliases, however in today’s multi-threaded programming environment workareas should
generally be avoided.
In fact, even aliases are not recommended in situations where simultaneous access to
data may be provided – such as through the web – since potentially two simultaneous threads
could reference the same alias. The preferred method is through a database connection handle
which is provided as a unique identifier when a database is opened. A variation of the
previous example using connection handles looks like:
<html>
<head>
<title>Database using connection handles example</title>
</head>
<body text=black bgcolor=white>
<[
// specify the file names
dbname = 'c:\fgl\data\temp\temp.db'
dxname = 'c:\fgl\data\temp\temp.dx'
// open the database, get the connector, open the index
db = dbuse( dbname, "mydb" )
(db)->dbOpenIndex( dxname )
// list the records
(db)->dbGoTop( )
while ( ! (db)->dbEOF( ) )
! (db)->lname + ", " + (db)->fname + " (age " + (db)->age + ") "
! "[rec #" + (db)->dbRecNo( ) + "]<br>"
(db)->dbSkip( )
end
(db)->dbClose( )
]>
</body>
</html>
|
The best way to interact with data is through an FGL database object wrapper which
provides an abstraction layer between the data and your application. This provides your
application with a method of accessing and interacting with data without knowing the
underlying components of the data including the storage methodology and data location.
For example:
<[
LIBRARY \fgl\libs\system.flb
obj = new( "objDatabase", 'c:\fgl\data\temp\temp.db' )
]>
<html>
<head>
<title>Simple database wrapper example</title>
</head>
<body>
<[
// open the database and operate on it through the wrapper
obj.open( )
obj.dbGoBottom( )
while ( ! obj.dbbof( ) )
// load the object with the current record information
obj.get( )
! obj.fname + " " + obj.lname + " (" + obj.dbRecNo( ) + ")<br>"
obj.dbskip( -1 )
end
obj.close( )
]>
</body>
</html>
|
The default FGL database object wrapper, objDatabase, provides access to a number of
database functions through the predefined object methods, including:
- open
- close
- seek
- get
- put
- CreateNewRecord
|
- GetRecord
- SetRecord
- dbOrder
- dbGoto
- dbGoTop
- dbGoBottom
|
- dbEOF
- dbBOF
- dbSeek
- dbSkip
- dbRecNo
- dbRecCount
|
- rlock
- unlock
- paging
- PagingDisplay
|
FGL makes it easy to create advanced object wrappers through the use of the inheritance
of the default objDatabase object contained in the SYSTEM.FLB library with the source in
the DATABASE.FGL file. Database object wrappers can be fully customized by inheriting the
default objDatabase class and adding your own database methods and functionality, as in:
<[
LIBRARY \fgl\libs\system.flb
CLASS myDatabaseObject
PUBLIC:
INHERIT objDatabase
METHOD new( )
::dbFileName = 'c:\fgl\data\temp\temp.db'
::dbAlias = "temp"
::dbStructure = {
{ "fname", "C", 20, 0 },
{ "lname", "C", 30, 0 },
{ "age", "N", 3, 0 }
}
::dbIndexes = {
{ "upper( field->lname + field->fname )", 0 }
}
return( 1 )
END
METHOD ListRecords( )
local s
s = new( "ServerBuffer" )
::open( )
while ( ! ::dbeof( ) )
::get( )
s += ::fname + " " + ::lname + " (" + ::dbRecNo( ) + ")<br>"
::dbskip( )
end
::close( )
return( s.str )
END
END
obj = new( "myDatabaseObject" )
]>
<html>
<head>
<title>Simple database wrapper example</title>
</head>
<body>
<[
! obj.ListRecords( )
]>
</body>
</html>
|
FGL makes it easy to display complex data sets using the paging object objPage found in
the SYSTEM.FLB library with its source located in the PAGING.FGL file. The next example
combines the dbViewer object (also in SYSTEM.FLB) as the data source for the paging object,
as in:
<[
LIBRARY \fgl\libs\system.flb
session = new( "session" )
// define the database and index file
dbname = 'c:\fgl\data\temp\temp.db'
dxname = 'c:\fgl\data\temp\temp.dx'
// create a database viewing and paging object
objViewer = new( "dbViewer", dbname, dxname )
objPage = new( "objPage", session, objViewer )
// configure the paging object
objPage.UnderlineHeader = 1
objPage.PageCounter = 0
objPage.hdrClass = objPage.bodyClass = objPage.btnClass = "smtxtBLACK"
]>
<html>
<head>
<title>Database paging example</title>
<link rel='stylesheet' href='../style.css' type='text/css' media='screen,print'>
</head>
<body class=smtxtBLACK>
<form name="input" action="sample9d.htm" method=get>
<[
// display the paging object
! objPage.GetCurPage( )
]>
</form>
</body>
</html>
|
The example above uses the paging object to interact with a database. The paging object
can be used in many other instances and with numerous other types of data sources to create
unique, advanced, and completely customized interfaces for your data.
You can also use the embedded paging object in the objDatabase class. In this case you
can simply call the PagingDisplay( ) method to handle all of the paging for the database.
The PagingDisplay( ) method optionally takes a parameter referencing which database index,
if any, the paging object should use. Access to all of the paging configuration options is
available through the paging object variable within the objDatabase class, as in:
<[
LIBRARY \fgl\libs\system.flb
obj = new( "objDatabase", 'c:\fgl\data\temp\temp.db', 'c:\fgl\data\temp\temp.dx' )
obj.paging.UnderlineHeader = 1
obj.paging.PageCounter = 0
obj.paging.hdrClass = obj.paging.bodyClass = obj.paging.btnClass = "smtxtBLACK"
]>
<html>
<head>
<title>Database wrapper with paging example</title>
<link rel='stylesheet' href='../style.css' type='text/css' media='screen,print'>
</head>
<body class=smtxtBLACK>
<form name="input" action="sample9e.htm" method=get>
<[
! obj.PagingDisplay( 1 )
]>
</form>
</body>
</html>
|
#####
|