CONST True 
= -1, False 
= 0 CONST DB_Static 
= 0, DB_Dynamic 
= 1  
    Style 
AS _BYTE '0 for STATIC, 1 for DYNAMIC -- totally changes our data structure/interaction 
 
    Size 
AS _UNSIGNED LONG '1 for byte, 2 for integer, 4 for long/single, 8 for int64/float, any value > 0 for strings 
REDIM SHARED DB_RecordStatus
(0, 0) AS _BYTE '1 = Normal, -1 = Deleted, -2 = Hidden, -3 = Password Protected  
 
 
'**************** END OF HEADER
 
 
DIM Customer 
AS foo 
'Our reference variable  
 
result = DB_SetMaxDatabases&(3) 'only 3 databases total
CDB = DB_CreateDatabase&(100, DB_Static) 'CDB = Customer DataBase; the name I chose for the reference handle
result = DB_AddField&(CDB, "Name", "STRING * 10")
IF result 
<> 0 THEN PRINT "ERROR ADDING NAME = "; result
 result = DB_AddField&(CDB, "Age", "INTEGER")
result = DB_AddField&(CDB, "Sex", "STRING * 1")
IF result 
<> 0 THEN PRINT "ERROR ADDING SEX = "; result
 result 
= DB_LinkToType&
(CDB
, _OFFSET(Customer
)) 'Offset to the reference variable 
PRINT "We're going to add some new records to our test database.  Just hit <ENTER> at the name to quit!"  
    INPUT "Enter Age =>"; Customer.Age
     INPUT "Enter Sex =>"; Customer.Sex
     result = DB_AddRecord&(CDB, 0)
    IF result 
< 0 THEN PRINT "ERROR ADDING RECORD = "; result
  
Customer.
Name = "": Customer.Age 
= 0: Customer.Sex 
= "" 
 
PRINT "Record", "Name", "Age", "Sex"     result = DB_GetRecord(CDB, 0)
    PRINT result
, Customer.
Name, Customer.Age
, Customer.Sex
  
 
 
'**************** START OF SUBS/FUNCTIONS
 
    'Error Codes
    '>0 = Proper return tells us the record number recovered
    '-1 = If user passed a 0 value handle
    '-2 = If handle not in use
    '-3 = If handle is larger than max set number of databases
    '-4 = Invalid database type.  Dynamic DBs dont link to user variables
    '-5 = Invalid Record
    '-6 = Reached End of Data; nothing left to read.
    '-7 = Blank Record
    '-8 = Deleted Record
    '-9 = Hidden Record
    '-10 = Password Protected Record
    IF DB_Handle 
= 0 THEN DB_GetRecord& 
= -1: 
EXIT FUNCTION '-1 if user passed a 0 value handle     IF DB_Handle 
> DB_MaxDataBases 
THEN DB_GetRecord& 
= -3 '-3 if handle is larger than max set number of databases     IF DatabaseHandle
(DB_Handle
) = False 
THEN DB_GetRecord& 
= -2: 
EXIT FUNCTION '-2 if handle not in use     IF Header
(DB_Handle
).Style 
= DB_Dynamic 
THEN DB_GetRecord& 
= -4: 
EXIT FUNCTION '-4 invalid database type.  Static DBs dont link to user variables  
    IF DB_RecordOn 
< 1 THEN DB_RecordOn 
= 1  
    DIM Temp 
AS _OFFSET: Temp 
= DB_InternalMemory
(DB_Handle
, 2).SIZE
  
            CASE 0, -1, -2, -3 'blank/deleted/hidden/password protected                 DB_GetRecord& = -7 - DB_RecordStatus(DB_Handle, DB_Record)
                _MEMFILL DB_InternalMemory
(DB_Handle
, 2), DB_InternalMemory
(DB_Handle
, 2).OFFSET
, Temp
, 0 AS _BYTE 'blank the return field             CASE 1 'It's all good and readable, no flags to worry about                 _MEMCOPY DB_InternalMemory
(DB_Handle
, 1), DB_InternalMemory
(DB_Handle
, 1).OFFSET 
+ Temp 
* (DB_Record 
- 1), Temp 
TO DB_InternalMemory
(DB_Handle
, 2), DB_InternalMemory
(DB_Handle
, 2).OFFSET
                 DB_GetRecord& = DB_Record 'proper return tells us the record number recovered
                IF DB_RecordOn 
< Header
(DB_Handle
).LastRecord 
THEN DB_RecordOn 
= DB_Record 
+ 1         FOR i 
= DB_RecordOn 
TO Header
(DB_Handle
).LastRecord 
'look for the next available record we can read             IF DB_RecordStatus
(DB_Handle
, i
) = 1 THEN                 _MEMCOPY DB_InternalMemory
(DB_Handle
, 1), DB_InternalMemory
(DB_Handle
, 1).OFFSET 
+ Temp 
* (i 
- 1), Temp 
TO DB_InternalMemory
(DB_Handle
, 2), DB_InternalMemory
(DB_Handle
, 2).OFFSET
                 DB_GetRecord& = i 'proper return tells us the record number recovered
                DB_RecordOn = i + 1
        DB_GetRecord& = -5 'Invalid Record (user passed a negative value handle)
    DB_GetRecord& = -6 'Reached End of Data
 
 
    'Error Codes
    '>0 = Proper return tells us the record number written
    '-1 = If user passed a 0 value handle
    '-2 = If handle not in use
    '-3 = If handle is larger than max set number of databases
    '-4 = Invalid database type.  Dynamic DBs dont link to user variables
    '-5 = Invalid Record
    '-6 = Failure to Write Data.  (All records probably full.)
 
    IF DB_Handle 
= 0 THEN DB_AddRecord& 
= -1: 
EXIT FUNCTION '-1 if user passed a 0 value handle     IF DB_Handle 
> DB_MaxDataBases 
THEN DB_AddRecord& 
= -3 '-3 if handle is larger than max set number of databases     IF DatabaseHandle
(DB_Handle
) = False 
THEN DB_AddRecord& 
= -2: 
EXIT FUNCTION '-2 if handle not in use     IF Header
(DatabasesInUse
).Style 
= DB_Dynamic 
THEN DB_AddRecord& 
= -4: 
EXIT FUNCTION '-4 invalid database type.  Static DBs dont link to user variables  
    DIM Temp 
AS _OFFSET: Temp 
= DB_InternalMemory
(DB_Handle
, 2).SIZE
  
        _MEMCOPY DB_InternalMemory
(DB_Handle
, 2), DB_InternalMemory
(DB_Handle
, 2).OFFSET
, Temp 
TO DB_InternalMemory
(DB_Handle
, 1), DB_InternalMemory
(DB_Handle
, 1).OFFSET 
+ Temp 
* (DB_Record 
- 1)         DB_RecordStatus(DB_Handle, DB_Record) = 1 'no unusal statuses; it's a new, good, visible, valid record
        DB_AddRecord& = DB_Record
        FOR i 
= 1 TO Header
(DB_Handle
).MaxNumberofRecords
                 CASE 0, -1 'blank or deleted record                     _MEMCOPY DB_InternalMemory
(DB_Handle
, 2), DB_InternalMemory
(DB_Handle
, 2).OFFSET
, Temp 
TO DB_InternalMemory
(DB_Handle
, 1), DB_InternalMemory
(DB_Handle
, 1).OFFSET 
+ Temp 
* (i 
- 1)                     DB_RecordStatus(DB_Handle, i) = 1 'no unusal statuses; it's a new, good, visible, valid record
                    DB_AddRecord& = i
                    IF i 
> Header
(DB_Handle
).LastRecord 
THEN Header
(DB_Handle
).LastRecord 
= Header
(DB_Handle
).LastRecord 
+ 1         DB_AddRecord& = -5 'Invalid Record
    DB_AddRecord& = -6 'Failure to Write Data.  (All records probably full.)
 
 
 
    IF DB_Handle 
= 0 THEN DB_LinkToType& 
= -1: 
EXIT FUNCTION '-1 if user passed a 0 value handle     IF DB_Handle 
> DB_MaxDataBases 
THEN DB_LinkToType& 
= -3 '-3 if handle is larger than max set number of databases     IF DatabaseHandle
(DB_Handle
) = False 
THEN DB_LinkToType& 
= -2: 
EXIT FUNCTION '-2 if handle not in use     IF Header
(DatabasesInUse
).Style 
= DB_Dynamic 
THEN DB_LinkToType& 
= -4: 
EXIT FUNCTION '-4 invalid database type.  Static DBs dont link to user variables         TotalSize&& = TotalSize&& + FieldHeader(DB_Handle, i).Size
    PRINT TotalSize&&; 
"SIZE"  
    DB_InternalMemory
(DB_Handle
, 1) = _MEMNEW(TotalSize&& 
* Header
(DB_Handle
).MaxNumberofRecords
) 'first field is the actual data    _MEMFILL DB_InternalMemory
(DB_Handle
, 1), DB_InternalMemory
(DB_Handle
, 1).OFFSET
, DB_InternalMemory
(DB_Handle
, 1).SIZE
, 0 AS _BYTE     DB_InternalMemory
(DB_Handle
, 2) = _MEM(DB_Offset
, TotalSize&&
) 'second field links to the refernce variable 
    IF Number 
= 0 THEN DB_SetMaxDatabases& 
= -1 'Can't set zero as a limit     IF DB_MaxDataBases 
<> 0 THEN DB_SetMaxDatabases& 
= -2 'Max has already been set     DB_MaxDataBases = Number
    REDIM DatabaseHandle
(1 TO DB_MaxDataBases
) AS _BIT 'True/False Flag     REDIM Header
(1 TO DB_MaxDataBases
) AS HeaderType
     REDIM FieldHeader
(1 TO DB_MaxDataBases
, 0 TO 255) AS FieldType 
'     FOR X 
= 1 TO DB_MaxDataBases
             FieldHeader
(X
, Y
).
Type = 255 'If all bits are set, the field is empty 
    'Error Codes
    '-1 = User hasn't set DB_SetMaxDatabases yet
    '-2 = Invalid number of max records
    '-3 = Too many databases open
    '-4 = Invalid style set for database
 
    IF DB_MaxDataBases 
= 0 THEN DB_CreateDatabase& 
= -1 'Max amount hasn't been set yet     IF DB_SetMaxRecords 
<= 0 THEN DB_CreateDatabase& 
= -2 'Invalid number of max records     IF STYLE 
< 0 OR STYLE 
> 1 THEN DB_CreateDatabase& 
= -4 'Invalid style set for database     FOR i 
= 1 TO DatabasesInUse
         IF DatabaseHandle
(i
) = False 
THEN             DB_CreateDatabase& = i
            Header(i).NumberOfRecords = 0
            Header(i).MaxNumberofRecords = DB_SetMaxRecords
            DatabaseHandle(i) = True
    IF DatabasesInUse 
= DB_MaxDataBases 
THEN DB_CreateDatabase& 
= -3: 
EXIT FUNCTION 'Return -3 if we have too many databases open     DatabasesInUse = DatabasesInUse + 1
    DB_CreateDatabase& = DatabasesInUse
    Header(DatabasesInUse).NumberOfRecords = 0
    Header(DatabasesInUse).MaxNumberofRecords = DB_SetMaxRecords
    DatabaseHandle(DatabasesInUse) = True
 
    IF DB_Handle 
= 0 THEN DB_FreeDatabase& 
= -1: 
EXIT FUNCTION '-1 if user passed a 0 value handle     IF DB_Handle 
> DB_MaxDataBases 
THEN DB_FreeDatabase& 
= -3 '-3 if handle is larger than max set number of databases     IF DatabaseHandle
(DB_Handle
) = False 
THEN DB_FreeDatabase& 
= -2: 
EXIT FUNCTION '-2 if handle not in use     DatabaseHandle(DB_Handle) = False
    IF DB_Handle 
= DatabaseHandle 
THEN DatabaseHandle 
= DatabaseHandle 
- 1 'clear up a handle if we're freeing the last one     DB_FreeDatabase& = True
    IF Header
(DatabasesInUse
).Style 
= DB_Dynamic 
THEN                 FieldHeader
(DB_Handle
, i
).
Type = 255                _MEMFREE DB_InternalMemory
(DB_Handle
, i
)         _MEMFREE DB_InternalMemory
(DB_Handle
, 1)  
    'Error Return Values:
    '-1 = Handle Value of 0
    '-2 = Handle > DB_MaxDataBases limit
    '-3 = Handle not in use
    '-4 = Too many fields in databse already (255 fields found)
    '-5 = Name contains invalid characters.  Only A-Z (upper or lowercase), 0-9, space, and period allowed
    '-6 = Invalid letters in type
    '-7 = Invalid information in type
    '-8 = Too large a STRING size (0 or blank for variable length, 1 - 255 for fixed length)
    '-9 = Database already has 255 fields; can't add any more.
    IF DB_Handle 
> DB_MaxDataBases 
THEN DB_AddField 
= -2 '-2 if handle is larger than max set number of databases     FOR i 
= 1 TO DB_MaxDataBases
                 DB_AddField = -5 'invalid characters in field name
            CASE "A" TO "Z", "0" TO "9" 'acceptable letters                 t$ 
= t$ 
+ MID$(t1$
, i
, 1)                DB_AddField = -6 'invalid letters in type
 
    FOR i 
= 1 TO Header
(DB_Handle
).NumberOfFields
         IF FieldHeader
(DB_Handle
, i
).
Type = 255 THEN n 
= Header
(DB_Handle
).NumberOfFields: 
EXIT FOR         IF Header
(DB_Handle
).NumberOfFields 
= 255 THEN             DB_AddField = -9 'Database already has 255 fields; can't add any more.
            n = Header(DB_Handle).NumberOfFields + 1 'prepare to update for a new field, if everything else passes muster
 
 
        IF v% 
> 255 THEN DB_AddField 
= -8 'too large a string size         Header(DB_Handle).NumberOfFields = n 'add a new field
        FieldHeader
(DB_Handle
, n
).
Name = DB_FieldLabel
        FieldHeader
(DB_Handle
, n
).
Type = 1        FieldHeader(DB_Handle, n).Size = v%
        SELECT CASE t$ 
'1 = (String)/Number, 2 = (Real)/Integer , 4 = (Signed)/Unsigned                 Header(DB_Handle).NumberOfFields = n 'add a new field
                FieldHeader
(DB_Handle
, n
).
Name = DB_FieldLabel
                FieldHeader
(DB_Handle
, n
).
Type = 2                FieldHeader(DB_Handle, n).Size = 4
                Header(DB_Handle).NumberOfFields = n 'add a new field
                FieldHeader
(DB_Handle
, n
).
Name = DB_FieldLabel
                FieldHeader
(DB_Handle
, n
).
Type = 2                FieldHeader(DB_Handle, n).Size = 8
                Header(DB_Handle).NumberOfFields = n 'add a new field
                FieldHeader
(DB_Handle
, n
).
Name = DB_FieldLabel
                FieldHeader
(DB_Handle
, n
).
Type = 2                FieldHeader(DB_Handle, n).Size = 32
                Header(DB_Handle).NumberOfFields = n 'add a new field
                FieldHeader
(DB_Handle
, n
).
Name = DB_FieldLabel
                FieldHeader
(DB_Handle
, n
).
Type = 4                FieldHeader(DB_Handle, n).Size = 1
                Header(DB_Handle).NumberOfFields = n 'add a new field
                FieldHeader
(DB_Handle
, n
).
Name = DB_FieldLabel
                FieldHeader
(DB_Handle
, n
).
Type = 4                FieldHeader(DB_Handle, n).Size = 2
                Header(DB_Handle).NumberOfFields = n 'add a new field
                FieldHeader
(DB_Handle
, n
).
Name = DB_FieldLabel
                FieldHeader
(DB_Handle
, n
).
Type = 4                FieldHeader(DB_Handle, n).Size = 4
                Header(DB_Handle).NumberOfFields = n 'add a new field
                FieldHeader
(DB_Handle
, n
).
Name = DB_FieldLabel
                FieldHeader
(DB_Handle
, n
).
Type = 4                FieldHeader(DB_Handle, n).Size = 8
                Header(DB_Handle).NumberOfFields = n 'add a new field
                FieldHeader
(DB_Handle
, n
).
Name = DB_FieldLabel
                FieldHeader
(DB_Handle
, n
).
Type = 0                FieldHeader(DB_Handle, n).Size = 1
                Header(DB_Handle).NumberOfFields = n 'add a new field
                FieldHeader
(DB_Handle
, n
).
Name = DB_FieldLabel
                FieldHeader
(DB_Handle
, n
).
Type = 0                FieldHeader(DB_Handle, n).Size = 2
                Header(DB_Handle).NumberOfFields = n 'add a new field
                FieldHeader
(DB_Handle
, n
).
Name = DB_FieldLabel
                FieldHeader
(DB_Handle
, n
).
Type = 0                FieldHeader(DB_Handle, n).Size = 4
                Header(DB_Handle).NumberOfFields = n 'add a new field
                FieldHeader
(DB_Handle
, n
).
Name = DB_FieldLabel
                FieldHeader
(DB_Handle
, n
).
Type = 0                FieldHeader(DB_Handle, n).Size = 8
                DB_AddField 
= -7: 
EXIT FUNCTION 'invalid information in type    IF Header
(DatabasesInUse
).Style 
= DB_Dynamic 
THEN         DB_InternalMemory
(DB_Handle
, n
) = _MEMNEW(FieldHeader
(DB_Handle
, n
).Size 
* Header
(DB_Handle
).MaxNumberofRecords
)        _MEMFILL DB_InternalMemory
(DB_Handle
, n
), DB_InternalMemory
(DB_Handle
, n
).OFFSET
, DB_InternalMemory
(DB_Handle
, n
).SIZE
, 0 AS _BYTE