240 |
|
procedure CloseDataSets; |
241 |
|
procedure CheckActive; |
242 |
|
procedure CheckInactive; |
243 |
< |
procedure CreateDatabase; |
243 |
> |
procedure CreateDatabase; overload; |
244 |
> |
procedure CreateDatabase(createDatabaseSQL: string); overload; |
245 |
|
procedure DropDatabase; |
246 |
|
procedure ForceClose; |
247 |
|
procedure GetFieldNames(const TableName: string; List: TStrings); |
476 |
|
implementation |
477 |
|
|
478 |
|
uses IBSQLMonitor, IBCustomDataSet, IBDatabaseInfo, IBSQL, IBUtils, |
479 |
< |
typInfo, FBMessages, IBErrorCodes; |
479 |
> |
typInfo, FBMessages, IBErrorCodes, RegExpr; |
480 |
|
|
481 |
|
{ TIBDatabase } |
482 |
|
|
610 |
|
Connected := true; |
611 |
|
end; |
612 |
|
|
613 |
+ |
procedure TIBDataBase.CreateDatabase(createDatabaseSQL: string); |
614 |
+ |
var RegexObj: TRegExpr; |
615 |
+ |
begin |
616 |
+ |
CheckInactive; |
617 |
+ |
FAttachment := FirebirdAPI.CreateDatabase(createDatabaseSQL,FSQLDialect); |
618 |
+ |
RegexObj := TRegExpr.Create; |
619 |
+ |
try |
620 |
+ |
{extact database file spec} |
621 |
+ |
RegexObj.ModifierG := false; {turn off greedy matches} |
622 |
+ |
RegexObj.Expression := '^ *CREATE +(DATABASE|SCHEMA) +''(.*)'''; |
623 |
+ |
if RegexObj.Exec(AnsiUpperCase(createDatabaseSQL)) then |
624 |
+ |
FDBName := system.copy(createDatabaseSQL,RegexObj.MatchPos[2],RegexObj.MatchLen[2]); |
625 |
+ |
finally |
626 |
+ |
RegexObj.Free; |
627 |
+ |
end; |
628 |
+ |
if assigned(FOnCreateDatabase) and (FAttachment <> nil) then |
629 |
+ |
OnCreateDatabase(self); |
630 |
+ |
end; |
631 |
+ |
|
632 |
|
procedure TIBDataBase.DropDatabase; |
633 |
|
begin |
634 |
|
CheckActive; |
956 |
|
TempDBParams := TStringList.Create; |
957 |
|
try |
958 |
|
TempDBParams.Assign(FDBParams); |
959 |
+ |
{$ifdef UNIX} |
960 |
+ |
{See below for WINDOWS UseDefaultSystemCodePage} |
961 |
|
if UseDefaultSystemCodePage then |
962 |
< |
begin |
963 |
< |
{$ifdef WINDOWS} |
942 |
< |
if FirebirdAPI.CodePage2CharSetID(GetACP,CharSetID) then |
943 |
< |
TempDBParams.Values['lc_ctype'] := FirebirdAPI.GetCharsetName(CharSetID) |
944 |
< |
{$else} |
945 |
< |
if FirebirdAPI.CodePage2CharSetID(DefaultSystemCodePage,CharSetID) then |
946 |
< |
TempDBParams.Values['lc_ctype'] := FirebirdAPI.GetCharsetName(CharSetID) |
947 |
< |
{$endif} |
948 |
< |
else |
949 |
< |
TempDBParams.Values['lc_ctype'] :='UTF8'; |
950 |
< |
end; |
962 |
> |
TempDBParams.Values['lc_ctype'] :='UTF8'; |
963 |
> |
{$endif} |
964 |
|
{Opportunity to override defaults} |
965 |
|
for i := 0 to FSQLObjects.Count - 1 do |
966 |
|
begin |
968 |
|
SQLObjects[i].DoBeforeDatabaseConnect(TempDBParams,aDBName); |
969 |
|
end; |
970 |
|
|
971 |
< |
FDefaultCharSetName := AnsiUpperCase(TempDBParams.Values['lc_ctype']); |
972 |
< |
if FDefaultCharSetName <> '' then |
973 |
< |
FirebirdAPI.CharSetName2CharSetID(FDefaultCharSetName,FDefaultCharSetID); |
974 |
< |
FirebirdAPI.CharSetID2CodePage(FDefaultCharSetID,FDefaultCodePage); |
975 |
< |
{ Generate a new DPB if necessary } |
976 |
< |
if (FDBParamsChanged or (TempDBParams.Text <> FDBParams.Text)) then |
977 |
< |
begin |
978 |
< |
FDBParamsChanged := False; |
979 |
< |
if (not LoginPrompt and not (csDesigning in ComponentState)) or (FHiddenPassword = '') then |
980 |
< |
FDPB := GenerateDPB(TempDBParams) |
971 |
> |
repeat |
972 |
> |
{ Generate a new DPB if necessary } |
973 |
> |
if (FDPB = nil) or FDBParamsChanged or (TempDBParams.Text <> FDBParams.Text) then |
974 |
> |
begin |
975 |
> |
FDBParamsChanged := False; |
976 |
> |
if (not LoginPrompt and not (csDesigning in ComponentState)) or (FHiddenPassword = '') then |
977 |
> |
FDPB := GenerateDPB(TempDBParams) |
978 |
> |
else |
979 |
> |
begin |
980 |
> |
TempDBParams.Values['password'] := FHiddenPassword; |
981 |
> |
FDPB := GenerateDPB(TempDBParams); |
982 |
> |
end; |
983 |
> |
end; |
984 |
> |
|
985 |
> |
if FCreateDatabase then |
986 |
> |
begin |
987 |
> |
FCreateDatabase := false; |
988 |
> |
FAttachment := FirebirdAPI.CreateDatabase(aDBName,FDPB, false); |
989 |
> |
if assigned(FOnCreateDatabase) and (FAttachment <> nil) then |
990 |
> |
OnCreateDatabase(self); |
991 |
> |
end |
992 |
|
else |
993 |
+ |
FAttachment := FirebirdAPI.OpenDatabase(aDBName,FDPB,false); |
994 |
+ |
|
995 |
+ |
if FAttachment = nil then |
996 |
+ |
begin |
997 |
+ |
Status := FirebirdAPI.GetStatus; |
998 |
+ |
{$IFDEF UNIX} |
999 |
+ |
if Pos(':',aDBName) = 0 then |
1000 |
+ |
begin |
1001 |
+ |
if ((Status.GetSQLCode = -901) and (Status.GetIBErrorCode = isc_random)) {Access permissions on firebird temp} |
1002 |
+ |
or |
1003 |
+ |
((Status.GetSQLCode = -902) and (Status.GetIBErrorCode = isc_sys_request)) {Security DB Problem} |
1004 |
+ |
or |
1005 |
+ |
((Status.GetSQLCode = -902) and (Status.GetIBErrorCode = isc_psw_attach)) {Security DB Problem} |
1006 |
+ |
or |
1007 |
+ |
((Status.GetSQLCode = -904) and (Status.GetIBErrorCode = isc_lock_dir_access)) {Lock File Problem} |
1008 |
+ |
then |
1009 |
+ |
begin |
1010 |
+ |
aDBName := 'localhost:' + aDBName; |
1011 |
+ |
Continue; |
1012 |
+ |
end |
1013 |
+ |
end; |
1014 |
+ |
{$ENDIF} |
1015 |
+ |
if ((Status.GetSQLCode = -902) and (Status.GetIBErrorCode = isc_io_error)) {Database not found} |
1016 |
+ |
and CreateIfNotExists and not (csDesigning in ComponentState) then |
1017 |
+ |
FCreateDatabase := true |
1018 |
+ |
else |
1019 |
+ |
raise EIBInterBaseError.Create(Status); |
1020 |
+ |
end; |
1021 |
+ |
|
1022 |
+ |
if UseDefaultSystemCodePage and (FAttachment <> nil) then |
1023 |
+ |
{Only now can we check the codepage in use by the Attachment. |
1024 |
+ |
If not that required then re-open with required LCLType.} |
1025 |
|
begin |
1026 |
< |
TempDBParams.Add('password=' + FHiddenPassword); |
1027 |
< |
FDPB := GenerateDPB(TempDBParams); |
1026 |
> |
{$ifdef WINDOWS} |
1027 |
> |
if Attachment.CodePage2CharSetID(GetACP,CharSetID) then |
1028 |
> |
{$else} |
1029 |
> |
if Attachment.CodePage2CharSetID(DefaultSystemCodePage,CharSetID) then |
1030 |
> |
{$endif} |
1031 |
> |
begin |
1032 |
> |
FDefaultCharSetName := Attachment.GetCharsetName(CharSetID); |
1033 |
> |
if FDefaultCharSetName <> AnsiUpperCase(TempDBParams.Values['lc_ctype']) then |
1034 |
> |
begin |
1035 |
> |
TempDBParams.Values['lc_ctype'] := FDefaultCharSetName; |
1036 |
> |
FDBParamsChanged := True; |
1037 |
> |
FAttachment := nil; |
1038 |
> |
end |
1039 |
> |
end |
1040 |
|
end; |
1041 |
< |
end; |
1041 |
> |
|
1042 |
> |
until FAttachment <> nil; |
1043 |
> |
|
1044 |
> |
FDefaultCharSetName := AnsiUpperCase(TempDBParams.Values['lc_ctype']); |
1045 |
|
finally |
1046 |
|
TempDBParams.Free; |
1047 |
|
end; |
1048 |
+ |
if FDefaultCharSetName <> '' then |
1049 |
+ |
Attachment.CharSetName2CharSetID(FDefaultCharSetName,FDefaultCharSetID); |
1050 |
+ |
Attachment.CharSetID2CodePage(FDefaultCharSetID,FDefaultCodePage); |
1051 |
|
|
978 |
– |
repeat |
979 |
– |
if FCreateDatabase then |
980 |
– |
begin |
981 |
– |
FCreateDatabase := false; |
982 |
– |
FAttachment := FirebirdAPI.CreateDatabase(aDBName,FDPB, false); |
983 |
– |
if assigned(FOnCreateDatabase) and (FAttachment <> nil) then |
984 |
– |
OnCreateDatabase(self); |
985 |
– |
end |
986 |
– |
else |
987 |
– |
FAttachment := FirebirdAPI.OpenDatabase(aDBName,FDPB,false); |
988 |
– |
if FAttachment = nil then |
989 |
– |
begin |
990 |
– |
Status := FirebirdAPI.GetStatus; |
991 |
– |
{$IFDEF UNIX} |
992 |
– |
if Pos(':',aDBName) = 0 then |
993 |
– |
begin |
994 |
– |
if ((Status.GetSQLCode = -901) and (Status.GetIBErrorCode = isc_random)) {Access permissions on firebird temp} |
995 |
– |
or |
996 |
– |
((Status.GetSQLCode = -902) and (Status.GetIBErrorCode = isc_sys_request)) {Security DB Problem} |
997 |
– |
or |
998 |
– |
((Status.GetSQLCode = -902) and (Status.GetIBErrorCode = isc_psw_attach)) {Security DB Problem} |
999 |
– |
or |
1000 |
– |
((Status.GetSQLCode = -904) and (Status.GetIBErrorCode = isc_lock_dir_access)) {Lock File Problem} |
1001 |
– |
then |
1002 |
– |
begin |
1003 |
– |
aDBName := 'localhost:' + aDBName; |
1004 |
– |
Continue; |
1005 |
– |
end |
1006 |
– |
end; |
1007 |
– |
{$ENDIF} |
1008 |
– |
if ((Status.GetSQLCode = -902) and (Status.GetIBErrorCode = isc_io_error)) {Database not found} |
1009 |
– |
and CreateIfNotExists and not (csDesigning in ComponentState) then |
1010 |
– |
FCreateDatabase := true |
1011 |
– |
else |
1012 |
– |
raise EIBInterBaseError.Create(Status); |
1013 |
– |
end; |
1014 |
– |
until FAttachment <> nil; |
1052 |
|
if not (csDesigning in ComponentState) then |
1053 |
|
FDBName := aDBName; {Synchronise at run time} |
1054 |
|
FDBSQLDialect := GetDBSQLDialect; |
1597 |
|
case Action of |
1598 |
|
TARollback, TACommit: |
1599 |
|
begin |
1600 |
< |
DoBeforeTransactionEnd; |
1600 |
> |
try |
1601 |
> |
DoBeforeTransactionEnd; |
1602 |
> |
except on E: EIBInterBaseError do |
1603 |
> |
begin |
1604 |
> |
if not Force then |
1605 |
> |
raise; |
1606 |
> |
end; |
1607 |
> |
end; |
1608 |
> |
|
1609 |
|
for i := 0 to FSQLObjects.Count - 1 do if FSQLObjects[i] <> nil then |
1610 |
+ |
try |
1611 |
|
SQLObjects[i].DoBeforeTransactionEnd(Action); |
1612 |
+ |
except on E: EIBInterBaseError do |
1613 |
+ |
begin |
1614 |
+ |
if not Force then |
1615 |
+ |
raise; |
1616 |
+ |
end; |
1617 |
+ |
end; |
1618 |
+ |
|
1619 |
|
if InTransaction then |
1620 |
|
begin |
1621 |
|
if (Action = TARollback) then |
1632 |
|
end; |
1633 |
|
end; |
1634 |
|
|
1635 |
< |
for i := 0 to FSQLObjects.Count - 1 do if FSQLObjects[i] <> nil then |
1636 |
< |
SQLObjects[i].DoAfterTransactionEnd; |
1637 |
< |
DoAfterTransactionEnd; |
1635 |
> |
for i := 0 to FSQLObjects.Count - 1 do if FSQLObjects[i] <> nil then |
1636 |
> |
try |
1637 |
> |
SQLObjects[i].DoAfterTransactionEnd; |
1638 |
> |
except on E: EIBInterBaseError do |
1639 |
> |
begin |
1640 |
> |
if not Force then |
1641 |
> |
raise; |
1642 |
> |
end; |
1643 |
> |
end; |
1644 |
> |
try |
1645 |
> |
DoAfterTransactionEnd; |
1646 |
> |
except on E: EIBInterBaseError do |
1647 |
> |
begin |
1648 |
> |
if not Force then |
1649 |
> |
raise; |
1650 |
> |
end; |
1651 |
> |
end; |
1652 |
|
end; |
1653 |
|
end; |
1654 |
|
TACommitRetaining: |