diff --git a/Source/BoldDbValidator.pas b/Source/BoldDbValidator.pas index 97624a8..cc45be4 100644 --- a/Source/BoldDbValidator.pas +++ b/Source/BoldDbValidator.pas @@ -122,83 +122,85 @@ procedure TBoldDbValidator.CheckTypeTableConsistency(SystemSQLMapper: TBoldSyste begin query := SystemSQLMapper.GetQuery; ExecQuery := SystemSQLMapper.GetExecQuery; - query.AssignSQLText(format('SELECT * FROM %s', [TypeTableName])); + try + query.AssignSQLText(format('SELECT * FROM %s', [TypeTableName])); - HighestBoldDbType := -1; + HighestBoldDbType := -1; - Query.Open; - BoldDBTypeField := Query.FieldByName('BOLD_TYPE'); - ClassNameField := Query.FieldByName('CLASSNAME'); - while not query.eof do - begin - BoldDbType := BoldDBTypeField.AsInteger; - if BoldDbType > HighestBoldDbType then - HighestBoldDbType := BoldDbType; + Query.Open; + BoldDBTypeField := Query.FieldByName('BOLD_TYPE'); + ClassNameField := Query.FieldByName('CLASSNAME'); + while not query.eof do + begin + BoldDbType := BoldDBTypeField.AsInteger; + if BoldDbType > HighestBoldDbType then + HighestBoldDbType := BoldDbType; - Name := ClassNameField.AsString; + Name := ClassNameField.AsString; - Found := false; - for i := 0 to SystemSQLMapper.ObjectPersistenceMappers.count - 1 do - begin - if assigned(SystemSQLMapper.ObjectPersistenceMappers[i]) and - (CompareText(SystemSQLMapper.ObjectPersistenceMappers[i].ExpressionName, Name) = 0) then + Found := false; + for i := 0 to SystemSQLMapper.ObjectPersistenceMappers.count - 1 do begin - ObjectPMapper := SystemSQLMapper.ObjectPersistenceMappers[i] as TBoldObjectSQLMapper; - ObjectPMapper.BoldDbType := BoldDbType; - Found := true; - Break; + if assigned(SystemSQLMapper.ObjectPersistenceMappers[i]) and + (CompareText(SystemSQLMapper.ObjectPersistenceMappers[i].ExpressionName, Name) = 0) then + begin + ObjectPMapper := SystemSQLMapper.ObjectPersistenceMappers[i] as TBoldObjectSQLMapper; + ObjectPMapper.BoldDbType := BoldDbType; + Found := true; + Break; + end; end; + if not found then + BoldLog.LogFmt(sClassInDBNotInModel, [Name, BoldDbType]); + Query.Next; end; - if not found then - BoldLog.LogFmt(sClassInDBNotInModel, [Name, BoldDbType]); - Query.Next; - end; - Query.Close; - - MissingClasses := false; - for i := 0 to SystemSQLMapper.ObjectPersistenceMappers.count - 1 do - begin - ObjectPMapper := SystemSQLMapper.ObjectPersistenceMappers[i] as TBoldObjectSQLMapper; - if assigned(ObjectPMapper) and (ObjectPMapper.BoldDbType = -1) then - begin - if not MissingClasses then - BoldLog.Separator; - BoldLog.LogFmt(sClassWithMissingID, [ObjectPMapper.ExpressionName]); - MissingClasses := true; - end; - end; + Query.Close; - if MissingClasses and (MessageDlg(sCorrectClassWithNoID, mtConfirmation, [mbYes, mbNo], 0) = mrYes) then - begin - BoldLog.Separator; - Execquery.AssignSQLText( - format('INSERT INTO %s (%s, %s) VALUES (:%s, :%s)', [ - TypeTablename, - TYPECOLUMN_NAME, - CLASSNAMECOLUMN_NAME, - TYPECOLUMN_NAME, - CLASSNAMECOLUMN_NAME])); - - ExecQuery.ParamCheck := true; - TypeParam := ExecQuery.ParamByName(TYPECOLUMN_NAME); - ClassParam := ExecQuery.ParamByName(CLASSNAMECOLUMN_NAME); + MissingClasses := false; for i := 0 to SystemSQLMapper.ObjectPersistenceMappers.count - 1 do begin ObjectPMapper := SystemSQLMapper.ObjectPersistenceMappers[i] as TBoldObjectSQLMapper; if assigned(ObjectPMapper) and (ObjectPMapper.BoldDbType = -1) then begin - Inc(HighestBoldDbType); - ObjectPMapper.BoldDbType := HighestBoldDbType; - BoldLog.LogFmt(sAddBoldDBTType, [ObjectPMapper.BoldDbType, ObjectPMapper.expressionName]); - TypeParam.AsInteger := HighestBoldDbType; - ClassParam.AsString := ObjectPMapper.ExpressionName; - ExecQuery.ExecSQL; + if not MissingClasses then + BoldLog.Separator; + BoldLog.LogFmt(sClassWithMissingID, [ObjectPMapper.ExpressionName]); + MissingClasses := true; end; end; - end; - SystemSQLMapper.ReleaseQuery(Query); - SystemSQLMapper.ReleaseExecQuery(ExecQuery); + if MissingClasses and (MessageDlg(sCorrectClassWithNoID, mtConfirmation, [mbYes, mbNo], 0) = mrYes) then + begin + BoldLog.Separator; + Execquery.AssignSQLText( + format('INSERT INTO %s (%s, %s) VALUES (:%s, :%s)', [ + TypeTablename, + TYPECOLUMN_NAME, + CLASSNAMECOLUMN_NAME, + TYPECOLUMN_NAME, + CLASSNAMECOLUMN_NAME])); + + ExecQuery.ParamCheck := true; + TypeParam := ExecQuery.ParamByName(TYPECOLUMN_NAME); + ClassParam := ExecQuery.ParamByName(CLASSNAMECOLUMN_NAME); + for i := 0 to SystemSQLMapper.ObjectPersistenceMappers.count - 1 do + begin + ObjectPMapper := SystemSQLMapper.ObjectPersistenceMappers[i] as TBoldObjectSQLMapper; + if assigned(ObjectPMapper) and (ObjectPMapper.BoldDbType = -1) then + begin + Inc(HighestBoldDbType); + ObjectPMapper.BoldDbType := HighestBoldDbType; + BoldLog.LogFmt(sAddBoldDBTType, [ObjectPMapper.BoldDbType, ObjectPMapper.expressionName]); + TypeParam.AsInteger := HighestBoldDbType; + ClassParam.AsString := ObjectPMapper.ExpressionName; + ExecQuery.ExecSQL; + end; + end; + end; + finally + SystemSQLMapper.ReleaseQuery(Query); + SystemSQLMapper.ReleaseExecQuery(ExecQuery); + end; end; procedure TBoldDbValidator.Activate; @@ -265,4 +267,4 @@ function TBoldDbValidator.TypeTableName: String; result := BoldExpandPrefix(TYPETABLE_NAME, '', PersistenceHandle.SQLDataBaseConfig.SystemTablePrefix, SystemSQLMapper.SQLDatabaseConfig.MaxDBIdentifierLength, SystemSQLMapper.NationalCharConversion); end; -end. \ No newline at end of file +end. diff --git a/Source/BoldFireDACInterfaces.pas b/Source/BoldFireDACInterfaces.pas index 171b773..bc6df78 100644 --- a/Source/BoldFireDACInterfaces.pas +++ b/Source/BoldFireDACInterfaces.pas @@ -1132,6 +1132,8 @@ procedure TBoldFireDACConnection.Reconnect; end; end; +type TCollectionAccess = class(TCollection); + procedure TBoldFireDACConnection.ReleaseQuery(var Query: IBoldQuery); var lBoldFireDACQuery: TBoldFireDACQuery; @@ -1140,6 +1142,10 @@ procedure TBoldFireDACConnection.ReleaseQuery(var Query: IBoldQuery); begin lBoldFireDACQuery := Query.Implementor as TBoldFireDACQuery; lBoldFireDACQuery.clear; + while lBoldFireDACQuery.SQLStrings.Updating do + lBoldFireDACQuery.SQLStrings.EndUpdate; + while TCollectionAccess(lBoldFireDACQuery.Params).UpdateCount > 0 do + lBoldFireDACQuery.Params.EndUpdate; Query := nil; if not Assigned(fCachedQuery1) then fCachedQuery1 := lBoldFireDACQuery @@ -1159,13 +1165,15 @@ procedure TBoldFireDACConnection.ReleaseExecQuery(var Query: IBoldExecQuery); if (Query.Implementor is TBoldFireDACQuery) then begin lBoldFireDACQuery := Query.Implementor as TBoldFireDACQuery; - if lBoldFireDACQuery.GetSQLStrings.Count <> 0 then + if lBoldFireDACQuery.SQLStrings.Count <> 0 then begin - lBoldFireDACQuery.GetSQLStrings.BeginUpdate; + lBoldFireDACQuery.SQLStrings.BeginUpdate; lBoldFireDACQuery.clear; end; - while TStringsAccess(lBoldFireDACQuery.GetSQLStrings).UpdateCount > 0 do - lBoldFireDACQuery.GetSQLStrings.EndUpdate; + while lBoldFireDACQuery.SQLStrings.Updating do + lBoldFireDACQuery.SQLStrings.EndUpdate; + while TCollectionAccess(lBoldFireDACQuery.Params).UpdateCount > 0 do + lBoldFireDACQuery.Params.EndUpdate; Query := nil; if not Assigned(fCachedExecQuery1) then fCachedExecQuery1 := lBoldFireDACQuery diff --git a/Source/BoldPMappers.pas b/Source/BoldPMappers.pas index b304455..09e220e 100644 --- a/Source/BoldPMappers.pas +++ b/Source/BoldPMappers.pas @@ -530,8 +530,11 @@ procedure TBoldSystemPersistenceMapper.PMUpdate(ObjectIDList: TBoldObjectIdList; Exit; Guard := TBoldGuard.Create(ModifiedObjectIDList, NewObjectIDList, DeletedObjectIDList); DeletedObjectIDList := TBoldObjectIdList.Create; + DeletedObjectIDList.OwnsEntries := false; NewObjectIDList := TBoldObjectIdList.Create; + NewObjectIDList.OwnsEntries := false; ModifiedObjectIDList := TBoldObjectIdList.Create; + ModifiedObjectIDList.OwnsEntries := false; // downto order is important here - Daniel for i := ObjectIDList.Count - 1 downto 0 do @@ -540,11 +543,11 @@ procedure TBoldSystemPersistenceMapper.PMUpdate(ObjectIDList: TBoldObjectIdList; if ObjectContents.BoldPersistenceState = bvpsModified then begin if ObjectContents.BoldExistenceState = besDeleted then - DeletedObjectIDList.Add(ObjectIDList[i]) + DeletedObjectIDList.AddAndAdopt(ObjectIDList[i]) else - NewObjectIDList.Add(ObjectIDList[i]); + NewObjectIDList.AddAndAdopt(ObjectIDList[i]); end else - ModifiedObjectIDList.Add(ObjectIDList[i]); + ModifiedObjectIDList.AddAndAdopt(ObjectIDList[i]); end; ReserveNewIds(ValueSpace, ObjectIdList, TranslationList); diff --git a/Source/BoldPMappersAttributeDefault.pas b/Source/BoldPMappersAttributeDefault.pas index 485a5ff..e05ca86 100644 --- a/Source/BoldPMappersAttributeDefault.pas +++ b/Source/BoldPMappersAttributeDefault.pas @@ -53,9 +53,11 @@ TBoldPMString = class(TBoldSingleColumnMember) {TBoldPMAnsiString} TBoldPMAnsiString = class(TBoldPMString) protected + function GetColumnTypeAsSQL(ColumnIndex: Integer): string; override; function CompareField(const ObjectContent: IBoldObjectContents; const Field: IBoldField; ColumnIndex: integer; const ValueSpace: IBoldValueSpace; TranslationList: TBoldIdTranslationList): Boolean; override; + function GetColumnBDEFieldType(ColumnIndex: Integer): TFieldType; override; public procedure ValueFromField(OwningObjectId: TBoldObjectId; const ObjectContent: IBoldObjectContents; const ValueSpace: IBoldValueSpace; TranslationList: @@ -343,7 +345,10 @@ class function TBoldPMString.CanStore(const ContentName: string): Boolean; function TBoldPMString.GetColumnBDEFieldType(ColumnIndex: Integer): TFieldType; begin - Result := ftMemo; // Changed from ftString to ftMemo as MSSQL truncates string params to 8000 + if SystemPersistenceMapper.SQLDataBaseConfig.TreatStringFieldAsUnicode then + result := ftWideString + else + Result := ftString; end; function TBoldPMString.GetColumnSize(ColumnIndex: Integer): Integer; @@ -1267,6 +1272,17 @@ function TBoldPMAnsiString.CompareField(const ObjectContent: IBoldObjectContents end; end; +function TBoldPMAnsiString.GetColumnBDEFieldType( + ColumnIndex: Integer): TFieldType; +begin + Result := ftString; +end; + +function TBoldPMAnsiString.GetColumnTypeAsSQL(ColumnIndex: Integer): string; +begin + Result := SystemPersistenceMapper.SQLDataBaseConfig.GetColumnTypeForAnsiString(GetColumnSize(ColumnIndex)); +end; + procedure TBoldPMAnsiString.ValueFromField(OwningObjectId: TBoldObjectId; const ObjectContent: IBoldObjectContents; const ValueSpace: IBoldValueSpace; TranslationList: TBoldIdTranslationList; const Field: IBoldField; ColumnIndex: diff --git a/Source/BoldPMappersDefault.pas b/Source/BoldPMappersDefault.pas index 6b0e369..ebdbf04 100644 --- a/Source/BoldPMappersDefault.pas +++ b/Source/BoldPMappersDefault.pas @@ -1334,7 +1334,7 @@ procedure TBoldObjectDefaultMapper.PMCreate(ObjectIDList: TBoldObjectIdList; con TickCounter := 0; end; inc(Row); - if UseParams or (i = ObjectIDList.Count-1) or (Row = Limit) or (aQuery.ParamCount + aQuery.BatchQueryParamCount >= SystemPersistenceMapper.SQLDataBaseConfig.MaxBatchQueryParams) then + if UseParams or (i = ObjectIDList.Count-1) or (Row = Limit) or (aQuery.Params.Count + aQuery.BatchQueryParamCount >= SystemPersistenceMapper.SQLDataBaseConfig.MaxBatchQueryParams) then begin if not UseParams then SB.Append(')'); @@ -1593,7 +1593,8 @@ procedure TBoldObjectDefaultMapper.PMUpdate(ObjectIDList: TBoldObjectIdList; con finally aQuery.SQLStrings.Clear; aQuery.ClearParams; - aQuery.SQLStrings.EndUpdate; + if aQuery.SQLStrings.Updating then + aQuery.SQLStrings.EndUpdate; SystemPersistenceMapper.ReleaseExecQuery(aQuery); end; diff --git a/Source/BoldSQLDatabaseConfig.pas b/Source/BoldSQLDatabaseConfig.pas index ef41e5a..4e39df7 100644 --- a/Source/BoldSQLDatabaseConfig.pas +++ b/Source/BoldSQLDatabaseConfig.pas @@ -32,20 +32,20 @@ TBoldSQLDataBaseConfig = class; TBoldSQLDataBaseConfig = class(TPersistent) private - FIfTemplate: string; - FColumnExistsTemplate: string; - FTableExistsTemplate: string; - FIndexExistsTemplate: string; - FIndexColumnExistsTemplate: string; - FColumnTypeForBlob: string; - FColumnTypeForDateTime: string; - FColumnTypeForDate: string; - FColumnTypeForTime: string; - FColumnTypeForFloat: string; - fColumnTypeForInt64: string; + fIfTemplate: string; + fColumnExistsTemplate: string; + fTableExistsTemplate: string; + fIndexExistsTemplate: string; + fIndexColumnExistsTemplate: string; + fColumnTypeForBlob: string; + fColumnTypeForDateTime: string; + fColumnTypeForDate: string; + fColumnTypeForTime: string; + fColumnTypeForFloat: string; + fColumnTypeForInt64: string; fDefaultValueForDateTime: string; - FDefaultSystemMapper: string; - FDefaultObjectMapper: string; + fDefaultSystemMapper: string; + fDefaultObjectMapper: string; fOnChange: TNotifyEvent; fUseSQL92Joins: boolean; fSingleIndexOrderedLinks: Boolean; @@ -54,24 +54,26 @@ TBoldSQLDataBaseConfig = class(TPersistent) fUseParamsForInteger: boolean; fUseParamsForEmptyString: boolean; fDefaultStringLength: integer; - FColumnTypeForString: string; - FColumnTypeForUnicodeString: string; - FColumnTypeForText: string; - FColumnTypeForUnicodeText: string; - FLongStringLimit: integer; + fColumnTypeForString: string; + fColumnTypeForUnicodeString: string; + fColumnTypeForAnsiString: string; + fColumnTypeForText: string; + fColumnTypeForUnicodeText: string; + fColumnTypeForAnsiText: string; + fLongStringLimit: integer; fDropColumnTemplate: string; fDropIndexTemplate: string; fDropTableTemplate: string; fIndexInfoTemplate: string; fSQLforNotNull: string; - FColumnTypeForInteger: string; + fColumnTypeForInteger: string; fColumnTypeForSmallInt: string; - FColumnTypeForGUID: string; + fColumnTypeForGUID: string; fSupportsConstraintsInCreateTable: Boolean; fQuoteNonStringDefaultValues: Boolean; fSupportsStringDefaultValues: Boolean; fReservedWords: TStringList; - FColumnTypeForCurrency: string; + fColumnTypeForCurrency: string; fEngine: TBoldDatabaseEngine; fMaxParamsInIdList: integer; fMaxIndexNameLength: integer; @@ -82,14 +84,14 @@ TBoldSQLDataBaseConfig = class(TPersistent) fEmptyStringMarker: String; fStoreEmptyStringsAsNULL: Boolean; fSystemTablePrefix: String; - FSqlScriptCommentStart: string; - FSqlScriptStartTransaction: string; - FSqlScriptTerminator: string; - FSqlScriptCommentStop: string; - FSqlScriptSeparator: string; - FSqlScriptRollBackTransaction: string; - FSqlScriptCommitTransaction: string; - FDatabaseCaseSensitiveTemplate: string; + fSqlScriptCommentStart: string; + fSqlScriptStartTransaction: string; + fSqlScriptTerminator: string; + fSqlScriptCommentStop: string; + fSqlScriptSeparator: string; + fSqlScriptRollBackTransaction: string; + fSqlScriptCommitTransaction: string; + fDatabaseCaseSensitiveTemplate: string; fQuoteLeftBracketInLike: Boolean; fIgnoreMissingObjects: boolean; fMaxBatchQueryLength: integer; @@ -104,6 +106,7 @@ TBoldSQLDataBaseConfig = class(TPersistent) fDropDatabaseTemplate: string; fDatabaseExistsTemplate: string; fUnicodeStringPrefix: string; + fTreatStringFieldAsUnicode: boolean; procedure SetIfTemplate(const Value: string); procedure SetColumnExistsTemplate(const Value: string); procedure SetTableExistsTemplate(const Value: string); @@ -136,7 +139,7 @@ TBoldSQLDataBaseConfig = class(TPersistent) procedure SetColumnTypeForInteger(const Value: string); function GetEffectiveSQLForNotNull: string; procedure SetColumnTypeForSmallInt(const Value: string); - procedure SetColumnTypeForInt64(const Value: string); + procedure SetColumnTypeForInt64(const Value: string); procedure SetColumnTypeForGUID(const Value: string); procedure SetSupportsConstraintsInCreateTable(const Value: Boolean); procedure SetQuoteNonStringDefaultValues(const Value: Boolean); @@ -149,7 +152,7 @@ TBoldSQLDataBaseConfig = class(TPersistent) procedure SetDBGenerationMode(const Value: TBoldDatabaseGenerationMode); procedure setAllowMetadataChangesInTransaction(const Value: Boolean); procedure ReadUseTransactionsDuringDBCreate(Reader: TReader); - procedure SetDatabaseCaseSensitiveTemplate(const Value: string); + procedure SetDatabaseCaseSensitiveTemplate(const Value: string); procedure SetFieldTypeForBlob(const Value: TFieldType); procedure SetEmptyStringMarker(const Value: String); procedure SetStoreEmptyStringsAsNULL(const Value: Boolean); @@ -178,6 +181,9 @@ TBoldSQLDataBaseConfig = class(TPersistent) procedure SetDropDatabaseTemplate(const Value: string); procedure SetDatabaseExistsTemplate(const Value: string); procedure SetUnicodeStringPrefix(const Value: string); + procedure SetColumnTypeForAnsiString(const Value: string); + procedure SetColumnTypeForAnsiText(const Value: string); + procedure SetTreatStringFieldAsUnicode(const Value: boolean); protected procedure DefineProperties(Filer: TFiler); override; public @@ -194,6 +200,7 @@ TBoldSQLDataBaseConfig = class(TPersistent) function GetIndexInfoQuery(const TableName: String): String; function GetColumnTypeForString(Size: Integer): string; function GetColumnTypeForUnicodeString(Size: Integer): string; + function GetColumnTypeForAnsiString(Size: Integer): string; procedure InitializeDbEngineSettings(Engine: TBoldDatabaseEngine); function CorrectlyQuotedDefaultValue(value: string): String; function GetColumnExistsQuery(const TableName, ColumnName: string): string; @@ -223,8 +230,10 @@ TBoldSQLDataBaseConfig = class(TPersistent) property ColumnTypeForCurrency: string read FColumnTypeForCurrency write SetColumnTypeForCurrency; property ColumnTypeForString: string read FColumnTypeForString write SetColumnTypeForString; property ColumnTypeForUnicodeString: string read FColumnTypeForUnicodeString write SetColumnTypeForUnicodeString; + property ColumnTypeForAnsiString: string read FColumnTypeForAnsiString write SetColumnTypeForAnsiString; property ColumnTypeForText: string read FColumnTypeForText write SetColumnTypeForText; - property ColumnTypeForUnicodeText: string read FColumnTypeForUnicodeText write SetColumnTypeForUnicodeText; + property ColumnTypeForUnicodeText: string read FColumnTypeForUnicodeText write SetColumnTypeForUnicodeText; + property ColumnTypeForAnsiText: string read FColumnTypeForAnsiText write SetColumnTypeForAnsiText; property LongStringLimit: integer read FLongStringLimit write SetLongStringLimit default -1; property ColumnTypeForInteger: string read FColumnTypeForInteger write SetColumnTypeForInteger; property ColumnTypeForSmallInt: string read fColumnTypeForSmallInt write SetColumnTypeForSmallInt; @@ -277,6 +286,8 @@ TBoldSQLDataBaseConfig = class(TPersistent) property SqlScriptStartTransaction: string read FSqlScriptStartTransaction write SetSqlScriptStartTransaction; property SqlScriptCommitTransaction: string read FSqlScriptCommitTransaction write SetSqlScriptCommitTransaction; property SqlScriptRollBackTransaction: string read FSqlScriptRollBackTransaction write SetSqlScriptRollBackTransaction; + property TreatStringFieldAsUnicode: boolean read fTreatStringFieldAsUnicode write SetTreatStringFieldAsUnicode; + end; implementation @@ -315,8 +326,10 @@ procedure TBoldSQLDataBaseConfig.AssignConfig(Source: TBoldSQLDataBaseConfig); FColumnTypeForCurrency := Source.ColumnTypeForCurrency; fColumnTypeForString := Source.ColumnTypeForString; fColumnTypeForUnicodeString := Source.ColumnTypeForUnicodeString; + fColumnTypeForAnsiString := Source.ColumnTypeForAnsiString; fColumnTypeForText := Source.ColumnTypeForText; fColumnTypeForUnicodeText := Source.ColumnTypeForUnicodeText; + fColumnTypeForAnsiText := Source.ColumnTypeForAnsiText; FLongStringLimit := Source.LongStringLimit; FColumnTypeForInteger := Source.ColumnTypeForInteger; fColumnTypeForSmallInt := Source.ColumnTypeForSmallInt; @@ -346,6 +359,7 @@ procedure TBoldSQLDataBaseConfig.AssignConfig(Source: TBoldSQLDataBaseConfig); fSystemTablePrefix := Source.SystemTablePrefix; fEmptyStringMarker := Source.EmptyStringMarker; fUnicodeStringPrefix := Source.UnicodeStringPrefix; + fTreatStringFieldAsUnicode := Source.TreatStringFieldAsUnicode; fAllowMetadataChangesInTransaction := Source.AllowMetadataChangesInTransaction; fDbGenerationMode := Source.DBGenerationMode; fDefaultStringLength := Source.DefaultStringLength; @@ -375,7 +389,7 @@ procedure TBoldSQLDataBaseConfig.AssignConfig(Source: TBoldSQLDataBaseConfig); FIndexExistsTemplate := Source.IndexExistsTemplate; FIndexColumnExistsTemplate := Source.IndexColumnExistsTemplate; FDatabaseCaseSensitiveTemplate := Source.DatabaseCaseSensitiveTemplate; - FIgnoreMissingObjects := Source.IgnoreMissingObjects; + FIgnoreMissingObjects := Source.IgnoreMissingObjects; Change; end; @@ -498,6 +512,16 @@ procedure TBoldSQLDataBaseConfig.SetColumnTypeForUnicodeString(const Value: stri end; end; +procedure TBoldSQLDataBaseConfig.SetColumnTypeForAnsiString( + const Value: string); +begin + if FColumnTypeForAnsiString <> Value then + begin + FColumnTypeForAnsiString := Value; + Change; + end; +end; + procedure TBoldSQLDataBaseConfig.SetColumnTypeForText(const Value: string); begin if FColumnTypeForText <> Value then @@ -516,6 +540,15 @@ procedure TBoldSQLDataBaseConfig.SetColumnTypeForUnicodeText(const Value: string end; end; +procedure TBoldSQLDataBaseConfig.SetColumnTypeForAnsiText(const Value: string); +begin + if FColumnTypeForAnsiText <> Value then + begin + FColumnTypeForAnsiText := Value; + Change; + end; +end; + procedure TBoldSQLDataBaseConfig.SetCreateDatabaseTemplate(const Value: string); begin if fCreateDatabaseTemplate <> Value then @@ -633,6 +666,15 @@ function TBoldSQLDataBaseConfig.GetColumnTypeForUnicodeString( Result := Format(ColumnTypeForUnicodeText, [Size]); end; +function TBoldSQLDataBaseConfig.GetColumnTypeForAnsiString( + Size: Integer): string; +begin + if ( LongStringLimit = -1) or (Size <= LongStringLimit) then + Result := Format(ColumnTypeForAnsiString, [Size]) + else + Result := Format(ColumnTypeForAnsiText, [Size]); +end; + function TBoldSQLDataBaseConfig.GetCreateDatabaseQuery( const DatabaseName: String): String; begin @@ -764,25 +806,27 @@ procedure TBoldSQLDataBaseConfig.SetIndexExistsTemplate(const Value: string); procedure TBoldSQLDataBaseConfig.SetInitialValues; begin - FDatabaseCaseSensitiveTemplate := ''; // is database specific - FIfTemplate := ''; // is database specific - FColumnExistsTemplate := ''; // is database specific - FTableExistsTemplate := ''; // is database specific - FIndexExistsTemplate := ''; // is database specific - FIndexColumnExistsTemplate := ''; // is database specific - FColumnTypeForBlob := 'BLOB'; - FColumnTypeForDateTime := 'DATE'; - FColumnTypeForDate := 'DATE'; - FColumnTypeForTime := 'DATE'; + fDatabaseCaseSensitiveTemplate := ''; // is database specific + fIfTemplate := ''; // is database specific + fColumnExistsTemplate := ''; // is database specific + fTableExistsTemplate := ''; // is database specific + fIndexExistsTemplate := ''; // is database specific + fIndexColumnExistsTemplate := ''; // is database specific + fColumnTypeForBlob := 'BLOB'; + fColumnTypeForDateTime := 'DATE'; + fColumnTypeForDate := 'DATE'; + fColumnTypeForTime := 'DATE'; fDefaultValueForDateTime := ''; - FColumnTypeForFloat := 'DOUBLE PRECISION'; - FColumnTypeForCurrency := 'DOUBLE PRECISION'; + fColumnTypeForFloat := 'DOUBLE PRECISION'; + fColumnTypeForCurrency := 'DOUBLE PRECISION'; fColumnTypeForString := 'VARCHAR(%d)'; fColumnTypeForUnicodeString := 'NVARCHAR(%d)'; // do not localize + fColumnTypeForAnsiString := 'VARCHAR(%d)'; // do not localize fColumnTypeForText := 'VARCHAR(MAX)'; // do not localize fColumnTypeForUnicodeText := 'NVARCHAR(MAX)'; // do not localize + fColumnTypeForAnsiText := 'VARCHAR(MAX)'; // do not localize fLongStringLimit := -1; - FColumnTypeForInteger := 'INTEGER'; + fColumnTypeForInteger := 'INTEGER'; fColumnTypeForSmallInt := 'SMALLINT'; fColumnTypeForInt64 := 'BIGINT'; // do not localize fDefaultStringLength := 255; @@ -800,9 +844,10 @@ procedure TBoldSQLDataBaseConfig.SetInitialValues; fSystemTablePrefix := 'BOLD'; fEmptyStringMarker := ''; fUnicodeStringPrefix := ''; + fTreatStringFieldAsUnicode := true; fMultiRowInsertLimit := 1; - UseParamsForInteger := false; - UseParamsForEmptyString := false; + fUseParamsForInteger := false; + fUseParamsForEmptyString := false; fIgnoreMissingObjects := false; fAllowMetadataChangesInTransaction := true; fDBGenerationMode := dbgQuery; @@ -816,15 +861,15 @@ procedure TBoldSQLDataBaseConfig.SetInitialValues; fSQLforNull := 'NULL'; fSQLforNotNull := 'NOT NULL'; fSupportsConstraintsInCreateTable := true; - FQuoteNonStringDefaultValues := false; + fQuoteNonStringDefaultValues := false; fSupportsStringDefaultValues := true; - FSqlScriptCommentStart := '/* '; - FSqlScriptStartTransaction := 'START TRANSACTION'; - FSqlScriptTerminator := ';'; - FSqlScriptCommentStop := ' */'; - FSqlScriptSeparator := ''; - FSqlScriptRollBackTransaction := 'ROLLBACK'; - FSqlScriptCommitTransaction := 'COMMIT'; + fSqlScriptCommentStart := '/* '; + fSqlScriptStartTransaction := 'START TRANSACTION'; + fSqlScriptTerminator := ';'; + fSqlScriptCommentStop := ' */'; + fSqlScriptSeparator := ''; + fSqlScriptRollBackTransaction := 'ROLLBACK'; + fSqlScriptCommitTransaction := 'COMMIT'; fReservedWords.Text := 'ACTIVE, ADD, ALL, AFTER, ALTER'#10'AND, ANY, AS, ASC, ASCENDING,'#10 + 'AT, AUTO, AUTOINC, AVG, BASE_NAME'#10'BEFORE, BEGIN, BETWEEN, BLOB, BOOLEAN,'#10 + 'BOTH, BY, BYTES, CACHE, CAST, CHAR'#10'CHARACTER, CHECK, CHECK_POINT_LENGTH, COLLATE,'#10 + @@ -1038,6 +1083,7 @@ procedure TBoldSQLDataBaseConfig.InitializeDbEngineSettings(Engine: TBoldDatabas fColumnTypeForText:='VARCHAR(32765)'; // do not localize fColumnTypeForUnicodeString:='VARCHAR(%d) CHARACTER SET UNICODE'; // do not localize fColumnTypeForUnicodeText:='VARCHAR(4000) CHARACTER SET UNICODE'; // do not localize + fColumnTypeForAnsiText:='VARCHAR(32765)'; // do not localize fIfTemplate:='EXECUTE BLOCK AS BEGIN IF () THEN EXECUTE STATEMENT ''''; END'; // do not localize fIndexColumnExistsTemplate:= 'SELECT IX.RDB$INDEX_NAME AS Name FROM RDB$INDICES IX, RDB$INDEX_SEGMENTS SG WHERE IX.RDB$INDEX_NAME = SG.RDB$INDEX_NAME AND ' // do not localize @@ -1068,6 +1114,7 @@ procedure TBoldSQLDataBaseConfig.InitializeDbEngineSettings(Engine: TBoldDatabas fColumnTypeForText:='VARCHAR(32765)'; // do not localize fColumnTypeForUnicodeString:='VARCHAR(%d) CHARACTER SET UNICODE'; // do not localize fColumnTypeForUnicodeText:='VARCHAR(4000) CHARACTER SET UNICODE'; // do not localize + fColumnTypeForAnsiText:='VARCHAR(32765)'; // do not localize fIfTemplate:='EXECUTE BLOCK AS BEGIN IF () THEN EXECUTE STATEMENT ''''; END'; // do not localize fIndexColumnExistsTemplate:= 'SELECT IX.RDB$INDEX_NAME AS Name FROM RDB$INDICES IX, RDB$INDEX_SEGMENTS SG WHERE IX.RDB$INDEX_NAME = SG.RDB$INDEX_NAME AND ' // do not localize @@ -1120,6 +1167,7 @@ procedure TBoldSQLDataBaseConfig.InitializeDbEngineSettings(Engine: TBoldDatabas fColumnTypeForText:='CLOB'; // do not localize fColumnTypeForUnicodeString:='NVARCHAR2(%d)'; // do not localize fColumnTypeForUnicodeText:='CLOB'; // do not localize + fColumnTypeForAnsiText:='CLOB'; // do not localize fMaxIndexNameLength := 30; fMaxDbIdentifierLength := 30; fSupportsStringDefaultValues:=False; @@ -1541,53 +1589,84 @@ procedure TBoldSQLDataBaseConfig.SetTableExistsTemplate(const Value: string); end; end; +procedure TBoldSQLDataBaseConfig.SetTreatStringFieldAsUnicode( + const Value: boolean); +begin + if fTreatStringFieldAsUnicode <> Value then + begin + fTreatStringFieldAsUnicode := Value; + Change; + end; +end; + procedure TBoldSQLDataBaseConfig.SetSqlScriptCommentStart( const Value: string); begin - FSqlScriptCommentStart := Value; - Change; + if FSqlScriptCommentStart <> Value then + begin + FSqlScriptCommentStart := Value; + Change; + end; end; procedure TBoldSQLDataBaseConfig.SetSqlScriptCommentStop( const Value: string); begin - FSqlScriptCommentStop := Value; - Change; + if FSqlScriptCommentStop <> Value then + begin + FSqlScriptCommentStop := Value; + Change; + end; end; procedure TBoldSQLDataBaseConfig.SetSqlScriptSeparator( const Value: string); begin - FSqlScriptSeparator := Value; - Change; + if FSqlScriptSeparator <> Value then + begin + FSqlScriptSeparator := Value; + Change; + end; end; procedure TBoldSQLDataBaseConfig.SetSqlScriptStartTransaction( const Value: string); begin - FSqlScriptStartTransaction := Value; - Change; + if FSqlScriptStartTransaction <> Value then + begin + FSqlScriptStartTransaction := Value; + Change; + end; end; procedure TBoldSQLDataBaseConfig.SetSqlScriptTerminator( const Value: string); begin - FSqlScriptTerminator := Value; - Change; + if FSqlScriptTerminator <> Value then + begin + FSqlScriptTerminator := Value; + Change; + end; end; procedure TBoldSQLDataBaseConfig.SetSqlScriptCommitTransaction( const Value: string); begin - FSqlScriptCommitTransaction := Value; - Change; + if FSqlScriptCommitTransaction <> Value then + begin + FSqlScriptCommitTransaction := Value; + Change; + end; end; procedure TBoldSQLDataBaseConfig.SetSqlScriptRollBackTransaction( const Value: string); begin - FSqlScriptRollBackTransaction := Value; - Change; + if FSqlScriptRollBackTransaction <> Value then + begin + FSqlScriptRollBackTransaction := Value; + Change; + end; end; end. diff --git a/Source/BoldSQLDirectInterfaces.pas b/Source/BoldSQLDirectInterfaces.pas index 41087e4..a3834e3 100644 --- a/Source/BoldSQLDirectInterfaces.pas +++ b/Source/BoldSQLDirectInterfaces.pas @@ -1,11 +1,3 @@ - -///////////////////////////////////////////////////////// -// // -// Bold for Delphi // -// Copyright (c) 2002 BoldSoft AB, Sweden // -// // -///////////////////////////////////////////////////////// - { Global compiler directives } {$include bold.inc} unit BoldSQLDirectInterfaces; @@ -542,6 +534,7 @@ function TBoldSQLDirectDatabase.GetDatabaseError(const E: Exception; case ESDEngineError(E).ErrorCode of -2147217900, -2139062144, -2147467259, -1, 2, 53, 233, 6005: aErrorType := bdetConnection; 4060, 18456: aErrorType := bdetLogin; + end; end else @@ -646,6 +639,8 @@ procedure TBoldSQLDirectDatabase.ReleaseCachedObjects; FreeAndNil(fCachedQuery); end; +type TCollectionAccess = class(TCollection); + procedure TBoldSQLDirectDatabase.ReleaseQuery(var Query: IBoldQuery); var SDQuery: TBoldSQLDirectQuery; @@ -658,7 +653,11 @@ procedure TBoldSQLDirectDatabase.ReleaseQuery(var Query: IBoldQuery); if FCachedQuery.Active then FCachedQuery.Close; FCachedQuery.SQL.Clear; + while FCachedQuery.SQL.Updating do + FCachedQuery.SQL.EndUpdate; FCachedQuery.Params.Clear; + while TCollectionAccess(FCachedQuery.Params).UpdateCount > 0 do + FCachedQuery.Params.EndUpdate; end else SDQuery.FQuery.free; diff --git a/Source/BoldSystem.pas b/Source/BoldSystem.pas index 8fdf43f..b1653b2 100644 --- a/Source/BoldSystem.pas +++ b/Source/BoldSystem.pas @@ -231,6 +231,7 @@ TBoldAbstractRegionFactory = class(TBoldMemoryManagedObject) function GetDirtyObjects: TBoldObjectList; procedure DiscardChanges; procedure WriteChangesToDb; + procedure ClearObjects; property DirtyObjects: TBoldObjectList read GetDirtyObjects; end; @@ -242,7 +243,6 @@ TBoldTransactionHandler = class(TBoldRefCountedObject, IBoldTransactionHandler protected procedure Receive(Originator: TObject; OriginalEvent: TBoldEvent; RequestedEvent: TBoldRequestedEvent; const Args: array of const); virtual; function CanCommitOrRollback: boolean; -// property DirtyObjects: TBoldObjectList read GetDirtyObjects; function GetValueSpace: IBoldValueSpace; property Valuespace: IBoldValueSpace read GetValueSpace; procedure Commit; @@ -268,6 +268,7 @@ TBoldDirtyObjectTracker = class(TBoldRefCountedObject, IBoldDirtyObjectTracker procedure BeforeDestruction; override; procedure StartTracking; procedure StopTracking; + procedure ClearObjects; procedure DiscardChanges; procedure WriteChangesToDb; property DirtyObjects: TBoldObjectList read GetDirtyObjects; @@ -1679,6 +1680,11 @@ procedure TBoldDirtyObjectTracker.CheckStillDirty; fDirtyObjects.RemoveByIndex(i); end; +procedure TBoldDirtyObjectTracker.ClearObjects; +begin + fDirtyObjects.Clear; +end; + procedure TBoldDirtyObjectTracker.StartTracking; begin fBoldSystem.AddSmallSubscription(fSubscriber, [beObjectBecomingClean, beObjectBecomingDirty, beDirtyListInvalidOrItemDeleted], beDefaultRequestedEvent); @@ -5368,6 +5374,11 @@ function TBoldMember.StartModify: Boolean; begin if not (BoldPersistenceState in [bvpsCurrent, bvpsModified, bvpsTransient, bvpsInvalid]) then StateError('StartModify'); + if IsInitializing then + begin + result := true; + exit; + end; result := CanModify; if result and assigned(BoldSystem) and assigned(OwningObject) and assigned(BoldSystem.PessimisticLockHandler) and @@ -5423,8 +5434,11 @@ procedure TBoldMember.EndModify; {$ENDIF} if Derived and not (DeriverState in bdsIsDeriving) then Deriver.ReverseDerive; - CompleteModify; - SendExtendedEvent(beCompleteModify, [self]); + if not IsInitializing then + begin + CompleteModify; + SendExtendedEvent(beCompleteModify, [self]); + end; if OwnedByObject then begin System.AddToTransaction(OwningObject); diff --git a/Source/BoldUniDACInterfaces.pas b/Source/BoldUniDACInterfaces.pas index 95fec6f..805448a 100644 --- a/Source/BoldUniDACInterfaces.pas +++ b/Source/BoldUniDACInterfaces.pas @@ -1,13 +1,4 @@ - -///////////////////////////////////////////////////////// -// // -// Bold for Delphi // -// Copyright (c) 1996-2002 Boldsoft AB // -// (c) 2002-2005 Borland Software Corp // -// // -///////////////////////////////////////////////////////// - -{ Global compiler directives } +{ Global compiler directives } {$include bold.inc} unit BoldUniDACInterfaces; @@ -464,7 +455,7 @@ procedure TBoldUniDACQuery.ExecSQL; fReadTransactionStarted := fUseReadTransactions; end; Query.Execute; - if fReadTransactionStarted and (DatabaseWrapper as TBoldUniDACConnection).GetInTransaction then + if fReadTransactionStarted and (DatabaseWrapper as TBoldUniDACConnection).GetInTransaction then begin (DatabaseWrapper as TBoldUniDACConnection).Commit; fReadTransactionStarted := false; @@ -1160,6 +1151,8 @@ procedure TBoldUniDACConnection.Reconnect; end; end; +type TCollectionAccess = class(TCollection); + procedure TBoldUniDACConnection.ReleaseQuery(var Query: IBoldQuery); var lBoldUniDACQuery: TBoldUniDACQuery; @@ -1168,6 +1161,10 @@ procedure TBoldUniDACConnection.ReleaseQuery(var Query: IBoldQuery); begin lBoldUniDACQuery := Query.Implementor as TBoldUniDACQuery; lBoldUniDACQuery.clear; + while lBoldUniDACQuery.SQLStrings.Updating do + lBoldUniDACQuery.SQLStrings.EndUpdate; + while TCollectionAccess(lBoldUniDACQuery.Params).UpdateCount > 0 do + lBoldUniDACQuery.Params.EndUpdate; Query := nil; if not Assigned(fCachedQuery1) then fCachedQuery1 := lBoldUniDACQuery @@ -1186,13 +1183,15 @@ procedure TBoldUniDACConnection.ReleaseExecQuery(var Query: IBoldExecQuery); if (Query.Implementor is TBoldUniDACQuery) then begin lBoldUniDACQuery := Query.Implementor as TBoldUniDACQuery; - if lBoldUniDACQuery.GetSQLStrings.Count <> 0 then + if lBoldUniDACQuery.SQLStrings.Count <> 0 then begin - lBoldUniDACQuery.GetSQLStrings.BeginUpdate; + lBoldUniDACQuery.SQLStrings.BeginUpdate; lBoldUniDACQuery.clear; end; - while TStringsAccess(lBoldUniDACQuery.GetSQLStrings).UpdateCount > 0 do - lBoldUniDACQuery.GetSQLStrings.EndUpdate; + while lBoldUniDACQuery.SQLStrings.Updating do + lBoldUniDACQuery.SQLStrings.EndUpdate; + while TCollectionAccess(lBoldUniDACQuery.Params).UpdateCount > 0 do + lBoldUniDACQuery.Params.EndUpdate; Query := nil; if not Assigned(fCachedExecQuery1) then fCachedExecQuery1 := lBoldUniDACQuery