From: <na...@us...> - 2006-11-14 16:16:50
|
Revision: 712 http://svn.sourceforge.net/instantobjects/revision/?rev=712&view=rev Author: nandod Date: 2006-11-14 08:16:43 -0800 (Tue, 14 Nov 2006) Log Message: ----------- * XML broker: now only creates one file for each object, in the concrete class' folder. * XML broker: removed support for versioning and utf-8 "BOT" encoding. * svn:ignore set on a bunch of folders. Modified Paths: -------------- trunk/Source/Brokers/XML/InstantXML.pas trunk/Source/Brokers/XML/InstantXMLConnectionDefEdit.dfm trunk/Source/Brokers/XML/InstantXMLConnectionDefEdit.pas Property Changed: ---------------- trunk/Demos/Intro/ trunk/Demos/PrimerCross/ trunk/Demos/PrimerCross/Model/ trunk/Source/Brokers/BDE/D2006/ trunk/Source/Brokers/DBX/D2006/ trunk/Source/Brokers/IBX/D2006/ trunk/Source/Brokers/XML/ trunk/Source/Brokers/XML/D2006/ trunk/Source/Catalogs/MSSql/D2006/ trunk/Source/Core/ trunk/Source/Design/ trunk/Source/Design/D2006/ trunk/Tests/ trunk/Tests/ubmock/src/ Property changes on: trunk/Demos/Intro ___________________________________________________________________ Name: svn:ignore - *.dcu *.~* *.ddp *.exe + *.dcu *.~* *.ddp *.exe __history *.identcache *.local Property changes on: trunk/Demos/PrimerCross ___________________________________________________________________ Name: svn:ignore - *.dcu *.~* *.ddp *.exe + *.dcu *.~* *.ddp *.exe __history *.identcache *.local Property changes on: trunk/Demos/PrimerCross/Model ___________________________________________________________________ Name: svn:ignore + *.dcu Property changes on: trunk/Source/Brokers/BDE/D2006 ___________________________________________________________________ Name: svn:ignore - *.dcu __history *.local *.cfg + *.dcu __history *.local *.cfg *.identcache Property changes on: trunk/Source/Brokers/DBX/D2006 ___________________________________________________________________ Name: svn:ignore - *.dcu __history *.local *.cfg + *.dcu __history *.local *.cfg *.identcache Property changes on: trunk/Source/Brokers/IBX/D2006 ___________________________________________________________________ Name: svn:ignore - __history *.dcu *.local *.cfg + __history *.dcu *.local *.cfg *.identcache Property changes on: trunk/Source/Brokers/XML ___________________________________________________________________ Name: svn:ignore - *.dcu + *.dcu __history *.~pas Property changes on: trunk/Source/Brokers/XML/D2006 ___________________________________________________________________ Name: svn:ignore - *.dcu __history *.local *.cfg + *.dcu __history *.local *.cfg *.identcache Modified: trunk/Source/Brokers/XML/InstantXML.pas =================================================================== --- trunk/Source/Brokers/XML/InstantXML.pas 2006-11-02 03:51:57 UTC (rev 711) +++ trunk/Source/Brokers/XML/InstantXML.pas 2006-11-14 16:16:43 UTC (rev 712) @@ -51,61 +51,47 @@ XML_EXT = 'xml'; DOT_XML_EXT = '.' + XML_EXT; XML_WILDCARD = '*' + DOT_XML_EXT; -{$IFNDEF LINUX} -{$IFDEF D5}PathDelim = '\'; -{$ENDIF} -{$ENDIF} + {$IFNDEF D6+} + PathDelim = '\'; + {$ENDIF} type - TXMLFileFormat = (xffUtf8, xffUtf8BOT, xffIso); + TXMLFileFormat = (xffUtf8, xffIso); - { TXMLFilesAccessor } TXMLFilesAccessor = class(TCustomConnection) private - FConnected: boolean; + FConnected: Boolean; FRootFolder: string; - FUseVersioning: Boolean; FXMLFileFormat: TXMLFileFormat; - procedure MkStorageDir(const StorageName: string); + procedure CreateStorageDir(const AStorageName: string); function GetRootFolder: string; - procedure SetRootFolder(const Value: string); - function SaveToFileXML_UTF8(AObject: TInstantObject; const FileName: - string): boolean; + procedure SetRootFolder(const AValue: string); + function SaveToFileXML_UTF8(AObject: TInstantObject; + const AFileName: string): Boolean; function LoadFromFileXML_UTF8(AObject: TInstantObject; const FileName: string): boolean; function PlainObjectFileName(const StorageName, ClassName, Id: string): string; - function NewObjectFileName(const StorageName, ClassName, Id: string): - string; - function DeleteObjectFileName(const StorageName, ClassName, Id: string): - string; - function VersionFromFilename(const longfilename: string): Integer; + function ObjectUpdateCountFromFileName(const AFileName: string): Integer; protected procedure DoConnect; override; procedure DoDisconnect; override; function GetConnected: Boolean; override; public constructor Create(AOwner: TComponent); override; - function LastObjectFileName(const StorageName, ClassName, Id: string): - string; function ReadInstantObject(AObject: TInstantObject; const StorageName, - AObjectId: string; - out Version: integer): boolean; - function WriteInstantObject(AObject: TInstantObject; const StorageName: - string; - out Version: integer): boolean; - function DeleteInstantObject(AObject: TInstantObject; const StorageName: - string): boolean; - function Locate(const StorageName, AObjectClassName, AObjectId: string): - Boolean; - function CheckConflict(AObject: TInstantObject; const StorageName, - AObjectId: string): Boolean; - procedure LoadFileList(FFileListAccessor: TStringList; const StorageName: - string); + AObjectId: string; out AObjectUpdateCount: Integer): Boolean; + function WriteInstantObject(AObject: TInstantObject; + const AStorageName: string; out AObjectUpdateCount: Integer): Boolean; + function DeleteInstantObject(AObject: TInstantObject; + const AStorageName: string): Boolean; + function Locate(const AStorageName, AObjectClassName, AObjectId: string): Boolean; + function CheckConflict(AObject: TInstantObject; + const AStorageName, AObjectId: string): Boolean; + procedure LoadFileList(const AFileList: TStringList; + const AStorageNames: TStrings); published property RootFolder: string read GetRootFolder write SetRootFolder; - property UseVersioning: Boolean read FUseVersioning write FUseVersioning - default False; property XMLFileFormat: TXMLFileFormat read FXMLFileFormat write FXMLFileFormat default xffUtf8; end; @@ -113,7 +99,6 @@ TInstantXMLConnectionDef = class(TInstantConnectionBasedConnectionDef) private FRootFolder: string; - FUseVersioning: Boolean; FXMLFileFormat: TXMLFileFormat; protected function CreateConnection(AOwner: TComponent): TCustomConnection; override; @@ -123,8 +108,6 @@ class function ConnectorClass: TInstantConnectorClass; override; published property RootFolder: string read FRootFolder write FRootFolder; - property UseVersioning: Boolean read FUseVersioning write FUseVersioning - default False; property XMLFileFormat: TXMLFileFormat read FXMLFileFormat write FXMLFileFormat default xffUtf8; end; @@ -203,10 +186,9 @@ function Locate(AObject: TObject; const AObjectId: string): Boolean; virtual; function ReadInstantObject(AObject: TInstantObject; const AObjectId: string; - out Version: integer): boolean; - function WriteInstantObject(AObject: TInstantObject; const AObjectId: - string; - out Version: integer): boolean; + out AObjectUpdateCount: Integer): Boolean; + function WriteInstantObject(AObject: TInstantObject; + const AObjectId: string; out AObjectUpdateCount: Integer): Boolean; public constructor Create(ABroker: TInstantCustomRelationalBroker; const AStorageName: string); @@ -225,13 +207,19 @@ FObjectReferenceList: TObjectList; FStatement: string; FParamsObject: TParams; + FStorageNames: TStringList; + FObjectClassNames: TStringList; procedure DestroyObjectReferenceList; function GetObjectReferenceCount: Integer; function GetObjectReferenceList: TObjectList; function GetObjectReferences(Index: Integer): TInstantObjectReference; - procedure InitObjectReferences(FileListAccessor: TStringList); + // Creates an object reference for each item in AFileList that represents + // an object of a class included in FObjectClassNames. + procedure InitObjectReferences(const AFileList: TStrings); function GetParamsObject: TParams; function GetConnector: TInstantXMLConnector; + procedure SetStorageNames(const Value: TStringList); + procedure SetObjectClassNames(const Value: TStringList); protected class function TranslatorClass: TInstantRelationalTranslatorClass; override; function GetActive: Boolean; override; @@ -256,13 +244,16 @@ GetObjectReferences; property ParamsObject: TParams read GetParamsObject; public - StorageName: string; + procedure AfterConstruction; override; + // List of folders from which files should be loaded in InternalOpen. + property StorageNames: TStringList read FStorageNames write SetStorageNames; + // Used to filter by class name the files loaded during InternalOpen. + property ObjectClassNames: TStringList read FObjectClassNames write SetObjectClassNames; destructor Destroy; override; property Connector: TInstantXMLConnector read GetConnector; end; - // Base class for all steps that work by executing one or more commands - // (that is, a script) each. + // Base class for all XML database build commands. TInstantDBBuildXMLCommand = class(TInstantDBBuildCommand) private function GetConnector: TInstantXMLConnector; @@ -306,7 +297,7 @@ SysUtils, InstantConsts, InstantClasses, TypInfo, InstantXMLCatalog, InstantXMLConnectionDefEdit, {$IFDEF MSWINDOWS} -{$IFDEF D5} +{$IFNDEF D6+} FileCtrl, {$ENDIF} Windows, Controls; @@ -321,10 +312,9 @@ function GetFileClassName(const FileName: string): string; forward; function GetFileId(const FileName: string): string; forward; -function GetFileVersion(const FileName: string): Integer; forward; +function GetObjectUpdateCount(const FileName: string): Integer; forward; -{$IFDEF D5} - +{$IFNDEF D6+} function IncludeTrailingPathDelimiter(const S: string): string; begin Result := IncludeTrailingBackSlash(S); @@ -337,7 +327,6 @@ R: Integer; PathWithWildCards: string; begin - FileList.Clear; PathWithWildCards := IncludeTrailingPathDelimiter(Path) + XML_WILDCARD; //Find the first file R := SysUtils.FindFirst(PathWithWildCards, faAnyFile, SearchRec); @@ -352,69 +341,6 @@ end; end; -// fill filelist with unique names of files, using the last version -// number or skipping the deleted files (version = 0) -// code badly needs to be optimized - marcoc - -procedure GlobalLoadFileListLastVersion(const Path: string; FileList: - TStringList); -var - i, currentVersion, activeVersionPos, newVersion: Integer; - currentid, shortFileName: string; -begin - // first load all of them - GlobalLoadFileList(Path, FileList); - - // now remove version duplicates and deleted documents - FileList.Sorted := True; - currentid := ''; - currentVersion := -1; - activeVersionPos := -1; - for i := FileList.Count - 1 downto 0 do - begin - shortFileName := extractFilename(filelist[i]); - if currentid = GetFileId(shortFileName) then - begin - newVersion := GetFileVersion(shortFileName); - // if the file is marked as deleted - if newVersion = 0 then - begin - CurrentVersion := NewVersion; - fileList.Delete(i); - activeVersionPos := 0; - if activeVersionPos <> -1 then - fileList.Delete(activeVersionPos); - end - // if it is already marked as deleted, skip it - else if currentVersion = 0 then - begin - fileList.Delete(i); - end - // if the file is "newer" - else if currentVersion < newVersion then - begin - // delete the other version, as this is newer - CurrentVersion := GetFileVersion(shortFileName); - if activeVersionPos <> -1 then - fileList.Delete(activeVersionPos); - activeVersionPos := i; - end - else - // delete this version, which is older - fileList.Delete(i); - end - else // we have moved to a new objectid, reset all - begin - currentid := GetFileId(shortFileName); - currentVersion := GetFileVersion(shortFileName); - activeVersionPos := i; - // if the first file of this instance is marked as deleted... - if CurrentVersion = 0 then - fileList.Delete(i); - end; - end; -end; - function RightPos(const ASubString, AString: string): Integer; var I: Integer; @@ -450,7 +376,7 @@ Delete(Result, RightPos('.', Result), MaxInt); end; -function GetFileVersion(const FileName: string): Integer; +function GetObjectUpdateCount(const FileName: string): Integer; var S: string; P: Integer; @@ -481,7 +407,6 @@ begin Result := TXMLFilesAccessor.Create(AOwner); TXMLFilesAccessor(Result).RootFolder := RootFolder; - TXMLFilesAccessor(Result).UseVersioning := UseVersioning; TXMLFilesAccessor(Result).FXMLFileFormat := XMLFileFormat; end; @@ -568,7 +493,7 @@ ConflictAction: TInstantConflictAction; Info: PInstantOperationInfo); var AInfo: TInstantOperationInfo; - Version: Integer; + LObjectUpdateCount: Integer; begin if not Assigned(Info) then begin @@ -577,13 +502,13 @@ end; //Read object from file Info.Success := Locate(AObject, AObjectId) and - ReadInstantObject(AObject, AObjectId, Version); + ReadInstantObject(AObject, AObjectId, LObjectUpdateCount); Info.Conflict := not Info.Success; if Info.Success then begin if Map.IsRootMap then begin - Broker.SetObjectUpdateCount(AObject, Version); + Broker.SetObjectUpdateCount(AObject, LObjectUpdateCount); end; end else @@ -625,7 +550,7 @@ Broker.SetObjectUpdateCount(AObject, version); end else - Info.Success := False; + Info.Success := True; except on E: Exception do begin @@ -651,12 +576,11 @@ FStorageName, AObject.ClassName, AObjectId); end; -function TInstantXMLResolver.ReadInstantObject(AObject: TInstantObject; const - AObjectId: string; - out Version: integer): boolean; +function TInstantXMLResolver.ReadInstantObject(AObject: TInstantObject; + const AObjectId: string; out AObjectUpdateCount: Integer): Boolean; begin Result := Broker.Connector.Connection.ReadInstantObject(AObject, FStorageName, - AObjectId, Version); + AObjectId, AObjectUpdateCount); end; procedure TInstantXMLResolver.ResetAttributes(AObject: TInstantObject; @@ -665,12 +589,17 @@ end; -function TInstantXMLResolver.WriteInstantObject(AObject: TInstantObject; const - AObjectId: string; - out Version: integer): boolean; +function TInstantXMLResolver.WriteInstantObject(AObject: TInstantObject; + const AObjectId: string; out AObjectUpdateCount: Integer): Boolean; begin - Result := Broker.Connector.Connection.WriteInstantObject(AObject, - FStorageName, Version); + if AObject.Metadata.TableName = FStorageName then + Result := Broker.Connector.Connection.WriteInstantObject(AObject, + FStorageName, AObjectUpdateCount) + else + begin + Result := True; + AObjectUpdateCount := 1; + end; end; { TInstantXMLConnector } @@ -710,24 +639,12 @@ end; procedure TInstantXMLConnector.InternalBuildDatabase(Scheme: TInstantScheme); -var - i: integer; - StorageName: string; begin CheckConnection; - //build RootFolder if not exists if not DirectoryExists(Connection.RootFolder) and - not ForceDirectories(Connection.RootFolder) then + not ForceDirectories(Connection.RootFolder) then raise EInOutError.CreateFmt(SCannotCreateDirectory, [Connection.RootFolder]); - - //build SubFolder for each "storage name" - for i := 0 to Scheme.TableMetadataCount - 1 do - begin - StorageName := Scheme.TableMetadatas[i].Name; - if not DirectoryExists(Connection.RootFolder + StorageName) then - MkDir(Connection.RootFolder + StorageName); - end; end; procedure TInstantXMLConnector.InternalCommitTransaction; @@ -840,10 +757,23 @@ { TInstantXMLQuery } +procedure TInstantXMLQuery.AfterConstruction; +begin + inherited; + FStorageNames := TStringList.Create; + FStorageNames.Sorted := True; + FStorageNames.Duplicates := dupIgnore; + FObjectClassNames := TStringList.Create; + FObjectClassNames.Sorted := True; + FObjectClassNames.Duplicates := dupIgnore; +end; + destructor TInstantXMLQuery.Destroy; begin DestroyObjectReferenceList; FParamsObject.Free; + FreeAndNil(FStorageNames); + FreeAndNil(FObjectClassNames); inherited; end; @@ -897,31 +827,35 @@ Result := FStatement; end; -procedure TInstantXMLQuery.InitObjectReferences(FileListAccessor: TStringList); +procedure TInstantXMLQuery.InitObjectReferences(const AFileList: TStrings); var - i: integer; + I: Integer; - function CreateObjectReference(const FileName: string): - TInstantObjectReference; + procedure AddObjectReference(const AFileName: string); var - ClassName, ObjectId: string; + vClassName, vObjectId: string; + vObjectReference: TInstantObjectReference; + vIndex: Integer; begin - ClassName := GetFileClassName(FileName); - ObjectId := GetFileId(FileName); - Result := TInstantObjectReference.Create(nil, True); - try - Result.ReferenceObject(ClassName, ObjectId); - except - Result.Free; - raise + vClassName := GetFileClassName(AFileName); + if FObjectClassNames.Find(vClassName, vIndex) then + begin + vObjectId := GetFileId(AFileName); + vObjectReference := TInstantObjectReference.Create(nil, True); + try + vObjectReference.ReferenceObject(vClassName, vObjectId); + ObjectReferenceList.Add(vObjectReference); + except + ObjectReferenceList.Remove(vObjectReference); + vObjectReference.Free; + raise; + end; end; end; begin - for i := 0 to FileListAccessor.Count - 1 do - begin - ObjectReferenceList.Add(CreateObjectReference(FileListAccessor.Strings[i])); - end; + for I := 0 to AFileList.Count - 1 do + AddObjectReference(AFileList[I]); end; function TInstantXMLQuery.InternalAddObject(AObject: TObject): Integer; @@ -978,16 +912,16 @@ procedure TInstantXMLQuery.InternalOpen; var - FFileListAccessor: TStringList; + vFileList: TStringList; begin inherited; - FFileListAccessor := TStringList.Create; + vFileList := TStringList.Create; try Connector.Connection.Open; - Connector.Connection.LoadFileList(FFileListAccessor, StorageName); - InitObjectReferences(FFileListAccessor); + Connector.Connection.LoadFileList(vFileList, FStorageNames); + InitObjectReferences(vFileList); finally - FFileListAccessor.Free; + vFileList.Free; end; end; @@ -1034,6 +968,11 @@ Result := ObjectReferences[Index].HasInstance; end; +procedure TInstantXMLQuery.SetObjectClassNames(const Value: TStringList); +begin + FObjectClassNames.Assign(Value); +end; + procedure TInstantXMLQuery.SetParams(Value: TParams); begin inherited; @@ -1046,6 +985,11 @@ FStatement := Value; end; +procedure TInstantXMLQuery.SetStorageNames(const Value: TStringList); +begin + FStorageNames.Assign(Value); +end; + class function TInstantXMLQuery.TranslatorClass: TInstantRelationalTranslatorClass; begin @@ -1059,16 +1003,16 @@ Result := IncludeTrailingPathDelimiter(FRootFolder); end; -procedure TXMLFilesAccessor.SetRootFolder(const Value: string); +procedure TXMLFilesAccessor.SetRootFolder(const AValue: string); begin - if FRootFolder <> Value then + if FRootFolder <> AValue then begin - FRootFolder := Value; + FRootFolder := AValue; end; end; function TXMLFilesAccessor.SaveToFileXML_UTF8(AObject: TInstantObject; - const FileName: string): boolean; + const AFileName: string): Boolean; var strstream: TStringStream; fileStream: TFileStream; @@ -1077,8 +1021,8 @@ strstream := TStringStream.Create(''); try InstantWriteObject(strStream, sfXML, AObject); -{$IFNDEF VER130} - if FXMLFileFormat in [xffUtf8, xffUtf8Bot] then +{$IFDEF D6+} + if FXMLFileFormat = xffUtf8 then DataStr := AnsiToUtf8(XML_UTF8_HEADER + strStream.DataString) else DataStr := XML_ISO_HEADER + strStream.DataString; @@ -1088,7 +1032,7 @@ finally strStream.Free; end; - fileStream := TFileStream.Create(FileName, fmCreate); + fileStream := TFileStream.Create(AFileName, fmCreate); try Result := fileStream.Write(DataStr[1], Length(DataStr)) <> 0; finally @@ -1116,8 +1060,6 @@ begin fileStream := TFileStream.Create(FileName, fmOpenRead); try - // if FXMLFileFormat = xffUtf8Bot then - // check/skip BOT SetLength(strUtf8, fileStream.Size); Result := fileStream.Read(strUtf8[1], fileStream.Size) <> 0; // skip XML HEADER (until the parser is "dumb") @@ -1126,8 +1068,8 @@ fileStream.Free; end; -{$IFNDEF VER130} - if FXMLFileFormat in [xffUtf8, xffUtf8Bot] then +{$IFDEF D6+} + if FXMLFileFormat = xffUtf8 then strUtf8 := Utf8ToAnsi(strUtf8); {$ENDIF} @@ -1139,223 +1081,86 @@ end; end; -function TXMLFilesAccessor.ReadInstantObject(AObject: TInstantObject; const - StorageName, AObjectId: string; - out Version: integer): boolean; +function TXMLFilesAccessor.ReadInstantObject(AObject: TInstantObject; + const StorageName, AObjectId: string; out AObjectUpdateCount: Integer): Boolean; var - filename: string; + LFileName: string; begin - if FUseVersioning then - filename := LastObjectFileName(StorageName, AObject.ClassName, AObjectId) - else - filename := PlainObjectFileName(StorageName, AObject.ClassName, AObjectId); - Result := LoadFromFileXML_UTF8(AObject, filename); - Version := VersionFromFilename(filename); + LFileName := PlainObjectFileName(StorageName, AObject.ClassName, AObjectId); + Result := LoadFromFileXML_UTF8(AObject, LFileName); + AObjectUpdateCount := ObjectUpdateCountFromFileName(LFileName); end; -function TXMLFilesAccessor.WriteInstantObject(AObject: TInstantObject; const - StorageName: string; - out Version: integer): boolean; +function TXMLFilesAccessor.WriteInstantObject(AObject: TInstantObject; + const AStorageName: string; out AObjectUpdateCount: Integer): Boolean; var - filename: string; + LFileName: string; begin - MkStorageDir(StorageName); - if FUseVersioning then - filename := NewObjectFileName(StorageName, AObject.ClassName, AObject.Id) - else - filename := PlainObjectFileName(StorageName, AObject.ClassName, AObject.Id); - Result := SavetoFileXML_UTF8(AObject, filename); - Version := VersionFromFilename(filename); + CreateStorageDir(AStorageName); + LFileName := PlainObjectFileName(AStorageName, AObject.ClassName, AObject.Id); + Result := SavetoFileXML_UTF8(AObject, LFileName); + AObjectUpdateCount := ObjectUpdateCountFromFileName(LFileName); end; -function TXMLFilesAccessor.Locate(const StorageName, AObjectClassName, +function TXMLFilesAccessor.Locate(const AStorageName, AObjectClassName, AObjectId: string): Boolean; var filename: string; begin - MkStorageDir(StorageName); - if FUseVersioning then - begin - filename := LastObjectFileName(StorageName, AObjectClassName, AObjectId); - Result := FileExists(filename) and (VersionFromFilename(filename) <> 0); - end - else - begin - filename := PlainObjectFileName(StorageName, AObjectClassName, AObjectId); - Result := FileExists(filename); - end; + filename := PlainObjectFileName(AStorageName, AObjectClassName, AObjectId); + Result := FileExists(filename); end; -procedure TXMLFilesAccessor.MkStorageDir(const StorageName: string); +procedure TXMLFilesAccessor.CreateStorageDir(const AStorageName: string); begin - if not DirectoryExists(RootFolder + StorageName) then - MkDir(RootFolder + StorageName); + if not DirectoryExists(RootFolder + AStorageName) then + MkDir(RootFolder + AStorageName); end; -function TXMLFilesAccessor.LastObjectFileName(const StorageName, ClassName, - Id: string): string; -var - sr: TSearchRec; - lastnum, nCurrent: Integer; +function TXMLFilesAccessor.ObjectUpdateCountFromFileName( + const AFileName: string): Integer; begin - if FindFirst( - RootFolder + StorageName + PathDelim + ClassName + '.' + Id + '.*' + - DOT_XML_EXT, - faAnyFile, SR) = 0 then - try - Result := RootFolder + StorageName + PathDelim + sr.Name; - lastnum := VersionFromFileName(sr.Name); - while FindNext(sr) = 0 do - begin - nCurrent := VersionFromFilename(sr.Name); - // version "zero" means the file has been deleted - if (nCurrent = 0) then - begin - Result := RootFolder + StorageName + PathDelim + sr.Name; - Break; - end; - if nCurrent > lastnum then - begin - lastnum := nCurrent; - Result := RootFolder + StorageName + PathDelim + sr.Name; - end; - end; - finally - SysUtils.FindClose(sr); - end - else - Result := ''; // not found, new object/file + Result := GetObjectUpdateCount(ExtractFileName(AFileName)); end; -function TXMLFilesAccessor.VersionFromFilename(const longfilename: string): - Integer; -begin - Result := GetFileVersion(ExtractFileName(longfilename)); -end; - -function TXMLFilesAccessor.NewObjectFileName(const StorageName, ClassName, - Id: string): string; -var - nVersion: Integer; - filename: string; -begin - // grab the current "last" version number - if FUseVersioning then - begin - filename := LastObjectFileName(storagename, ClassName, Id); - if filename <> '' then - begin - nVersion := VersionFromFilename(filename); - inc(nVersion); - end - else - nVersion := 1; // new object, first version - end - else - begin - filename := PlainObjectFileName(StorageName, ClassName, Id); - nVersion := 1; // no version always 1 - end; - Result := RootFolder + StorageName + PathDelim + ClassName + '.' + Id + '.' + - IntToStr(nVersion) + DOT_XML_EXT; -end; - function TXMLFilesAccessor.DeleteInstantObject(AObject: TInstantObject; - const StorageName: string): boolean; + const AStorageName: string): Boolean; begin - if UseVersioning then - begin - // save the document once more with 0 in the version name - Result := SavetoFileXML_UTF8(AObject, - DeleteObjectFileName(StorageName, AObject.ClassName, AObject.Id)); - end - else - begin - // delete file from disk - Result := SysUtils.DeleteFile(PlainObjectFileName(StorageName, - AObject.ClassName, AObject.Id)); - end; + Result := SysUtils.DeleteFile(PlainObjectFileName(AStorageName, + AObject.ClassName, AObject.Id)); end; -function TXMLFilesAccessor.DeleteObjectFileName(const StorageName, - ClassName, Id: string): string; -begin - // mark deleted file as version 0 - Result := RootFolder + StorageName + PathDelim + ClassName + '.' + Id + '.' + - IntToStr(0) + DOT_XML_EXT; -end; - constructor TXMLFilesAccessor.Create(AOwner: TComponent); begin inherited; - - // default values for properties - FUseVersioning := False; FXMLFileFormat := xffUtf8; end; function TXMLFilesAccessor.PlainObjectFileName(const StorageName, ClassName, Id: string): string; begin - // ignore versioning - //FileName: ClassName.Id.UpdateCount.xml Result := RootFolder + StorageName + PathDelim + ClassName + '.' + Id + '.1' + DOT_XML_EXT; end; function TXMLFilesAccessor.CheckConflict(AObject: TInstantObject; - const StorageName, AObjectId: string): Boolean; -var - version: Integer; + const AStorageName, AObjectId: string): Boolean; begin - if FUseVersioning then - begin - // check version of XML object - version := GetFileVersion(LastObjectFileName - (StorageName, AObject.ClassName, AObjectId)); - Result := (version = 0) or (Version <> AObject.UpdateCount); - end - else - Result := False; // don't care about updatecount and versioning + Result := False; // don't care about updatecount end; -procedure TXMLFilesAccessor.LoadFileList(FFileListAccessor: TStringList; const - StorageName: string); -//var - // xmldom: TGeoXslProcess; - to be finished by marcoc - //strXPath, - to be finished by marcoc - // result: string; - // posOpenSquare, posCloseSquare: Integer; +procedure TXMLFilesAccessor.LoadFileList(const AFileList: TStringList; + const AStorageNames: TStrings); +var + I: Integer; begin - if FUseVersioning then - GlobalLoadFileListLastVersion(RootFolder + StorageName, FFileListAccessor) - else - GlobalLoadFileList(RootFolder + StorageName, FFileListAccessor); - - // tentative XPATH support by marcoc - {posOpenSquare := Pos ('[', Statement); - to be finished by marcoc - posCloseSquare := Pos (']', Statement); - strXPath := Copy (Statement, posOpenSquare, posCloseSquare - posOpenSquare + 1); - strXpath := '/' + GetObjectClassName + strXPath; - for i := FFileListAccessor.Count - 1 downto 0 do - begin - xmldom := TGeoXslProcess.Create; - try - xmldom.LoadXmlFile(Connector.Connection.RootFolder+StorageName + - PathDelim + FFileListAccessor[i]); - result := xmldom.applyXPathToXml(strXpath); - if result = '' then - FFileListAccessor.Delete (i); - finally - xmldom.Free; - end; - end; - to be finished by marcoc } - + AFileList.Clear; + for I := 0 to AStorageNames.Count - 1 do + GlobalLoadFileList(RootFolder + AStorageNames[I], AFileList); end; procedure TXMLFilesAccessor.DoConnect; begin - //Check rootfolder if DirectoryExists(RootFolder) then FConnected := True; end; @@ -1374,12 +1179,38 @@ function TInstantXMLTranslator.TranslateClassRef( ClassRef: TInstantIQLClassRef; Writer: TInstantIQLWriter): Boolean; +var + vInheritedClasses: TList; + I: Integer; begin Result := inherited TranslateClassRef(ClassRef, Writer); if TablePathCount > 0 then - (Query as TInstantXMLQuery).StorageName := ClassTablePath + begin + (Query as TInstantXMLQuery).StorageNames.Text := TablePaths[0]; + (Query as TInstantXMLQuery).ObjectClassNames.Text := ClassRef.ObjectClassName; + if ClassRef.Any then + begin + // Need to add all inherited classes as well. + vInheritedClasses := TList.Create; + try + InstantGetClasses(vInheritedClasses, InstantFindClass(ClassRef.ObjectClassName)); + for I := 0 to vInheritedClasses.Count - 1 do + begin + (Query as TInstantXMLQuery).StorageNames.Add( + TInstantObjectClass(vInheritedClasses[I]).Metadata.TableName); + (Query as TInstantXMLQuery).ObjectClassNames.Add( + TInstantObjectClass(vInheritedClasses[I]).ClassName); + end; + finally + FreeAndNil(vInheritedClasses); + end; + end; + end else - (Query as TInstantXMLQuery).StorageName := ''; + begin + (Query as TInstantXMLQuery).StorageNames.Clear; + (Query as TInstantXMLQuery).ObjectClassNames.Clear; + end; end; { TInstantDBBuildXMLCommand } @@ -1420,14 +1251,12 @@ Connector.CheckConnection; vDatabaseName := Connector.DatabaseName; - //build RootFolder if not exists if not DirectoryExists(vDatabaseName) and - not ForceDirectories(vDatabaseName) then + not ForceDirectories(vDatabaseName) then raise EInOutError.CreateFmt(SCannotCreateDirectory, [vDatabaseName]); - // Create a subFolder for the "storage name" - if not DirectoryExists(vDatabaseName + TableMetadata.Name) then - MkDir(vDatabaseName + TableMetadata.Name); + // No need to create the class-specific folders, which will be created + // when instances are written. end; function TInstantDBBuildXMLDropTableCommand.GetTableMetadata: Modified: trunk/Source/Brokers/XML/InstantXMLConnectionDefEdit.dfm =================================================================== --- trunk/Source/Brokers/XML/InstantXMLConnectionDefEdit.dfm 2006-11-02 03:51:57 UTC (rev 711) +++ trunk/Source/Brokers/XML/InstantXMLConnectionDefEdit.dfm 2006-11-14 16:16:43 UTC (rev 712) @@ -1,9 +1,9 @@ object InstantXMLConnectionDefEditForm: TInstantXMLConnectionDefEditForm Left = 425 Top = 292 - Width = 302 - Height = 190 Caption = 'XML Connection' + ClientHeight = 133 + ClientWidth = 294 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -17,7 +17,7 @@ TextHeight = 13 object BottomBevel: TBevel Left = 0 - Top = 133 + Top = 103 Width = 294 Height = 2 Align = alBottom @@ -27,7 +27,7 @@ Left = 0 Top = 0 Width = 294 - Height = 133 + Height = 103 Align = alClient BevelOuter = bvNone TabOrder = 0 @@ -41,7 +41,7 @@ end object Label1: TLabel Left = 8 - Top = 83 + Top = 60 Width = 69 Height = 13 Caption = 'XML &encoding' @@ -63,27 +63,19 @@ TabOrder = 1 OnClick = FolderButtonClick end - object cbVersioning: TCheckBox + object EncodingComboBox: TComboBox Left = 8 - Top = 60 - Width = 149 - Height = 17 - Caption = 'Enable file versioning' - TabOrder = 2 - end - object cbEncoding: TComboBox - Left = 8 - Top = 98 + Top = 75 Width = 145 Height = 21 Style = csDropDownList - ItemHeight = 13 - TabOrder = 3 + ItemHeight = 0 + TabOrder = 2 end end object BottomPanel: TPanel Left = 0 - Top = 135 + Top = 105 Width = 294 Height = 28 Align = alBottom Modified: trunk/Source/Brokers/XML/InstantXMLConnectionDefEdit.pas =================================================================== --- trunk/Source/Brokers/XML/InstantXMLConnectionDefEdit.pas 2006-11-02 03:51:57 UTC (rev 711) +++ trunk/Source/Brokers/XML/InstantXMLConnectionDefEdit.pas 2006-11-14 16:16:43 UTC (rev 712) @@ -48,12 +48,7 @@ QForms, QStdCtrls, QControls, QExtCtrls; {$ENDIF} -const - AXMLFileFormatStr : Array[TXMLFileFormat] of string = - ('xffUtf8', 'xffUtf8BOT', 'xffIso'); - type - TInstantXMLConnectionDefEditForm = class(TForm) BottomBevel: TBevel; BottomPanel: TPanel; @@ -64,8 +59,7 @@ ButtonsPanel: TPanel; OkButton: TButton; CancelButton: TButton; - cbVersioning: TCheckBox; - cbEncoding: TComboBox; + EncodingComboBox: TComboBox; Label1: TLabel; procedure FolderButtonClick(Sender: TObject); procedure FormCreate(Sender: TObject); @@ -80,6 +74,7 @@ {$R *.dfm} uses + TypInfo, {$IFDEF MSWINDOWS} FileCtrl; {$ELSE} @@ -91,19 +86,15 @@ procedure TInstantXMLConnectionDefEditForm.LoadData( ConnectionDef: TInstantXMLConnectionDef); begin - { TODO: Copy data from ConnectionDef to edit controls } RootDirEdit.Text := ConnectionDef.RootFolder; - cbEncoding.ItemIndex := Ord(ConnectionDef.XMLFileFormat); - cbVersioning.Checked := ConnectionDef.UseVersioning; + EncodingComboBox.ItemIndex := Ord(ConnectionDef.XMLFileFormat); end; procedure TInstantXMLConnectionDefEditForm.SaveData( ConnectionDef: TInstantXMLConnectionDef); begin - { TODO: Copy data from edit controls to ConnectionDef } ConnectionDef.RootFolder := RootDirEdit.Text; - ConnectionDef.XMLFileFormat := TXMLFileFormat(cbEncoding.ItemIndex); - ConnectionDef.UseVersioning := cbVersioning.Checked; + ConnectionDef.XMLFileFormat := TXMLFileFormat(EncodingComboBox.ItemIndex); end; procedure TInstantXMLConnectionDefEditForm.FolderButtonClick( @@ -134,12 +125,10 @@ procedure TInstantXMLConnectionDefEditForm.InitXMLEncoding; var - i : TXMLFileFormat; + I: TXMLFileFormat; begin - for i := Low(TXMLFileFormat) to High(TXMLFileFormat) do - begin - cbEncoding.Items.Add(AXMLFileFormatStr[i]); - end; + for I := Low(TXMLFileFormat) to High(TXMLFileFormat) do + EncodingComboBox.Items.Add(GetEnumName(TypeInfo(TXMLFileFormat), Ord(I))); end; end. Property changes on: trunk/Source/Catalogs/MSSql/D2006 ___________________________________________________________________ Name: svn:ignore - *.local *.dcu + *.local *.dcu *.identcache Property changes on: trunk/Source/Core ___________________________________________________________________ Name: svn:ignore - *.dcu *.~* *.ddp + *.dcu *.~* *.ddp __history Property changes on: trunk/Source/Design ___________________________________________________________________ Name: svn:ignore - *.dcu *.~* *.ddp + *.dcu *.~* *.ddp __history Property changes on: trunk/Source/Design/D2006 ___________________________________________________________________ Name: svn:ignore - *.local *.cfg *.dcu + *.local *.cfg *.dcu *.identcache Property changes on: trunk/Tests ___________________________________________________________________ Name: svn:ignore - __history *.dcu *.local *.exe + __history *.dcu *.local *.exe *.identcache Property changes on: trunk/Tests/ubmock/src ___________________________________________________________________ Name: svn:ignore - *.rst + *.rst *.dcu |