Hi all,
Im planned to make a database function and I want to make it reusable.
Here is what come to my mind.
DATA_BINARY equ 0
DATA_TEXT equ 1
DATA_PICTURE equ 2
fDataB struct
nSize dword 0
nType dword 0
lpData dword 0
fDataB ends
fDataBFile struct
nData dword 0
lpData dword 0
fDataBFile ends
.code
;--------------------------------------------------------------------------------
; Low Level Function- Internal Use
fDataBaseCreatefDataB proc uses esi edi nSize:dword,nType:dword,lpData:dword
mov ecx,nSize
add ecx,8
invoke mAlloc,ecx
mov esi,eax
push nSize
add dword ptr[esp],8
pop [esi].fDataB.nSize
push nType
pop [esi].fDataB.nType
.if lpData==0
invoke MessageBox,0,CADD("Data pointing to a zero memory address. System error and will be terminated"),0,0
invoke GlobalFree,esi
ret
.endif
lea eax,[esi].fDataB.lpData
invoke MemCopy,lpData,eax,nSize
mov eax,esi
ret
fDataBaseCreatefDataB endp
fDataBaseAddData proc uses esi edi lpStruct:dword,lpfDataB:dword,nPosition:dword
LOCAL data_ln,data_cpyd:dword
LOCAL nmem:dword
mov esi,lpStruct
mov ecx,[esi].fDataBFile.nData
.if ecx==0
invoke mAlloc,4
push eax
pop [esi].fDataBFile.lpData
mov ecx,lpfDataB
mov dword ptr[eax],ecx
inc [esi].fDataBFile.nData
.else
.if ecx<nPosition
mov ecx,[esi].fDataBFile.nData
mov data_ln,ecx
shl data_ln,2
inc ecx
shl ecx,2
invoke mAlloc,ecx
push eax
invoke MemCopy,[esi].fDataBFile.lpData,eax,data_ln
invoke GlobalFree,[esi].fDataBFile.lpData
pop [esi].fDataBFile.lpData
inc [esi].fDataBFile.nData
mov ecx,[esi].fDataBFile.nData
dec ecx
mov eax,[esi].fDataBFile.lpData
push lpfDataB
pop dword ptr [eax+ecx*4]
.elseif ecx>=nPosition
mov ecx,[esi].fDataBFile.nData
mov data_ln,ecx
shl data_ln,2
inc ecx
shl ecx,2
invoke mAlloc,ecx
mov nmem,eax
mov ecx,nPosition ; Calculate the data length
dec ecx
shl ecx,2
mov data_cpyd,ecx
invoke MemCopy,[esi].fDataBFile.lpData,nmem,ecx
mov ecx,nPosition ; Calculate data position
dec ecx
mov eax,nmem
push lpfDataB
pop dword ptr[eax+ecx*4] ; Put it on the new memory
; Now is the hardest part
; Calculate the remaining data lenght and copy it
mov ecx,[esi].fDataBFile.nData
sub ecx,nPosition
inc ecx ;It so annoying when we need to adjust from 0 based to 1 based
shl ecx,2
mov eax,[esi].fDataBFile.lpData
add eax,data_cpyd
mov edx,nmem
add edx,data_cpyd
add edx,4
invoke MemCopy,eax,edx,ecx
invoke GlobalFree,[esi].fDataBFile.lpData
push nmem
pop [esi].fDataBFile.lpData
inc [esi].fDataBFile.nData
.endif
.endif
ret
fDataBaseAddData endp
fDataBaseGetData proc uses esi edi lpStruct:dword,nPosition:dword
mov esi,lpStruct
mov ecx,[esi].fDataBFile.nData
.if nPosition>ecx
xor eax,eax
dec eax
ret
.endif
mov eax,[esi].fDataBFile.lpData
mov ecx,nPosition
dec ecx
mov eax,[eax+ecx*4]
ret
fDataBaseGetData endp
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
; Use this function each time you want to add data
fDataBaseAdd proc uses esi edi lpStruct:dword,nSize:dword,nType:dword,lpData:dword
mov esi,lpStruct
invoke fDataBaseCreatefDataB,nSize,nType,lpData
invoke fDataBaseAddData,esi,eax,0fffffffeh
ret
fDataBaseAdd endp
fDataBaseInsert proc uses esi edi lpStruct:dword,nSize:dword,nType:dword,lpData:dword,nPosition:dword
mov esi,lpStruct
invoke fDataBaseCreatefDataB,nSize,nType,lpData
invoke fDataBaseAddData,esi,eax,nPosition
ret
fDataBaseInsert endp
fDataBaseDelete proc uses esi edi lpStruct:dword,nPosition:dword
LOCAL data_ln,data_cpyd:dword
LOCAL nmem:dword
mov esi,lpStruct
mov ecx,[esi].fDataBFile.nData
.if ecx==0
ret
.else
.if ecx<nPosition
dec ecx
shl ecx,2
push ecx
invoke mAlloc,ecx
mov nmem,eax
pop ecx
invoke MemCopy,nmem,[esi].fDataBFile.lpData,ecx
dec [esi].fDataBFile.nData
.elseif ecx>=nPosition
sub ecx,nPosition
shl ecx,2
mov data_ln,ecx
mov ecx,nPosition
dec ecx
shl ecx,2
mov data_cpyd,ecx
invoke fDataBaseGetData,esi,nPosition
invoke GlobalFree,eax
mov ecx,[esi].fDataBFile.nData
dec ecx
shl ecx,2
invoke mAlloc,ecx
mov nmem,eax
invoke MemCopy,[esi].fDataBFile.lpData,nmem,data_cpyd
mov ecx,data_cpyd
add ecx,[esi].fDataBFile.lpData
add ecx,4
mov edx,nmem
add edx,data_cpyd
invoke MemCopy,ecx,edx,data_ln
push nmem
invoke GlobalFree,[esi].fDataBFile.lpData
pop [esi].fDataBFile.lpData
dec [esi].fDataBFile.nData
.endif
.endif
ret
fDataBaseDelete endp
fDataBaseEdit proc uses esi edi lpStruct:dword,nSize:dword,nType:dword,lpData:dword,nPosition:dword
LOCAL old_data:dword
mov esi,lpStruct
invoke fDataBaseGetData,esi,nPosition
invoke GlobalFree,eax
invoke fDataBaseCreatefDataB,nSize,nType,lpData
mov edx,[esi].fDataBFile.lpData
mov ecx,nPosition
dec ecx
mov [edx+ecx*4],eax
ret
fDataBaseEdit endp
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
; Disk Function
fDataBaseWrite proc uses esi edi lpStruct:dword, lpFileName:dword
LOCAL fsize:dword
LOCAL data,data_offset:dword
mov esi,lpStruct
.if [esi].fDataBFile.nData==0
xor eax,eax
dec eax
ret
.endif
xor ecx,ecx
mov data_offset,ecx
mov fsize,ecx
loop_get_size:
pushad
;inc ecx
mov eax,[esi].fDataBFile.lpData
mov eax,[eax+ecx*4]
mov eax,[eax].fDataB.nSize
add fsize,eax
popad
inc ecx
cmp ecx,[esi].fDataBFile.nData
jl loop_get_size
add fsize,4
invoke mAlloc,fsize
mov data,eax
mov dword ptr[eax],"FDB1"
add data,4
xor ecx,ecx
loop_write:
pushad
inc ecx
invoke fDataBaseGetData,esi,ecx
mov ecx,[eax].fDataB.nSize
mov edx,data
add edx,data_offset
add data_offset,ecx
invoke MemCopy,eax,edx,ecx
popad
inc ecx
cmp ecx,[esi].fDataBFile.nData
jl loop_write
sub data,4
invoke write_disk_file,lpFileName,data,fsize
invoke GlobalFree,data
ret
fDataBaseWrite endp
fDataBaseLoad proc uses esi edi lpStruct:dword,lpFileName:dword
LOCAL fl,fsz:dword
LOCAL dt_off:dword
mov esi,lpStruct
invoke filesize,lpFileName
.if eax!=-1
mov fsz,eax
invoke mAlloc,fsz
mov fl,eax
invoke read_disk_file,lpFileName,addr fl,addr fsz
mov eax,fl
mov eax,[eax]
.if eax!="FDB1"
invoke MessageBox,0,CADD("Not a Valid File"),0,0
invoke GlobalFree,fl
xor eax,eax
dec eax
ret
.endif
mov ecx,fsz
sub ecx,4
mov dt_off,0
loop_count_data:
push ecx
mov eax,fl
add eax,4
add eax,dt_off
mov ecx,[eax]
add dt_off,ecx
lea edx,[eax].fDataB.lpData
sub [eax].fDataB.nSize,8
invoke fDataBaseAdd,esi,[eax].fDataB.nSize,[eax].fDataB.nType,edx
pop ecx
cmp ecx,dt_off
jnz loop_count_data
invoke GlobalFree,fl
.else
xor eax,eax
dec eax
.endif
ret
fDataBaseLoad endp
fDataBaseLoadFromMemory proc uses esi edi lpStruct:dword,lpData:dword,nSize:Dword
LOCAL fl,fsz:dword
LOCAL dt_off:dword
mov esi,lpStruct
mov eax,lpData
mov eax,[eax]
.if eax!="FDB1"
invoke MessageBox,0,CADD("Not a Valid File"),0,0
invoke GlobalFree,lpData
xor eax,eax
dec eax
ret
.endif
mov ecx,nSize
sub ecx,4
mov dt_off,0
loop_count_data:
push ecx
mov eax,lpData
add eax,4
add eax,dt_off
mov ecx,[eax]
add dt_off,ecx
lea edx,[eax].fDataB.lpData
sub [eax].fDataB.nSize,8
invoke fDataBaseAdd,esi,[eax].fDataB.nSize,[eax].fDataB.nType,edx
pop ecx
mov eax,ecx
sub eax,dt_off
cmp eax,sizeof fDataB
ja loop_count_data
; cmp ecx,dt_off
; jnz loop_count_data
ret
fDataBaseLoadFromMemory endp
;--------------------------------------------------------------------------------
So my database would be have 3 type of data. I planned to copy each data every time the user input a data so the database has it own memory data.
I need your idea for what function I should add. I only have find, compare, and some idea on mind.
select, add, delete, update
A simple MySQL db select statement might be something like this:
SELECT `field1`, `field2` FROM `table` WHERE `id`=5 ORDER BY `field1` DESC
Hm, MySQL looks like an interpreter for me. I think I will just create a database function, not as advance as mySQL.
Yeah it is rather complex, select (field/row), add (row), delete (row), update (field/row) and maybe a sort (column) would suffice
These are the different types of accesses to data you would likely need to perform
I will create the erase data and all done.
Databases can be awefully complex, I have written many different versions over the years and they still dont account for everything, now-a-days I tend to go for specialised array functions that save to disk rather than full 'database' modules because they integrate somewhere between hard coded memory management and databases
Quote from: oex on January 16, 2010, 11:22:55 AM
Databases can be awefully complex, I have written many different versions over the years and they still dont account for everything, now-a-days I tend to go for specialised array functions that save to disk rather than full 'database' modules because they integrate somewhere between hard coded memory management and databases
Oh, I guess this is not a database then, it was a ...
What should I named it? File packer?
If somebody could create encryption procedure it would be a good folder locker.
Just put the File type value to some value so I can identify it as a readable format.
Okay done, I will create a tiny example for this.
Here is the example I promised, sorry for the delay if you waited. I have no time to make it quick.
Updated. Now the database can be loaded from memory. I Guess this is the final release.