@database "SymBase"
@$VER 0.57 (1999.01.07)
@WORDWRAP
@SMARTWRAP
@Node main "SymBase V0.1"

			S y m B a s e
			_____________

@{JCENTER}@{B}Database programming environment for Amos Pro.
@{UB}

        @{" Overview              " Link "Overview"}
	@{" What is an extension? " Link "About Extensions"} - Short explanation about Amos extensions.
	@{" SymBase features      " Link "Features"} - Capabilities of the current version.
	@{" How to install?       " Link "install"} - How could you starting to use.
	@{" Database handling     " Link "database"} - About the database handling in general.
	@{" Structures            " Link "struct"}

	@{" SymBase statements " Link "Statements"} - new statements.
	@{" SymBase procedures " Link "procedures"} - which will moving under the prev. link
	@{" SymBase tools      " Link "tools"} - external programs

	@{" Disclaimer " Link "Disclaimer"}
	@{" Future     " Link "Future"}
	@{" History    " Link "History"}
	@{" Bugs       " Link "Bugs"}
	@{" Author     " Link "Author"}


@EndNode
@Node "About Extensions"
(from the file: |Music.s by Francois Lionet)

; >>> What's an extension?
;
; An extension to AMOS is a machine language program that adds new
; instructions to the already huge AMOS instruction set. This system is
; designed to be as powerfull as AMOS itself: the extension includes its
; own token list, its own routines. It can even access some main AMOS
; routines via special macros. It has a total access to the internal AMOS
; data zone, and to the graphic library functions.

Using SymBase, this added instructions gives the ability of Dbase database
handling to Amos programs.
@EndNode

@Node "Overview"

SymBase overview

 This package is a relational database managing system. With it, you can create and store databases, manipulate its contents and structure. You can develop database programs, with the included Amos extension. You don't need to learn any database language. Your existing Amos experiences will help you to develop the program, which using databases.

 The package contains some external program besides the extension. Within those programs started the next stage of the development, the Amos independent system.

 (The Amos is an outdated programming language, which can't keep its abilities with the AGA chip set, and it will useless when the P-OS arrives. In the present version's core is the Amos, because it has the largest part of my experiences.)

 The above is written at the beginning of the project. Some things changed since then. There is a group who taking care of Amos. The next generation Amiga is a vapor, and there is still no other alternative choice for a great computer beside my loved Amiga. So, I don't want to port my code to anywhere. Yes, I loose my mind as early as I got my first Amiga.

 The whole project started as a billing, and inventory program, for our little shop. If you looking for about a similar application, feel free to contact @{"me" Link "Author"}.

@EndNode

@Node "Features"

- the used database file is Xbase compatible
- internal routines are written in assembly, so it must be fast;
- you can open up to 65000 file at a time;
- not tested on animals;
- in the development not used any M$ product;

@EndNode

@Node "Install"

The simplest and recommended way is to using the Install_SymBase script.

@{B}Manual installation:@{UB}
If you have any problem with the installer script, or you don't want to use that, you must install the components of SymBase manually.
Every SymBase related file lying under the Comp/Symbase folder. You can simply copy that folder.

The AmosPro extension's name is: SBASE_EX. To use this, copy to the AmosProSystem:Apsystem/ folder, and use the 'Set Interpreter' from the 'Config' menu of AmosPro editor.
In the configuration programm type 'SBASE_EX' to the 21th extension slot. 

Contents of this package:

file name	length		overview
--------------------------------------------------
Sbase_ex			the extension file
Create				the structure creation tool
SymBase.guide			this guide
Create.guide			guide for Create
Isntall_SymBase			installation script

@EndNode

@Node "database"
@{B}Database handling@{UB}


@EndNode

@Node "Statements"
@{B}SymBase extension statements@{UB}

@{B}Instructions:@{UB}

 @{" Db Use          " Link "db_use"} - opens a database
 @{" Db Close        " Link "db_close"} - closes an opened database
 @{" Db Saved On     " Link "db_saved"} - sets the record state
 @{" Db Saved Off    " Link "db_saved"} - sets the record state
 @{" Db Select       " Link "db_select"} - selects a given channel
 @{" Db Select First " Link "db_select"} - select the first used channel
 @{" Db Select Next  " Link "db_select"} - select the first unused channel
 @{" Db Goto         " Link "db_goto"} - record positioning
 @{" Db Put          " Link "db_put"} - puts data to a field
 @{" Db Append       " Link "db_append"} - add a new record
 @{" Db Append Blank " Link "db_append"}
 @{" Db Swap         " Link "db_swap"} - swap two record
 @{" Db Delete       " Link "db_delete"} - delete the current record
 @{" Db Recall       " Link "db_recall"} - recall a deleted record
 @{" Db Pack         " Link "db_pack"} - remove deleted records
 @{" Db Zap          " Link "db_zap"} - remove all records
 @{" Db Skip         " Link "db_skip"} - step to the next record

@{B}Functions:@{UB}

 @{" =Db Flen()   " Link "db_flen"} - length of each field
 @{" =Db Ftype()  " Link "db_ftype"} - type of the date
 @{" =Db Field$() " Link "db_field$"} - the name of the given field
 @{" =Db Field()  " Link "db_field"} - the number of the named field
 @{" =Db Get$()   " Link "db_get"} - the contents of a field

@{B}System variables:@{UB}

 @{" Db Sel       " Link "db_sel"} - number of the work area
 @{" Db Address   " Link "db_address"} - address of the internal date zone
 @{" Db Fieldno   " Link "db_fieldno"} - number of the fields
 @{" Db Recsaved  " Link "db_recsaved"} - state of the record
 @{" Db Opencount " Link "db_opencount"} - return the number of used channels
 @{" Db State     " Link "db_state"} - used or unused, this is the question
 @{" Db Reccount  " Link "db_reccount"} - number of the records
 @{" Db Recno     " Link "db_recno"} - number of the current record
 @{" Db Recle     " Link "db_recle"} - record length
 @{" Db Deleted   " Link "db_deleted"}

@EndNode

@Node "db_use"
@{B}Syntax:@{UB}	Db Use f$

@{B}Function:@{UB}

 Check file, allocate memory for the related dates, tables. Open the database file, get the structure information from it.

@{B}Input:@{UB}

 f$ - the name of the database file

@{B}Result:@{UB}

 A work type memory bank with Dbase name. This bank contains the database structure information, and room for one buffered record.

@{B}Errors:@{UB}

 Not a dbase file! - the first byte must be $03 or $83
 I/O error - file not found, file is used, etc. 
 Channel already used! - this channel has an opened database (see Db Select)

@{B}Example:@{UB}
	Db Use "work:Inventory"

@EndNode

@Node "db_close"
@{B}Syntax:@{UB}	Db Close

@{B}Function:@{UB}

 Closes the database in the actual channel.

@{B}Errors:@{UB}

 No file is used!

@{B}Example:@{UB}

	Db Use "test.dbf"
	Db Goto 10
	A$=Db Get$(2)
	Db Close

@EndNode
@Node "db_saved"
@{B}Syntax:@{UB}
			Db Saved On
			Db Saved Off

@{B}Function:@{UB}

 Sets the state of a record. If it is off, then the record will be stored at the next positioning.
 You don't need to use these instructions, because other instructions and functions handle this thing, normally.

@{B}Result:@{UB}

 The record's saved flag is set.

@{B}Example:@{UB}

	Db Use "work:Inventory.dbf"
	Db Goto 10
	Db Put "123",2
	Db Saved On
	Db Close

 The above don't change the 2nd field of the 10th record.

@EndNode
@Node "db_select"
@{B}Syntax:@{UB}
		Db Select n
		Db Select First
		Db Select Next

@{B}Function:@{UB}

 Db Select n - changes the current channel.
 Db Select First - selects the first used channel
 Db Select Next - selects the first unused channel

@{B}Input:@{UB}

 n - the number of the channel

@{B}Example:@{UB}

	Db Select 5
	Db Use "work:Inventory"

	For i=1 to Db Opencount
	  Db Select First
	  Db Close
	Next i

  The second example closes all of the opened channels.

@EndNode
@Node "db_goto"
@{B}Syntax:@{UB}
		Db Goto n

@{B}Function:@{UB}

 Read the n. record of the database.

@{B}Input:@{UB}

 n - the number of the record

@{B}Example:@{UB}

	For i=1 to Db Reccount
	  Db Goto i
	  Print Db Get$(1)
	Next i

  This will prints the first record of every record.

@{B}Bugs:@{UB}

 The current version can't add new record to the file. (V 0.42)

@EndNode
@Node "db_put"
@{B}Syntax:@{UB}

		Db Put n$,f

@{B}Function:@{UB}

  Puts the given string to the given field of the current record.
  The string must be equal or shorter as the field length.

  The data not saved immidiately. When going to another record, then modifications will be saved.

@{B}Input:@{UB}

 n$ - string
 f  - the number of the field

@{B}Example:@{UB}

	Db Goto 3
	Db Put "Apple",2

  Puts the string "Apple" to the second field of third record.
@EndNode
@Node "db_flen"
@{B}Syntax:@{UB}

		x=Db Flen(f)

@{B}Function:@{UB}

  Returns the length of the given field in characters.

@{B}Input:@{UB}

 f  - the number of the field

@EndNode
@Node "db_ftype"
@{B}Syntax:@{UB}

		x=Db Ftype(f)

@{B}Function:@{UB}

  Returns the type of the given field in characters.

@{B}Input:@{UB}

 f  - the number of the field
@EndNode
@Node "db_field$"
@{B}Syntax:@{UB}

		x$=Db Field$(f)

@{B}Function:@{UB}

  Returns the name of the given field.

@{B}Input:@{UB}

 f  - the number of the field

@EndNode
@Node "db_field"
@{B}Syntax:@{UB}

		x=Db Field(n$)

@{B}Function:@{UB}

  Returns the number corresponding to the given field name.

@{B}Input:@{UB}

 n$  - the name of the field
@EndNode
@Node "db_get"
@{B}Syntax:@{UB}

		x$=Db Get$(f)

@{B}Function:@{UB}

  Returns the content of the given field.

@{B}Input:@{UB}

 f  - the number of the field
@EndNode
@Node "db_sel"
@{B}Syntax:@{UB}

		x=Db Sel

@{B}Function:@{UB}

  Holds the number of the current database channel.
@EndNode
@Node "db_address"
@{B}Syntax:@{UB}

		x=Db Address

@{B}Function:@{UB}

  Holds the address of the extension's internal data zone.
@EndNode
@Node "db_fieldno"
@{B}Syntax:@{UB}

		x=Db Fieldno

@{B}Function:@{UB}

  Holds the number of the fields in the current database.
@EndNode
@Node "db_recsaved"
@{B}Syntax:@{UB}

		x=Db Recsaved

@{B}Function:@{UB}

  Holds the status of the current record. If this is True, then the record's current data is saved. If this is False, then the first Db Goto will save the record.

@EndNode
@Node "db_opencount"
@{B}Syntax:@{UB}

		x=Db Opencount

@{B}Function:@{UB}

  Holds the number of the opened databases. If this is 0, then no database is used.
@EndNode
@Node "db_state"
@{B}Syntax:@{UB}

		x=Db State

@{B}Function:@{UB}

  Gives information about the current channel. If this is false, then no used database is in the current channel.
@EndNode
@Node "db_reccount"
@{B}Syntax:@{UB}

		x=Db Reccount

@{B}Function:@{UB}

  Holds the number of the records in the current database.
@EndNode
@Node "db_recno"
@{B}Syntax:@{UB}

		x=Db Recno

@{B}Function:@{UB}

  Holds the number of the current record. This record is in memory, and readable with the Db Get$..
@EndNode
@Node "db_recle"
@{B}Syntax:@{UB}

		x=Db Recle

@{B}Function:@{UB}

  Holds the length of the record.
@EndNode
@Node "db_append"
@{B}Syntax:@{UB}

		Db Append
		Db Append Blank

@{B}Function:@{UB}

 Add a new record to the end of the file. The contents of this new rekord depends on the syntax of the instruction. The simple Db Append links a clone of the current record to the end of the database. With the Blank option, an empty -space filled- record will be added.
 Before execution, the not saved record will be stored automatically.

@EndNode
@Node "db_recle"
@{B}Syntax:@{UB}

		x=Db Recle

@{B}Function:@{UB}

  Holds the length of the record.
@EndNode
@Node "db_swap"
@{B}Syntax:@{UB}

		Db Swap r1,r2

@{B}Input:@{UB}

 Two valid record number.

@{B}Function:@{UB}

 Swap the contents of the <r1> and <r2> records. After the execution the current record will be the <r1>, which is now in the position of <r2>.

@EndNode
@Node "db_zap"

@EndNode
@Node "db_skip"

@EndNode
@Node "Dbhead"


@{U}A DbaseIII típusú adatállományok felépítése:
@{UU}


Az adatállomány három részre osztható:

	I.   - Header
	II.  - A mező sruktúra
	III. - Header lezárása
	IV.  - adatrekordok

I. - Header
-----------
Hossza mindíg 32 byte.
Offszetek a header elejétől.


byte      offszet név       leírás
-------+-----------------+-------------------------------------------------
0.     | DBF_Id		 | azonosító byte = $03 v. $83
-------+-----------------+-------------------------------------------------
1.-3.  | DBF_Date	 | az utolsó módosítás dátuma (yy mm dd)
-------+-----------------+-------------------------------------------------
4.-7.  | DBF_RecNo	 | az adatállomány rekordjainak száma
       |		 | a byte-ok fordított sorrendben
-------+-----------------+-------------------------------------------------
8.-9 . | DBF_HeadLe      | az első adatrekord címe a header elejéhez képest
       |		 | vagy a header hossza eggyel növelve (alsó,felső)
-------+-----------------+-------------------------------------------------
10.-11.| DBF_RecLe	 | az adatrekord hossza (alsó, felső)
       |		 | a hosszba beleszámít a deleted flag byte is
-------+-----------------+-------------------------------------------------
12.-31.|		 | fenntartva
-------+-----------------+-------------------------------------------------


II. - A mező struktúra
----------------------
Egy tag hossza 32 byte.
A tagok száma a header hosszából számítható.

byte      offszet név       leírás
-------+-----------------+-------------------------------------------------
0.-9.  | DBF_FieldName	 | a mező neve 10 byte
-------+-----------------+-------------------------------------------------
10.    |		 | a mező nevét lezáró $00
-------+-----------------+-------------------------------------------------
11.    | DBF_FieldType	 | a mező típusa (lásd lejjebb)
-------+-----------------+-------------------------------------------------
12.-15.|		 | mező adat cím (a file-ban csak a helye fenntartva)
-------+-----------------+-------------------------------------------------
16.    | DBF_FieldLe	 | a mező hossza
-------+-----------------+-------------------------------------------------
17.    | DBF_FieldDec    | numerikus típus esetén a tizedesjegyek száma
-------+-----------------+-------------------------------------------------
18.-27.|                 | fenntartva
-------+-----------------+-------------------------------------------------
28.-31.| DBF_IFilehd     | a mezőhöz tartozó megnyitott ndx handlere
-------+-----------------+-------------------------------------------------

III. - Header lezárása
----------------------
$0D
v.
$0D $00


IV. - Adatrekord
-----------------
Az első byte a deleted flag.


@EndNode

@Node "BANK"

A DB_USE által létrehozott bank szerkezete, felépítése:


Offszet:							 Hossz:
		    +-------------------------------------------+
BANK start  	    |   I.- adatállomány jellemzők    128 byte  |   DE_BankHead
		    |                                           |
		    +-------------------------------------------+
		    |                                           |
+DB_HeadOff 	    | II.  - Head                      32 byte  |   DE_DataHead
		    |                                           |
		    +-------------------------------------------+
		    |                                           |
+DB_FieldOff	    | III. - mező struktúra          n*32 byte  |   DB_FieldOff
		    |                                           |
		    +-------------------------------------------+
		    |                                           |
*DB_CFieldOff	    | V.   - a mező számított adatai n*12 byte  |   *DB_CFieldOff
		    |                                           |
		    +-------------------------------------------+
		    |                                           |
*DB_RecSt	    | IV.  - 1 db adatrekord                    |   *DB_RecSt
		    |                                           |
		    +-------------------------------------------+




I. Adatállomány jellemzők:
--------------------------
Hossz: DE_BankHead == 128

byte      offszet név       leírás
-------+-----------------+-------------------------------------------------
0.-3.  | DB_Filehd	 | a megnyitott file FILEHD-je
-------+-----------------+-------------------------------------------------
4.-7.  | DB_HeadLe	 | a DBF struktúra hossza, ami magában foglalja a
       |		 | headert és a mező struktúrát
-------+-----------------+-------------------------------------------------
8.-9.  | DB_RecLe	 | a rekord hossza
-------+-----------------+-------------------------------------------------
10.-13.| DB_RecSt        | az adatrekord kezdőcíme
-------+-----------------+-------------------------------------------------
14.-15.| DB_FieldNum	 | a mezők száma
-------+-----------------+-------------------------------------------------
16.-19.| DB_RecNum	 | a rekordok száma
-------+-----------------+-------------------------------------------------
20.-23.| DB_RecOff	 | IV. Adatrekord kezdőcím offszet
-------+-----------------+-------------------------------------------------
24.-27 | DB_CFieldOff	 | V. A mező számított adatok kezdőcím offszet
-------+-----------------+-------------------------------------------------
28.-31.| DB_CurRec	 | az aktuális rekord száma
-------+-----------------+-------------------------------------------------
32.-35.| DB_Order        | a rendezett mező száma, ill. 0>natural order
-------+-----------------+-------------------------------------------------
36.-39.| DB_PrevSel	 | az előző megnyitott adatállomány csatornája
-------+-----------------+-------------------------------------------------
40.-43.| DB_NextSel	 | a következő megnyitott adatáll. csatornája
-------+-----------------+-------------------------------------------------
-127.  |		 | fenntartva
-------+-----------------+-------------------------------------------------


A fenti adatok nagyrésze megtalálható az adatáll. headerben is.
Mivel ott alsó-felső sorrendben találhatóak a byte-ok, könnyebben
kezelhető formában tároljuk itt.



II. A dbase adatállomány header
-------------------------------
Hossz:   DE_DataHead == 32
Offszet: DB_HeadOff  == 128

@{"  A DbaseIII típusú adatállományok felépítése  " Link "Dbhead"}


III. Mező struktúra
-------------------
Hossz:    DE_FieldStruc == 32
Offszet : DB_FieldOff	== 160

@{"  A DbaseIII típusú adatállományok felépítése  " Link "Dbhead"}


IV. Adatrekord
--------------
Hossz:   *DB_RecLe
Offszet: *DB_RecSt

Az aktuális adatrekord másolata.

byte
------+------------+-------------------------------------------------------
0.    | DE_RecDel  | Deleted flag
------+------------+-------------------------------------------------------
1.-   | DE_RecData | Itt kezdődnek az adatok
------+------------+-------------------------------------------------------


V. A mezők számított adatai
---------------------------
Hossz:  DE_CFieldStruc == 16
Offszet *DB_CFieldOff


byte     offszet név       leírás
-------+-----------------+-------------------------------------------------
0.-3.  | DF_FieldSt	 | mező struktúraelem offszet
-------+-----------------+-------------------------------------------------
4.-7.  | DF_FieldRec	 | mező offszet a rekordban
-------+-----------------+-------------------------------------------------
8.-9.  | DF_LinkSel	 | a mezőhöz linkelt megnyitott adatáll csatornája
-------+-----------------+-------------------------------------------------
10.-11.| DF_LinkField	 | a DF_LinkSel-hez tartozó mezö
-------+-----------------+-------------------------------------------------
12.-15.|                 | fenntartva
-------+-----------------+-------------------------------------------------

Constansok:
-----------

-------------+--------+----------------------------------------------------
NOT_DELETED  | $20    | a nem törölt rekord jelzése a rekord 1. byteban
-------------+--------+----------------------------------------------------


@EndNode
@Node "procedures"
I don't know what did I want to write here!
@EndNode
@Node "tools"

Currently there is one tool exist, but this one is very important.

 Create
 ------

 With this Amos independent stuff, you can create new databases.
@EndNode
@Node "author"

 Ok, I am a hungarian guy, a fanatic Amiga user. I think Amiga cannot die, because this is a computer, not an organic creature. :))

 If you want to contact me, then here are the addresses:

	Snail mail: H2013 Pomáz, Petőfi Sándor u. 16. Hungary
	e-mail    : lazi@freemail.c3.hu
	phone	  : +36 26 326 139
@EndNode
@Node "history"

 00.45	- The projects's name changed to SymBase
	  Extension's name to Sbase_ex
 00.46	- fix a small bug in Db Get$
 00.47	- fix in Db Get$ - no return string, if all char is space
	  fix in Db Put - replace the moved 0 if the strint shorter
 00.48	- fix in Db Get$ - cuts the spaces from the end
 	  remove a recently generated bug in Db Put
 00.49	- trying to fix Db Append Blank
 00.50	- Added the Db Swap instruction
 00.51	- Added the Delete Recall instructions and the Deleted variable
 00.52	- Added the Db Pack instruction
	  fix Delete and Recall
	  added the L_CHANGE internal subroutine
 00.53	- added the L_STORE_RECNO internal routine
 00.54	- added the Db Zap instruction
	  Db_Ftype now check param correctly
 00.55	- Db_Field$() fix
 00.56	- L_REC_SEEK and L_REC_SEEK fix to use recno>$FFFF
 00.57	- fix Db Get$() crash on the 2044th call
 00.58	- added the Db Skip instruction


@EndNode
@Node "struct"

 @{" Dbf file structure " Link "DbHead"}
 @{" Internal structure " Link "BANK"}

@EndNode
@Node "disclaimer"

This software is freeware. Feel free to use it.
If you want to use SymBase in a commercial product, contact the author, before do that.
@EndNode
@Node "Future"

@{B}Future:@{UB}
This version (0.58) is just a sample.

@EndNode
@Node "bugs"
Known bugs:

- After Db Pack it can accept illegal record number with Db Goto
@EndNode
