80 |
|
TIBLocalOption = (iblAutoUpgrade, iblAllowDowngrade, iblQuiet); |
81 |
|
TIBLocalOptions = set of TIBLocalOption; |
82 |
|
|
83 |
+ |
EIBLocalException = class(Exception); |
84 |
+ |
|
85 |
|
|
86 |
|
{ TCustomIBLocalDBSupport } |
87 |
|
|
108 |
|
FDownGradeArchive: string; |
109 |
|
FSharedDataDir: string; |
110 |
|
FUpgradeConf: TUpgradeConfFile; |
111 |
+ |
FInCreateNew: boolean; |
112 |
+ |
FSavedAfterConnect: TNotifyEvent; |
113 |
+ |
FSavedAfterDisconnect: TNotifyEvent; |
114 |
+ |
FSavedBeforeConnect: TNotifyEvent; |
115 |
+ |
FSavedBeforeDisconnect: TNotifyEvent; |
116 |
|
procedure CheckEnabled; |
117 |
|
procedure CreateDatabase(DBName: string; DBParams: TStrings; Overwrite: boolean); |
118 |
|
function GetDatabase: TIBDatabase; |
119 |
+ |
function GetSharedDataDir: string; |
120 |
|
procedure SetDatabase(AValue: TIBDatabase); |
121 |
|
function GetDBNameAndPath: string; |
122 |
|
procedure InitDatabaseParameters(DBParams: TStrings; |
131 |
|
procedure SetFirebirdDirectory(AValue: string); |
132 |
|
procedure SetupFirebirdEnv; |
133 |
|
procedure UpgradeCheck; |
134 |
+ |
procedure SaveEvents; |
135 |
+ |
procedure RestoreEvents; |
136 |
|
protected |
137 |
|
{ Protected declarations } |
138 |
|
function AllowInitialisation: boolean; virtual; |
139 |
|
function AllowRestore: boolean; virtual; |
140 |
|
procedure CreateDir(DirName: string); |
141 |
< |
function CreateNewDatabase(DBName:string; DBParams: TStrings; DBArchive: string): boolean; virtual; abstract; |
142 |
< |
procedure HandleGetParamValue(Sender: TObject; ParamName: string; var BlobID: TISC_QUAD); |
141 |
> |
function InternalCreateNewDatabase(DBName:string; DBParams: TStrings; DBArchive: string): boolean; virtual; abstract; |
142 |
> |
function CreateNewDatabase(DBName:string; DBParams: TStrings; DBArchive: string): boolean; |
143 |
|
procedure Downgrade(DBArchive: string); virtual; |
144 |
|
procedure DowngradeDone; |
145 |
|
procedure Loaded; override; |
176 |
|
is prompted for archive filename if filename empty.} |
177 |
|
procedure SaveDatabase(filename: string = ''); |
178 |
|
|
169 |
– |
{Copies database parameters as give in the DBParams to the Service |
170 |
– |
omitting any parameters not appropriate for TIBService. Typically, the |
171 |
– |
DBParams are TIBDatabase.Params} |
172 |
– |
class procedure SetDBParams(aService: TIBCustomService; DBParams: TStrings); |
173 |
– |
|
179 |
|
property ActiveDatabasePathName: string read FActiveDatabasePathName; |
180 |
|
property CurrentDBVersionNo: integer read FCurrentDBVersionNo; |
181 |
+ |
property SharedDataDir: string read GetSharedDataDir; |
182 |
|
|
183 |
|
{ Likely to be Published declarations } |
184 |
|
property Database: TIBDatabase read GetDatabase write SetDatabase; |
200 |
|
|
201 |
|
implementation |
202 |
|
|
203 |
< |
uses DB, IBBlob, ZStream |
204 |
< |
{$IFDEF Unix} ,initc, regexpr {$ENDIF} |
199 |
< |
{$IFDEF WINDOWS} ,Windows ,Windirs {$ENDIF}; |
203 |
> |
{$IFDEF Unix} uses initc, regexpr {$ENDIF} |
204 |
> |
{$IFDEF WINDOWS} uses Windows ,Windirs {$ENDIF}; |
205 |
|
|
206 |
|
resourcestring |
207 |
|
sNoDowngrade = 'Database Schema is %d. Unable to downgrade to version %d'; |
208 |
|
sLocalDBDisabled = 'Local Database Access Disabled'; |
209 |
|
sEmptyDBArchiveMissing = 'Unable to create database - no empty DB archive specified'; |
210 |
< |
sEmptyDBArchiveNotFound = 'Unable to create database - empty DB archive file not found'; |
210 |
> |
sEmptyDBArchiveNotFound = 'Unable to create database - empty DB archive file (%s) not found'; |
211 |
|
sNoEmbeddedServer = 'Firebird Embedded Server is required but is not installed'; |
212 |
+ |
sCreateFailed = 'Unable to Create Personal Database'; |
213 |
|
|
214 |
|
{ TCustomIBLocalDBSupport } |
215 |
|
|
216 |
|
|
211 |
– |
procedure TCustomIBLocalDBSupport.HandleGetParamValue(Sender: TObject; |
212 |
– |
ParamName: string; var BlobID: TISC_QUAD); |
213 |
– |
var Blob: TIBBlobStream; |
214 |
– |
Source: TStream; |
215 |
– |
FileName: string; |
216 |
– |
begin |
217 |
– |
Blob := TIBBlobStream.Create; |
218 |
– |
try |
219 |
– |
Blob.Database := (Sender as TIBXScript).Database; |
220 |
– |
Blob.Transaction := (Sender as TIBXScript).Transaction; |
221 |
– |
Blob.Mode := bmWrite; |
222 |
– |
if not assigned(UpgradeConf) or |
223 |
– |
not UpgradeConf.GetSourceFile(ParamName,FileName) then Exit; |
224 |
– |
|
225 |
– |
if CompareText(ExtractFileExt(FileName),'.gz') = 0 then {gzip compressed file} |
226 |
– |
Source := TGZFileStream.Create(FileName,gzopenread) |
227 |
– |
else |
228 |
– |
Source := TFileStream.Create(FileName,fmOpenRead or fmShareDenyNone); |
229 |
– |
try |
230 |
– |
Blob.CopyFrom(Source,0) |
231 |
– |
finally |
232 |
– |
Source.Free |
233 |
– |
end; |
234 |
– |
Blob.Finalize; |
235 |
– |
BlobID := Blob.BlobID |
236 |
– |
finally |
237 |
– |
Blob.Free |
238 |
– |
end |
239 |
– |
end; |
240 |
– |
|
217 |
|
procedure TCustomIBLocalDBSupport.CheckEnabled; |
218 |
|
begin |
219 |
|
if not Enabled then |
220 |
< |
raise Exception.Create(sLocalDBDisabled); |
220 |
> |
raise EIBLocalException.Create(sLocalDBDisabled); |
221 |
|
end; |
222 |
|
|
223 |
|
procedure TCustomIBLocalDBSupport.CreateDatabase(DBName: string; DBParams: TStrings; |
227 |
|
CheckEnabled; |
228 |
|
DBArchive := EmptyDBArchive; |
229 |
|
if DBArchive = '' then |
230 |
< |
raise Exception.Create(sEmptyDBArchiveMissing); |
230 |
> |
raise EIBLocalException.Create(sEmptyDBArchiveMissing); |
231 |
|
|
232 |
|
if not TUpgradeConfFile.IsAbsolutePath(DBArchive) then |
233 |
< |
DBArchive := FSharedDataDir + DBArchive; |
233 |
> |
DBArchive := SharedDataDir + DBArchive; |
234 |
|
|
235 |
|
if not FileExists(DBArchive) then |
236 |
< |
raise Exception.Create(sEmptyDBArchiveNotFound); |
236 |
> |
raise EIBLocalException.CreateFmt(sEmptyDBArchiveNotFound,[DBArchive]); |
237 |
|
|
238 |
|
if FileExists(DBName) then |
239 |
|
begin |
243 |
|
end; |
244 |
|
|
245 |
|
SetupFirebirdEnv; |
246 |
< |
CreateNewDatabase(DBName,DBParams,DBArchive); |
247 |
< |
FNewDBCreated := true; |
246 |
> |
SaveEvents; |
247 |
> |
try |
248 |
> |
if not CreateNewDatabase(DBName,DBParams,DBArchive) then |
249 |
> |
begin |
250 |
> |
Database.Connected := true; |
251 |
> |
Database.DropDatabase; |
252 |
> |
raise EIBLocalException.Create(sCreateFailed); |
253 |
> |
end |
254 |
> |
else |
255 |
> |
FNewDBCreated := true; |
256 |
> |
finally |
257 |
> |
RestoreEvents; |
258 |
> |
end; |
259 |
|
end; |
260 |
|
|
261 |
|
function TCustomIBLocalDBSupport.GetDatabase: TIBDatabase; |
263 |
|
Result := FIBBase.Database; |
264 |
|
end; |
265 |
|
|
266 |
+ |
function TCustomIBLocalDBSupport.GetSharedDataDir: string; |
267 |
+ |
begin |
268 |
+ |
if FSharedDataDir = '' then |
269 |
+ |
FSharedDataDir := MapSharedDataDir(ExtractFilePath(ParamStr(0))); |
270 |
+ |
Result := FSharedDataDir; |
271 |
+ |
end; |
272 |
+ |
|
273 |
|
procedure TCustomIBLocalDBSupport.SetDatabase(AValue: TIBDatabase); |
274 |
|
begin |
275 |
|
FIBBase.Database := AValue; |
284 |
|
{$IFDEF UNIX} |
285 |
|
|
286 |
|
{Under Unix transform application exe paths that are in installed locations |
287 |
< |
e.g. /usr/local/bin to corresponding shared data locations ee.g. /usr/local/shared} |
287 |
> |
e.g. /usr/local/bin to corresponding shared data locations e.g. /usr/local/shared} |
288 |
|
RegexObj := TRegExpr.Create; |
289 |
|
try |
290 |
|
RegexObj.Expression := '^/usr(/local|)/(s|)bin/.*$'; |
294 |
|
RegexObj.Free; |
295 |
|
end; |
296 |
|
{$ENDIF} |
297 |
< |
if assigned (OnGetSharedDataDir) then |
297 |
> |
if assigned (FOnGetSharedDataDir) then |
298 |
|
OnGetSharedDataDir(self,Result); |
299 |
+ |
{Ensure a trailing separator} |
300 |
+ |
if (Length(Result) > 0) and (Result[Length(Result)] <> DirectorySeparator) then |
301 |
+ |
Result := Result + DirectorySeparator; |
302 |
|
end; |
303 |
|
|
304 |
|
{$IFDEF Unix} |
324 |
|
procedure TCustomIBLocalDBSupport.OnBeforeDatabaseConnect(Sender: TObject; |
325 |
|
DBParams: TStrings; var DBName: string); |
326 |
|
begin |
327 |
< |
if not Enabled or (csDesigning in ComponentState) then Exit; |
327 |
> |
if FInCreateNew or not Enabled or (csDesigning in ComponentState) then Exit; |
328 |
|
|
329 |
|
if not FirebirdAPI.IsEmbeddedServer then |
330 |
|
raise EIBLocalFatalError.Create(sNoEmbeddedServer); |
359 |
|
end; |
360 |
|
|
361 |
|
procedure TCustomIBLocalDBSupport.SetupFirebirdEnv; |
362 |
+ |
var sdd: string; |
363 |
|
begin |
364 |
|
if sysutils.GetEnvironmentVariable('FIREBIRD') = '' then |
365 |
|
begin |
366 |
|
if FirebirdDirectory <> '' then |
367 |
|
begin |
368 |
|
if not TUpgradeConfFile.IsAbsolutePath(FirebirdDirectory) then |
369 |
< |
FirebirdDirectory := FSharedDataDir + FirebirdDirectory; |
369 |
> |
FirebirdDirectory := SharedDataDir + FirebirdDirectory; |
370 |
|
if FileExists(FirebirdDirectory + DirectorySeparator + 'firebird.conf') then |
371 |
|
begin |
372 |
|
SetEnvironmentVariable('FIREBIRD',PChar(FirebirdDirectory)); |
373 |
|
Exit; |
374 |
|
end; |
375 |
|
end; |
376 |
< |
if FileExists(FSharedDataDir + 'firebird.conf') then |
377 |
< |
SetEnvironmentVariable('FIREBIRD',PChar(FSharedDataDir)); |
376 |
> |
if FileExists(SharedDataDir + 'firebird.conf') then |
377 |
> |
begin |
378 |
> |
sdd := SharedDataDir; |
379 |
> |
SetEnvironmentVariable('FIREBIRD',PChar(sdd)); |
380 |
> |
end; |
381 |
|
end; |
382 |
|
end; |
383 |
|
|
394 |
|
PerformUpgrade(RequiredVersionNo); |
395 |
|
end; |
396 |
|
|
397 |
+ |
procedure TCustomIBLocalDBSupport.SaveEvents; |
398 |
+ |
begin |
399 |
+ |
FSavedAfterConnect := Database.AfterConnect; |
400 |
+ |
Database.AfterConnect := nil; |
401 |
+ |
FSavedAfterDisconnect := Database.AfterDisconnect; |
402 |
+ |
Database.AfterDisconnect := nil; |
403 |
+ |
FSavedBeforeConnect := Database.BeforeConnect; |
404 |
+ |
Database.BeforeConnect := nil; |
405 |
+ |
FSavedBeforeDisconnect := Database.BeforeDisconnect; |
406 |
+ |
Database.BeforeDisconnect := nil; |
407 |
+ |
end; |
408 |
+ |
|
409 |
+ |
procedure TCustomIBLocalDBSupport.RestoreEvents; |
410 |
+ |
begin |
411 |
+ |
Database.AfterConnect := FSavedAfterConnect; |
412 |
+ |
Database.AfterDisconnect := FSavedAfterDisconnect; |
413 |
+ |
Database.BeforeConnect := FSavedBeforeConnect; |
414 |
+ |
Database.BeforeDisconnect := FSavedBeforeDisconnect; |
415 |
+ |
end; |
416 |
+ |
|
417 |
|
function TCustomIBLocalDBSupport.AllowInitialisation: boolean; |
418 |
|
begin |
419 |
|
Result := true; |
434 |
|
mkdir(DirName); |
435 |
|
end; |
436 |
|
|
437 |
+ |
function TCustomIBLocalDBSupport.CreateNewDatabase(DBName: string; |
438 |
+ |
DBParams: TStrings; DBArchive: string): boolean; |
439 |
+ |
begin |
440 |
+ |
Result := false; |
441 |
+ |
if FInCreateNew then Exit; |
442 |
+ |
FInCreateNew := true; |
443 |
+ |
try |
444 |
+ |
Result := InternalCreateNewDatabase(DBName,DBParams,DBArchive); |
445 |
+ |
finally |
446 |
+ |
FInCreateNew := false; |
447 |
+ |
end; |
448 |
+ |
end; |
449 |
+ |
|
450 |
|
procedure TCustomIBLocalDBSupport.Downgrade(DBArchive: string); |
451 |
|
begin |
452 |
|
FDownGradeArchive := DBArchive; |
501 |
|
FDatabaseName := ExtractFileName(AValue); |
502 |
|
end; |
503 |
|
|
470 |
– |
class procedure TCustomIBLocalDBSupport.SetDBParams(aService: TIBCustomService; |
471 |
– |
DBParams: TStrings); |
472 |
– |
var i: integer; |
473 |
– |
j: integer; |
474 |
– |
k: integer; |
475 |
– |
ParamName: string; |
476 |
– |
begin |
477 |
– |
aService.Params.Clear; |
478 |
– |
for i := 0 to DBParams.Count - 1 do |
479 |
– |
begin |
480 |
– |
ParamName := DBParams[i]; |
481 |
– |
k := Pos('=',ParamName); |
482 |
– |
if k > 0 then system.Delete(ParamName,k,Length(ParamName)-k+1); |
483 |
– |
for j := 1 to isc_spb_last_spb_constant do |
484 |
– |
if ParamName = SPBConstantNames[j] then |
485 |
– |
begin |
486 |
– |
aService.Params.Add(DBParams[i]); |
487 |
– |
break; |
488 |
– |
end; |
489 |
– |
end; |
490 |
– |
end; |
491 |
– |
|
504 |
|
function TCustomIBLocalDBSupport.UpdateVersionNo: boolean; |
505 |
|
begin |
506 |
|
Result := assigned(OnGetDBVersionNo); |
518 |
|
FIBBase.AfterDatabaseDisconnect := @OnAfterDatabaseDisconnect; |
519 |
|
FUpgradeConfFile := 'upgrade.conf'; |
520 |
|
FOptions := [iblAutoUpgrade, iblAllowDowngrade]; |
509 |
– |
FSharedDataDir := MapSharedDataDir(ExtractFilePath(ParamStr(0))); |
521 |
|
end; |
522 |
|
|
523 |
|
destructor TCustomIBLocalDBSupport.Destroy; |
568 |
|
if Result = '' then Exit; |
569 |
|
|
570 |
|
if not TUpgradeConfFile.IsAbsolutePath(Result) then |
571 |
< |
Result := FSharedDataDir + Result; |
571 |
> |
Result := SharedDataDir + Result; |
572 |
|
end; |
573 |
|
|
574 |
|
begin |