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