Seite 1 von 1

Datenbankserver

Verfasst: Mo, 15. Okt 2007 14:53
von stevie
Ich erstelle mit
oSrv1 := dsDbServer():new("DiffGS")
ein Server-Object.
Um Dbpack ausführen zu können, muss ich die Db aber exclusive öffnen und möglichst shared.
Wie macht man so was?

Außerdem hätte ich gern gewusst, wie man den Datentyp eines dssle() festlegt. D. h. bei mir sind alle Values "c". Ich brauche sie aber "n", also den Typ den ich eingebe. Wie kann man das tun?

Verfasst: Mo, 15. Okt 2007 15:06
von Jan
Hallo Stevie,

Du musst Dich entscheiden: Exclusive oder Shared. Beides zusammen geht selbstverständlich nicht, die schließen sich gegenseitig aus.

Abgesehen davon muß die Datenbank für Pack bzw. Dbpack() immer Exclusive geöffnet sein.

Jan

Verfasst: Mo, 15. Okt 2007 15:13
von brandelh
Hi,

um das Problem mit PACK (braucht zwingend exclusive) zu umgehen nutzen viele (ich auch) ein Satz recycling. Aber nicht mit set deleted on, denn das ist viel zu langsam, sondern über den Index:

Alle Felder eines 'gelöschten' Satzes werden blank gesetzt.
Der Index sortiert den an den Anfang.
Bei DBSEEK wird er immer übersprungen, nur bei Browsern muss man verhindern dass die leeren Sätze angezeigt werden. Z.B. durch Softseek auf chr(33).
Bevor nun ein append blank für neue Sätze gemacht wird, muss man erst mit GO TOP prüfen ob dort ein leerer Satz vorhanden ist ...

PS: zu Clipper Zeiten (oder bei DBFNTX) habe ich auch schon das Indexfeld mit chr(255) gefüllt, dann sind die leeren Sätze ganz hinten.
Die Abfrage do while ! eof() muss man dann ergänzen auf do while ! eof() .and. ! left(Indexfeld,1) = chr(255)

Verfasst: Mo, 15. Okt 2007 15:18
von Tom
@Hubert: Ich mache das über Indexkonditionen:

Code: Alles auswählen

INDEX ON nr to KDNR FOR !Deleted()
Das wird beim logischen Löschen automatisch mitaktualisiert. Man muß also keine Felder umbefüllen oder ähnliches.

Verfasst: Mo, 15. Okt 2007 15:36
von brandelh
Hi,

ich lösche die Feldinhalte aus Datenschutzgründen - auch wenn eigentlich kein Anwender an die Serverdatei ran kommt.

Von der Handhabung ist die Indexvariante aber sicher die einfachste Art.

Verfasst: Mo, 15. Okt 2007 15:46
von stevie
brandelh hat geschrieben:Hi,

ich lösche die Feldinhalte aus Datenschutzgründen - auch wenn eigentlich kein Anwender an die Serverdatei ran kommt.

Von der Handhabung ist die Indexvariante aber sicher die einfachste Art.
Genau deswegen will ich ja wissen, wie man die Db nun exclusive öffnet. Auch weil die damit bearbeitete dbf weiterverwendet wird.

Verfasst: Mo, 15. Okt 2007 16:21
von Jan
Stevie,

wie oben schon von Hubert und von mir gesagt: Packen geht nur im Exklusiven Modus. Und das heißt: Alle anderen MÜSSEN raus! Das ist ja das, was Exklusiv aussagt: Nur packen, sonst nix.

Jan

Verfasst: Mo, 15. Okt 2007 16:43
von Tom
Hallo, Stevie.

Du arbeitest mit XClass++. Ich habe mir gerade mal die Doku runtergeladen. Um eine Tabelle exclusiv zu öffnen, müßtest Du das Serverobjekt mit OpenDbServer erzeugen:

Code: Alles auswählen

Syntax:  OpenDbServer(uFile, [lAutoIndex], [lShared], [lReadonly], [cDbe], [lMsg], [uSession], [cAlias]) 
Also:

Code: Alles auswählen

oSrv1 := OpenDbServer("DiffGS",,.F.)
für exclusives Öffnen.

Eigentlich gehört dieser Thread nach "3rd Party".

Verfasst: Di, 16. Okt 2007 9:05
von Rolf Ramacher
Hi Stevie,

hier ein Auszug aus meinem code, wie ich die Datenbanken packe.

aDb:=Directory("*.dbf")

oDlg := XbpDialog():new( AppDesktop(), , {150,300}, {300,200}, , .F.)
oDlg:taskList := .T.
oDlg:title :="Datenbanken werden gepackt"
oDlg:create()

drawingArea := oDlg:drawingArea
drawingArea:setFontCompoundName( "9.Arial" )

oStatic := XbpStatic():new( oDlg,, {50, 50}, {150, 30} )
oStatic:options := XBPSTATIC_TEXT_CENTER
oStatic:caption := ""
oStatic:Create()

oDlg:show()
SetAppFocus(oDlg)

For i = 1 to Len(aDb)
cAltFile:=""
cFile:=aDb[1]
nPos:=At(".",cFile)
cDb:=substr(cFile,1,nPos-1)
If Val(cDb)>0
cAltFile:=cDb
cDb:="A"+cAltFile
FRename(cAltFile+".dbf",cDb+".dbf")
EndIf
oStatic:setcaption(cDB)

If Netz_Use((cDb),.t.,"Zugiff")
(cDB)->(DbPack())
Close (cDb)
If !empty(cAltFile)
FRename(cDb+".dbf",cAltFile+".dbf")
EndIf
EndIf
Sleep(001)
Next i
oDlg:destroy()
msgbox("Die Datenbanken wurden bereinigt!","Programmhinweis")
Return Nil


p.s. die Abfrage mit Val() habe ich deshalb, um Datenbanken abzufangen,
die einen numerischen Namen haben.

Verfasst: Di, 16. Okt 2007 12:28
von brandelh
Hallo,

eventuell verstehen wir uns ja auch falsch.

Wenn man verhindern will, dass eine SHARED geöffnete Datei geändert wird während eine Operation abläuft (PACK geht da nicht !), kann man auch die gesamte DBF im Zugriff SPERREN mit FLOCK() geöffnet ist sie immer noch SHARED und andere können sie geöffnet haben aber man kann z.B. Summen berechnen oder mehrere Felder replacen ...