IF SOMETHING WRONG - DOWNLOAD FREE INTERNET EXPLORER 5 + more
A FEW TESTIMONIES FROM USERS OF THE dbPager - YOU CAN READ HERE
THE dbPager - YOU CAN LEARN IT HERE

DOWNLOAD THE dbPager - DOWNLOAD FORM

DBPAGER IS A POWERFUL GENERATOR OF HTML REPORTS FROM DATABASES AND TEXT FILES.
IT IS SIMPLE, FLEXIBLE AND EASILY EXTENDIBLE SCRIPT LANGUAGE. IT IS BUILT ON THE NEW PRINCIPLES.
THIS IS NEW LIFE FOR YOUR WWW-SERVER.

dbPager significantly eases the manual coding of HTML.

The pre-processor will take care of HTML end tags. The flexible system of scripts binding is more powerful than SSI. It lets you easily create diverse module documents.

dbPager enables you to create the abstract functions (templates).

The abstract function is an analogy for a tag. Thus, the author of the Internet documents gets the advantage to expand the set of the commands he can use (like in XML).

dbPager is easy to learn.

dbPager is easy to learn, because it comprises small set of basic commands. The commands have simple syntax and just 7 of them are mostly used. It allows you to learn and use dbPager very soon.



dbPager provides simple and efficient access to the databases.

When applying to the external sources of data, dbPager uses Borland Database Engine (BDE 5.0). It enables you to work with wide variety of databases - from desk ones (like dBase and Paradox) to the server ones (as Oracle, MS SQL, Interbase)

dbPager is highly efficient.

The dbPager scripts are compiled in RAM while the first applying to them (the Just In Time Compiler method is used). Usage of the managed cache increases the efficiency even more.

dbPager supports CGI and ISAP protocols.

The most efficient solution is offered for MS IIS, where dbPager is set as an ISAPI extension, but thanks to CGI implementation dbPager can be used on the servers of other producers.


THE DESCRIPTORS' MANUAL

The Program Building Principles

sql - To execute the SQL commands
Syntax:

--------------------------------------------
sql (ofset,count) query 
--------------------------------------------

The SQL queries language is used in dbPager for the access to the external sources of data. The sql descriptor is used for it. This descriptor execute both the returning the data queries (SELECT) and the modifying queries (INSERT, UPDATE, DELETE, CREATE, ALTER). If the query returns data then the context variables created for it. After that the all the imbedded descriptors are executed. It goes this way for every line of the selection's result. You can limit the range of selection using the limits in parentheses:

........
	<ul> :: sql (0,10) select * from userlist order by username
		<li>%username%
........

This sample outputs first 10 user's names in the alphabetic order. If the query doesn't output the result data you may need to control the success of the operation. So, if the query is executed successfully then the processing will be passed to the imbedded descriptors.
Example:

........
	<p>SQL: %query%
	sql %query%
		<p>SUCCESS
........

The SUCCESS word will appear only if the query contained in the variable query is successfully executed.
NOTE: the file database.ini containes the descriptions for connections with databases. The first of those descriptions is used as default. The rest of them are accessible through the DatabaseName variable. Let's say that the database.ini containes a line "mydb=ODBC_ALIAS,Admin,masterkey", then the appeal to the DB ODBC_ALIAS will look this way:

........
	var "DatabaseName=mydb"
		<ul> :: sql (0,10) select * from userlist order by username
			<li>%username%
........

This value is correct for the descriptors save and dbcontext.


save - To change the records in database according the key
Syntax:

--------------------------------------------
save table 
--------------------------------------------

In some dialects of SQL language it is difficult to work with the fields like BLOB, besides of that sometimes is more convenient to update the information in DB using the save descriptor. This descriptor positions the record (according to the value of original key) in the appointed table and it updates the values of assigned fields. If there is no a record with an assigned key then the there won't be updates.
Example:

--------------------------------------------
@html("Updating the DB records")
	sql insert into userlist(userid) values(1000) // adding a record into DB
	save userlist // to save information about a client
		#1000 // the original key
		#username=John Smith
		#useremail=john@usa.net
		#title=%title% // the title value is passed over as parameter 
--------------------------------------------

Every line in the subjected descriptors is correspondent to the format "the name of the field"="the new value". But the first line containing the value of the original key. The sequence and number of the fields doesn't matter. To work with the fields of different types (numbers, dates, strings, BLOB) is done the same way as with the "string" type of fields.


dbcontext - The arbitrary access to the selection results
Syntax:

--------------------------------------------
dbcontext "var=var_map","sql=query"
--------------------------------------------

This descriptor came to existence in dbPager when the speed of applying to the data in DB became critically important. If your DB's reference book has small amount of information and it very frequently visited then you can to bind its values with the main table without SQL, but directly in the program. Let's say we have the reference book of an activity codes and you want to apply to its elements in arbitrary way. Then you write:

--------------------------------------------
dbcontext "var=act_%id%=%name%","sql=select id,name from activity"
--------------------------------------------

This construction forms the variables act_1, act_2, act_3 ..... according to the var mask and the sql selection results. If you want using the name to get the code then the var will look differently:

--------------------------------------------
dbcontext "var=act_%id%=%name%,cod_%name%=%id%","sql=select id,name from activity"
--------------------------------------------

Now you can get the code of an activity approximately this way: %cod_Sailing%. If the name of an activity is in variable act, then you can refer to the code in this way: [cod_%act%].


dir - To watch the list of files in a directory
Syntax:

--------------------------------------------
dir the_mask
--------------------------------------------

To get the access to the list of files you can use the dir descriptor which is similar with the same DOS command. The file's mask may contain the special symbols (* or ?) to select the group of files. Descriptor checks all the files according the mask, initiates the context variables FileName and FileSize and initializes in cycle processing of the context-subjected levels for every file.

--------------------------------------------
@html("the list of files")
	<ul> :: dir *.ht*
		<li>%FileName% (%FileSize% byte)
--------------------------------------------


read - To read information from a file
Syntax:

--------------------------------------------
read file_name
--------------------------------------------

The read descriptor reads information from a file and downloads its content into variable file. If the program uses several imbedded read descriptors then the file variable will contain the content of file associated with the most inner descriptor. To access the file's content use the parser command split which provides the access to the distinct strings and fields inside of strings in the file. See the example of "bulk-mail list" for the mailto descriptor.


write - To record into a file
Syntax:

--------------------------------------------
write file_name
--------------------------------------------

After the descriptor write in the same line put the file name and it includes into the file the processing result of imbedded in write descriptors. It's convenient to create the static HTML pages with this command if they don't need to be dynamically created, but should exist as an independent file. This way is useful when you make the statistic reports, they may be created once a day or up on the request.
Example:

--------------------------------------------
@html("The report generator")
	<p>The start of report generating 
	work :: write report.htm :: @gen_report // to generate and to save in file
	<p>The work is done
--------------------------------------------

You can save in files the counters values and other technical information.


append - To add information to the end of file
Syntax:

--------------------------------------------
append file_name
--------------------------------------------

This command adds the content of the context dependent levels to the end of the appointed file. The example of recording the protocol of referring to the page into the log-file. The save_log.dbl:

--------------------------------------------
append log.txt
	#%now% |%space%
	#%script_name% |%space%
	#%HTTP_USER_AGENT% |%space%
	#%HTTP_REFERER% |%space%
	#%REMOTE_ADDR%%CrLf%
--------------------------------------------

You can use this script this way test.dbp:

--------------------------------------------
@html("Simple page")
	<h3>Simple page
	<p>This is page's content
@save_log // and this is saving of the log
--------------------------------------------


switch - To compare with a pattern to make branches
Syntax:

--------------------------------------------
switch string
--------------------------------------------

The switch descriptor is similar to the case constructions (in Pascal) and switch (in C/C++). The string within the descriptor is compared with the strings of the subjected levels descriptors. In the case of coinciding the context dependent levels (relatively to the sample) descriptors are processed. If there was now coinciding the program considers that the initial line coincides with the line "else".
Example:

--------------------------------------------
@html("A simple page")
	default "a=1"
		switch %a%
			#1 :: <h3>Hi
			#2 :: <h3>Hello
			#else
				<h1>Nothing matched 
				var "LoopLimit=10" :: #<hr>
--------------------------------------------

Assigning the different values to the variable a you can manage the output. To make complicate arithmetic comparing you can use this descriptor the next way:

--------------------------------------------
@html("Simple page")
	default "a=1"
		switch [%a%>0 and %a%<10]
			#1 :: <h3>The value is in the range
			#0 :: <h3>Exceeding the limits
			#else :: <h3>Non-number value 
--------------------------------------------

The result of processing the logic operations is 1 - truth, 0 - false.


while - To process in a cycle
Syntax:

--------------------------------------------
while condition
--------------------------------------------

while executes the context dependent levels until the argument of this descriptor will become equal to zero or while it will be executed the number of times contained in the LoopLimit variable. Let's say that you want to make 10 horizontal lines:

--------------------------------------------
@html("Ten lines")
	var "LoopLimit=10" :: while 1 :: #<hr> // 10 iterations
--------------------------------------------

If this cycle construction is not enough for you take the for cycle as an extension of the language (the pattern). See the example for the link descriptor.


stop - To forbid the iteration
Syntax:

--------------------------------------------
stop any_string
--------------------------------------------

If you want to turn off any block in your program just put this block into the stop descriptor. Instead of the word stop you can use ! (the exclamation sign).
Example:

--------------------------------------------
@html("A simple page")
	var "a=aaa","b=bbb"
		<p>The value of variables a=%a%, b=%b% // aaa bbbb
		!var "a=AAA","b=BBB" // this one and the embedded levels are blocked 
			<p>The value of variables a=%a%, b=%b% // AAA BBBB
		<p>The value of variables a=%a%, b=%b% // aaa bbbb
	<p>The value of variables a=%a%, b=%b% // not defined
--------------------------------------------


link - To bind scripts
Syntax:

--------------------------------------------
link name("arg1","arg2",...)
--------------------------------------------

This is one of the most important descriptors in dbPager. Besides binding of scripts it passes parameters and does the undefined call for the scripts. The first function of the descriptor is referring toward the scripts and it is quite common for the programmers. It is similar with the way to call a function or procedure.
The undefined call is some modification of well-known for programmers callback method. Besides procedures or functions it allows to create the abstract functions (the patterns). For instance, you can create by yourself the new construction for (which originally didn't exist in dbPager).
Example of for.dbl:

--------------------------------------------
split "Str=%Arg1%","Sep==" :: var "var=%Str1%" // to apply to the arguments by their numbers 
	split "Str=%Str2%","Sep=;" :: var "%var%=%Str1%"
		while [%Str1%<=%Str3%]
			@@ // the callback
			set "Str1=[%Str1%+%Str2%]","%var%=%Str1%"
--------------------------------------------

It's easy to use your created pattern:

--------------------------------------------
@html("Multiplication Chart")
	<h3>The Multiplication Chart
	<table border=1 cellspacing=0>
		@for(i=1;1;10) :: <tr>
			@for(j=1;1;10) :: <td>%i%*%j%=<b>[%i%*%j%]
--------------------------------------------

You can consider the callback principal as inheriting of the scripts' properties and composition. Besides of that the script can have more than one callbacks different by the points of entering (the entry descriptor).
Example of test.dbp:

--------------------------------------------
@html("callbacks")
	<h3> :: @test:check_time
		:day :: #Good day
		:night :: #Good night
:check_time // To check the time of the day 
	split "str=%now%","Sep= " :: split "str=%str2%","Sep=:" // to calculate hours
		switch [%str1%<=8 and %str1%<=17]
			#1 :: @@:day // the day
			#else :: @@:night // the night
--------------------------------------------

In some cases you don't know in advance the name of the script which will process the data. Like data about an object are kept in the BLOB field for the database, but the name of processing script (the name of class) are kept in the string field of the same record, so the processor will look the next way:

..............
	sql select class,data from object where ....
		@%class%:view // formatted output
..............

Besides of the formatted output the script %class% can contain the form for editing, the script for saving the object in DB and other methods to work with an object. The name of the script may be omitted for the recursive call or for the call of the same script, but from other entering point. In the "Day and Night" example you can write @:check_time instead of @test:check_time.
As you see, the passed arguments are not named, but put into variables with the names Arg1, Arg2, ... The total number of transmitted arguments is put into ArgsCount variable and Arg0 contanes the name of script with the entry point.


entry - To define an additional point of the entry into the script file
Syntax:

--------------------------------------------
entry name
--------------------------------------------

This descriptor makes additional entry points into the script file what allows to avoid growing the number of small files in your folders.
Example of test.dbp:

--------------------------------------------
@html("A Simple Page")
	var "a=aaa","b=bbb"
		@test:show_vars // aaa bbb
		var "a=AAA","b=BBB"
			@test:show_vars // AAA BBB
		@test:show_vars // aaa bbb
	@test:show_vars // not defined
:show_vars // the additional entry point
	<p>The values of variables a=%a%, b=%b% // output for the values
--------------------------------------------


work - Guarantees the executing of the block if the connection with a client is broken
Syntax:

--------------------------------------------
work
--------------------------------------------

If the connection is broken the dbPager server stops executing of the script, but in some cases it is necessary to accomplish the task (like modifying the DB, changing of the global variables, recording and modifying of the files, sending emails). To tell the server that a critical block is executing you put this block into the work descriptor
Example:

--------------------------------------------
work :: @html("A Simple Page") // Whole the script will be executed completely 
	default "count=1" // Local initialization of the counter
		<p>You entered this page %count% times // the visitors counter
		global "count=[%count%+1]" // we change the global value of the counter
--------------------------------------------
Imbedding of the work descriptors into other work descriptors guarantees the execution of the outer block.


mailto - To send email
Syntax:

--------------------------------------------
mailto "From=email1","To=email2","Subject=string","Type=plane|html","SmtpHost=host"
--------------------------------------------

It is so easy to create your own mailing-list. Let's say that the message is contained in the file message.txt and the list of addresses is in the file list.txt then the script will look like this:

--------------------------------------------
@html("Mailing-list") :: var "msg="
	read message.txt :: set "msg=%file%"
	<p>%msg% // output of the message
	read list.txt :: <ul> :: split "email=%file%","Sep=%CrLf%","Loop=Y"
		mailto "To=%email%", "From=gevlich@octava.com", "Subject=test", "SmtpHost=info.khv.ru"
			#%msg% // body of the letter
		<li>%email% // processed address
--------------------------------------------

To send the email in HTML format you need to put a parameter "Type=html". Unfortunately, this version doesn't have a control of successful email sending, but there was no malfunctions yet, according the practice.
Note: the cycle of email sending is better to put into the work block.


style - Automated closing tags
Syntax:

--------------------------------------------
style any_string
--------------------------------------------

This is one of the most useful descriptors. It is executed by default. All the tags met in the line of this descriptor are closed in the backward order automatically after the execution of the embedded levels descriptors. The tag's parameters are omitted. If you want to block the tag closing you put this tag into <<>>
Example:

--------------------------------------------
@html("A Simple page")
	<a href="http://www.yahoo.com"><<img src="yahoo.gif" border=0>> // Reference to the search engine
--------------------------------------------

text - Output of a line "as it is"
Syntax:

--------------------------------------------
text any_string
--------------------------------------------

The dbPager has the text descriptor to prevent the closing of the tags (like <br> <img ...> etc.) You can shorten it to #. The line after this descriptor is output "as it is". It is useful descriptor (!) everywhere when you don't want to use the default closing of the tags. It increase the productivity and eliminates the conflict with new descriptors.

I had an experience when with adding new descriptors to work with files in the dbPager the old ones stopped working. The problem was: some lines processed formally by the default descriptor style begun to be processed by the new descriptors and the logic of the program was broken.

It is also convenient to use this descriptor for blocking some other descriptors when you are working on the program or are testing it.


gifimage - Generates images
Syntax:

--------------------------------------------
gifimage the_image_file | width,height
--------------------------------------------

To make the graphic counters and diagram generators is possible with such descriptor. It works in two regimes: using the template (drawing over the existing .gif file if you use the name of the image file the new picture gets the same size) and another one is creating a new image in the white background (if you assign the size of the picture).

In both cases the image is made by interpreting the graphical primitives put into context-dependent levels of this descriptor. The created image can be saved in the file, in database or sent to the client without saving (you can do it changing the standard header of the reply).

--------------------------------------------
#GIF :: gifimage 100,100 // the scheme generator
	#brush.color ff00; // green
	var i=1 :: while [%i%<10] // cycle
		#fillrect [10*%i%],10,[10*%i%+5],[int(rnd*90)]; // rectangles in a raw
		set "i=[%i%+1]"
--------------------------------------------

The list of graphic primitives must be formed by the text descriptor and be separated by semicolons. Probably this list will be widened in future, but now it contains the most necessary commands:


cache - To create a new cache element
Syntax:

--------------------------------------------
cache unique_ident
--------------------------------------------

Often, the code made by dbPager is not enough productive. It happens when the page is built from multiple imbedded SQL-quests or they require much time to be executed. With high bandwidth such page may paralyze your server.

To lessen the work of the server dbPager has special cash commands. The cache descriptor creates cache for all imbedded descriptors according the name of the cache identifier, which defines the unique parameters of the cache.

--------------------------------------------
@html("The list of users")
	<h3>The list of users on %now%
	cache user_list_%title% // Caching of the selection with formatting of the list
		<ul> :: sql select * from userlist where title='%title%' order by username
			<li>%username% - <a href="mailto:%useremail%">%useremail%
--------------------------------------------

This sample creates cache for the whole class of selection from the table userlist according the title of a user which is passed to the script as a parameter.


reset - To drop down the value of the cache element
Syntax:

--------------------------------------------
reset unique_ident
--------------------------------------------

When the cached part of the script must be changed (like in the case when the table content was changed in database) it is necessary to re-initialize the cache. This for is the reset descriptor which must appoint the same cache identifier

--------------------------------------------
@html("Update the list of users")
	<h3>Adding the user %username%
	sql insert into userlist(username,useremail,title) values('%username%','%useremail%','%title%')
	reset user_list_%title% // Drop down the cache
--------------------------------------------

We drop down the cache when we add a record into the table userlist. The cache is also dropped down in 20 minutes if there was no quests to the script.


THIS IS ALL WHAT YOUR SERVER NEEDS!

You see, it is very fast and easy to program with dbPager!


DOWNLOAD THE dbPager - DOWNLOAD FORM

THE dbPager - BACK TO THE PREVIOUS PAGE

BACK HOME

WELCOME to send an e-mail to:
nDraw at my address on @yahoo.com

Click here to visit site!