public void Type(IVersionType persistentType) { if (persistentType != null) { versionMapping.type = persistentType.Name; } }
public static VersionValue GetUnsavedVersionValue( String versionUnsavedValue, IGetter versionGetter, IVersionType versionType, ConstructorInfo constructor) { if (versionUnsavedValue == null) { if (constructor != null) { object defaultValue = versionGetter.Get(Instantiate(constructor)); if (defaultValue != null && defaultValue.GetType().IsValueType) { return(new VersionValue(defaultValue)); } else { // if the version of a newly instantiated object is not the same // as the version seed value, use that as the unsaved-value return (versionType.IsEqual(versionType.Seed(null), defaultValue) ? VersionValue.VersionUndefined : new VersionValue(defaultValue)); } } else { return(VersionValue.VersionUndefined); } } else if ("undefined" == versionUnsavedValue) { return(VersionValue.VersionUndefined); } else if ("null" == versionUnsavedValue) { return(VersionValue.VersionSaveNull); } else if ("negative" == versionUnsavedValue) { return(VersionValue.VersionNegative); } else { // NHibernate-specific try { return(new VersionValue(versionType.FromStringValue(versionUnsavedValue))); } catch (InvalidCastException ice) { throw new MappingException("Bad version type: " + versionType.Name, ice); } catch (Exception e) { throw new MappingException("Could not parse version unsaved-value: " + versionUnsavedValue, e); } } }
/// <summary> /// Sets the VersionColumn for the <c>DELETE</c> sql to use. /// </summary> /// <param name="columnNames">An array of the column names for the Property</param> /// <param name="versionType">The IVersionType of the Version Property.</param> /// <returns>The SqlDeleteBuilder.</returns> public SqlDeleteBuilder SetVersionColumn( string[ ] columnNames, IVersionType versionType ) { Parameter[ ] parameters = Parameter.GenerateParameters( Mapping, columnNames, versionType ); versionFragmentIndex = whereStrings.Add( ToWhereString( columnNames, parameters ) ); return this; }
/// <summary> /// Sets the VersionColumn for the <c>DELETE</c> sql to use. /// </summary> /// <param name="columnNames">An array of the column names for the Property</param> /// <param name="versionType">The IVersionType of the Version Property.</param> /// <returns>The SqlDeleteBuilder.</returns> public SqlDeleteBuilder SetVersionColumn(string[] columnNames, IVersionType versionType) { Parameter[] parameters = Parameter.GenerateParameters(Mapping, columnNames, versionType); versionFragmentIndex = whereStrings.Add(ToWhereString(columnNames, parameters)); return(this); }
/// <summary> /// Increment the given version number /// </summary> /// <param name="version">The value of the current version.</param> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> /// <param name="session">The current <see cref="ISession" />.</param> /// <returns>Returns the next value for the version.</returns> public static object Increment(object version, IVersionType versionType, ISessionImplementor session) { object next = versionType.Next(version, session); if (log.IsDebugEnabled) { log.Debug("Incrementing: " + version + " to " + next); } return next; }
public static VersionValue GetUnsavedVersionValue( String versionUnsavedValue, IGetter versionGetter, IVersionType versionType, ConstructorInfo constructor) { if (versionUnsavedValue == null) { if (constructor != null) { object defaultValue = versionGetter.Get(Instantiate(constructor)); if (defaultValue != null && defaultValue.GetType().IsValueType) return new VersionValue(defaultValue); else { // if the version of a newly instantiated object is not the same // as the version seed value, use that as the unsaved-value return versionType.IsEqual(versionType.Seed(null), defaultValue) ? VersionValue.VersionUndefined : new VersionValue(defaultValue); } } else { return VersionValue.VersionUndefined; } } else if ("undefined" == versionUnsavedValue) { return VersionValue.VersionUndefined; } else if ("null" == versionUnsavedValue) { return VersionValue.VersionSaveNull; } else if ("negative" == versionUnsavedValue) { return VersionValue.VersionNegative; } else { // NHibernate-specific try { return new VersionValue(versionType.FromStringValue(versionUnsavedValue)); } catch (InvalidCastException ice) { throw new MappingException("Bad version type: " + versionType.Name, ice); } catch (Exception e) { throw new MappingException("Could not parse version unsaved-value: " + versionUnsavedValue, e); } } }
/// <summary> /// Create an initial version number /// </summary> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> /// <param name="session">The current <see cref="ISession" />.</param> /// <returns>A seed value to initialize the versioned property with.</returns> public static object Seed(IVersionType versionType, ISessionImplementor session) { object seed = versionType.Seed(session); if (log.IsDebugEnabled) { log.Debug("Seeding: " + seed); } return seed; }
/// <summary> /// Create an initial version number /// </summary> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> /// <param name="session">The current <see cref="ISession" />.</param> /// <returns>A seed value to initialize the versioned property with.</returns> public static object Seed(IVersionType versionType, ISessionImplementor session) { object seed = versionType.Seed(session); if (log.IsDebugEnabled) { log.Debug("Seeding: " + seed); } return(seed); }
/// <summary> /// Create an initial version number /// </summary> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> /// <returns>A seed value to initialize the versioned property with.</returns> public static object Seed(IVersionType versionType) { object seed = versionType.Seed; if (log.IsDebugEnabled) { log.Debug("Seeding: " + seed); } return(seed); }
/// <summary> /// Increment the given version number /// </summary> /// <param name="version">The value of the current version.</param> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> /// <returns>Returns the next value for the version.</returns> public static object Increment(object version, IVersionType versionType) { object next = versionType.Next(version); if (log.IsDebugEnabled) { log.Debug("Incrementing: " + version + " to " + next); } return(next); }
/// <summary> /// Create an initial version number /// </summary> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> /// <param name="session">The current <see cref="ISession" />.</param> /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param> /// <returns>A seed value to initialize the versioned property with.</returns> public static async Task <object> SeedAsync(IVersionType versionType, ISessionImplementor session, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); object seed = await(versionType.SeedAsync(session, cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug("Seeding: {0}", seed); } return(seed); }
/// <summary> /// When a row already exists, choose the latest version /// </summary> public override bool ShouldOverwriteCurrentVersion(object entity, object currentVersion, object newVersion, IVersionType versionType) { if (versionType == null) { // always overwrite nonversioned data return(true); } return(versionType.Comparator.Compare(currentVersion, newVersion) <= 0); }
/// <summary> /// Increment the given version number /// </summary> /// <param name="version">The value of the current version.</param> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> /// <param name="session">The current <see cref="ISession" />.</param> /// <returns>Returns the next value for the version.</returns> public static object Increment(object version, IVersionType versionType, ISessionImplementor session) { object next = versionType.Next(version, session); if (log.IsDebugEnabled) { log.Debug( string.Format("Incrementing: {0} to {1}", versionType.ToLoggableString(version, session.Factory), versionType.ToLoggableString(next, session.Factory))); } return next; }
/// <summary> /// When a row already exists, choose the latest version /// </summary> public override bool ShouldOverwriteCurrentVersion(object entity, object currentVersion, object newVersion, IVersionType versionType) { if (versionType == null) { // always overwrite nonversioned data return true; } return versionType.Comparator.Compare(currentVersion, newVersion) <= 0; }
/// <summary> /// Increment the given version number /// </summary> /// <param name="version">The value of the current version.</param> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> /// <param name="session">The current <see cref="ISession" />.</param> /// <returns>Returns the next value for the version.</returns> public static object Increment(object version, IVersionType versionType, ISessionImplementor session) { object next = versionType.Next(version, session); if (log.IsDebugEnabled) { log.Debug( string.Format("Incrementing: {0} to {1}", versionType.ToLoggableString(version, session.Factory), versionType.ToLoggableString(next, session.Factory))); } return(next); }
void PrepareVersioned(IASTNode updateNode, IASTNode versioned) { var updateStatement = (UpdateStatement)updateNode; FromClause fromClause = updateStatement.FromClause; if (versioned != null) { // Make sure that the persister is versioned IQueryable persister = fromClause.GetFromElement().Queryable; if (!persister.IsVersioned) { throw new SemanticException("increment option specified for update of non-versioned entity"); } IVersionType versionType = persister.VersionType; if (versionType is IUserVersionType) { throw new SemanticException("user-defined version types not supported for increment option"); } IASTNode eq = ASTFactory.CreateNode(EQ, "="); IASTNode versionPropertyNode = GenerateVersionPropertyNode(persister); eq.SetFirstChild(versionPropertyNode); IASTNode versionIncrementNode; if (typeof(DateTime).IsAssignableFrom(versionType.ReturnedClass)) { versionIncrementNode = ASTFactory.CreateNode(PARAM, "?"); IParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification(versionType); ((ParameterNode)versionIncrementNode).HqlParameterSpecification = paramSpec; Parameters.Insert(0, paramSpec); } else { // Not possible to simply re-use the versionPropertyNode here as it causes // OOM errors due to circularity :( versionIncrementNode = ASTFactory.CreateNode(PLUS, "+"); versionIncrementNode.SetFirstChild(GenerateVersionPropertyNode(persister)); versionIncrementNode.AddChild(ASTFactory.CreateNode(IDENT, "1")); } eq.AddChild(versionIncrementNode); EvaluateAssignment(eq, persister, 0); IASTNode setClause = updateStatement.SetClause; IASTNode currentFirstSetElement = setClause.GetFirstChild(); setClause.SetFirstChild(eq); eq.NextSibling = currentFirstSetElement; } }
/// <summary> /// Increment the given version number /// </summary> /// <param name="version">The value of the current version.</param> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> /// <param name="session">The current <see cref="ISession" />.</param> /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param> /// <returns>Returns the next value for the version.</returns> public static async Task <object> IncrementAsync(object version, IVersionType versionType, ISessionImplementor session, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); object next = await(versionType.NextAsync(version, session, cancellationToken)).ConfigureAwait(false); if (log.IsDebugEnabled()) { log.Debug("Incrementing: {0} to {1}", versionType.ToLoggableString(version, session.Factory), versionType.ToLoggableString(next, session.Factory)); } return(next); }
/// <summary> /// Seed the given instance state snapshot with an initial version number /// </summary> /// <param name="fields">An array of objects that contains a snapshot of a persistent object.</param> /// <param name="versionProperty">The index of the version property in the <c>fields</c> parameter.</param> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> /// <param name="force">Force the version to initialize</param> /// <returns><c>true</c> if the version property needs to be seeded with an initial value.</returns> public static bool SeedVersion(object[] fields, int versionProperty, IVersionType versionType, bool force) { object initialVersion = fields[versionProperty]; if (initialVersion == null || force) { fields[versionProperty] = Seed(versionType); return(true); } else { if (log.IsDebugEnabled) { log.Debug("using initial version: " + initialVersion); } return(false); } }
/// <summary> /// Seed the given instance state snapshot with an initial version number /// </summary> /// <param name="fields">An array of objects that contains a snapshot of a persistent object.</param> /// <param name="versionProperty">The index of the version property in the <c>fields</c> parameter.</param> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> /// <param name="force">Force the version to initialize</param> /// <param name="session">The current session, if any.</param> /// <returns><see langword="true" /> if the version property needs to be seeded with an initial value.</returns> public static bool SeedVersion(object[] fields, int versionProperty, IVersionType versionType, bool? force, ISessionImplementor session) { object initialVersion = fields[versionProperty]; if (initialVersion == null || !force.HasValue || force.Value) { fields[versionProperty] = Seed(versionType, session); return true; } else { if (log.IsDebugEnabled) { log.Debug("using initial version: " + initialVersion); } return false; } }
/// <summary> /// Seed the given instance state snapshot with an initial version number /// </summary> /// <param name="fields">An array of objects that contains a snapshot of a persistent object.</param> /// <param name="versionProperty">The index of the version property in the <c>fields</c> parameter.</param> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> /// <param name="force">Force the version to initialize</param> /// <param name="session">The current session, if any.</param> /// <returns><see langword="true" /> if the version property needs to be seeded with an initial value.</returns> public static bool SeedVersion(object[] fields, int versionProperty, IVersionType versionType, bool?force, ISessionImplementor session) { object initialVersion = fields[versionProperty]; if (initialVersion == null || !force.HasValue || force.Value) { fields[versionProperty] = Seed(versionType, session); return(true); } else { if (log.IsDebugEnabled) { log.Debug("using initial version: " + initialVersion); } return(false); } }
/// <summary> /// /// </summary> /// <param name="entity"></param> /// <param name="currentVersion"></param> /// <param name="newVersion"></param> /// <param name="versionType"></param> /// <returns></returns> public abstract bool ShouldOverwriteCurrentVersion(object entity, object currentVersion, object newVersion, IVersionType versionType);
public VersionTypeSeedParameterSpecification(IVersionType type) { this.type = type; }
/// <summary> /// Gets the value of the version. /// </summary> /// <param name="fields">An array of objects that contains a snapshot of a persistent object.</param> /// <param name="versionProperty">The index of the version property in the <c>fields</c> parameter.</param> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> /// <returns>The value of the version.</returns> private static object GetVersion(object[] fields, int versionProperty, IVersionType versionType) { return(fields[versionProperty]); }
/// <summary> /// Overwrite existing rows when a row already exists /// </summary> /// <param name="entity"></param> /// <param name="currentVersion"></param> /// <param name="newVersion"></param> /// <param name="versionType"></param> /// <returns></returns> public override bool ShouldOverwriteCurrentVersion(object entity, object currentVersion, object newVersion, IVersionType versionType) { return(true); }
/// <summary> /// Sets the value of the version. /// </summary> /// <param name="fields">An array of objects that contains a snapshot of a persistent object.</param> /// <param name="version">The value the version should be set to in the <c>fields</c> parameter.</param> /// <param name="versionProperty">The index of the version property in the <c>fields</c> parameter.</param> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> private static void SetVersion(object[] fields, object version, int versionProperty, IVersionType versionType) { fields[versionProperty] = version; }
protected AbstractEntityPersister(PersistentClass persistentClass, ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory) { this.factory = factory; dialect = factory.Dialect; this.cache = cache; //sqlExceptionConverter = factory.SQLExceptionConverter; entityMetamodel = new EntityMetamodel(persistentClass, factory); // CLASS mappedClass = persistentClass.MappedClass; sqlWhereString = persistentClass.Where; sqlWhereStringTemplate = sqlWhereString == null ? null : Template.RenderWhereStringTemplate(sqlWhereString, Dialect, factory.SQLFunctionRegistry); batchSize = persistentClass.BatchSize; hasSubselectLoadableCollections = persistentClass.HasSubselectLoadableCollections; constructor = ReflectHelper.GetDefaultConstructor(mappedClass); // verify that the class has a default constructor if it is not abstract - it is considered // a mapping exception if the default ctor is missing. if (!entityMetamodel.IsAbstract && constructor == null) { throw new MappingException("The mapped class " + mappedClass.FullName + " must declare a default (no-arg) constructor."); } // IDENTIFIER hasEmbeddedIdentifier = persistentClass.HasEmbeddedIdentifier; IValue idValue = persistentClass.Identifier; if (persistentClass.HasIdentifierProperty) { Mapping.Property idProperty = persistentClass.IdentifierProperty; identifierSetter = idProperty.GetSetter(mappedClass); identifierGetter = idProperty.GetGetter(mappedClass); } else { identifierGetter = null; identifierSetter = null; } System.Type prox = persistentClass.ProxyInterface; MethodInfo proxySetIdentifierMethod = null; MethodInfo proxyGetIdentifierMethod = null; if (persistentClass.HasIdentifierProperty && prox != null) { Mapping.Property idProperty = persistentClass.IdentifierProperty; proxyGetIdentifierMethod = idProperty.GetGetter(prox).Method; proxySetIdentifierMethod = idProperty.GetSetter(prox).Method; } // HYDRATE SPAN hydrateSpan = persistentClass.PropertyClosureCollection.Count; // IDENTIFIER identifierColumnSpan = persistentClass.Identifier.ColumnSpan; rootTableKeyColumnNames = new string[identifierColumnSpan]; identifierAliases = new string[identifierColumnSpan]; loaderName = persistentClass.LoaderName; int i = 0; foreach (Column col in idValue.ColumnCollection) { rootTableKeyColumnNames[i] = col.GetQuotedName(factory.Dialect); identifierAliases[i] = col.GetAlias(Dialect, persistentClass.RootTable); i++; } // VERSION: if (persistentClass.IsVersioned) { foreach (Column col in persistentClass.Version.ColumnCollection) { versionColumnName = col.GetQuotedName(Dialect); break; //only happens once } } else { versionColumnName = null; } if (persistentClass.IsVersioned) { versionGetter = persistentClass.Version.GetGetter(mappedClass); versionType = (IVersionType) persistentClass.Version.Type; } else { versionGetter = null; versionType = null; } // PROPERTIES getters = new IGetter[hydrateSpan]; setters = new ISetter[hydrateSpan]; string[] setterNames = new string[hydrateSpan]; string[] getterNames = new string[hydrateSpan]; System.Type[] classes = new System.Type[hydrateSpan]; i = 0; // NH: reflection optimizer works with custom accessors //bool foundCustomAccessor = false; foreach (Mapping.Property prop in persistentClass.PropertyClosureCollection) { //if( !prop.IsBasicPropertyAccessor ) //{ // foundCustomAccessor = true; //} getters[i] = prop.GetGetter(mappedClass); setters[i] = prop.GetSetter(mappedClass); getterNames[i] = getters[i].PropertyName; setterNames[i] = setters[i].PropertyName; classes[i] = getters[i].ReturnType; string propertyName = prop.Name; gettersByPropertyName[propertyName] = getters[i]; settersByPropertyName[propertyName] = setters[i]; i++; } // PROPERTIES (FROM ABSTRACTENTITYPERSISTER SUBCLASSES) propertyColumnNames = new string[HydrateSpan][]; propertyColumnAliases = new string[HydrateSpan][]; propertyColumnSpans = new int[HydrateSpan]; propertyColumnFormulaTemplates = new string[HydrateSpan][]; propertyColumnUpdateable = new bool[HydrateSpan][]; propertyColumnInsertable = new bool[HydrateSpan][]; propertyUniqueness = new bool[HydrateSpan]; HashedSet thisClassProperties = new HashedSet(); i = 0; bool foundFormula = false; foreach (Mapping.Property prop in persistentClass.PropertyClosureCollection) { thisClassProperties.Add(prop); int span = prop.ColumnSpan; propertyColumnSpans[i] = span; string[] colNames = new string[span]; string[] colAliases = new string[span]; string[] templates = new string[span]; int k = 0; foreach (ISelectable thing in prop.ColumnCollection) { colAliases[k] = thing.GetAlias(factory.Dialect, prop.Value.Table); if (thing.IsFormula) { foundFormula = true; templates[k] = thing.GetTemplate(factory.Dialect, factory.SQLFunctionRegistry); } else { colNames[k] = thing.GetTemplate(factory.Dialect, factory.SQLFunctionRegistry); } k++; } propertyColumnNames[i] = colNames; propertyColumnFormulaTemplates[i] = templates; propertyColumnAliases[i] = colAliases; propertyColumnInsertable[i] = prop.Value.ColumnInsertability; propertyColumnUpdateable[i] = prop.Value.ColumnUpdateability; propertyUniqueness[i] = prop.Value.IsUnique; i++; } hasFormulaProperties = foundFormula; // NH: reflection optimizer works with custom accessors if (Environment.UseReflectionOptimizer) { optimizer = Environment.BytecodeProvider.GetReflectionOptimizer(MappedClass, Getters, Setters); } // SUBCLASS PROPERTY CLOSURE ArrayList columns = new ArrayList(); //this.subclassColumnClosure ArrayList aliases = new ArrayList(); ArrayList formulaAliases = new ArrayList(); ArrayList formulaTemplates = new ArrayList(); ArrayList types = new ArrayList(); //this.subclassPropertyTypeClosure ArrayList names = new ArrayList(); //this.subclassPropertyNameClosure ArrayList subclassTemplates = new ArrayList(); ArrayList propColumns = new ArrayList(); //this.subclassPropertyColumnNameClosure ArrayList joinedFetchesList = new ArrayList(); //this.subclassPropertyEnableJoinedFetch ArrayList cascades = new ArrayList(); ArrayList definedBySubclass = new ArrayList(); // this.propertyDefinedOnSubclass ArrayList formulas = new ArrayList(); ArrayList propNullables = new ArrayList(); foreach (Mapping.Property prop in persistentClass.SubclassPropertyClosureCollection) { names.Add(prop.Name); bool isDefinedBySubclass = !thisClassProperties.Contains(prop); definedBySubclass.Add(isDefinedBySubclass); propNullables.Add(prop.IsOptional || isDefinedBySubclass); //TODO: is this completely correct? types.Add(prop.Type); string[] cols = new string[prop.ColumnSpan]; string[] forms = new string[prop.ColumnSpan]; int[] colnos = new int[prop.ColumnSpan]; int[] formnos = new int[prop.ColumnSpan]; int l = 0; foreach (ISelectable thing in prop.ColumnCollection) { if (thing.IsFormula) { string template = thing.GetTemplate(factory.Dialect, factory.SQLFunctionRegistry); formnos[l] = formulaTemplates.Count; colnos[l] = -1; formulaTemplates.Add(template); forms[l] = template; formulas.Add(thing.GetText(factory.Dialect)); formulaAliases.Add(thing.GetAlias(factory.Dialect)); // TODO H3: formulasLazy.add( lazy ); } else { String colName = thing.GetTemplate(factory.Dialect, factory.SQLFunctionRegistry); colnos[l] = columns.Count; //before add :-) formnos[l] = -1; columns.Add(colName); cols[l] = colName; aliases.Add(thing.GetAlias(factory.Dialect, prop.Value.Table)); // TODO H3: columnsLazy.add( lazy ); // TODO H3: columnSelectables.add( new Boolean( prop.isSelectable() ) ); } l++; } propColumns.Add(cols); subclassTemplates.Add(forms); //propColumnNumbers.Add( colnos ); //propFormulaNumbers.Add( formnos ); joinedFetchesList.Add(prop.Value.FetchMode); cascades.Add(prop.CascadeStyle); } subclassColumnClosure = (string[]) columns.ToArray(typeof(string)); subclassFormulaClosure = (string[]) formulas.ToArray(typeof(string)); subclassFormulaTemplateClosure = (string[]) formulaTemplates.ToArray(typeof(string)); subclassPropertyTypeClosure = (IType[]) types.ToArray(typeof(IType)); subclassColumnAliasClosure = (string[]) aliases.ToArray(typeof(string)); subclassFormulaAliasClosure = (string[]) formulaAliases.ToArray(typeof(string)); subclassPropertyNameClosure = (string[]) names.ToArray(typeof(string)); subclassPropertyNullabilityClosure = (bool[]) propNullables.ToArray(typeof(bool)); subclassPropertyFormulaTemplateClosure = ArrayHelper.To2DStringArray(subclassTemplates); subclassPropertyColumnNameClosure = (string[][]) propColumns.ToArray(typeof(string[])); subclassPropertyCascadeStyleClosure = new Cascades.CascadeStyle[cascades.Count]; int m = 0; foreach (Cascades.CascadeStyle cs in cascades) { subclassPropertyCascadeStyleClosure[m++] = cs; } subclassPropertyFetchModeClosure = new FetchMode[joinedFetchesList.Count]; m = 0; foreach (FetchMode qq in joinedFetchesList) { subclassPropertyFetchModeClosure[m++] = qq; } propertyDefinedOnSubclass = new bool[definedBySubclass.Count]; m = 0; foreach (bool val in definedBySubclass) { propertyDefinedOnSubclass[m++] = val; } // CALLBACK INTERFACES implementsLifecycle = typeof(ILifecycle).IsAssignableFrom(mappedClass); implementsValidatable = typeof(IValidatable).IsAssignableFrom(mappedClass); // PROXIES concreteProxyClass = persistentClass.ProxyInterface; bool hasProxy = concreteProxyClass != null; if (hasProxy) { HashedSet proxyInterfaces = new HashedSet(); proxyInterfaces.Add(typeof(INHibernateProxy)); if (!mappedClass.Equals(concreteProxyClass)) { if (!concreteProxyClass.IsInterface) { throw new MappingException( "proxy must be either an interface, or the class itself: " + mappedClass.FullName); } proxyInterfaces.Add(concreteProxyClass); } if (mappedClass.IsInterface) { proxyInterfaces.Add(mappedClass); } if (HasProxy) { foreach (Subclass subclass in persistentClass.SubclassCollection) { System.Type subclassProxy = subclass.ProxyInterface; if (subclassProxy == null) { throw new MappingException("All subclasses must also have proxies: " + mappedClass.Name); } if (!subclass.MappedClass.Equals(subclassProxy)) { proxyInterfaces.Add(subclassProxy); } } } if (HasProxy) { proxyFactory = CreateProxyFactory(); proxyFactory.PostInstantiate(mappedClass, proxyInterfaces, proxyGetIdentifierMethod, proxySetIdentifierMethod); } else { proxyFactory = null; } } else { proxyFactory = null; } // Handle any filters applied to the class level filterHelper = new FilterHelper(persistentClass.FilterMap, factory.Dialect, factory.SQLFunctionRegistry); }
public abstract bool ShouldOverwriteCurrentVersion(object entity, object currentVersion, object newVersion, IVersionType versionType);
/// <summary> /// Throw an exception when a row already exists /// </summary> /// <param name="entity"></param> /// <param name="currentVersion"></param> /// <param name="newVersion"></param> /// <param name="versionType"></param> /// <returns></returns> public override bool ShouldOverwriteCurrentVersion( object entity, object currentVersion, object newVersion, IVersionType versionType ) { throw new NotSupportedException( "should not be called" ); }
/// <summary> /// Throw an exception when a row already exists /// </summary> public override bool ShouldOverwriteCurrentVersion(object entity, object currentVersion, object newVersion, IVersionType versionType) { throw new AssertionFailure("should not be called"); }
/// <summary> /// Throw an exception when a row already exists /// </summary> /// <param name="entity"></param> /// <param name="currentVersion"></param> /// <param name="newVersion"></param> /// <param name="versionType"></param> /// <returns></returns> public override bool ShouldOverwriteCurrentVersion(object entity, object currentVersion, object newVersion, IVersionType versionType) { throw new NotSupportedException("should not be called"); }
/// <summary> /// Overwrite existing rows when a row already exists /// </summary> public override bool ShouldOverwriteCurrentVersion(object entity, object currentVersion, object newVersion, IVersionType versionType) { return true; }
/// <summary> /// Seed the given instance state snapshot with an initial version number /// </summary> /// <param name="fields">An array of objects that contains a snapshot of a persistent object.</param> /// <param name="versionProperty">The index of the version property in the <c>fields</c> parameter.</param> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> /// <param name="force">Force the version to initialize</param> /// <param name="session">The current session, if any.</param> /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param> /// <returns><see langword="true" /> if the version property needs to be seeded with an initial value.</returns> public static async Task <bool> SeedVersionAsync(object[] fields, int versionProperty, IVersionType versionType, bool?force, ISessionImplementor session, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); object initialVersion = fields[versionProperty]; if (initialVersion == null || !force.HasValue || force.Value) { fields[versionProperty] = await(SeedAsync(versionType, session, cancellationToken)).ConfigureAwait(false); return(true); } else { if (log.IsDebugEnabled()) { log.Debug("using initial version: {0}", initialVersion); } return(false); } }
/// <summary> /// Sets the VersionColumn for the <c>SELECT</c> sql to use. /// </summary> /// <param name="columnNames">An array of the column names for the Property</param> /// <param name="versionType">The IVersionType of the Version Property.</param> /// <returns>The SqlSimpleSelectBuilder.</returns> public SqlSimpleSelectBuilder SetVersionColumn(string[] columnNames, IVersionType versionType) { whereStrings.Add(ToWhereString(columnNames)); return this; }
protected AbstractEntityPersister( PersistentClass model, ISessionFactoryImplementor factory ) { dialect = factory.Dialect; //sqlExceptionConverter = factory.SQLExceptionConverter; // CLASS className = model.MappedClass.FullName; rootClassName = model.RootClazz.Name; mappedClass = model.MappedClass; mutable = model.IsMutable; selectBeforeUpdate = model.SelectBeforeUpdate; dynamicUpdate = model.DynamicUpdate; dynamicInsert = model.DynamicInsert; sqlWhereString = model.Where; sqlWhereStringTemplate = sqlWhereString == null ? null : Template.RenderWhereStringTemplate( sqlWhereString, Dialect ); polymorphic = model.IsPolymorphic; explicitPolymorphism = model.IsExplicitPolymorphism; inherited = model.IsInherited; superclass = inherited ? model.Superclass.MappedClass : null; hasSubclasses = model.HasSubclasses; batchSize = model.BatchSize; constructor = ReflectHelper.GetDefaultConstructor( mappedClass ); abstractClass = ReflectHelper.IsAbstractClass( mappedClass ); entityType = NHibernateUtil.Entity( mappedClass ); optimisticLockMode = model.OptimisticLockMode; if( optimisticLockMode > OptimisticLockMode.Version && !dynamicUpdate ) { throw new MappingException( string.Format( "optimistic-lock setting requires dynamic-update=\'true\': {0}", className ) ); } // verify that the class has a default constructor if it is not abstract - it is considered // a mapping exception if the default ctor is missing. if( abstractClass == false && constructor == null ) { throw new MappingException( "The mapped class " + mappedClass.FullName + " must declare a default (no-arg) constructor." ); } // IDENTIFIER hasEmbeddedIdentifier = model.HasEmbeddedIdentifier; IValue idValue = model.Identifier; identifierType = idValue.Type; if( model.HasIdentifierProperty ) { Mapping.Property idProperty = model.IdentifierProperty; identifierPropertyName = idProperty.Name; identifierSetter = idProperty.GetSetter( mappedClass ); identifierGetter = idProperty.GetGetter( mappedClass ); } else { identifierPropertyName = null; identifierGetter = null; identifierSetter = null; } System.Type prox = model.ProxyInterface; MethodInfo proxySetIdentifierMethod = null; MethodInfo proxyGetIdentifierMethod = null; if( model.HasIdentifierProperty && prox != null ) { Mapping.Property idProperty = model.IdentifierProperty; PropertyInfo getIdPropertyInfo = idProperty.GetGetter( prox ).Property; if( getIdPropertyInfo != null ) { proxyGetIdentifierMethod = getIdPropertyInfo.GetGetMethod( true ); } PropertyInfo setIdPropertyInfo = idProperty.GetSetter( prox ).Property; if( setIdPropertyInfo != null ) { proxySetIdentifierMethod = setIdPropertyInfo.GetSetMethod( true ); } } // HYDRATE SPAN hydrateSpan = model.PropertyClosureCollection.Count; // IDENTIFIER int idColumnSpan = model.Identifier.ColumnSpan; identifierColumnNames = new string[idColumnSpan]; identifierAliases = new string[idColumnSpan]; int i = 0; foreach( Column col in idValue.ColumnCollection ) { identifierColumnNames[ i ] = col.GetQuotedName( Dialect ); identifierAliases[ i ] = col.Alias( Dialect ); i++; } // GENERATOR identifierGenerator = model.Identifier.CreateIdentifierGenerator( Dialect ); useIdentityColumn = identifierGenerator is IdentityGenerator; identitySelectString = useIdentityColumn ? dialect.IdentitySelectString : null; // UNSAVED-VALUE: unsavedIdentifierValue = UnsavedValueFactory.GetUnsavedIdentifierValue( model.Identifier.NullValue, identifierGetter, identifierType, constructor ); // VERSION: if( model.IsVersioned ) { foreach( Column col in model.Version.ColumnCollection ) { versionColumnName = col.GetQuotedName( Dialect ); break; //only happens once } } else { versionColumnName = null; } if( model.IsVersioned ) { //versionPropertyName = model.Version.Name; versioned = true; versionGetter = model.Version.GetGetter( mappedClass ); versionType = ( IVersionType ) model.Version.Type; } else { //versionPropertyName = null; versioned = false; versionGetter = null; versionType = null; } // VERSION UNSAVED-VALUE: unsavedVersionValue = model.IsVersioned ? UnsavedValueFactory.GetUnsavedVersionValue( model.Version.NullValue, versionGetter, versionType, constructor ) : Cascades.VersionValue.VersionUndefined; // PROPERTIES propertyTypes = new IType[hydrateSpan]; propertyNames = new string[hydrateSpan]; propertyUpdateability = new bool[hydrateSpan]; propertyInsertability = new bool[hydrateSpan]; propertyNullability = new bool[hydrateSpan]; getters = new IGetter[hydrateSpan]; setters = new ISetter[hydrateSpan]; cascadeStyles = new Cascades.CascadeStyle[hydrateSpan]; string[ ] setterNames = new string[hydrateSpan]; string[ ] getterNames = new string[hydrateSpan]; System.Type[ ] types = new System.Type[hydrateSpan]; i = 0; int tempVersionProperty = -66; bool foundCascade = false; bool foundCustomAccessor = false; foreach( Mapping.Property prop in model.PropertyClosureCollection ) { if( prop == model.Version ) { tempVersionProperty = i; } propertyNames[ i ] = prop.Name; if( !prop.IsBasicPropertyAccessor ) { foundCustomAccessor = true; } getters[ i ] = prop.GetGetter( mappedClass ); setters[ i ] = prop.GetSetter( mappedClass ); getterNames[ i ] = getters[ i ].PropertyName; setterNames[ i ] = setters[ i ].PropertyName; types[ i ] = getters[ i ].ReturnType; propertyTypes[ i ] = prop.Type; propertyUpdateability[ i ] = prop.IsUpdateable; propertyInsertability[ i ] = prop.IsInsertable; propertyNullability[ i ] = prop.IsNullable; gettersByPropertyName[ propertyNames[ i ] ] = getters[ i ]; settersByPropertyName[ propertyNames[ i ] ] = setters[ i ]; typesByPropertyName[ propertyNames[ i ] ] = propertyTypes[ i ]; cascadeStyles[ i ] = prop.CascadeStyle; if( cascadeStyles[ i ] != Cascades.CascadeStyle.StyleNone ) { foundCascade = true; } i++; } // NH: reflection optimizer works with custom accessors if( /*!foundCustomAccessor &&*/ Cfg.Environment.UseReflectionOptimizer ) { getset = GetSetHelperFactory.Create( MappedClass, Setters, Getters ); } hasCascades = foundCascade; versionProperty = tempVersionProperty; // CALLBACK INTERFACES implementsLifecycle = typeof( ILifecycle ).IsAssignableFrom( mappedClass ); implementsValidatable = typeof( IValidatable ).IsAssignableFrom( mappedClass ); cache = model.Cache; hasCollections = InitHasCollections(); // PROXIES concreteProxyClass = model.ProxyInterface; hasProxy = concreteProxyClass != null; if( hasProxy ) { HashedSet proxyInterfaces = new HashedSet(); proxyInterfaces.Add( typeof( INHibernateProxy ) ); if( !mappedClass.Equals( concreteProxyClass ) ) { if( !concreteProxyClass.IsInterface ) { throw new MappingException( "proxy must be either an interface, or the class itself: " + mappedClass.FullName ); } proxyInterfaces.Add( concreteProxyClass ); } if( mappedClass.IsInterface ) { proxyInterfaces.Add( mappedClass ); } if( hasProxy ) { foreach( Subclass subclass in model.SubclassCollection ) { System.Type subclassProxy = subclass.ProxyInterface; if( subclassProxy == null ) { throw new MappingException( "All subclasses must also have proxies: " + mappedClass.Name ); } if( !subclass.MappedClass.Equals( subclassProxy ) ) { proxyInterfaces.Add( subclassProxy ); } } } if( hasProxy ) { proxyFactory = CreateProxyFactory(); proxyFactory.PostInstantiate( mappedClass, proxyInterfaces, proxyGetIdentifierMethod, proxySetIdentifierMethod ); } else { proxyFactory = null; } } else { proxyFactory = null; } }
/// <summary> /// Sets the VersionColumn for the <c>DELETE</c> sql to use. /// </summary> /// <param name="columnNames">An array of the column names for the Property</param> /// <param name="versionType">The IVersionType of the Version Property.</param> /// <returns>The SqlDeleteBuilder.</returns> public SqlDeleteBuilder SetVersionColumn(string[] columnNames, IVersionType versionType) { whereStrings.Add(ToWhereString(columnNames)); parameterTypes.AddRange(versionType.SqlTypes(Mapping)); return this; }
/// <summary> /// Gets the value of the version. /// </summary> /// <param name="fields">An array of objects that contains a snapshot of a persistent object.</param> /// <param name="versionProperty">The index of the version property in the <c>fields</c> parameter.</param> /// <param name="versionType">The <see cref="IVersionType"/> of the versioned property.</param> /// <returns>The value of the version.</returns> private static object GetVersion(object[] fields, int versionProperty, IVersionType versionType) { return fields[versionProperty]; }
void PostProcessInsert(IASTNode insert) { var insertStatement = (InsertStatement)insert; insertStatement.Validate(); SelectClause selectClause = insertStatement.SelectClause; var persister = insertStatement.IntoClause.Queryable; if (!insertStatement.IntoClause.IsExplicitIdInsertion) { // We need to generate ids as part of this bulk insert. // // Note that this is only supported for sequence-style generators and // post-insert-style generators; basically, only in-db generators IIdentifierGenerator generator = persister.IdentifierGenerator; if (!SupportsIdGenWithBulkInsertion(generator)) { throw new QueryException("can only generate ids as part of bulk insert with either sequence or post-insert style generators"); } IASTNode idSelectExprNode = null; var seqGenerator = generator as SequenceGenerator; if (seqGenerator != null) { string seqName = seqGenerator.GeneratorKey(); string nextval = SessionFactoryHelper.Factory.Dialect.GetSelectSequenceNextValString(seqName); idSelectExprNode = ASTFactory.CreateNode(SQL_TOKEN, nextval); } else { //Don't need this, because we should never ever be selecting no columns in an insert ... select... //and because it causes a bug on DB2 /*String idInsertString = sessionFactoryHelper.getFactory().getDialect().getIdentityInsertString(); * if ( idInsertString != null ) { * idSelectExprNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, idInsertString ); * }*/ } if (idSelectExprNode != null) { selectClause.InsertChild(0, idSelectExprNode); insertStatement.IntoClause.PrependIdColumnSpec(); } } bool includeVersionProperty = persister.IsVersioned && !insertStatement.IntoClause.IsExplicitVersionInsertion && persister.VersionPropertyInsertable; if (includeVersionProperty) { // We need to seed the version value as part of this bulk insert IVersionType versionType = persister.VersionType; IASTNode versionValueNode; if (SessionFactoryHelper.Factory.Dialect.SupportsParametersInInsertSelect) { versionValueNode = ASTFactory.CreateNode(PARAM, "?"); IParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification(versionType); ((ParameterNode)versionValueNode).HqlParameterSpecification = paramSpec; _parameters.Insert(0, paramSpec); } else { if (IsIntegral(versionType)) { try { object seedValue = versionType.Seed(null); versionValueNode = ASTFactory.CreateNode(SQL_TOKEN, seedValue.ToString()); } catch (Exception t) { throw new QueryException("could not determine seed value for version on bulk insert [" + versionType + "]", t); } } else if (IsDatabaseGeneratedTimestamp(versionType)) { string functionName = SessionFactoryHelper.Factory.Dialect.CurrentTimestampSQLFunctionName; versionValueNode = ASTFactory.CreateNode(SQL_TOKEN, functionName); } else { throw new QueryException("cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements"); } } selectClause.InsertChild(0, versionValueNode); insertStatement.IntoClause.PrependVersionColumnSpec(); } if (insertStatement.IntoClause.IsDiscriminated) { string sqlValue = insertStatement.IntoClause.Queryable.DiscriminatorSQLValue; IASTNode discrimValue = ASTFactory.CreateNode(SQL_TOKEN, sqlValue); insertStatement.SelectClause.AddChild(discrimValue); } }
/// <summary> /// Sets the VersionColumn for the <c>DELETE</c> sql to use. /// </summary> /// <param name="columnNames">An array of the column names for the Property</param> /// <param name="versionType">The IVersionType of the Version Property.</param> /// <returns>The SqlDeleteBuilder.</returns> public SqlDeleteBuilder SetVersionColumn(string[] columnNames, IVersionType versionType) { whereStrings.Add(ToWhereString(columnNames)); parameterTypes.AddRange(versionType.SqlTypes(Mapping)); return(this); }
/// <summary> /// Sets the VersionColumn for the <c>SELECT</c> sql to use. /// </summary> /// <param name="columnNames">An array of the column names for the Property</param> /// <param name="versionType">The IVersionType of the Version Property.</param> /// <returns>The SqlSimpleSelectBuilder.</returns> public SqlSimpleSelectBuilder SetVersionColumn(string[] columnNames, IVersionType versionType) { whereStrings.Add(ToWhereString(columnNames)); return(this); }