The MASM Forum Archive 2004 to 2012

General Forums => The Laboratory => Topic started by: Farabi on January 16, 2010, 04:34:53 AM

Title: Data Base
Post by: Farabi on January 16, 2010, 04:34:53 AM
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.
Title: Re: Data Base
Post by: oex on January 16, 2010, 07:51:42 AM
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
Title: Re: Data Base
Post by: Farabi on January 16, 2010, 09:54:10 AM
Hm, MySQL looks like an interpreter for me. I think I will just create a database function, not as advance as mySQL.
Title: Re: Data Base
Post by: oex on January 16, 2010, 10:02:38 AM
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
Title: Re: Data Base
Post by: Farabi on January 16, 2010, 11:15:16 AM
I will create the erase data and all done.
Title: Re: Data Base
Post by: 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
Title: Re: Data Base
Post by: Farabi on January 16, 2010, 01:43:34 PM
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.
Title: Re: Data Base
Post by: Farabi on January 17, 2010, 01:19:07 AM
Okay done, I will create a tiny example for this.
Title: Re: Data Base
Post by: Farabi on March 01, 2010, 06:57:41 AM
Here is the example I promised, sorry for the delay if you waited. I have no time to make it quick.
Title: Re: Data Base
Post by: Farabi on June 05, 2010, 09:50:07 PM
Updated. Now the database can be loaded from memory. I Guess this is the final release.