You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(248) |
May
(82) |
Jun
(90) |
Jul
(177) |
Aug
(253) |
Sep
(157) |
Oct
(151) |
Nov
(143) |
Dec
(278) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(152) |
Feb
(107) |
Mar
(177) |
Apr
(133) |
May
(259) |
Jun
(81) |
Jul
(119) |
Aug
(306) |
Sep
(416) |
Oct
(240) |
Nov
(329) |
Dec
(206) |
2006 |
Jan
(466) |
Feb
(382) |
Mar
(153) |
Apr
(162) |
May
(133) |
Jun
(21) |
Jul
(18) |
Aug
(37) |
Sep
(97) |
Oct
(114) |
Nov
(110) |
Dec
(28) |
2007 |
Jan
(74) |
Feb
(65) |
Mar
(49) |
Apr
(76) |
May
(43) |
Jun
(15) |
Jul
(68) |
Aug
(55) |
Sep
(63) |
Oct
(59) |
Nov
(70) |
Dec
(66) |
2008 |
Jan
(71) |
Feb
(60) |
Mar
(120) |
Apr
(31) |
May
(48) |
Jun
(81) |
Jul
(107) |
Aug
(51) |
Sep
(80) |
Oct
(83) |
Nov
(83) |
Dec
(79) |
2009 |
Jan
(83) |
Feb
(110) |
Mar
(97) |
Apr
(91) |
May
(291) |
Jun
(250) |
Jul
(197) |
Aug
(58) |
Sep
(54) |
Oct
(122) |
Nov
(68) |
Dec
(34) |
2010 |
Jan
(50) |
Feb
(17) |
Mar
(63) |
Apr
(61) |
May
(84) |
Jun
(81) |
Jul
(138) |
Aug
(144) |
Sep
(78) |
Oct
(26) |
Nov
(30) |
Dec
(61) |
2011 |
Jan
(33) |
Feb
(35) |
Mar
(166) |
Apr
(221) |
May
(109) |
Jun
(76) |
Jul
(27) |
Aug
(37) |
Sep
(1) |
Oct
(4) |
Nov
(2) |
Dec
(1) |
2012 |
Jan
|
Feb
|
Mar
(2) |
Apr
(2) |
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
(1) |
Oct
|
Nov
(1) |
Dec
|
2013 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(3) |
Oct
(2) |
Nov
|
Dec
(1) |
2014 |
Jan
(1) |
Feb
(1) |
Mar
(3) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <jul...@us...> - 2011-02-10 15:25:39
|
Revision: 5378 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5378&view=rev Author: julian-maughan Date: 2011-02-10 15:25:32 +0000 (Thu, 10 Feb 2011) Log Message: ----------- Adding first draft of 'read-only entity' documentation Modified Paths: -------------- branches/ReadOnlyEntities/nhibernate/doc/reference/master.xml Added Paths: ----------- branches/ReadOnlyEntities/nhibernate/doc/reference/modules/readonly.xml Modified: branches/ReadOnlyEntities/nhibernate/doc/reference/master.xml =================================================================== --- branches/ReadOnlyEntities/nhibernate/doc/reference/master.xml 2011-02-10 14:29:39 UTC (rev 5377) +++ branches/ReadOnlyEntities/nhibernate/doc/reference/master.xml 2011-02-10 15:25:32 UTC (rev 5378) @@ -13,13 +13,14 @@ <!ENTITY manipulating-data SYSTEM "modules/manipulating_data.xml"> <!ENTITY transactions SYSTEM "modules/transactions.xml"> <!ENTITY events SYSTEM "modules/events.xml"> -<!ENTITY batch SYSTEM "modules/batch.xml"> +<!ENTITY batch SYSTEM "modules/batch.xml"> <!ENTITY query-hql SYSTEM "modules/query_hql.xml"> <!ENTITY query-criteria SYSTEM "modules/query_criteria.xml"> <!ENTITY query-queryover SYSTEM "modules/query_queryover.xml"> <!ENTITY query-sql SYSTEM "modules/query_sql.xml"> <!ENTITY filters SYSTEM "modules/filters.xml"> <!ENTITY performance SYSTEM "modules/performance.xml"> +<!ENTITY read-only SYSTEM "modules/readonly.xml"> <!ENTITY toolset-guide SYSTEM "modules/toolset_guide.xml"> <!ENTITY example-parentchild SYSTEM "modules/example_parentchild.xml"> <!ENTITY example-weblog SYSTEM "modules/example_weblog.xml"> @@ -38,7 +39,7 @@ <bookinfo> <title>NHibernate - Relational Persistence for Idiomatic .NET</title> <subtitle>NHibernate Reference Documentation</subtitle> - <releaseinfo>3.0.0</releaseinfo> + <releaseinfo>3.0.1</releaseinfo> </bookinfo> <toc /> @@ -59,6 +60,7 @@ &inheritance-mapping; &manipulating-data; + &read-only; &transactions; &events; &batch; Added: branches/ReadOnlyEntities/nhibernate/doc/reference/modules/readonly.xml =================================================================== --- branches/ReadOnlyEntities/nhibernate/doc/reference/modules/readonly.xml (rev 0) +++ branches/ReadOnlyEntities/nhibernate/doc/reference/modules/readonly.xml 2011-02-10 15:25:32 UTC (rev 5378) @@ -0,0 +1,823 @@ +<chapter id="readonly"> + <title>Read-only entities</title> + + <important> + <para> + NHibernate's treatment of <emphasis>read-only</emphasis> entities may + differ from what you may have encountered elsewhere. Incorrect usage + may cause unexpected results. + </para> + </important> + + <para> + When an entity is read-only: + + <itemizedlist> + <listitem> + <para> + NHibernate does not dirty-check the entity's simple + properties or single-ended associations; + </para> + </listitem> + <listitem> + <para> + NHibernate will not update simple properties or updatable + single-ended associations; + </para> + </listitem> + <listitem> + <para> + NHibernate will not update the version of the read-only + entity if only simple properties or single-ended + updatable associations are changed; + </para> + </listitem> + </itemizedlist> + </para> + + <para> + In some ways, NHibernate treats read-only entities the same as entities that are + not read-only: + + <itemizedlist> + <listitem> + <para> + NHibernate cascades operations to associations as + defined in the entity mapping. + </para> + </listitem> + <listitem> + <para> + NHibernate updates the version if the entity has a + collection with changes that dirties the entity; + </para> + </listitem> + <listitem> + <para> + A read-only entity can be deleted. + </para> + </listitem> + </itemizedlist> + </para> + + <para> + Even if an entity is not read-only, its collection association can + be affected if it contains a read-only entity. + </para> + + <para> + For details about the affect of read-only entities on different + property and association types, see + <xref linkend="readonly-proptypes"/>. + </para> + + <para> + For details about how to make entities read-only, see + <xref linkend="readonly-api"/> + </para> + + <para> + NHibernate does some optimizing for read-only entities: + </para> + <itemizedlist> + <listitem> + <para> + It saves execution time by not dirty-checking simple properties or + single-ended associations. + </para> + </listitem> + <listitem> + <para> + It saves memory by deleting database snapshots. + </para> + </listitem> + </itemizedlist> + + <section id="readonly-api"> + <title>Making persistent entities read-only</title> + + <para> + Only persistent entities can be made read-only. Transient and + detached entities must be put in persistent state before they + can be made read-only. + </para> + + <para> + NHibernate provides the following ways to make persistent entities read-only: + </para> + + <itemizedlist> + <listitem> + <para> + you can map an entity class as <emphasis>immutable</emphasis>; + when an entity of an immutable class is made persistent, + NHibernate automatically makes it read-only. + see <xref linkend="readonly-api-immutable"/> for details + </para> + </listitem> + <listitem> + <para> + you can change a default so that entities loaded + into the session by NHibernate are automatically + made read-only; see <xref linkend="readonly-api-loaddefault"/> for details + </para> + </listitem> + <listitem> + <para> + you can make an HQL query or criteria read-only so + that entities loaded when the query or criteria executes, + or iterates, are automatically + made read-only; see <xref linkend="readonly-api-querycriteria"/> for details + </para> + </listitem> + <listitem> + <para> + you can make a persistent entity that is already in the + in the session read-only; see + <xref linkend="readonly-api-entity"/> for details + </para> + </listitem> + </itemizedlist> + + <section id="readonly-api-immutable"> + <title>Entities of immutable classes</title> + + <para> + When an entity instance of an immutable class is made + persistent, NHibernate automatically makes it read-only. + </para> + <para> + An entity of an immutable class can created + and deleted the same as an entity of a mutable class. + </para> + + <para> + NHibernate treats a persistent entity of an immutable + class the same way as a read-only persistent entity + of a mutable class. The only exception is that + NHibernate will not allow an entity of an immutable + class to be changed so it is not read-only. + </para> + + </section> + + <section id="readonly-api-loaddefault"> + <title>Loading persistent entities as read-only</title> + + <note> + <para> + Entities of immutable classes are automatically loaded + as read-only. + </para> + </note> + + <para> + To change the default behavior so NHibernate loads entity + instances of mutable classes into the session and automatically + makes them read-only, call: + </para> + <programlisting role="c#">Session.DefaultReadOnly = true;</programlisting> + + <para> + To change the default back so entities loaded by NHibernate are not + made read-only, call: + </para> + <programlisting role="c#">Session.DefaultReadOnly = false;</programlisting> + + <para> + You can determine the current setting by using the property: + </para> + <programlisting role="c#">Session.DefaultReadOnly;</programlisting> + + <para> + If Session.DefaultReadOnly property returns true, entities loaded by + the following are automatically made read-only: + </para> + <itemizedlist> + <listitem> + <para> + Session.Load() and Session.Load<T> + </para> + </listitem> + <listitem> + <para> + Session.Get() and Session.Get<T> + </para> + </listitem> + <listitem> + <para> + Session.Merge() + </para> + </listitem> + <listitem> + <para> + executing, or iterating HQL queries and + criteria; to override this setting for a particular + HQL query or criteria see + <xref linkend="readonly-api-querycriteria"/> + </para> + </listitem> + </itemizedlist> + + <para> + Changing this default has no effect on: + </para> + <itemizedlist> + <listitem> + <para> + persistent entities already in the session when the + default was changed + </para> + </listitem> + <listitem> + <para> + persistent entities that are refreshed via + Session.Refresh(); a refreshed persistent + entity will only be read-only if it was + read-only before refreshing + </para> + </listitem> + <listitem> + <para> + persistent entities added by the application via + Session.Persist(), Session.Save(), and Session.Update() + Session.SaveOrUpdate() + </para> + </listitem> + </itemizedlist> + + </section> + + <section id="readonly-api-querycriteria"> + <title>Loading read-only entities from an HQL query/criteria</title> + + <note> + <para> + Entities of immutable classes are automatically loaded + as read-only. + </para> + </note> + + <para> + If Session.DefaultReadOnly returns false (the default) + when an HQL query or criteria executes, then entities + and proxies of mutable classes loaded by the query will + not be read-only. + </para> + + <para> + You can override this behavior so that entities and proxies loaded + by an HQL query or criteria are automatically made read-only. + </para> + + <para> + For an HQL query, call: + </para> + <programlisting role="c#">Query.SetReadOnly(true);</programlisting> + + <para> + <literal>Query.SetReadOnly(true)</literal> must be called before + <literal>Query.List()</literal>, <literal>Query.UniqueResult()</literal>, or <literal>Query.Iterate()</literal> + </para> + + <para> + For an HQL criteria, call: + </para> + <programlisting role="c#">Criteria.SetReadOnly(true);</programlisting> + + <para> + <literal>Criteria.SetReadOnly(true)</literal> must be called before + <literal>Criteria.List()</literal>, or <literal>Criteria.UniqueResult()</literal> + </para> + + <para> + Entities and proxies that exist in the session before being returned + by an HQL query or criteria are not affected. + </para> + + <para> + Uninitialized persistent collections returned by the query are + not affected. Later, when the collection is initialized, + entities loaded into the session will be read-only if + Session.DefaultReadOnly returns true. + </para> + + <para> + Using <literal>Query.SetReadOnly(true)</literal> or + <literal>Criteria.SetReadOnly(true)</literal> works well + when a single HQL query or criteria loads all the entities and + intializes all the proxies and collections that the application + needs to be read-only. + </para> + + <para> + When it is not possible to load and initialize all + necessary entities in a single query or criteria, + you can temporarily change the session default to load + entities as read-only before the query is executed. + Then you can explicitly initialize proxies and collections + before restoring the session default. + </para> + + <programlisting role="c#"> +ISession session = factory.OpenSession(); +ITransaction tx = session.BeginTransaction(); + +session.DefaultReadOnly = true; +Contract contract = session.CreateQuery("from Contract where CustomerName = 'Sherman'").UniqueResult<Contract>(); +NHibernate.Initialize(contract.Plan); +NHibernate.Initialize(contract.Variations); +NHibernate.Initialize(contract.Notes); +session.DefaultReadOnly = false; +... +tx.Commit(); +session.Close(); + +</programlisting> + + <para> + If Session.DefaultReadOnly returns true, then you can + use Query.SetReadOnly(false) and Criteria.SetReadOnly(false) + to override this session setting and load entities that are + not read-only. + </para> + + </section> + + <section id="readonly-api-entity"> + <title>Making a persistent entity read-only</title> + <note> + <para> + Persistent entities of immutable classes are automatically + made read-only. + </para> + </note> + + <para> + To make a persistent entity or proxy read-only, call: + </para> + <programlisting>Session.SetReadOnly(entityOrProxy, true)</programlisting> + + <para> + To change a read-only entity or proxy of a mutable class so + it is no longer read-only, call: + </para> + <programlisting>Session.SetReadOnly(entityOrProxy, false)</programlisting> + + <important> + <para> + When a read-only entity or proxy is changed so it is no longer + read-only, NHibernate assumes that the current state of the + read-only entity is consistent with its database representation. + If this is not true, then any non-flushed changes made before + or while the entity was read-only, will be ignored. + </para> + </important> + + <para> + To throw away non-flushed changes and make the persistent entity + consistent with its database representation, call: + </para> + <programlisting role="c#">Session.Refresh(entity);</programlisting> + + <para> + To flush changes made before or while the entity + was read-only and make the database representation + consistent with the current state of the persistent + entity: + </para> +<programlisting role="c#"> +// evict the read-only entity so it is detached +session.Evict(entity); + +// make the detached entity (with the non-flushed changes) persistent +session.Update(entity); + +// now entity is no longer read-only and its changes can be flushed +s.Flush(); +</programlisting> + </section> + </section> + + <section id="readonly-proptypes"> + <title>Read-only affect on property type</title> + + <para> + The following table summarizes how different property types are + affected by making an entity read-only. + </para> + + <table frame="topbot" id="readonly-proptype-summary"> + <title>Affect of read-only entity on property types</title> + <tgroup cols="2"> + <colspec colwidth="1*"/> + <colspec colwidth="1*"/> + <thead> + <row> + <entry>Property/Association Type</entry> + <entry>Changes flushed to DB?</entry> + </row> + </thead> + <tbody> + <row> + <entry> + Simple + <para> + (<xref linkend="readonly-proptypes-simple"/>) + </para> + </entry> + <entry>no*</entry> + </row> + <row> + <entry> + <para>Unidirectional one-to-one</para> + <para>Unidirectional many-to-one</para> + <para> + (<xref linkend="readonly-proptypes-singleended-unidir"/>) + </para> + </entry> + + <entry> + <para>no*</para> + <para>no*</para> + </entry> + </row> + <row> + <entry> + <para>Unidirectional one-to-many</para> + <para>Unidirectional many-to-many</para> + <para> + (<xref linkend="readonly-proptypes-manyended-unidir"/>) + </para> + </entry> + <entry> + <para>yes</para> + <para>yes</para> + </entry> + </row> + <row> + <entry> + <para>Bidirectional one-to-one</para> + <para> + (<xref linkend="readonly-proptypes-onetoone-bidir"/>) + </para> + </entry> + <entry>only if the owning entity is not read-only*</entry> + </row> + <row> + <entry> + <para>Bidirectional one-to-many/many-to-one</para> + <para>inverse collection</para> + <para>non-inverse collection</para> + <para> + (<xref linkend="readonly-proptypes-onetomany-manytoone"/>) + </para> + </entry> + <entry> + <para> </para> + <para>only added/removed entities that are not read-only*</para> + <para>yes</para> + </entry> + </row> + <row> + <entry> + <para>Bidirectional many-to-many</para> + <para> + (<xref linkend="readonly-proptypes-manytomany-bidir"/>) + </para> + </entry> + <entry>yes</entry> + </row> + </tbody> + </tgroup> + </table> + + <para> + * Behavior is different when the entity having the property/association + is read-only, compared to when it is not read-only. + </para> + + <section id="readonly-proptypes-simple"> + <title>Simple properties</title> + + <para> + When a persistent object is read-only, NHibernate does not + dirty-check simple properties. + </para> + + <para> + NHibernate will not synchronize simple property state changes + to the database. If you have automatic versioning, NHibernate + will not increment the version if any simple properties change. + </para> + + <programlisting role="c#"> +ISession session = factory.OpenSession(); +ITransaction tx = session.BeginTransaction(); + +// get a contract and make it read-only +Contract contract = session.Get<Contract>(contractId); +session.SetReadOnly(contract, true); + +// contract.CustomerName is "Sherman" +contract.CustomerName = "Yogi"; +tx.Commit(); + +tx = session.BeginTransaction(); + +contract = session.Get<Contract>(contractId); +// contract.CustomerName is still "Sherman" +... +tx.Commit(); +session.Close(); + </programlisting> + + </section> + + <section id="readonly-prop-types-unidir"> + <title>Unidirectional associations</title> + + <section id="readonly-proptypes-singleended-unidir"> + <title>Unidirectional one-to-one and many-to-one</title> + + <para> + NHibernate treats unidirectional one-to-one and many-to-one + associations in the same way when the owning entity is + read-only. + </para> + + <para> + We use the term <emphasis>unidirectional single-ended + association</emphasis> when referring to functionality + that is common to unidirectional one-to-one and many-to-one + associations. + </para> + + <para> + NHibernate does not dirty-check unidirectional single-ended + associations when the owning entity is read-only. + </para> + + <para> + If you change a read-only entity's reference to a + unidirectional single-ended association to null, + or to refer to a different entity, that change + will not be flushed to the database. + </para> + + <note> + <para> + If an entity is of an immutable class, + then its references to unidirectional single-ended + associations must be assigned when that + entity is first created. Because the entity is + automatically made read-only, these references can + not be updated. + </para> + </note> + + <para> + If automatic versioning is used, NHibernate will not + increment the version due to local changes to + unidirectional single-ended associations. + </para> + + <para> + In the following examples, Contract has a unidirectional + many-to-one association with Plan. Contract cascades save and + update operations to the association. + </para> + + <para> + The following shows that changing a read-only entity's + many-to-one association reference to null has no effect + on the entity's database representation. + </para> + +<programlisting role="c#">// get a contract with an existing plan; +// make the contract read-only and set its plan to null +tx = session.BeginTransaction(); +Contract contract = session.Get<Contract>(contractId); +session.SetReadOnly(contract, true); +contract.Plan = null; +tx.Commit(); + +// get the same contract +tx = session.BeginTransaction(); +Contract contract = session.Get<Contract>(contractId); + +// contract.Plan still refers to the original plan; + +tx.Commit(); +session.Close();</programlisting> + + <para> + The following shows that, even though + an update to a read-only entity's many-to-one + association has no affect on the entity's + database representation, flush still cascades + the save-update operation to the locally + changed association. + </para> + +<programlisting role="c#">// get a contract with an existing plan; +// make the contract read-only and change to a new plan +tx = session.BeginTransaction(); +Contract contract = session.Get<Contract>(contractId); +session.SetReadOnly(contract, true); +Plan newPlan = new Plan("new plan"); +contract.Plan = newPlan; +tx.Commit(); + +// get the same contract +tx = session.BeginTransaction(); +contract = session.Get<Contract>(contractId); +newPlan = session.Get<Plan>(newPlan.Id); + +// contract.Plan still refers to the original plan; +// newPlan is non-null because it was persisted when +// the previous transaction was committed; + +tx.Commit(); +session.Close();</programlisting> + + </section> + + <section id="readonly-proptypes-manyended-unidir"> + <title>Unidirectional one-to-many and many-to-many</title> + + <para> + NHibernate treats unidirectional one-to-many + and many-to-many associations owned by a read-only + entity the same as when owned by an entity that is not + read-only. + </para> + + <para> + NHibernate dirty-checks unidirectional one-to-many and + many-to-many associations; + </para> + + <para> + The collection can contain entities that + are read-only, as well as entities + that are not read-only. + </para> + + <para> + Entities can be added and removed from the + collection; changes are flushed to the database. + </para> + + <para> + If automatic versioning is used, NHibernate will + update the version due to changes in the collection + if they dirty the owning entity. + </para> + + </section> + + </section> + + <section id="readonly-proptypes-bidir"> + <title>Bidirectional associations</title> + + <section id="readonly-proptypes-onetoone-bidir"> + <title>Bidirectional one-to-one</title> + + <para> + If a read-only entity owns a bidirectional + one-to-one association: + </para> + + <itemizedlist> + <listitem> + <para> + NHibernate does not dirty-check the association. + </para> + </listitem> + <listitem> + <para> + updates that change the association reference + to null or to refer to a different entity + will not be flushed to the database. + </para> + </listitem> + <listitem> + <para> + If automatic versioning is used, NHibernate will not + increment the version due to local changes to + the association. + </para> + </listitem> + </itemizedlist> + + <note> + <para> + If an entity is of an immutable class, + and it owns a bidirectional one-to-one + association, then its reference must be + assigned when that entity is first created. + Because the entity is automatically made + read-only, these references cannot be updated. + </para> + </note> + + <para> + When the owner is not read-only, NHibernate treats + an association with a read-only entity the same + as when the association is with an entity that is + not read-only. + </para> + + </section> + + <section id="readonly-proptypes-onetomany-manytoone"> + <title>Bidirectional one-to-many/many-to-one</title> + + <para> + A read-only entity has no impact on a bidirectional + one-to-many/many-to-one association if: + </para> + + <itemizedlist> + <listitem> + <para> + the read-only entity is on the one-to-many side + using an inverse collection; + </para> + </listitem> + <listitem> + <para> + the read-only entity is on the one-to-many side + using a non-inverse collection; + </para> + </listitem> + <listitem> + <para> + the one-to-many side uses a non-inverse collection + that contains the read-only entity + </para> + </listitem> + </itemizedlist> + + <para> + When the one-to-many side uses an inverse collection: + </para> + + <itemizedlist> + <listitem> + <para> + a read-only entity can only be added to the collection + when it is created; + </para> + </listitem> + <listitem> + <para> + a read-only entity can only be removed from the + collection by an orphan delete or by explicitly + deleting the entity. + </para> + </listitem> + </itemizedlist> + + </section> + + <section id="readonly-proptypes-manytomany-bidir"> + <title>Bidirectional many-to-many</title> + <para> + NHibernate treats bidirectional many-to-many + associations owned by a read-only entity the + same as when owned by an entity that is not + read-only. + </para> + + <para> + NHibernate dirty-checks bidirectional many-to-many + associations. + </para> + + <para> + The collection on either side of the association + can contain entities that are read-only, as well + as entities that are not read-only. + </para> + + <para> + Entities are added and removed from both sides + of the collection; changes are flushed to the + database. + </para> + + <para> + If automatic versioning is used, NHibernate will + update the version due to changes in both sides of + the collection if they dirty the entity owning the + respective collections. + </para> + + </section> + + </section> + </section> +</chapter> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2011-02-10 14:29:45
|
Revision: 5377 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5377&view=rev Author: julian-maughan Date: 2011-02-10 14:29:39 +0000 (Thu, 10 Feb 2011) Log Message: ----------- Renamed feature branch to something more appropriate Added Paths: ----------- branches/ReadOnlyEntities/ Removed Paths: ------------- branches/ReadOnlyCriteria/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2011-02-07 09:21:55
|
Revision: 5376 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5376&view=rev Author: julian-maughan Date: 2011-02-07 09:21:46 +0000 (Mon, 07 Feb 2011) Log Message: ----------- Merged latest trunk (r5375) to ReadOnlyCriteria branch. Modified Paths: -------------- branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Dialect/DB2400Dialect.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Driver/SqlClientDriver.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Engine/QueryParameters.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/ReWriters/ResultOperatorRewriter.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Loader/Loader.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Mapping/SimpleValue.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Type/SerializableType.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Type/TypeFactory.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/DriverTest/SqlClientDriverFixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/ByMethod/AnyTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/QueryCacheableTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHibernate.Test.build branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/DomainClass.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/NH2467Test.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Model.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/food-photo.jpg branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Animal.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Mappings.hbm.xml Removed Paths: ------------- branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/DomainClass.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/NH2467Test.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Model.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/food-photo.jpg branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Animal.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Mappings.hbm.xml Property Changed: ---------------- branches/ReadOnlyCriteria/ branches/ReadOnlyCriteria/nhibernate/ branches/ReadOnlyCriteria/nhibernate/src/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Customer.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Model.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1927/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1928/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Tools/hbm2ddl/SchemaExportTests/ Property changes on: branches/ReadOnlyCriteria ___________________________________________________________________ Modified: svn:mergeinfo - /branches/2.1.x:4505-4508,4510-4513,4537-4538 /trunk:5306-5362 + /branches/2.1.x:4505-4508,4510-4513,4537-4538 /trunk:5306-5375 Property changes on: branches/ReadOnlyCriteria/nhibernate ___________________________________________________________________ Modified: svn:mergeinfo - /branches/2.1.x/nhibernate:4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate:5306-5362 + /branches/2.1.x/nhibernate:4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate:5306-5375 Property changes on: branches/ReadOnlyCriteria/nhibernate/src ___________________________________________________________________ Modified: svn:mergeinfo - /branches/2.1.x/nhibernate/src:4659,4671,4681,4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src:5306-5362 + /branches/2.1.x/nhibernate/src:4659,4671,4681,4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src:5306-5375 Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Dialect/DB2400Dialect.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Dialect/DB2400Dialect.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Dialect/DB2400Dialect.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -46,6 +46,12 @@ get { return false; } } + public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit, int? offsetParameterIndex, int? limitParameterIndex) + { + // override the base-class's implementation that uses limit parameters + return GetLimitString(querySqlString, offset, limit); + } + public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit) { return new SqlStringBuilder(querySqlString) Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -5,6 +5,7 @@ using System.Text.RegularExpressions; using NHibernate.Dialect.Function; using NHibernate.Dialect.Schema; +using NHibernate.Driver; using NHibernate.Engine; using NHibernate.Mapping; using NHibernate.SqlCommand; @@ -40,18 +41,16 @@ /// </remarks> public class MsSql2000Dialect : Dialect { - public const int MaxSizeForLengthLimitedStrings = 4000; - /// <summary></summary> public MsSql2000Dialect() { RegisterColumnType(DbType.AnsiStringFixedLength, "CHAR(255)"); RegisterColumnType(DbType.AnsiStringFixedLength, 8000, "CHAR($l)"); RegisterColumnType(DbType.AnsiString, "VARCHAR(255)"); - RegisterColumnType(DbType.AnsiString, 8000, "VARCHAR($l)"); - RegisterColumnType(DbType.AnsiString, 2147483647, "TEXT"); + RegisterColumnType(DbType.AnsiString, SqlClientDriver.MaxSizeForLengthLimitedAnsiString, "VARCHAR($l)"); + RegisterColumnType(DbType.AnsiString, SqlClientDriver.MaxSizeForAnsiClob, "TEXT"); RegisterColumnType(DbType.Binary, "VARBINARY(8000)"); - RegisterColumnType(DbType.Binary, 8000, "VARBINARY($l)"); - RegisterColumnType(DbType.Binary, 2147483647, "IMAGE"); + RegisterColumnType(DbType.Binary, SqlClientDriver.MaxSizeForLengthLimitedBinary, "VARBINARY($l)"); + RegisterColumnType(DbType.Binary, SqlClientDriver.MaxSizeForBlob, "IMAGE"); RegisterColumnType(DbType.Boolean, "BIT"); RegisterColumnType(DbType.Byte, "TINYINT"); RegisterColumnType(DbType.Currency, "MONEY"); @@ -66,10 +65,10 @@ RegisterColumnType(DbType.Int64, "BIGINT"); RegisterColumnType(DbType.Single, "REAL"); //synonym for FLOAT(24) RegisterColumnType(DbType.StringFixedLength, "NCHAR(255)"); - RegisterColumnType(DbType.StringFixedLength, MaxSizeForLengthLimitedStrings, "NCHAR($l)"); + RegisterColumnType(DbType.StringFixedLength, SqlClientDriver.MaxSizeForLengthLimitedString, "NCHAR($l)"); RegisterColumnType(DbType.String, "NVARCHAR(255)"); - RegisterColumnType(DbType.String, MaxSizeForLengthLimitedStrings, "NVARCHAR($l)"); - RegisterColumnType(DbType.String, 1073741823, "NTEXT"); + RegisterColumnType(DbType.String, SqlClientDriver.MaxSizeForLengthLimitedString, "NVARCHAR($l)"); + RegisterColumnType(DbType.String, SqlClientDriver.MaxSizeForClob, "NTEXT"); RegisterColumnType(DbType.Time, "DATETIME"); RegisterFunction("count", new CountBigQueryFunction()); Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Data; +using NHibernate.Driver; using NHibernate.Mapping; using NHibernate.SqlCommand; using NHibernate.Util; @@ -11,9 +12,9 @@ { public MsSql2005Dialect() { - RegisterColumnType(DbType.String, 1073741823, "NVARCHAR(MAX)"); - RegisterColumnType(DbType.AnsiString, 2147483647, "VARCHAR(MAX)"); - RegisterColumnType(DbType.Binary, 2147483647, "VARBINARY(MAX)"); + RegisterColumnType(DbType.String, SqlClientDriver.MaxSizeForClob, "NVARCHAR(MAX)"); + RegisterColumnType(DbType.AnsiString, SqlClientDriver.MaxSizeForAnsiClob, "VARCHAR(MAX)"); + RegisterColumnType(DbType.Binary, SqlClientDriver.MaxSizeForBlob, "VARBINARY(MAX)"); RegisterColumnType(DbType.Xml, "XML"); } Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Driver/SqlClientDriver.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Driver/SqlClientDriver.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Driver/SqlClientDriver.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -12,8 +12,19 @@ /// </summary> public class SqlClientDriver : DriverBase, IEmbeddedBatcherFactoryProvider { + public const int MaxSizeForAnsiClob = 2147483647; // int.MaxValue + public const int MaxSizeForClob = 1073741823; // int.MaxValue / 2 + public const int MaxSizeForBlob = 2147483647; // int.MaxValue + public const int MaxSizeForLengthLimitedAnsiString = 8000; + public const int MaxSizeForLengthLimitedString = 4000; + public const int MaxSizeForLengthLimitedBinary = 8000; + public const byte MaxPrecision = 28; + public const byte MaxScale = 5; + public const byte MaxDateTime2 = 8; + public const byte MaxDateTimeOffset = 10; + /// <summary> - /// Creates an uninitialized <see cref="IDbConnection" /> object for + /// Creates an uninitialized <see cref="IDbConnection" /> object for /// the SqlClientDriver. /// </summary> /// <value>An unitialized <see cref="System.Data.SqlClient.SqlConnection"/> object.</value> @@ -23,7 +34,7 @@ } /// <summary> - /// Creates an uninitialized <see cref="IDbCommand" /> object for + /// Creates an uninitialized <see cref="IDbCommand" /> object for /// the SqlClientDriver. /// </summary> /// <value>An unitialized <see cref="System.Data.SqlClient.SqlCommand"/> object.</value> @@ -33,7 +44,7 @@ } /// <summary> - /// MsSql requires the use of a Named Prefix in the SQL statement. + /// MsSql requires the use of a Named Prefix in the SQL statement. /// </summary> /// <remarks> /// <see langword="true" /> because MsSql uses "<c>@</c>". @@ -44,7 +55,7 @@ } /// <summary> - /// MsSql requires the use of a Named Prefix in the Parameter. + /// MsSql requires the use of a Named Prefix in the Parameter. /// </summary> /// <remarks> /// <see langword="true" /> because MsSql uses "<c>@</c>". @@ -55,7 +66,7 @@ } /// <summary> - /// The Named Prefix for parameters. + /// The Named Prefix for parameters. /// </summary> /// <value> /// Sql Server uses <c>"@"</c>. @@ -71,8 +82,8 @@ /// </summary> /// <value><see langword="false" /> - it is not supported.</value> /// <remarks> - /// MS SQL Server 2000 (and 7) throws an exception when multiple IDataReaders are - /// attempted to be opened. When SQL Server 2005 comes out a new driver will be + /// MS SQL Server 2000 (and 7) throws an exception when multiple IDataReaders are + /// attempted to be opened. When SQL Server 2005 comes out a new driver will be /// created for it because SQL Server 2005 is supposed to support it. /// </remarks> public override bool SupportsMultipleOpenReaders @@ -80,6 +91,20 @@ get { return false; } } + public override bool SupportsMultipleQueries + { + get { return true; } + } + + public override IDbCommand GenerateCommand(CommandType type, SqlString sqlString, SqlType[] parameterTypes) + { + IDbCommand command = base.GenerateCommand(type, sqlString, parameterTypes); + + SetParameterSizes(command.Parameters, parameterTypes); + + return command; + } + // Used from SqlServerCeDriver as well public static void SetParameterSizes(IDataParameterCollection parameters, SqlType[] parameterTypes) { @@ -89,34 +114,33 @@ } } - private const int MaxAnsiStringSize = 8000; - private const int MaxBinarySize = MaxAnsiStringSize; - private const int MaxStringSize = MaxAnsiStringSize / 2; - private const int MaxBinaryBlobSize = int.MaxValue; - private const int MaxStringClobSize = MaxBinaryBlobSize / 2; - private const byte MaxPrecision = 28; - private const byte MaxScale = 5; - private const byte MaxDateTime2 = 8; - private const byte MaxDateTimeOffset = 10; + private static void SetVariableLengthParameterSize(IDbDataParameter dbParam, SqlType sqlType) + { + SetDefaultParameterSize(dbParam, sqlType); + // Override the defaults using data from SqlType - except for LOB types + if (sqlType.LengthDefined && !IsText(dbParam, sqlType) && !IsBlob(dbParam, sqlType)) + { + dbParam.Size = sqlType.Length; + } + + if (sqlType.PrecisionDefined) + { + dbParam.Precision = sqlType.Precision; + dbParam.Scale = sqlType.Scale; + } + } + private static void SetDefaultParameterSize(IDbDataParameter dbParam, SqlType sqlType) { switch (dbParam.DbType) { case DbType.AnsiString: case DbType.AnsiStringFixedLength: - dbParam.Size = MaxAnsiStringSize; + dbParam.Size = MaxSizeForLengthLimitedAnsiString; break; - case DbType.Binary: - if (sqlType is BinaryBlobSqlType) - { - dbParam.Size = MaxBinaryBlobSize; - } - else - { - dbParam.Size = MaxBinarySize; - } + dbParam.Size = IsBlob(dbParam, sqlType) ? MaxSizeForBlob : MaxSizeForLengthLimitedBinary; break; case DbType.Decimal: dbParam.Precision = MaxPrecision; @@ -124,7 +148,7 @@ break; case DbType.String: case DbType.StringFixedLength: - dbParam.Size = IsText(dbParam, sqlType) ? MaxStringClobSize : MaxStringSize; + dbParam.Size = IsText(dbParam, sqlType) ? MaxSizeForClob : MaxSizeForLengthLimitedString; break; case DbType.DateTime2: dbParam.Size = MaxDateTime2; @@ -135,44 +159,28 @@ } } + /// <summary> + /// Interprets if a parameter is a Clob (for the purposes of setting its default size) + /// </summary> + /// <param name="dbParam">The parameter</param> + /// <param name="sqlType">The <see cref="SqlType" /> of the parameter</param> + /// <returns>True, if the parameter should be interpreted as a Clob, otherwise False</returns> private static bool IsText(IDbDataParameter dbParam, SqlType sqlType) { - return (sqlType is StringClobSqlType) || (sqlType.LengthDefined && sqlType.Length > MsSql2000Dialect.MaxSizeForLengthLimitedStrings && - (DbType.String == dbParam.DbType || DbType.StringFixedLength == dbParam.DbType)); + return (sqlType is StringClobSqlType) || ((DbType.String == dbParam.DbType || DbType.StringFixedLength == dbParam.DbType) && sqlType.LengthDefined && (sqlType.Length > MaxSizeForLengthLimitedString)); } - - private static void SetVariableLengthParameterSize(IDbDataParameter dbParam, SqlType sqlType) + + /// <summary> + /// Interprets if a parameter is a Blob (for the purposes of setting its default size) + /// </summary> + /// <param name="dbParam">The parameter</param> + /// <param name="sqlType">The <see cref="SqlType" /> of the parameter</param> + /// <returns>True, if the parameter should be interpreted as a Blob, otherwise False</returns> + private static bool IsBlob(IDbDataParameter dbParam, SqlType sqlType) { - SetDefaultParameterSize(dbParam, sqlType); - - // Override the defaults using data from SqlType. - if (sqlType.LengthDefined && !IsText(dbParam, sqlType)) - { - dbParam.Size = sqlType.Length; - } - - if (sqlType.PrecisionDefined) - { - dbParam.Precision = sqlType.Precision; - dbParam.Scale = sqlType.Scale; - } + return (sqlType is BinaryBlobSqlType) || ((DbType.Binary == dbParam.DbType) && sqlType.LengthDefined && (sqlType.Length > MaxSizeForLengthLimitedBinary)); } - public override IDbCommand GenerateCommand(CommandType type, SqlString sqlString, SqlType[] parameterTypes) - { - IDbCommand command = base.GenerateCommand(type, sqlString, parameterTypes); - //if (IsPrepareSqlEnabled) - { - SetParameterSizes(command.Parameters, parameterTypes); - } - return command; - } - - public override bool SupportsMultipleQueries - { - get { return true; } - } - #region IEmbeddedBatcherFactoryProvider Members System.Type IEmbeddedBatcherFactoryProvider.BatcherFactoryClass @@ -182,4 +190,4 @@ #endregion } -} +} \ No newline at end of file Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Engine/QueryParameters.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -553,12 +553,12 @@ else { paramTypeList.Add(NHibernateUtil.Int32); - limitParameterIndex = totalSpan; + limitParameterIndex = startParameterIndex + totalSpan; if (addOffset) { paramTypeList.Add(NHibernateUtil.Int32); - offsetParameterIndex = totalSpan; - limitParameterIndex = totalSpan + 1; + offsetParameterIndex = startParameterIndex + totalSpan; + limitParameterIndex = startParameterIndex + totalSpan + 1; } } Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -5,11 +5,10 @@ using System.Diagnostics; using Iesi.Collections; using Iesi.Collections.Generic; - using NHibernate.Cache; +using NHibernate.Criterion; using NHibernate.Driver; using NHibernate.Engine; -using NHibernate.Criterion; using NHibernate.Loader.Criteria; using NHibernate.SqlCommand; using NHibernate.SqlTypes; @@ -319,18 +318,19 @@ { int limitParameterSpan = BindLimitParametersFirstIfNeccesary(command, queryIndex, colIndex); colIndex = BindQueryParameters(command, queryIndex, colIndex + limitParameterSpan); - BindLimitParametersLastIfNeccesary(command, queryIndex, colIndex); + colIndex += BindLimitParametersLastIfNeccesary(command, queryIndex, colIndex); } } - private void BindLimitParametersLastIfNeccesary(IDbCommand command, int queryIndex, int colIndex) + private int BindLimitParametersLastIfNeccesary(IDbCommand command, int queryIndex, int colIndex) { QueryParameters parameter = parameters[queryIndex]; RowSelection selection = parameter.RowSelection; if (Loader.Loader.UseLimit(selection, dialect) && !dialect.BindLimitParametersFirst) { - Loader.Loader.BindLimitParameters(command, colIndex, selection, session); + return Loader.Loader.BindLimitParameters(command, colIndex, selection, session); } + return 0; } private int BindQueryParameters(IDbCommand command, int queryIndex, int colIndex) Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -1,9 +1,10 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Data; using System.Diagnostics; using Iesi.Collections; - +using Iesi.Collections.Generic; using NHibernate.Cache; using NHibernate.Driver; using NHibernate.Engine; @@ -12,8 +13,6 @@ using NHibernate.SqlTypes; using NHibernate.Transform; using NHibernate.Type; -using Iesi.Collections.Generic; -using System.Collections.Generic; namespace NHibernate.Impl { @@ -653,18 +652,19 @@ { int limitParameterSpan = BindLimitParametersFirstIfNeccesary(command, queryIndex, colIndex); colIndex = BindQueryParameters(command, queryIndex, colIndex + limitParameterSpan); - BindLimitParametersLastIfNeccesary(command, queryIndex, colIndex); + colIndex += BindLimitParametersLastIfNeccesary(command, queryIndex, colIndex); } } - private void BindLimitParametersLastIfNeccesary(IDbCommand command, int queryIndex, int colIndex) + private int BindLimitParametersLastIfNeccesary(IDbCommand command, int queryIndex, int colIndex) { QueryParameters parameter = parameters[queryIndex]; RowSelection selection = parameter.RowSelection; if (Loader.Loader.UseLimit(selection, dialect) && !dialect.BindLimitParametersFirst) { - Loader.Loader.BindLimitParameters(command, colIndex, selection, session); + return Loader.Loader.BindLimitParameters(command, colIndex, selection, session); } + return 0; } private int BindQueryParameters(IDbCommand command, int queryIndex, int colIndex) Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/ReWriters/ResultOperatorRewriter.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/ReWriters/ResultOperatorRewriter.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/ReWriters/ResultOperatorRewriter.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -63,6 +63,7 @@ { typeof(FetchRequestBase), typeof(OfTypeResultOperator), + typeof(CacheableResultOperator), }; private readonly List<ResultOperatorBase> resultOperators = new List<ResultOperatorBase>(); Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -330,6 +330,7 @@ case ExpressionType.Not: return _hqlTreeBuilder.BooleanNot(VisitExpression(expression.Operand).AsBooleanExpression()); case ExpressionType.Convert: + case ExpressionType.ConvertChecked: return VisitExpression(expression.Operand); } Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Loader/Loader.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Loader/Loader.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Loader/Loader.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -1222,7 +1222,8 @@ private int GetFirstLimitParameterCount(Dialect.Dialect dialect, bool useLimit, bool hasFirstRow, bool useOffset) { - if (!useLimit) return 0; + if (!useLimit) return 0; + if (!dialect.SupportsVariableLimit) return 0; if (!dialect.BindLimitParametersFirst) return 0; return (hasFirstRow && useOffset) ? 2 : 1; } Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Mapping/SimpleValue.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Mapping/SimpleValue.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Mapping/SimpleValue.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -247,18 +247,21 @@ { // NH different behavior // If the mapping has a type as "Double(10,5)" our SqlType will be created with all information - // including the rigth SqlType specification but when the length/presion/scale was specified - // trough attributes the SqlType is wrong (does not include length/presion/scale specification) + // including the right SqlType specification, but when the length/precision/scale was specified + // through attributes the SqlType is wrong (does not include length/precision/scale specification) IType result = null; if (ColumnSpan == 1 && !columns[0].IsFormula) { - var col = (Column) columns[0]; - if(col.IsLengthDefined()) + var col = (Column)columns[0]; + if (col.IsLengthDefined()) { result = TypeFactory.BuiltInType(typeName, col.Length); + + if (result == null) + result = TypeFactory.HeuristicType(typeName, typeParameters, col.Length); } - else if(col.IsPrecisionDefined()) + else if (col.IsPrecisionDefined()) { result = TypeFactory.BuiltInType(typeName, Convert.ToByte(col.Precision), Convert.ToByte(col.Scale)); } Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -3898,29 +3898,19 @@ { return this; } - else + // TODO : really need a way to do something like : + // getTuplizer(entityMode).determineConcreteSubclassEntityName(instance) + var clazz = instance.GetType(); + if (clazz == GetMappedClass(entityMode)) { - // TODO : really need a way to do something like : - // getTuplizer(entityMode).determineConcreteSubclassEntityName(instance) - System.Type clazz = instance.GetType(); - if (clazz == GetMappedClass(entityMode)) - { - return this; - } - else - { - string subclassEntityName = GetSubclassEntityName(clazz); - if (subclassEntityName == null) - { - throw new HibernateException("instance not of expected entity type: " + clazz.FullName + " is not a: " - + EntityName); - } - else - { - return factory.GetEntityPersister(subclassEntityName); - } - } + return this; } + var subclassEntityName = GetSubclassEntityName(clazz); + if (subclassEntityName == null || EntityName.Equals(subclassEntityName)) + { + return this; + } + return factory.GetEntityPersister(subclassEntityName); } public virtual EntityMode? GuessEntityMode(object obj) Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Type/SerializableType.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Type/SerializableType.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Type/SerializableType.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -14,8 +14,9 @@ /// </summary> /// <remarks> /// <para> - /// The SerializableType should be used when you know that Bytes are - /// not going to be greater than 8,000. + /// For performance reasons, the SerializableType should be used when you know that Bytes are + /// not going to be greater than 8,000. Implementing a custom type is recommended for larger + /// types. /// </para> /// <para> /// The base class is <see cref="MutableType"/> because the data is stored in Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Type/TypeFactory.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Type/TypeFactory.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Type/TypeFactory.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -21,7 +21,7 @@ /// <remarks> /// Applications should use static methods and constants on NHibernate.NHibernateUtil if the default /// IType is good enough. For example, the TypeFactory should only be used when the String needs - /// to have a length of 300 instead of 255. At this point NHibernate.String does not get you the + /// to have a length of 300 instead of 255. At this point NHibernateUtil.String does not get you the /// correct IType. Instead use TypeFactory.GetString(300) and keep a local variable that holds /// a reference to the IType. /// </remarks> @@ -33,8 +33,8 @@ Length, PrecisionScale } + private static readonly string[] EmptyAliases= new string[0]; - private static readonly char[] PrecisionScaleSplit = new[] { '(', ')', ',' }; private static readonly char[] LengthSplit = new[] { '(', ')' }; private static readonly TypeFactory Instance; @@ -446,14 +446,25 @@ } /// <summary> - /// Uses heuristics to deduce a NHibernate type given a string naming the - /// type. + /// Uses heuristics to deduce a NHibernate type given a string naming the type. /// </summary> /// <param name="typeName">the type name</param> /// <param name="parameters">parameters for the type</param> /// <returns>An instance of <c>NHibernate.Type.IType</c></returns> public static IType HeuristicType(string typeName, IDictionary<string, string> parameters) { + return HeuristicType(typeName, parameters, null); + } + + /// <summary> + /// Uses heuristics to deduce a NHibernate type given a string naming the type. + /// </summary> + /// <param name="typeName">the type name</param> + /// <param name="parameters">parameters for the type</param> + /// <param name="length">optionally, the size of the type</param> + /// <returns></returns> + public static IType HeuristicType(string typeName, IDictionary<string, string> parameters, int? length) + { IType type = Basic(typeName); if (type == null) @@ -518,6 +529,10 @@ { type = GetSerializableType(typeClass, Int32.Parse(parsedTypeName[1])); } + else if (length != null) + { + type = GetSerializableType(typeClass, length.Value); + } else { type = GetSerializableType(typeClass); Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/DriverTest/SqlClientDriverFixture.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/DriverTest/SqlClientDriverFixture.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/DriverTest/SqlClientDriverFixture.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -29,10 +29,6 @@ [TestFixture] public class SqlClientDriverFixture : TestCase { - protected override void Configure(Configuration configuration) - { - configuration.SetProperty(Environment.PrepareSql, "true"); - } protected override string MappingsAssembly { get { return "NHibernate.Test"; } @@ -45,24 +41,28 @@ protected override bool AppliesTo(Dialect.Dialect dialect) { - return dialect is MsSql2000Dialect; + return dialect is MsSql2008Dialect; } [Test] public void Crud() { - // Should use default dimension for CRUD op and prepare_sql='true' because the mapping does not + // Should use default dimension for CRUD op because the mapping does not // have dimensions specified. object savedId; using (ISession s = OpenSession()) using (ITransaction t = s.BeginTransaction()) { savedId = s.Save(new MultiTypeEntity - { - StringProp = "a", StringClob = "a",BinaryBlob = new byte[]{1,2,3}, - Binary = new byte[] { 4, 5, 6 }, Currency = 123.4m, Double = 123.5d, - Decimal = 789.5m - }); + { + StringProp = "a", + StringClob = "a", + BinaryBlob = new byte[]{1,2,3}, + Binary = new byte[] { 4, 5, 6 }, + Currency = 123.4m, + Double = 123.5d, + Decimal = 789.5m + }); t.Commit(); } Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/ByMethod/AnyTests.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/ByMethod/AnyTests.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/ByMethod/AnyTests.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -9,11 +9,25 @@ [TestFixture] public class AnyTests : LinqTestCase { - [Test] - public void AnySublist() - { - var orders = db.Orders.Where(o => o.OrderLines.Any(ol => ol.Quantity == 5)).ToList(); - Assert.AreEqual(61, orders.Count); - } + [Test] + public void AnySublist() + { + var orders = db.Orders.Where(o => o.OrderLines.Any(ol => ol.Quantity == 5)).ToList(); + Assert.AreEqual(61, orders.Count); + + orders = db.Orders.Where(o => o.OrderLines.Any(ol => ol.Order == null)).ToList(); + Assert.AreEqual(0, orders.Count); + } + + [Test] + public void NestedAny() + { + var test = (from c in db.Customers + where c.ContactName == "Bob" && + (c.CompanyName == "NormalooCorp" || + c.Orders.Any(o => o.OrderLines.Any(ol => ol.Discount < 20 && ol.Discount >= 10))) + select c).ToList(); + Assert.AreEqual(0, test.Count); + } } } Modified: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/QueryCacheableTests.cs =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/QueryCacheableTests.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/QueryCacheableTests.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -85,5 +85,34 @@ Assert.That(Sfi.Statistics.QueryCachePutCount, Is.EqualTo(2)); Assert.That(Sfi.Statistics.QueryCacheHitCount, Is.EqualTo(1)); } + + [Test] + public void CacheableBeforeOtherClauses() + { + Sfi.Statistics.Clear(); + Sfi.QueryCache.Clear(); + + db.Customers.Cacheable().Where(c => c.ContactName != c.CompanyName).Take(1).ToList(); + db.Customers.Where(c => c.ContactName != c.CompanyName).Take(1).ToList(); + + Assert.That(Sfi.Statistics.QueryExecutionCount, Is.EqualTo(2)); + Assert.That(Sfi.Statistics.QueryCachePutCount, Is.EqualTo(1)); + Assert.That(Sfi.Statistics.QueryCacheHitCount, Is.EqualTo(0)); + } + + [Test] + public void CacheableRegionBeforeOtherClauses() + { + Sfi.Statistics.Clear(); + Sfi.QueryCache.Clear(); + + db.Customers.Cacheable().CacheRegion("test").Where(c => c.ContactName != c.CompanyName).Take(1).ToList(); + db.Customers.Cacheable().CacheRegion("test").Where(c => c.ContactName != c.CompanyName).Take(1).ToList(); + db.Customers.Cacheable().CacheRegion("other").Where(c => c.ContactName != c.CompanyName).Take(1).ToList(); + + Assert.That(Sfi.Statistics.QueryExecutionCount, Is.EqualTo(2)); + Assert.That(Sfi.Statistics.QueryCachePutCount, Is.EqualTo(2)); + Assert.That(Sfi.Statistics.QueryCacheHitCount, Is.EqualTo(1)); + } } } Deleted: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Fixture.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Fixture.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -1,48 +0,0 @@ - -using System.Collections; -using NUnit.Framework; - -namespace NHibernate.Test.NHSpecificTest.EntityNameAndInheritance -{ - public class Fixture : BugTestCase - { - private int id; - private const string entityName = "SuperClass"; - - protected override void OnSetUp() - { - using (var s = OpenSession()) - { - using (var tx = s.BeginTransaction()) - { - id = (int)s.Save(entityName, new Hashtable()); - tx.Commit(); - } - } - } - - [Test] - public void DoesNotCrash() - { - using (var s = OpenSession()) - { - using (s.BeginTransaction()) - { - Assert.IsNotNull(s.Get(entityName, id)); - } - } - } - - protected override void OnTearDown() - { - using (var s = OpenSession()) - { - using (var tx = s.BeginTransaction()) - { - s.CreateSQLQuery("delete from " + entityName).ExecuteUpdate(); - tx.Commit(); - } - } - } - } -} Copied: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Fixture.cs (from rev 5375, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Fixture.cs) =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Fixture.cs (rev 0) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Fixture.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -0,0 +1,48 @@ + +using System.Collections; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.EntityNameAndInheritance +{ + public class Fixture : BugTestCase + { + private int id; + private const string entityName = "SuperClass"; + + protected override void OnSetUp() + { + using (var s = OpenSession()) + { + using (var tx = s.BeginTransaction()) + { + id = (int)s.Save(entityName, new Hashtable()); + tx.Commit(); + } + } + } + + [Test] + public void DoesNotCrash() + { + using (var s = OpenSession()) + { + using (s.BeginTransaction()) + { + Assert.IsNotNull(s.Get(entityName, id)); + } + } + } + + protected override void OnTearDown() + { + using (var s = OpenSession()) + { + using (var tx = s.BeginTransaction()) + { + s.CreateSQLQuery("delete from " + entityName).ExecuteUpdate(); + tx.Commit(); + } + } + } + } +} Deleted: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Mappings.hbm.xml 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Mappings.hbm.xml 2011-02-07 09:21:46 UTC (rev 5376) @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" - namespace="NHibernate.Test.NHSpecificTest.EntityNameAndCompositeId" - assembly="NHibernate.Test"> - <class entity-name="SuperClass"> - <id name="Id" type="int"> - <generator class="native"/> - </id> - <discriminator column="DISC" type="string" /> - <subclass entity-name="Subclass" discriminator-value="B" /> - </class> -</hibernate-mapping> Copied: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Mappings.hbm.xml (from rev 5375, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Mappings.hbm.xml) =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Mappings.hbm.xml (rev 0) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Mappings.hbm.xml 2011-02-07 09:21:46 UTC (rev 5376) @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + namespace="NHibernate.Test.NHSpecificTest.EntityNameAndCompositeId" + assembly="NHibernate.Test"> + <class entity-name="SuperClass"> + <id name="Id" type="int"> + <generator class="native"/> + </id> + <discriminator column="DISC" type="string" /> + <subclass entity-name="Subclass" discriminator-value="B" /> + </class> +</hibernate-mapping> Property changes on: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Customer.cs ___________________________________________________________________ Modified: svn:mergeinfo - /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Customer.cs:4593-4594,4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Customer.cs:5306-5362 + /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Customer.cs:4593-4594,4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Customer.cs:5306-5375 Property changes on: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Fixture.cs ___________________________________________________________________ Modified: svn:mergeinfo - /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Fixture.cs:4593-4594,4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Fixture.cs:5306-5362 + /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Fixture.cs:4593-4594,4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Fixture.cs:5306-5375 Property changes on: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Mappings.hbm.xml ___________________________________________________________________ Modified: svn:mergeinfo - /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Mappings.hbm.xml:4593-4594,4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Mappings.hbm.xml:5306-5362 + /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Mappings.hbm.xml:4593-4594,4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Mappings.hbm.xml:5306-5375 Property changes on: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Fixture.cs ___________________________________________________________________ Modified: svn:mergeinfo - /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Fixture.cs:4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Fixture.cs:5306-5362 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908/Fixture.cs:4657 + /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Fixture.cs:4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Fixture.cs:5306-5375 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908/Fixture.cs:4657 Property changes on: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Mappings.hbm.xml ___________________________________________________________________ Modified: svn:mergeinfo - /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Mappings.hbm.xml:4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Mappings.hbm.xml:5306-5362 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908/Mappings.hbm.xml:4657 + /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Mappings.hbm.xml:4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Mappings.hbm.xml:5306-5375 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908/Mappings.hbm.xml:4657 Property changes on: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Model.cs ___________________________________________________________________ Modified: svn:mergeinfo - /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Model.cs:4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Model.cs:5306-5362 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908/Model.cs:4657 + /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Model.cs:4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Model.cs:5306-5375 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1908/Model.cs:4657 Property changes on: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1927 ___________________________________________________________________ Modified: svn:mergeinfo - /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1927:4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1927:5306-5362 + /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1927:4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1927:5306-5375 Property changes on: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1928 ___________________________________________________________________ Modified: svn:mergeinfo - /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1928:4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1928:5306-5362 + /branches/2.1.x/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1928:4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1928:5306-5375 Deleted: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/DomainClass.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/DomainClass.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/DomainClass.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -1,20 +0,0 @@ - - -namespace NHibernate.Test.NHSpecificTest.NH2467 -{ - public class DomainClass - { - - public int Id - { - get; - set; - } - - public string Data - { - get; - set; - } - } -} Copied: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/DomainClass.cs (from rev 5375, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/DomainClass.cs) =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/DomainClass.cs (rev 0) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/DomainClass.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -0,0 +1,20 @@ + + +namespace NHibernate.Test.NHSpecificTest.NH2467 +{ + public class DomainClass + { + + public int Id + { + get; + set; + } + + public string Data + { + get; + set; + } + } +} Deleted: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/Mappings.hbm.xml 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/Mappings.hbm.xml 2011-02-07 09:21:46 UTC (rev 5376) @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test" - namespace="NHibernate.Test.NHSpecificTest.NH2467" - default-lazy="false"> - <class name="DomainClass"> - <id name="Id"> - <generator class="assigned" /> - </id> - <property name="Data" /> - </class> -</hibernate-mapping> Copied: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/Mappings.hbm.xml (from rev 5375, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/Mappings.hbm.xml) =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/Mappings.hbm.xml (rev 0) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/Mappings.hbm.xml 2011-02-07 09:21:46 UTC (rev 5376) @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2467" + default-lazy="false"> + <class name="DomainClass"> + <id name="Id"> + <generator class="assigned" /> + </id> + <property name="Data" /> + </class> +</hibernate-mapping> Deleted: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/NH2467Test.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/NH2467Test.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/NH2467Test.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -1,126 +0,0 @@ -using System.Linq; -using NHibernate.Criterion; -using NUnit.Framework; - -namespace NHibernate.Test.NHSpecificTest.NH2467 -{ - [TestFixture] - public class NH2467Test : BugTestCase - { - protected override void OnSetUp() - { - base.OnSetUp(); - using (var session = OpenSession()) - { - var entity = new DomainClass {Id = 1, Data = "Test"}; - session.Save(entity); - session.Flush(); - } - } - - protected override bool AppliesTo(Dialect.Dialect dialect) - { - return dialect.SupportsLimit && !dialect.BindLimitParametersFirst; - } - - protected override void OnTearDown() - { - base.OnTearDown(); - using (var session = OpenSession()) - { - session.Delete("from System.Object"); - session.Flush(); - } - } - - [Test] - public void ShouldNotThrowOnFuturePaging() - { - using (var session = OpenSession()) - { - - var contentQuery = session - .CreateCriteria<DomainClass>() - .Add(Restrictions.Eq("Data", "Test")); - contentQuery.SetMaxResults(2); - contentQuery.SetFirstResult(0); - var content = contentQuery.Future<DomainClass>(); - - var countQuery = session - .CreateCriteria<DomainClass>() - .Add(Restrictions.Eq("Data", "Test")); - countQuery.SetProjection(Projections.RowCount()); - var count = countQuery.FutureValue<int>(); - - // triggers batch operation, should not throw - var result = content.ToList(); - } - } - - [Test] - public void ShouldNotThrowOnReversedFuturePaging() - { - using (var session = OpenSession()) - { - - var countQuery = session - .CreateCriteria<DomainClass>() - .Add(Restrictions.Eq("Data", "Test")); - countQuery.SetProjection(Projections.RowCount()); - var count = countQuery.FutureValue<int>(); - - var contentQuery = session - .CreateCriteria<DomainClass>() - .Add(Restrictions.Eq("Data", "Test")); - contentQuery.SetMaxResults(2); - contentQuery.SetFirstResult(0); - var content = contentQuery.Future<DomainClass>(); - - // triggers batch operation, should not throw - var result = content.ToList(); - } - } - - [Test] - public void ShouldNotThrowOnFuturePagingUsingHql() - { - using (var session = OpenSession()) - { - - var contentQuery = session.CreateQuery("from DomainClass as d where d.Data = ?"); - contentQuery.SetString(0, "Test"); - contentQuery.SetMaxResults(2); - contentQuery.SetFirstResult(0); - var content = contentQuery.Future<DomainClass>(); - - var countQuery = session.CreateQuery("select count(d) from DomainClass as d where d.Data = ?"); - countQuery.SetString(0, "Test"); - var count = countQuery.FutureValue<long>(); - - Assert.AreEqual(1, content.ToList().Count); - Assert.AreEqual(1, count.Value); - } - } - - [Test] - public void ShouldNotThrowOnReversedFuturePagingUsingHql() - { - using (var session = OpenSession()) - { - - var contentQuery = session.CreateQuery("from DomainClass as d where d.Data = ?"); - contentQuery.SetString(0, "Test"); - contentQuery.SetMaxResults(2); - contentQuery.SetFirstResult(0); - var content = contentQuery.Future<DomainClass>(); - - var countQuery = session.CreateQuery("select count(d) from DomainClass as d where d.Data = ?"); - countQuery.SetString(0, "Test"); - var count = countQuery.FutureValue<long>(); - - Assert.AreEqual(1, content.ToList().Count); - Assert.AreEqual(1, count.Value); - } - } - } -} Copied: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/NH2467Test.cs (from rev 5375, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/NH2467Test.cs) =================================================================== --- branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/NH2467Test.cs (rev 0) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/NH2467Test.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -0,0 +1,126 @@ +using System.Linq; +using NHibernate.Criterion; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2467 +{ + [TestFixture] + public class NH2467Test : BugTestCase + { + protected override void OnSetUp() + { + base.OnSetUp(); + using (var session = OpenSession()) + { + var entity = new DomainClass {Id = 1, Data = "Test"}; + session.Save(entity); + session.Flush(); + } + } + + protected override bool AppliesTo(Dialect.Dialect dialect) + { + return dialect.SupportsLimit && !dialect.BindLimitParametersFirst; + } + + protected override void OnTearDown() + { + base.OnTearDown(); + using (var session = OpenSession()) + { + session.Delete("from System.Object"); + session.Flush(); + } + } + + [Test] + public void ShouldNotThrowOnFuturePaging() + { + using (var session = OpenSession()) + { + + var contentQuery = session + .CreateCriteria<DomainClass>() + .Add(Restrictions.Eq("Data", "Test")); + contentQuery.SetMaxResults(2); + contentQuery.SetFirstResult(0); + var content = contentQuery.Future<DomainClass>(); + + var countQuery = session + .CreateCriteria<DomainClass>() + .Add(Restrictions.Eq("Data", "Test")); + countQuery.SetProjection(Projections.RowCount()); + var count = countQuery.FutureValue<int>(); + + // triggers batch operation, should not throw + var result = content.ToList(); + } + } + + [Test] + public void ShouldNotThrowOnReversedFuturePaging() + { + using (var session = OpenSession()) + { + + var countQuery = session + .CreateCriteria<DomainClass>() + .Add(Restrictions.Eq("Data", "Test")); + countQuery.SetProjection(Projections.RowCount()); + var count = countQuery.FutureValue<int>(); + + var contentQuery = session + .CreateCriteria<DomainClass>() + .Add(Restrictions.Eq("Data", "Test")); + contentQuery.SetMaxResults(2); + contentQuery.SetFirstResult(0); + var content = contentQuery.Future<DomainClass>(); + + // triggers batch operation, should not throw + var result = content.ToList(); + } + } + + [Test] + public void ShouldNotThrowOnFuturePagingUsingHql() + { + using (var session = OpenSession()) + { + + var contentQuery = session.CreateQuery("from DomainClass as d where d.Data = ?"); + contentQuery.SetString(0, "Test"); + contentQuery.SetMaxResults(2); + contentQuery.SetFirstResult(0); + var content = contentQuery.Future<DomainClass>(); + + var countQuery = session.CreateQuery("select count(d) from DomainClass as d where d.Data = ?"); + countQuery.SetString(0, "Test"); + var count = countQuery.FutureValue<long>(); + + Assert.AreEqual(1, content.ToList().Count); + Assert.AreEqual(1, count.Value); + } + } + + [Test] + public void ShouldNotThrowOnReversedFuturePagingUsingHql() + { + using (var session = OpenSession()) + { + + var contentQuery = session.CreateQuery("from DomainClass as d where d.Data = ?"); + contentQuery.SetString(0, "Test"); + contentQuery.SetMaxResults(2); + contentQuery.SetFirstResult(0); + var content = contentQuery.Future<DomainClass>(); + + var countQuery = session.CreateQuery("select count(d) from DomainClass as d where d.Data = ?"); + countQuery.SetString(0, "Test"); + var count = countQuery.FutureValue<long>(); + + Assert.AreEqual(1, content.ToList().Count); + Assert.AreEqual(1, count.Value); + } + } + } +} Deleted: branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs 2011-02-05 23:18:25 UTC (rev 5375) +++ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs 2011-02-07 09:21:46 UTC (rev 5376) @@ -1,82 +0,0 @@ -using System; -using System.Drawing; -using System.Reflection; -using NUn... [truncated message content] |
From: <pa...@us...> - 2011-02-05 23:18:31
|
Revision: 5375 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5375&view=rev Author: patearl Date: 2011-02-05 23:18:25 +0000 (Sat, 05 Feb 2011) Log Message: ----------- Linq: Added more tests for the Any() method. Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/AnyTests.cs Modified: trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/AnyTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/AnyTests.cs 2011-02-05 22:43:48 UTC (rev 5374) +++ trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/AnyTests.cs 2011-02-05 23:18:25 UTC (rev 5375) @@ -9,11 +9,25 @@ [TestFixture] public class AnyTests : LinqTestCase { - [Test] - public void AnySublist() - { - var orders = db.Orders.Where(o => o.OrderLines.Any(ol => ol.Quantity == 5)).ToList(); - Assert.AreEqual(61, orders.Count); - } + [Test] + public void AnySublist() + { + var orders = db.Orders.Where(o => o.OrderLines.Any(ol => ol.Quantity == 5)).ToList(); + Assert.AreEqual(61, orders.Count); + + orders = db.Orders.Where(o => o.OrderLines.Any(ol => ol.Order == null)).ToList(); + Assert.AreEqual(0, orders.Count); + } + + [Test] + public void NestedAny() + { + var test = (from c in db.Customers + where c.ContactName == "Bob" && + (c.CompanyName == "NormalooCorp" || + c.Orders.Any(o => o.OrderLines.Any(ol => ol.Discount < 20 && ol.Discount >= 10))) + select c).ToList(); + Assert.AreEqual(0, test.Count); + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-02-05 22:43:54
|
Revision: 5374 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5374&view=rev Author: patearl Date: 2011-02-05 22:43:48 +0000 (Sat, 05 Feb 2011) Log Message: ----------- Linq: Support Cacheable before other operators. (NH-2502, thanks to Dean Ward for the fix.) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Linq/ReWriters/ResultOperatorRewriter.cs trunk/nhibernate/src/NHibernate.Test/Linq/QueryCacheableTests.cs Modified: trunk/nhibernate/src/NHibernate/Linq/ReWriters/ResultOperatorRewriter.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/ReWriters/ResultOperatorRewriter.cs 2011-01-30 14:36:08 UTC (rev 5373) +++ trunk/nhibernate/src/NHibernate/Linq/ReWriters/ResultOperatorRewriter.cs 2011-02-05 22:43:48 UTC (rev 5374) @@ -63,6 +63,7 @@ { typeof(FetchRequestBase), typeof(OfTypeResultOperator), + typeof(CacheableResultOperator), }; private readonly List<ResultOperatorBase> resultOperators = new List<ResultOperatorBase>(); Modified: trunk/nhibernate/src/NHibernate.Test/Linq/QueryCacheableTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/QueryCacheableTests.cs 2011-01-30 14:36:08 UTC (rev 5373) +++ trunk/nhibernate/src/NHibernate.Test/Linq/QueryCacheableTests.cs 2011-02-05 22:43:48 UTC (rev 5374) @@ -85,5 +85,34 @@ Assert.That(Sfi.Statistics.QueryCachePutCount, Is.EqualTo(2)); Assert.That(Sfi.Statistics.QueryCacheHitCount, Is.EqualTo(1)); } + + [Test] + public void CacheableBeforeOtherClauses() + { + Sfi.Statistics.Clear(); + Sfi.QueryCache.Clear(); + + db.Customers.Cacheable().Where(c => c.ContactName != c.CompanyName).Take(1).ToList(); + db.Customers.Where(c => c.ContactName != c.CompanyName).Take(1).ToList(); + + Assert.That(Sfi.Statistics.QueryExecutionCount, Is.EqualTo(2)); + Assert.That(Sfi.Statistics.QueryCachePutCount, Is.EqualTo(1)); + Assert.That(Sfi.Statistics.QueryCacheHitCount, Is.EqualTo(0)); + } + + [Test] + public void CacheableRegionBeforeOtherClauses() + { + Sfi.Statistics.Clear(); + Sfi.QueryCache.Clear(); + + db.Customers.Cacheable().CacheRegion("test").Where(c => c.ContactName != c.CompanyName).Take(1).ToList(); + db.Customers.Cacheable().CacheRegion("test").Where(c => c.ContactName != c.CompanyName).Take(1).ToList(); + db.Customers.Cacheable().CacheRegion("other").Where(c => c.ContactName != c.CompanyName).Take(1).ToList(); + + Assert.That(Sfi.Statistics.QueryExecutionCount, Is.EqualTo(2)); + Assert.That(Sfi.Statistics.QueryCachePutCount, Is.EqualTo(2)); + Assert.That(Sfi.Statistics.QueryCacheHitCount, Is.EqualTo(1)); + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2011-01-30 14:36:14
|
Revision: 5373 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5373&view=rev Author: ricbrown Date: 2011-01-30 14:36:08 +0000 (Sun, 30 Jan 2011) Log Message: ----------- Fix NH-2513 (SetMaxResults issue with DB2400Dialect) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Dialect/DB2400Dialect.cs Modified: trunk/nhibernate/src/NHibernate/Dialect/DB2400Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/DB2400Dialect.cs 2011-01-29 18:06:40 UTC (rev 5372) +++ trunk/nhibernate/src/NHibernate/Dialect/DB2400Dialect.cs 2011-01-30 14:36:08 UTC (rev 5373) @@ -46,6 +46,12 @@ get { return false; } } + public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit, int? offsetParameterIndex, int? limitParameterIndex) + { + // override the base-class's implementation that uses limit parameters + return GetLimitString(querySqlString, offset, limit); + } + public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit) { return new SqlStringBuilder(querySqlString) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-01-29 18:06:47
|
Revision: 5372 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5372&view=rev Author: patearl Date: 2011-01-29 18:06:40 +0000 (Sat, 29 Jan 2011) Log Message: ----------- Linq: Handle ConvertChecked when generating HQL. (NH-2507, thanks Sue Hackett.) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Animal.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Mappings.hbm.xml Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2011-01-26 15:02:50 UTC (rev 5371) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2011-01-29 18:06:40 UTC (rev 5372) @@ -330,6 +330,7 @@ case ExpressionType.Not: return _hqlTreeBuilder.BooleanNot(VisitExpression(expression.Operand).AsBooleanExpression()); case ExpressionType.Convert: + case ExpressionType.ConvertChecked: return VisitExpression(expression.Operand); } Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507 ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:logregex + NH-\d+ Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Animal.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Animal.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Animal.cs 2011-01-29 18:06:40 UTC (rev 5372) @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH2507 +{ + public enum Sex + { + Undefined = 0, + Male = 1, + Female = 2 + } + + public class Animal + { + public virtual int Id { get; set; } + public virtual string Description { get; set; } + public virtual double BodyWeight { get; set; } + public virtual Sex Sex { get; set; } + public virtual Animal Mother { get; set; } + public virtual Animal Father { get; set; } + public virtual IList<Animal> Children { get; set; } + public virtual string SerialNumber { get; set; } + } + + public abstract class Reptile : Animal + { + public virtual double BodyTemperature { get; set; } + } + + public class Lizard : Reptile { } + + public abstract class Mammal : Animal + { + public virtual bool Pregnant { get; set; } + public virtual DateTime? BirthDate { get; set; } + } + + public class Dog : Mammal { } + + public class Cat : Mammal { } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Fixture.cs 2011-01-29 18:06:40 UTC (rev 5372) @@ -0,0 +1,133 @@ +using System; +using System.Linq; +using NHibernate.Dialect; +using NHibernate.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2507 +{ + /// <summary> + /// Used for testing LINQ queries in NHibernate that compare enumeration values. + /// </summary> + [TestFixture] + public class Fixture : BugTestCase + { + #region BugTestCase Overrides + + protected override void OnSetUp() + { + base.OnSetUp(); + using (ISession session = this.OpenSession()) + { + Animal animal = new Animal() + { + Id = 1, BodyWeight = 2, Sex = Sex.Undefined, Description = "Animal", + SerialNumber = "111" + }; + Lizard lizard = new Lizard() + { + Id = 2, + BodyTemperature = 98, + BodyWeight = 10, + Sex = Sex.Male, + Description = "Lizard", + SerialNumber = "222", + Mother = animal + }; + Dog momDog = new Dog() + { + BirthDate = new DateTime(2007, 01, 01), + BodyWeight = 65, + Sex = Sex.Female, + Description = "MyDogMom", + Pregnant = false, + SerialNumber = "333" + }; + Dog dadDog = new Dog() + { + BirthDate = new DateTime(2007, 02, 02), + BodyWeight = 75, + Sex = Sex.Male, + Description = "MyDogDad", + Pregnant = false, + SerialNumber = "444" + }; + Dog puppy = new Dog() + { + BirthDate = new DateTime(2010, 01, 01), + BodyWeight = 50, + Sex = Sex.Male, + Description = "Puppy", + Pregnant = false, + Father = dadDog, + Mother = momDog, + SerialNumber = "555" + }; + Cat cat = new Cat() + { + BirthDate = new DateTime(2007, 03, 03), + BodyWeight = 10, + Sex = Sex.Female, + Description = "MyCat", + Pregnant = true, + SerialNumber = "777" + }; + + session.Save(animal); + session.Save(lizard); + session.Save(momDog); + session.Save(dadDog); + session.Save(puppy); + session.Save(cat); + session.Flush(); + } + } + + protected override void OnTearDown() + { + base.OnTearDown(); + using (ISession session = this.OpenSession()) + { + const string hql = "from System.Object"; + session.Delete(hql); + session.Flush(); + } + } + + #endregion BugTestCase Overrides + + /// <summary> + /// Test LINQ query that compares enumeration values while simulating projects with Advanced Build property + /// value for "Check for arithmetic overflow/underflow" as <b>checked</b>. + /// </summary> + [Test] + public void QueryEnumerationWithCheckedArithmeticOverflowTest() + { + using (ISession session = this.OpenSession()) + { + checked + { + var query = session.Query<Animal>().Where(item => item.Sex == Sex.Undefined).ToList(); + Assert.AreEqual(1, query.Count); + } + } + } + + /// <summary> + /// Test LINQ query that compares enumeration values while simulating projects with Advanced Build property + /// value for "Check for arithmetic overflow/underflow" as <b>unchecked</b>. + /// </summary> + [Test] + public void QueryEnumerationWithUncheckedArithmeticOverflowTest() + { + using (ISession session = this.OpenSession()) + { + unchecked + { + var query = session.Query<Animal>().Where(item => item.Sex == Sex.Undefined).ToList(); + Assert.AreEqual(1, query.Count); + } + } + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2507/Mappings.hbm.xml 2011-01-29 18:06:40 UTC (rev 5372) @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + namespace="NHibernate.Test.NHSpecificTest.NH2507" + assembly="NHibernate.Test" + default-lazy="false"> + + <class name="Animal"> + <id name="Id"> + <generator class="native"/> + </id> + + <property name="Description"/> + <property name="BodyWeight" column="body_weight"/> + <property name="Sex" type="int" column="sex"/> + <many-to-one name="Mother" column="mother_id"/> + <many-to-one name="Father" column="father_id"/> + <property name="SerialNumber"/> + + <bag name="Children" lazy="true"> + <key column="ParentId" /> + <one-to-many class="Animal" /> + </bag> + + <joined-subclass name="Reptile"> + <key column="Animal"/> + <property name="BodyTemperature"/> + + <joined-subclass name="Lizard"> + <key column="Reptile"/> + </joined-subclass> + </joined-subclass> + + <joined-subclass name="Mammal"> + <key column="Animal"/> + <property name="Pregnant"/> + <property name="BirthDate" type="DateTime"/> + + <joined-subclass name="Dog"> + <key column="Mammal"/> + </joined-subclass> + + <joined-subclass name="Cat"> + <key column="Mammal"/> + </joined-subclass> + </joined-subclass> + </class> + +</hibernate-mapping> \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-26 15:02:50 UTC (rev 5371) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-29 18:06:40 UTC (rev 5372) @@ -611,6 +611,8 @@ <Compile Include="NHSpecificTest\NH2470\DTO.cs" /> <Compile Include="NHSpecificTest\NH2484\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2484\Model.cs" /> + <Compile Include="NHSpecificTest\NH2507\Animal.cs" /> + <Compile Include="NHSpecificTest\NH2507\Fixture.cs" /> <Compile Include="NHSpecificTest\Properties\CompositePropertyRefTest.cs" /> <Compile Include="NHSpecificTest\Properties\DynamicEntityTest.cs" /> <Compile Include="NHSpecificTest\Properties\Model.cs" /> @@ -2405,6 +2407,7 @@ <EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" /> </ItemGroup> <ItemGroup> + <EmbeddedResource Include="NHSpecificTest\NH2507\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\EntityNameAndInheritance\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2467\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2459\Mappings.hbm.xml" /> @@ -2784,7 +2787,6 @@ <EmbeddedResource Include="DynamicEntity\Tuplizer\Customer.hbm.xml" /> </ItemGroup> <ItemGroup> - <Folder Include="NHSpecificTest\NH2484" /> <Folder Include="Properties\" /> </ItemGroup> <ItemGroup> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2011-01-26 15:02:56
|
Revision: 5371 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5371&view=rev Author: julian-maughan Date: 2011-01-26 15:02:50 +0000 (Wed, 26 Jan 2011) Log Message: ----------- Attempting to resolve test failures (in r5368 and r5369) by changing NHibernate.Test build script to include JPEG file types as resources. Currently only XML resources are included. Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.build Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs 2011-01-24 17:51:11 UTC (rev 5370) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs 2011-01-26 15:02:50 UTC (rev 5371) @@ -7,7 +7,7 @@ namespace NHibernate.Test.NHSpecificTest.NH2484 { -[TestFixture] + [TestFixture] public class Fixture : BugTestCase { protected override bool AppliesTo(NHibernate.Dialect.Dialect dialect) @@ -16,7 +16,6 @@ } [Test] - [Ignore("Unable to locate embedded image resource on TeamCity")] public void TestPersistenceOfClassWithUnknownSerializableType() { Assembly assembly = Assembly.Load(MappingsAssembly); @@ -49,7 +48,6 @@ } [Test] - [Ignore("Unable to locate embedded image resource on TeamCity")] public void TestPersistenceOfClassWithSerializableType() { Assembly assembly = Assembly.Load(MappingsAssembly); Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.build =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.build 2011-01-24 17:51:11 UTC (rev 5370) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.build 2011-01-26 15:02:50 UTC (rev 5371) @@ -1,8 +1,11 @@ <?xml version="1.0" ?> <project name="NHibernate.Test" default="build" xmlns="http://nant.sf.net/release/0.85-rc3/nant.xsd"> + <property name="root.dir" value="../.." /> <property name="config.FileName" value="hibernate.cfg.xml" /> + <include buildfile="${root.dir}/build-common/common-project.xml" /> + <target name="init" depends="common.init"> <property name="assembly.description" value="The Unit Tests for NHibernate." /> <property name="assembly.is-cls-compliant" value="false" /> @@ -23,28 +26,32 @@ <include name="NHibernate.dll" /> <include name="LinFu.DynamicProxy.dll" /> <include name="nunit.framework.dll" /> - <include name="SharpTestsEx.NUnit.dll" /> - <include name="Antlr3.Runtime.dll" /> + <include name="SharpTestsEx.NUnit.dll" /> + <include name="Antlr3.Runtime.dll" /> <include name="System.Linq.Dynamic.dll" /> </assemblyfileset> <resourcefileset id="project.resources" prefix="NHibernate.Test" dynamicprefix="true"> <include name="**/*.xml" /> + <include name="**/*.jpg" /> <exclude name="bin/**/*.xml" /> </resourcefileset> </target> + <target name="generate-assemblyinfo" depends="init common.generate-assemblyinfo" /> + <target name="build" depends="init generate-assemblyinfo common.compile-tests"> - - <if test="${file::exists(config.FileName)}"> + <if test="${file::exists(config.FileName)}"> <copy file="hibernate.cfg.xml" tofile="${bin.dir}/hibernate.cfg.xml" /> </if> <copy file="TestEnbeddedConfig.cfg.xml" tofile="${bin.dir}/TestEnbeddedConfig.cfg.xml" /> - <copy todir="${bin.dir}/DbScripts"> - <fileset basedir="${root.dir}/src/NHibernate.Test/DbScripts"> - <include name="*.sql" /> - </fileset> - </copy> - <copy file="${root.dir}/src/NHibernate.DomainModel/ABC.hbm.xml" tofile="${bin.dir}/ABC.hbm.xml" /> + <copy todir="${bin.dir}/DbScripts"> + <fileset basedir="${root.dir}/src/NHibernate.Test/DbScripts"> + <include name="*.sql" /> + </fileset> + </copy> + <copy file="${root.dir}/src/NHibernate.DomainModel/ABC.hbm.xml" tofile="${bin.dir}/ABC.hbm.xml" /> </target> + <target name="test" depends="init build common.run-database-tests" /> -</project> + +</project> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2011-01-24 17:51:17
|
Revision: 5370 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5370&view=rev Author: julian-maughan Date: 2011-01-24 17:51:11 +0000 (Mon, 24 Jan 2011) Log Message: ----------- Disabling tests added in r5368 - failing on TeamCity due to inability to locate embedded resource. Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs 2011-01-24 17:37:19 UTC (rev 5369) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs 2011-01-24 17:51:11 UTC (rev 5370) @@ -16,6 +16,7 @@ } [Test] + [Ignore("Unable to locate embedded image resource on TeamCity")] public void TestPersistenceOfClassWithUnknownSerializableType() { Assembly assembly = Assembly.Load(MappingsAssembly); @@ -48,6 +49,7 @@ } [Test] + [Ignore("Unable to locate embedded image resource on TeamCity")] public void TestPersistenceOfClassWithSerializableType() { Assembly assembly = Assembly.Load(MappingsAssembly); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2011-01-24 17:37:25
|
Revision: 5369 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5369&view=rev Author: julian-maughan Date: 2011-01-24 17:37:19 +0000 (Mon, 24 Jan 2011) Log Message: ----------- Fix for tests added in previous commit (r5368). Failing on TeamCity due to inability to locate embedded image resource. Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs 2011-01-24 16:17:41 UTC (rev 5368) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs 2011-01-24 17:37:19 UTC (rev 5369) @@ -1,5 +1,6 @@ using System; using System.Drawing; +using System.Reflection; using NUnit.Framework; using NHibernate.Type; using NHibernate.SqlTypes; @@ -17,7 +18,8 @@ [Test] public void TestPersistenceOfClassWithUnknownSerializableType() { - var stream = this.GetType().Assembly.GetManifestResourceStream("NHibernate.Test.NHSpecificTest.NH2484.food-photo.jpg"); + Assembly assembly = Assembly.Load(MappingsAssembly); + var stream = assembly.GetManifestResourceStream("NHibernate.Test.NHSpecificTest.NH2484.food-photo.jpg"); var image = Bitmap.FromStream(stream); var model = new ClassWithImage() { Image = image }; @@ -48,7 +50,8 @@ [Test] public void TestPersistenceOfClassWithSerializableType() { - var stream = this.GetType().Assembly.GetManifestResourceStream("NHibernate.Test.NHSpecificTest.NH2484.food-photo.jpg"); + Assembly assembly = Assembly.Load(MappingsAssembly); + var stream = assembly.GetManifestResourceStream("NHibernate.Test.NHSpecificTest.NH2484.food-photo.jpg"); var image = Bitmap.FromStream(stream); var model = new ClassWithSerializableType() { Image = image }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2011-01-24 16:17:47
|
Revision: 5368 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5368&view=rev Author: julian-maughan Date: 2011-01-24 16:17:41 +0000 (Mon, 24 Jan 2011) Log Message: ----------- Fixed minor deficiency whereby the value of a 'length' attribute on the property mapping of a serialiable type is ignored [ref. NH-2484]. Thanks to Ivan Zlatev. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Mapping/SimpleValue.cs trunk/nhibernate/src/NHibernate/Type/SerializableType.cs trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Model.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/food-photo.jpg Modified: trunk/nhibernate/src/NHibernate/Mapping/SimpleValue.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/SimpleValue.cs 2011-01-24 15:51:51 UTC (rev 5367) +++ trunk/nhibernate/src/NHibernate/Mapping/SimpleValue.cs 2011-01-24 16:17:41 UTC (rev 5368) @@ -247,18 +247,21 @@ { // NH different behavior // If the mapping has a type as "Double(10,5)" our SqlType will be created with all information - // including the rigth SqlType specification but when the length/presion/scale was specified - // trough attributes the SqlType is wrong (does not include length/presion/scale specification) + // including the right SqlType specification, but when the length/precision/scale was specified + // through attributes the SqlType is wrong (does not include length/precision/scale specification) IType result = null; if (ColumnSpan == 1 && !columns[0].IsFormula) { - var col = (Column) columns[0]; - if(col.IsLengthDefined()) + var col = (Column)columns[0]; + if (col.IsLengthDefined()) { result = TypeFactory.BuiltInType(typeName, col.Length); + + if (result == null) + result = TypeFactory.HeuristicType(typeName, typeParameters, col.Length); } - else if(col.IsPrecisionDefined()) + else if (col.IsPrecisionDefined()) { result = TypeFactory.BuiltInType(typeName, Convert.ToByte(col.Precision), Convert.ToByte(col.Scale)); } Modified: trunk/nhibernate/src/NHibernate/Type/SerializableType.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Type/SerializableType.cs 2011-01-24 15:51:51 UTC (rev 5367) +++ trunk/nhibernate/src/NHibernate/Type/SerializableType.cs 2011-01-24 16:17:41 UTC (rev 5368) @@ -14,8 +14,9 @@ /// </summary> /// <remarks> /// <para> - /// The SerializableType should be used when you know that Bytes are - /// not going to be greater than 8,000. + /// For performance reasons, the SerializableType should be used when you know that Bytes are + /// not going to be greater than 8,000. Implementing a custom type is recommended for larger + /// types. /// </para> /// <para> /// The base class is <see cref="MutableType"/> because the data is stored in Modified: trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs 2011-01-24 15:51:51 UTC (rev 5367) +++ trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs 2011-01-24 16:17:41 UTC (rev 5368) @@ -21,7 +21,7 @@ /// <remarks> /// Applications should use static methods and constants on NHibernate.NHibernateUtil if the default /// IType is good enough. For example, the TypeFactory should only be used when the String needs - /// to have a length of 300 instead of 255. At this point NHibernate.String does not get you the + /// to have a length of 300 instead of 255. At this point NHibernateUtil.String does not get you the /// correct IType. Instead use TypeFactory.GetString(300) and keep a local variable that holds /// a reference to the IType. /// </remarks> @@ -33,8 +33,8 @@ Length, PrecisionScale } + private static readonly string[] EmptyAliases= new string[0]; - private static readonly char[] PrecisionScaleSplit = new[] { '(', ')', ',' }; private static readonly char[] LengthSplit = new[] { '(', ')' }; private static readonly TypeFactory Instance; @@ -446,14 +446,25 @@ } /// <summary> - /// Uses heuristics to deduce a NHibernate type given a string naming the - /// type. + /// Uses heuristics to deduce a NHibernate type given a string naming the type. /// </summary> /// <param name="typeName">the type name</param> /// <param name="parameters">parameters for the type</param> /// <returns>An instance of <c>NHibernate.Type.IType</c></returns> public static IType HeuristicType(string typeName, IDictionary<string, string> parameters) { + return HeuristicType(typeName, parameters, null); + } + + /// <summary> + /// Uses heuristics to deduce a NHibernate type given a string naming the type. + /// </summary> + /// <param name="typeName">the type name</param> + /// <param name="parameters">parameters for the type</param> + /// <param name="length">optionally, the size of the type</param> + /// <returns></returns> + public static IType HeuristicType(string typeName, IDictionary<string, string> parameters, int? length) + { IType type = Basic(typeName); if (type == null) @@ -518,6 +529,10 @@ { type = GetSerializableType(typeClass, Int32.Parse(parsedTypeName[1])); } + else if (length != null) + { + type = GetSerializableType(typeClass, length.Value); + } else { type = GetSerializableType(typeClass); Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Fixture.cs 2011-01-24 16:17:41 UTC (rev 5368) @@ -0,0 +1,79 @@ +using System; +using System.Drawing; +using NUnit.Framework; +using NHibernate.Type; +using NHibernate.SqlTypes; + +namespace NHibernate.Test.NHSpecificTest.NH2484 +{ +[TestFixture] + public class Fixture : BugTestCase + { + protected override bool AppliesTo(NHibernate.Dialect.Dialect dialect) + { + return (dialect is Dialect.MsSql2008Dialect); + } + + [Test] + public void TestPersistenceOfClassWithUnknownSerializableType() + { + var stream = this.GetType().Assembly.GetManifestResourceStream("NHibernate.Test.NHSpecificTest.NH2484.food-photo.jpg"); + var image = Bitmap.FromStream(stream); + + var model = new ClassWithImage() { Image = image }; + var imageSize = model.Image.Size; + int id = -1; + + using (ISession session = OpenSession()) + { + session.SaveOrUpdate(model); + session.Flush(); + id = model.Id; + Assert.That(id, Is.GreaterThan(-1)); + } + using (ISession session = OpenSession()) + { + model = session.Get<ClassWithImage>(id); + Assert.That(model.Image.Size, Is.EqualTo(imageSize)); // Ensure type is not truncated + } + using (ISession session = OpenSession()) + { + session.CreateQuery("delete from ClassWithImage").ExecuteUpdate(); + session.Flush(); + } + + stream.Dispose(); + } + + [Test] + public void TestPersistenceOfClassWithSerializableType() + { + var stream = this.GetType().Assembly.GetManifestResourceStream("NHibernate.Test.NHSpecificTest.NH2484.food-photo.jpg"); + var image = Bitmap.FromStream(stream); + + var model = new ClassWithSerializableType() { Image = image }; + var imageSize = ((Image)model.Image).Size; + int id = -1; + + using (ISession session = OpenSession()) + { + session.SaveOrUpdate(model); + session.Flush(); + id = model.Id; + Assert.That(id, Is.GreaterThan(-1)); + } + using (ISession session = OpenSession()) + { + model = session.Get<ClassWithSerializableType>(id); + Assert.That(((Image)model.Image).Size, Is.EqualTo(imageSize)); // Ensure type is not truncated + } + using (ISession session = OpenSession()) + { + session.CreateQuery("delete from ClassWithSerializableType").ExecuteUpdate(); + session.Flush(); + } + + stream.Dispose(); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Mappings.hbm.xml 2011-01-24 16:17:41 UTC (rev 5368) @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping + xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2484"> + + <class name="ClassWithImage"> + + <id name="Id"> + <generator class="native" /> + </id> + + <property name="Image" type="System.Drawing.Image, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> + <column name="Image" length="10000" not-null="false" /> + </property> + + </class> + + <class name="ClassWithSerializableType"> + + <id name="Id"> + <generator class="native" /> + </id> + + <property name="Image" type="Serializable(10000)"> + <column name="Image" not-null="false" /> + </property> + + </class> + +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Model.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/Model.cs 2011-01-24 16:17:41 UTC (rev 5368) @@ -0,0 +1,17 @@ +using System; +using System.Runtime.Serialization; + +namespace NHibernate.Test.NHSpecificTest.NH2484 +{ + public class ClassWithImage + { + public virtual int Id { get; set; } + public virtual System.Drawing.Image Image { get; set; } + } + + public class ClassWithSerializableType + { + public virtual int Id { get; set; } + public virtual ISerializable Image { get; set; } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/food-photo.jpg =================================================================== (Binary files differ) Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2484/food-photo.jpg ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-24 15:51:51 UTC (rev 5367) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-24 16:17:41 UTC (rev 5368) @@ -91,6 +91,7 @@ </Reference> <Reference Include="System.Data" /> <Reference Include="System.Data.OracleClient" /> + <Reference Include="System.Drawing" /> <Reference Include="System.Linq.Dynamic, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>..\..\lib\net\3.5\System.Linq.Dynamic.dll</HintPath> @@ -608,6 +609,8 @@ <Compile Include="NHSpecificTest\NH2470\Class1Class2Tests.cs" /> <Compile Include="NHSpecificTest\NH2470\DomainObject.cs" /> <Compile Include="NHSpecificTest\NH2470\DTO.cs" /> + <Compile Include="NHSpecificTest\NH2484\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2484\Model.cs" /> <Compile Include="NHSpecificTest\Properties\CompositePropertyRefTest.cs" /> <Compile Include="NHSpecificTest\Properties\DynamicEntityTest.cs" /> <Compile Include="NHSpecificTest\Properties\Model.cs" /> @@ -1912,6 +1915,8 @@ <EmbeddedResource Include="NHSpecificTest\NH2409\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2420\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2441\Mappings.hbm.xml" /> + <EmbeddedResource Include="NHSpecificTest\NH2484\food-photo.jpg" /> + <EmbeddedResource Include="NHSpecificTest\NH2484\Mappings.hbm.xml" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\NHibernate.ByteCode.Castle\NHibernate.ByteCode.Castle.csproj"> @@ -2779,6 +2784,7 @@ <EmbeddedResource Include="DynamicEntity\Tuplizer\Customer.hbm.xml" /> </ItemGroup> <ItemGroup> + <Folder Include="NHSpecificTest\NH2484" /> <Folder Include="Properties\" /> </ItemGroup> <ItemGroup> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2011-01-24 15:51:57
|
Revision: 5367 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5367&view=rev Author: julian-maughan Date: 2011-01-24 15:51:51 +0000 (Mon, 24 Jan 2011) Log Message: ----------- Changed SqlClientDriver to push out the parameter size to int.MaxValue/2147483647 if the IType is, 1) a BinaryType with internal SqlType Length greater than 8000, or 2) a BinaryBlobType. Blobs and Clobs are now handled similarly by the driver [ref. NH-2484] Updated SqlClientDriverFixture dialect - so tests execute on MS SQL Server 2008. Also performed some light refactoring of the driver: no functional changes, for readability. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs trunk/nhibernate/src/NHibernate/Driver/SqlClientDriver.cs trunk/nhibernate/src/NHibernate.Test/DriverTest/SqlClientDriverFixture.cs Modified: trunk/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs 2011-01-23 19:45:35 UTC (rev 5366) +++ trunk/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs 2011-01-24 15:51:51 UTC (rev 5367) @@ -5,6 +5,7 @@ using System.Text.RegularExpressions; using NHibernate.Dialect.Function; using NHibernate.Dialect.Schema; +using NHibernate.Driver; using NHibernate.Engine; using NHibernate.Mapping; using NHibernate.SqlCommand; @@ -40,18 +41,16 @@ /// </remarks> public class MsSql2000Dialect : Dialect { - public const int MaxSizeForLengthLimitedStrings = 4000; - /// <summary></summary> public MsSql2000Dialect() { RegisterColumnType(DbType.AnsiStringFixedLength, "CHAR(255)"); RegisterColumnType(DbType.AnsiStringFixedLength, 8000, "CHAR($l)"); RegisterColumnType(DbType.AnsiString, "VARCHAR(255)"); - RegisterColumnType(DbType.AnsiString, 8000, "VARCHAR($l)"); - RegisterColumnType(DbType.AnsiString, 2147483647, "TEXT"); + RegisterColumnType(DbType.AnsiString, SqlClientDriver.MaxSizeForLengthLimitedAnsiString, "VARCHAR($l)"); + RegisterColumnType(DbType.AnsiString, SqlClientDriver.MaxSizeForAnsiClob, "TEXT"); RegisterColumnType(DbType.Binary, "VARBINARY(8000)"); - RegisterColumnType(DbType.Binary, 8000, "VARBINARY($l)"); - RegisterColumnType(DbType.Binary, 2147483647, "IMAGE"); + RegisterColumnType(DbType.Binary, SqlClientDriver.MaxSizeForLengthLimitedBinary, "VARBINARY($l)"); + RegisterColumnType(DbType.Binary, SqlClientDriver.MaxSizeForBlob, "IMAGE"); RegisterColumnType(DbType.Boolean, "BIT"); RegisterColumnType(DbType.Byte, "TINYINT"); RegisterColumnType(DbType.Currency, "MONEY"); @@ -66,10 +65,10 @@ RegisterColumnType(DbType.Int64, "BIGINT"); RegisterColumnType(DbType.Single, "REAL"); //synonym for FLOAT(24) RegisterColumnType(DbType.StringFixedLength, "NCHAR(255)"); - RegisterColumnType(DbType.StringFixedLength, MaxSizeForLengthLimitedStrings, "NCHAR($l)"); + RegisterColumnType(DbType.StringFixedLength, SqlClientDriver.MaxSizeForLengthLimitedString, "NCHAR($l)"); RegisterColumnType(DbType.String, "NVARCHAR(255)"); - RegisterColumnType(DbType.String, MaxSizeForLengthLimitedStrings, "NVARCHAR($l)"); - RegisterColumnType(DbType.String, 1073741823, "NTEXT"); + RegisterColumnType(DbType.String, SqlClientDriver.MaxSizeForLengthLimitedString, "NVARCHAR($l)"); + RegisterColumnType(DbType.String, SqlClientDriver.MaxSizeForClob, "NTEXT"); RegisterColumnType(DbType.Time, "DATETIME"); RegisterFunction("count", new CountBigQueryFunction()); Modified: trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2011-01-23 19:45:35 UTC (rev 5366) +++ trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2011-01-24 15:51:51 UTC (rev 5367) @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Data; +using NHibernate.Driver; using NHibernate.Mapping; using NHibernate.SqlCommand; using NHibernate.Util; @@ -11,9 +12,9 @@ { public MsSql2005Dialect() { - RegisterColumnType(DbType.String, 1073741823, "NVARCHAR(MAX)"); - RegisterColumnType(DbType.AnsiString, 2147483647, "VARCHAR(MAX)"); - RegisterColumnType(DbType.Binary, 2147483647, "VARBINARY(MAX)"); + RegisterColumnType(DbType.String, SqlClientDriver.MaxSizeForClob, "NVARCHAR(MAX)"); + RegisterColumnType(DbType.AnsiString, SqlClientDriver.MaxSizeForAnsiClob, "VARCHAR(MAX)"); + RegisterColumnType(DbType.Binary, SqlClientDriver.MaxSizeForBlob, "VARBINARY(MAX)"); RegisterColumnType(DbType.Xml, "XML"); } Modified: trunk/nhibernate/src/NHibernate/Driver/SqlClientDriver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Driver/SqlClientDriver.cs 2011-01-23 19:45:35 UTC (rev 5366) +++ trunk/nhibernate/src/NHibernate/Driver/SqlClientDriver.cs 2011-01-24 15:51:51 UTC (rev 5367) @@ -12,8 +12,19 @@ /// </summary> public class SqlClientDriver : DriverBase, IEmbeddedBatcherFactoryProvider { + public const int MaxSizeForAnsiClob = 2147483647; // int.MaxValue + public const int MaxSizeForClob = 1073741823; // int.MaxValue / 2 + public const int MaxSizeForBlob = 2147483647; // int.MaxValue + public const int MaxSizeForLengthLimitedAnsiString = 8000; + public const int MaxSizeForLengthLimitedString = 4000; + public const int MaxSizeForLengthLimitedBinary = 8000; + public const byte MaxPrecision = 28; + public const byte MaxScale = 5; + public const byte MaxDateTime2 = 8; + public const byte MaxDateTimeOffset = 10; + /// <summary> - /// Creates an uninitialized <see cref="IDbConnection" /> object for + /// Creates an uninitialized <see cref="IDbConnection" /> object for /// the SqlClientDriver. /// </summary> /// <value>An unitialized <see cref="System.Data.SqlClient.SqlConnection"/> object.</value> @@ -23,7 +34,7 @@ } /// <summary> - /// Creates an uninitialized <see cref="IDbCommand" /> object for + /// Creates an uninitialized <see cref="IDbCommand" /> object for /// the SqlClientDriver. /// </summary> /// <value>An unitialized <see cref="System.Data.SqlClient.SqlCommand"/> object.</value> @@ -33,7 +44,7 @@ } /// <summary> - /// MsSql requires the use of a Named Prefix in the SQL statement. + /// MsSql requires the use of a Named Prefix in the SQL statement. /// </summary> /// <remarks> /// <see langword="true" /> because MsSql uses "<c>@</c>". @@ -44,7 +55,7 @@ } /// <summary> - /// MsSql requires the use of a Named Prefix in the Parameter. + /// MsSql requires the use of a Named Prefix in the Parameter. /// </summary> /// <remarks> /// <see langword="true" /> because MsSql uses "<c>@</c>". @@ -55,7 +66,7 @@ } /// <summary> - /// The Named Prefix for parameters. + /// The Named Prefix for parameters. /// </summary> /// <value> /// Sql Server uses <c>"@"</c>. @@ -71,8 +82,8 @@ /// </summary> /// <value><see langword="false" /> - it is not supported.</value> /// <remarks> - /// MS SQL Server 2000 (and 7) throws an exception when multiple IDataReaders are - /// attempted to be opened. When SQL Server 2005 comes out a new driver will be + /// MS SQL Server 2000 (and 7) throws an exception when multiple IDataReaders are + /// attempted to be opened. When SQL Server 2005 comes out a new driver will be /// created for it because SQL Server 2005 is supposed to support it. /// </remarks> public override bool SupportsMultipleOpenReaders @@ -80,6 +91,20 @@ get { return false; } } + public override bool SupportsMultipleQueries + { + get { return true; } + } + + public override IDbCommand GenerateCommand(CommandType type, SqlString sqlString, SqlType[] parameterTypes) + { + IDbCommand command = base.GenerateCommand(type, sqlString, parameterTypes); + + SetParameterSizes(command.Parameters, parameterTypes); + + return command; + } + // Used from SqlServerCeDriver as well public static void SetParameterSizes(IDataParameterCollection parameters, SqlType[] parameterTypes) { @@ -89,34 +114,33 @@ } } - private const int MaxAnsiStringSize = 8000; - private const int MaxBinarySize = MaxAnsiStringSize; - private const int MaxStringSize = MaxAnsiStringSize / 2; - private const int MaxBinaryBlobSize = int.MaxValue; - private const int MaxStringClobSize = MaxBinaryBlobSize / 2; - private const byte MaxPrecision = 28; - private const byte MaxScale = 5; - private const byte MaxDateTime2 = 8; - private const byte MaxDateTimeOffset = 10; + private static void SetVariableLengthParameterSize(IDbDataParameter dbParam, SqlType sqlType) + { + SetDefaultParameterSize(dbParam, sqlType); + // Override the defaults using data from SqlType - except for LOB types + if (sqlType.LengthDefined && !IsText(dbParam, sqlType) && !IsBlob(dbParam, sqlType)) + { + dbParam.Size = sqlType.Length; + } + + if (sqlType.PrecisionDefined) + { + dbParam.Precision = sqlType.Precision; + dbParam.Scale = sqlType.Scale; + } + } + private static void SetDefaultParameterSize(IDbDataParameter dbParam, SqlType sqlType) { switch (dbParam.DbType) { case DbType.AnsiString: case DbType.AnsiStringFixedLength: - dbParam.Size = MaxAnsiStringSize; + dbParam.Size = MaxSizeForLengthLimitedAnsiString; break; - case DbType.Binary: - if (sqlType is BinaryBlobSqlType) - { - dbParam.Size = MaxBinaryBlobSize; - } - else - { - dbParam.Size = MaxBinarySize; - } + dbParam.Size = IsBlob(dbParam, sqlType) ? MaxSizeForBlob : MaxSizeForLengthLimitedBinary; break; case DbType.Decimal: dbParam.Precision = MaxPrecision; @@ -124,7 +148,7 @@ break; case DbType.String: case DbType.StringFixedLength: - dbParam.Size = IsText(dbParam, sqlType) ? MaxStringClobSize : MaxStringSize; + dbParam.Size = IsText(dbParam, sqlType) ? MaxSizeForClob : MaxSizeForLengthLimitedString; break; case DbType.DateTime2: dbParam.Size = MaxDateTime2; @@ -135,44 +159,28 @@ } } + /// <summary> + /// Interprets if a parameter is a Clob (for the purposes of setting its default size) + /// </summary> + /// <param name="dbParam">The parameter</param> + /// <param name="sqlType">The <see cref="SqlType" /> of the parameter</param> + /// <returns>True, if the parameter should be interpreted as a Clob, otherwise False</returns> private static bool IsText(IDbDataParameter dbParam, SqlType sqlType) { - return (sqlType is StringClobSqlType) || (sqlType.LengthDefined && sqlType.Length > MsSql2000Dialect.MaxSizeForLengthLimitedStrings && - (DbType.String == dbParam.DbType || DbType.StringFixedLength == dbParam.DbType)); + return (sqlType is StringClobSqlType) || ((DbType.String == dbParam.DbType || DbType.StringFixedLength == dbParam.DbType) && sqlType.LengthDefined && (sqlType.Length > MaxSizeForLengthLimitedString)); } - - private static void SetVariableLengthParameterSize(IDbDataParameter dbParam, SqlType sqlType) + + /// <summary> + /// Interprets if a parameter is a Blob (for the purposes of setting its default size) + /// </summary> + /// <param name="dbParam">The parameter</param> + /// <param name="sqlType">The <see cref="SqlType" /> of the parameter</param> + /// <returns>True, if the parameter should be interpreted as a Blob, otherwise False</returns> + private static bool IsBlob(IDbDataParameter dbParam, SqlType sqlType) { - SetDefaultParameterSize(dbParam, sqlType); - - // Override the defaults using data from SqlType. - if (sqlType.LengthDefined && !IsText(dbParam, sqlType)) - { - dbParam.Size = sqlType.Length; - } - - if (sqlType.PrecisionDefined) - { - dbParam.Precision = sqlType.Precision; - dbParam.Scale = sqlType.Scale; - } + return (sqlType is BinaryBlobSqlType) || ((DbType.Binary == dbParam.DbType) && sqlType.LengthDefined && (sqlType.Length > MaxSizeForLengthLimitedBinary)); } - public override IDbCommand GenerateCommand(CommandType type, SqlString sqlString, SqlType[] parameterTypes) - { - IDbCommand command = base.GenerateCommand(type, sqlString, parameterTypes); - //if (IsPrepareSqlEnabled) - { - SetParameterSizes(command.Parameters, parameterTypes); - } - return command; - } - - public override bool SupportsMultipleQueries - { - get { return true; } - } - #region IEmbeddedBatcherFactoryProvider Members System.Type IEmbeddedBatcherFactoryProvider.BatcherFactoryClass @@ -182,4 +190,4 @@ #endregion } -} +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/DriverTest/SqlClientDriverFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/DriverTest/SqlClientDriverFixture.cs 2011-01-23 19:45:35 UTC (rev 5366) +++ trunk/nhibernate/src/NHibernate.Test/DriverTest/SqlClientDriverFixture.cs 2011-01-24 15:51:51 UTC (rev 5367) @@ -29,10 +29,6 @@ [TestFixture] public class SqlClientDriverFixture : TestCase { - protected override void Configure(Configuration configuration) - { - configuration.SetProperty(Environment.PrepareSql, "true"); - } protected override string MappingsAssembly { get { return "NHibernate.Test"; } @@ -45,24 +41,28 @@ protected override bool AppliesTo(Dialect.Dialect dialect) { - return dialect is MsSql2000Dialect; + return dialect is MsSql2008Dialect; } [Test] public void Crud() { - // Should use default dimension for CRUD op and prepare_sql='true' because the mapping does not + // Should use default dimension for CRUD op because the mapping does not // have dimensions specified. object savedId; using (ISession s = OpenSession()) using (ITransaction t = s.BeginTransaction()) { savedId = s.Save(new MultiTypeEntity - { - StringProp = "a", StringClob = "a",BinaryBlob = new byte[]{1,2,3}, - Binary = new byte[] { 4, 5, 6 }, Currency = 123.4m, Double = 123.5d, - Decimal = 789.5m - }); + { + StringProp = "a", + StringClob = "a", + BinaryBlob = new byte[]{1,2,3}, + Binary = new byte[] { 4, 5, 6 }, + Currency = 123.4m, + Double = 123.5d, + Decimal = 789.5m + }); t.Commit(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2011-01-23 19:45:41
|
Revision: 5366 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5366&view=rev Author: ricbrown Date: 2011-01-23 19:45:35 +0000 (Sun, 23 Jan 2011) Log Message: ----------- Fix NH-2512 (QueryOver with Where clause and Take crashes) - Informix failing on NHibernate.Test.NHSpecificTest.NH1413.PagingTest.Bug Also fixes Informix tests: NHibernate.Test.ProjectionFixtures.Fixture.LimitingResultSetOnQueryThatIsOrderedByProjection NHibernate.Test.ProjectionFixtures.Fixture.QueryingWithParemetersAndParaemtersInOrderBy Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Loader/Loader.cs Modified: trunk/nhibernate/src/NHibernate/Loader/Loader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2011-01-22 14:50:28 UTC (rev 5365) +++ trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2011-01-23 19:45:35 UTC (rev 5366) @@ -1222,7 +1222,8 @@ private int GetFirstLimitParameterCount(Dialect.Dialect dialect, bool useLimit, bool hasFirstRow, bool useOffset) { - if (!useLimit) return 0; + if (!useLimit) return 0; + if (!dialect.SupportsVariableLimit) return 0; if (!dialect.BindLimitParametersFirst) return 0; return (hasFirstRow && useOffset) ? 2 : 1; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-01-22 14:50:36
|
Revision: 5365 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5365&view=rev Author: fabiomaulo Date: 2011-01-22 14:50:28 +0000 (Sat, 22 Jan 2011) Log Message: ----------- Fix NH-2473 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Mappings.hbm.xml Modified: trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs 2011-01-22 13:50:30 UTC (rev 5364) +++ trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs 2011-01-22 14:50:28 UTC (rev 5365) @@ -3898,29 +3898,19 @@ { return this; } - else + // TODO : really need a way to do something like : + // getTuplizer(entityMode).determineConcreteSubclassEntityName(instance) + var clazz = instance.GetType(); + if (clazz == GetMappedClass(entityMode)) { - // TODO : really need a way to do something like : - // getTuplizer(entityMode).determineConcreteSubclassEntityName(instance) - System.Type clazz = instance.GetType(); - if (clazz == GetMappedClass(entityMode)) - { - return this; - } - else - { - string subclassEntityName = GetSubclassEntityName(clazz); - if (subclassEntityName == null) - { - throw new HibernateException("instance not of expected entity type: " + clazz.FullName + " is not a: " - + EntityName); - } - else - { - return factory.GetEntityPersister(subclassEntityName); - } - } + return this; } + var subclassEntityName = GetSubclassEntityName(clazz); + if (subclassEntityName == null || EntityName.Equals(subclassEntityName)) + { + return this; + } + return factory.GetEntityPersister(subclassEntityName); } public virtual EntityMode? GuessEntityMode(object obj) Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Fixture.cs 2011-01-22 14:50:28 UTC (rev 5365) @@ -0,0 +1,48 @@ + +using System.Collections; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.EntityNameAndInheritance +{ + public class Fixture : BugTestCase + { + private int id; + private const string entityName = "SuperClass"; + + protected override void OnSetUp() + { + using (var s = OpenSession()) + { + using (var tx = s.BeginTransaction()) + { + id = (int)s.Save(entityName, new Hashtable()); + tx.Commit(); + } + } + } + + [Test] + public void DoesNotCrash() + { + using (var s = OpenSession()) + { + using (s.BeginTransaction()) + { + Assert.IsNotNull(s.Get(entityName, id)); + } + } + } + + protected override void OnTearDown() + { + using (var s = OpenSession()) + { + using (var tx = s.BeginTransaction()) + { + s.CreateSQLQuery("delete from " + entityName).ExecuteUpdate(); + tx.Commit(); + } + } + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/EntityNameAndInheritance/Mappings.hbm.xml 2011-01-22 14:50:28 UTC (rev 5365) @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + namespace="NHibernate.Test.NHSpecificTest.EntityNameAndCompositeId" + assembly="NHibernate.Test"> + <class entity-name="SuperClass"> + <id name="Id" type="int"> + <generator class="native"/> + </id> + <discriminator column="DISC" type="string" /> + <subclass entity-name="Subclass" discriminator-value="B" /> + </class> +</hibernate-mapping> Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-22 13:50:30 UTC (rev 5364) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-22 14:50:28 UTC (rev 5365) @@ -473,6 +473,7 @@ <Compile Include="NHSpecificTest\BagWithLazyExtraAndFilter\Domain.cs" /> <Compile Include="NHSpecificTest\BagWithLazyExtraAndFilter\Fixture.cs" /> <Compile Include="NHSpecificTest\EntityNameAndCompositeId\Fixture.cs" /> + <Compile Include="NHSpecificTest\EntityNameAndInheritance\Fixture.cs" /> <Compile Include="NHSpecificTest\EntityNameWithFullName\Fixture.cs" /> <Compile Include="NHSpecificTest\Futures\LinqFutureFixture.cs" /> <Compile Include="NHSpecificTest\NH1136\Address.cs" /> @@ -2399,6 +2400,7 @@ <EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" /> </ItemGroup> <ItemGroup> + <EmbeddedResource Include="NHSpecificTest\EntityNameAndInheritance\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2467\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2459\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2412\Mappings.hbm.xml" /> @@ -2777,7 +2779,6 @@ <EmbeddedResource Include="DynamicEntity\Tuplizer\Customer.hbm.xml" /> </ItemGroup> <ItemGroup> - <Folder Include="Cascade\Circle" /> <Folder Include="Properties\" /> </ItemGroup> <ItemGroup> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2011-01-22 13:50:37
|
Revision: 5364 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5364&view=rev Author: ricbrown Date: 2011-01-22 13:50:30 +0000 (Sat, 22 Jan 2011) Log Message: ----------- Fix NH-2467 (Futures in 3.0.0.GA not working when using PostgreSQL) - thanks to Artem Tikhomirov for the patch. Also fixes PostgresSQL tests: NHibernate.Test.NHSpecificTest.NH2251.Fixture.EnlistingFirstThePaginationAndThenTheRowCountDoesNotThrows NHibernate.Test.NHSpecificTest.NH2251.Fixture.FuturePagedHql NHibernate.Test.NHSpecificTest.NH2251.Fixture.WhenUseFutureSkipTakeThenNotThrow NHibernate.Test.NHSpecificTest.NH2362.Fixture.CanParseMultipleGroupBy NHibernate.Test.NHSpecificTest.NH2362.Fixture.CanParseMultipleGroupByAndSelect Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/DomainClass.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/NH2467Test.cs Modified: trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2011-01-18 07:02:44 UTC (rev 5363) +++ trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2011-01-22 13:50:30 UTC (rev 5364) @@ -553,12 +553,12 @@ else { paramTypeList.Add(NHibernateUtil.Int32); - limitParameterIndex = totalSpan; + limitParameterIndex = startParameterIndex + totalSpan; if (addOffset) { paramTypeList.Add(NHibernateUtil.Int32); - offsetParameterIndex = totalSpan; - limitParameterIndex = totalSpan + 1; + offsetParameterIndex = startParameterIndex + totalSpan; + limitParameterIndex = startParameterIndex + totalSpan + 1; } } Modified: trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2011-01-18 07:02:44 UTC (rev 5363) +++ trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2011-01-22 13:50:30 UTC (rev 5364) @@ -5,11 +5,10 @@ using System.Diagnostics; using Iesi.Collections; using Iesi.Collections.Generic; - using NHibernate.Cache; +using NHibernate.Criterion; using NHibernate.Driver; using NHibernate.Engine; -using NHibernate.Criterion; using NHibernate.Loader.Criteria; using NHibernate.SqlCommand; using NHibernate.SqlTypes; @@ -319,18 +318,19 @@ { int limitParameterSpan = BindLimitParametersFirstIfNeccesary(command, queryIndex, colIndex); colIndex = BindQueryParameters(command, queryIndex, colIndex + limitParameterSpan); - BindLimitParametersLastIfNeccesary(command, queryIndex, colIndex); + colIndex += BindLimitParametersLastIfNeccesary(command, queryIndex, colIndex); } } - private void BindLimitParametersLastIfNeccesary(IDbCommand command, int queryIndex, int colIndex) + private int BindLimitParametersLastIfNeccesary(IDbCommand command, int queryIndex, int colIndex) { QueryParameters parameter = parameters[queryIndex]; RowSelection selection = parameter.RowSelection; if (Loader.Loader.UseLimit(selection, dialect) && !dialect.BindLimitParametersFirst) { - Loader.Loader.BindLimitParameters(command, colIndex, selection, session); + return Loader.Loader.BindLimitParameters(command, colIndex, selection, session); } + return 0; } private int BindQueryParameters(IDbCommand command, int queryIndex, int colIndex) Modified: trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2011-01-18 07:02:44 UTC (rev 5363) +++ trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2011-01-22 13:50:30 UTC (rev 5364) @@ -1,9 +1,10 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Data; using System.Diagnostics; using Iesi.Collections; - +using Iesi.Collections.Generic; using NHibernate.Cache; using NHibernate.Driver; using NHibernate.Engine; @@ -12,8 +13,6 @@ using NHibernate.SqlTypes; using NHibernate.Transform; using NHibernate.Type; -using Iesi.Collections.Generic; -using System.Collections.Generic; namespace NHibernate.Impl { @@ -653,18 +652,19 @@ { int limitParameterSpan = BindLimitParametersFirstIfNeccesary(command, queryIndex, colIndex); colIndex = BindQueryParameters(command, queryIndex, colIndex + limitParameterSpan); - BindLimitParametersLastIfNeccesary(command, queryIndex, colIndex); + colIndex += BindLimitParametersLastIfNeccesary(command, queryIndex, colIndex); } } - private void BindLimitParametersLastIfNeccesary(IDbCommand command, int queryIndex, int colIndex) + private int BindLimitParametersLastIfNeccesary(IDbCommand command, int queryIndex, int colIndex) { QueryParameters parameter = parameters[queryIndex]; RowSelection selection = parameter.RowSelection; if (Loader.Loader.UseLimit(selection, dialect) && !dialect.BindLimitParametersFirst) { - Loader.Loader.BindLimitParameters(command, colIndex, selection, session); + return Loader.Loader.BindLimitParameters(command, colIndex, selection, session); } + return 0; } private int BindQueryParameters(IDbCommand command, int queryIndex, int colIndex) Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/DomainClass.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/DomainClass.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/DomainClass.cs 2011-01-22 13:50:30 UTC (rev 5364) @@ -0,0 +1,20 @@ + + +namespace NHibernate.Test.NHSpecificTest.NH2467 +{ + public class DomainClass + { + + public int Id + { + get; + set; + } + + public string Data + { + get; + set; + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/Mappings.hbm.xml 2011-01-22 13:50:30 UTC (rev 5364) @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2467" + default-lazy="false"> + <class name="DomainClass"> + <id name="Id"> + <generator class="assigned" /> + </id> + <property name="Data" /> + </class> +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/NH2467Test.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/NH2467Test.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2467/NH2467Test.cs 2011-01-22 13:50:30 UTC (rev 5364) @@ -0,0 +1,126 @@ +using System.Linq; +using NHibernate.Criterion; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2467 +{ + [TestFixture] + public class NH2467Test : BugTestCase + { + protected override void OnSetUp() + { + base.OnSetUp(); + using (var session = OpenSession()) + { + var entity = new DomainClass {Id = 1, Data = "Test"}; + session.Save(entity); + session.Flush(); + } + } + + protected override bool AppliesTo(Dialect.Dialect dialect) + { + return dialect.SupportsLimit && !dialect.BindLimitParametersFirst; + } + + protected override void OnTearDown() + { + base.OnTearDown(); + using (var session = OpenSession()) + { + session.Delete("from System.Object"); + session.Flush(); + } + } + + [Test] + public void ShouldNotThrowOnFuturePaging() + { + using (var session = OpenSession()) + { + + var contentQuery = session + .CreateCriteria<DomainClass>() + .Add(Restrictions.Eq("Data", "Test")); + contentQuery.SetMaxResults(2); + contentQuery.SetFirstResult(0); + var content = contentQuery.Future<DomainClass>(); + + var countQuery = session + .CreateCriteria<DomainClass>() + .Add(Restrictions.Eq("Data", "Test")); + countQuery.SetProjection(Projections.RowCount()); + var count = countQuery.FutureValue<int>(); + + // triggers batch operation, should not throw + var result = content.ToList(); + } + } + + [Test] + public void ShouldNotThrowOnReversedFuturePaging() + { + using (var session = OpenSession()) + { + + var countQuery = session + .CreateCriteria<DomainClass>() + .Add(Restrictions.Eq("Data", "Test")); + countQuery.SetProjection(Projections.RowCount()); + var count = countQuery.FutureValue<int>(); + + var contentQuery = session + .CreateCriteria<DomainClass>() + .Add(Restrictions.Eq("Data", "Test")); + contentQuery.SetMaxResults(2); + contentQuery.SetFirstResult(0); + var content = contentQuery.Future<DomainClass>(); + + // triggers batch operation, should not throw + var result = content.ToList(); + } + } + + [Test] + public void ShouldNotThrowOnFuturePagingUsingHql() + { + using (var session = OpenSession()) + { + + var contentQuery = session.CreateQuery("from DomainClass as d where d.Data = ?"); + contentQuery.SetString(0, "Test"); + contentQuery.SetMaxResults(2); + contentQuery.SetFirstResult(0); + var content = contentQuery.Future<DomainClass>(); + + var countQuery = session.CreateQuery("select count(d) from DomainClass as d where d.Data = ?"); + countQuery.SetString(0, "Test"); + var count = countQuery.FutureValue<long>(); + + Assert.AreEqual(1, content.ToList().Count); + Assert.AreEqual(1, count.Value); + } + } + + [Test] + public void ShouldNotThrowOnReversedFuturePagingUsingHql() + { + using (var session = OpenSession()) + { + + var contentQuery = session.CreateQuery("from DomainClass as d where d.Data = ?"); + contentQuery.SetString(0, "Test"); + contentQuery.SetMaxResults(2); + contentQuery.SetFirstResult(0); + var content = contentQuery.Future<DomainClass>(); + + var countQuery = session.CreateQuery("select count(d) from DomainClass as d where d.Data = ?"); + countQuery.SetString(0, "Test"); + var count = countQuery.FutureValue<long>(); + + Assert.AreEqual(1, content.ToList().Count); + Assert.AreEqual(1, count.Value); + } + } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-18 07:02:44 UTC (rev 5363) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-22 13:50:30 UTC (rev 5364) @@ -598,6 +598,8 @@ <Compile Include="NHSpecificTest\NH2420\MyTable.cs" /> <Compile Include="NHSpecificTest\NH2441\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2441\Model.cs" /> + <Compile Include="NHSpecificTest\NH2467\DomainClass.cs" /> + <Compile Include="NHSpecificTest\NH2467\NH2467Test.cs" /> <Compile Include="NHSpecificTest\NH2459\Test.cs" /> <Compile Include="NHSpecificTest\NH2459\TrainingComponent.cs" /> <Compile Include="NHSpecificTest\NH2470\Class1Class2Classes.cs" /> @@ -2397,6 +2399,7 @@ <EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" /> </ItemGroup> <ItemGroup> + <EmbeddedResource Include="NHSpecificTest\NH2467\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2459\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2412\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2280\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2011-01-18 07:02:55
|
Revision: 5363 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5363&view=rev Author: julian-maughan Date: 2011-01-18 07:02:44 +0000 (Tue, 18 Jan 2011) Log Message: ----------- Merged latest trunk (r5362) to ReadOnlyCriteria branch. Modified Paths: -------------- branches/ReadOnlyCriteria/nhibernate/ShowBuildMenu.bat branches/ReadOnlyCriteria/nhibernate/build-common/common-project.xml branches/ReadOnlyCriteria/nhibernate/build-common/common.xml branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/basic_mapping.xml branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/configuration.xml branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/manipulating_data.xml branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/performance.xml branches/ReadOnlyCriteria/nhibernate/lib/net/3.5/Remotion.Data.Linq.dll branches/ReadOnlyCriteria/nhibernate/releasenotes.txt branches/ReadOnlyCriteria/nhibernate/src/Iesi.Collections/Iesi.Collections.csproj branches/ReadOnlyCriteria/nhibernate/src/Iesi.Collections.Test/Iesi.Collections.Test.csproj branches/ReadOnlyCriteria/nhibernate/src/Iesi.Collections.sln branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Cfg/MappingSchema/Hbm.generated.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Collection/PersistentIdentifierBag.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Criterion/DetachedCriteria.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Criterion/Restrictions.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Driver/DriverBase.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Engine/CascadeStyle.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Engine/CascadingAction.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Engine/ISessionImplementor.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Event/Default/DefaultMergeEventListener.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Event/IEventSource.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlLexer.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlParser.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlSqlWalker.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Hql.g branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Hql/Ast/ANTLR/HqlSqlWalker.g branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/CaseNode.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElement.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/IQuery.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/ISession.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/IStatelessSession.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Impl/SessionImpl.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Impl/StatelessSessionImpl.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/NhQueryable.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/ReWriters/AddLeftJoinsReWriter.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/Visitors/LeftJoinDetector.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessGroupBy.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessOfType.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/NHibernate.csproj branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Persister/Collection/AbstractCollectionPersister.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/PropertyValueException.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Type/AbstractBinaryType.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Type/CompositeCustomType.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Type/CustomType.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Type/DateTime2Type.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Type/DateTimeType.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Type/EntityType.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Util/ArrayHelper.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/nhibernate-mapping.xsd branches/ReadOnlyCriteria/nhibernate/src/NHibernate.ByteCode.Castle/NHibernate.ByteCode.Castle.csproj branches/ReadOnlyCriteria/nhibernate/src/NHibernate.ByteCode.Castle.Tests/NHibernate.ByteCode.Castle.Tests.csproj branches/ReadOnlyCriteria/nhibernate/src/NHibernate.ByteCode.LinFu/NHibernate.ByteCode.LinFu.csproj branches/ReadOnlyCriteria/nhibernate/src/NHibernate.ByteCode.LinFu.Tests/App.config branches/ReadOnlyCriteria/nhibernate/src/NHibernate.ByteCode.LinFu.Tests/NHibernate.ByteCode.LinFu.Tests.csproj branches/ReadOnlyCriteria/nhibernate/src/NHibernate.ByteCode.Spring/NHibernate.ByteCode.Spring.csproj branches/ReadOnlyCriteria/nhibernate/src/NHibernate.ByteCode.Spring.Tests/App.config branches/ReadOnlyCriteria/nhibernate/src/NHibernate.ByteCode.Spring.Tests/NHibernate.ByteCode.Spring.Tests.csproj branches/ReadOnlyCriteria/nhibernate/src/NHibernate.DomainModel/NHibernate.DomainModel.csproj branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Everything.sln branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Example.Web/Web.Config branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/HQL/Ast/HqlFixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/BinaryExpressionOrdererTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/EagerLoadTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/ProjectionsTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/WhereTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH479/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Stateless/StatelessSessionFixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/TypesTest/Decima2lTypeFixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.TestDatabaseSetup/NHibernate.TestDatabaseSetup.csproj branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Tool.HbmXsd/NHibernate.Tool.HbmXsd.csproj branches/ReadOnlyCriteria/nhibernate/src/NHibernate.sln Added Paths: ----------- branches/ReadOnlyCriteria/.hgignore branches/ReadOnlyCriteria/nhibernate/Tools/Antlr/ branches/ReadOnlyCriteria/nhibernate/Tools/Antlr/antlr-3.2.jar branches/ReadOnlyCriteria/nhibernate/lib/net/3.5/Remotion.Data.Linq.pdb branches/ReadOnlyCriteria/nhibernate/lib/net/3.5/Remotion.Data.Linq.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Event/Default/EventCache.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Hql/Ast/ANTLR/AntlrHql.bat branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Hql/Ast/ANTLR/AntlrHqlDebug.bat branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Hql/Ast/ANTLR/AntlrHqlSqlWalker.bat branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Hql/Ast/ANTLR/AntlrHqlSqlWalkerDebug.bat branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/ReWriters/MoveOrderByToEndRewriter.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/ReWriters/ResultOperatorRewriter.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Linq/ReWriters/ResultOperatorRewriterResult.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Util/EnumerableExtensions.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/A.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/CascadeMergeToChildBeforeParent.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/CascadeMergeToChildBeforeParentTest.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/MultiPathCircleCascade.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/MultiPathCircleCascadeTest.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/Node.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/Route.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/Tour.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/Transport.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/Vehicle.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/G.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/H.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/MultiPathCascade.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/MultiPathCascadeTest.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/ByMethod/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/ByMethod/AnyTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/ByMethod/GroupByTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/ByMethod/OrderByTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/ByMethod/SumTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/StatelessSessionQueringTest.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/BagWithLazyExtraAndFilter/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/BagWithLazyExtraAndFilter/Domain.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/BagWithLazyExtraAndFilter/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/BagWithLazyExtraAndFilter/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2037/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2037/Domain.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2037/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2037/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2043/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2043/Domain.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2043/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2043/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2056/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2056/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2056/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2118/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2118/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2118/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2203/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2203/Domain.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2203/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2203/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2228/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2228/Domain.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2228/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2228/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/InvalidSqlTest.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/Organisation.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/OrganisationCode.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2341/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2341/Domain.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2341/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2341/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Category.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Product.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Supplier.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2386/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2386/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2386/Organisation.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2386/ResponsibleLegalPerson.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2386/Test.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2386/TradingName.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Customer.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Order.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/Test.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/TrainingComponent.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2470/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2470/Class1Class2Classes.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2470/Class1Class2DTOs.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2470/Class1Class2Tests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2470/DTO.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2470/DomainObject.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2470/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/UtilityTest/EnumerableExtensionsTests/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/UtilityTest/EnumerableExtensionsTests/AnyExtensionTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/UtilityTest/EnumerableExtensionsTests/FirstExtensionTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/UtilityTest/EnumerableExtensionsTests/FirstOrNullExtensionTests.cs Removed Paths: ------------- branches/ReadOnlyCriteria/nhibernate/Tools/Antlr/antlr-3.2.jar branches/ReadOnlyCriteria/nhibernate/src/NHibernate/Hql/Ast/ANTLR/output/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/CascadeMergeToChildBeforeParent.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/CascadeMergeToChildBeforeParentTest.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/MultiPathCircleCascade.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/MultiPathCircleCascadeTest.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/Node.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/Route.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/Tour.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/Transport.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Cascade/Circle/Vehicle.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/ByMethod/AnyTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/ByMethod/GroupByTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/ByMethod/OrderByTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/ByMethod/SumTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Linq/OrderByTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/BagWithLazyExtraAndFilter/Domain.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/BagWithLazyExtraAndFilter/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/BagWithLazyExtraAndFilter/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2037/Domain.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2037/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2037/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2043/Domain.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2043/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2043/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2056/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2056/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2118/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2118/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2203/Domain.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2203/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2203/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2228/Domain.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2228/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2228/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/InvalidSqlTest.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/Organisation.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/OrganisationCode.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2341/Domain.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2341/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2341/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Category.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Product.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Supplier.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2386/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2386/Organisation.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2386/ResponsibleLegalPerson.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2386/Test.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2386/TradingName.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Customer.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Order.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/Test.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/TrainingComponent.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2470/Class1Class2Classes.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2470/Class1Class2DTOs.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2470/Class1Class2Tests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2470/DTO.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2470/DomainObject.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2470/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/UtilityTest/EnumerableExtensionsTests/AnyExtensionTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/UtilityTest/EnumerableExtensionsTests/FirstExtensionTests.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/UtilityTest/EnumerableExtensionsTests/FirstOrNullExtensionTests.cs Property Changed: ---------------- branches/ReadOnlyCriteria/ branches/ReadOnlyCriteria/nhibernate/ branches/ReadOnlyCriteria/nhibernate/src/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Customer.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1850/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Fixture.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Mappings.hbm.xml branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1904/Model.cs branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1927/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1928/ branches/ReadOnlyCriteria/nhibernate/src/NHibernate.Test/Tools/hbm2ddl/SchemaExportTests/ Property changes on: branches/ReadOnlyCriteria ___________________________________________________________________ Modified: svn:mergeinfo - /branches/2.1.x:4505-4508,4510-4513,4537-4538 + /branches/2.1.x:4505-4508,4510-4513,4537-4538 /trunk:5306-5362 Copied: branches/ReadOnlyCriteria/.hgignore (from rev 5362, trunk/.hgignore) =================================================================== --- branches/ReadOnlyCriteria/.hgignore (rev 0) +++ branches/ReadOnlyCriteria/.hgignore 2011-01-18 07:02:44 UTC (rev 5363) @@ -0,0 +1,37 @@ +# Ignore file for Visual Studio 2008/2010 + +# use glob syntax +syntax: glob + +*.obj +*.exe +*.pdb +*.user +*.aps +*.pch +*.vspscc +*_i.c +*_p.c +*.ncb +*.suo +*.tlb +*.tlh +*.bak +*.cache +*.ilk +*.log +*.lib +*.sbr +*.scc +[Bb]in +[Db]ebug*/ +obj/ +[Rr]elease*/ +*resharper* +_ReSharper*/ +[Tt]est[Rr]esult* +[Bb]uild[Ll]og.* +*.[Pp]ublish.xml +glob:NHibernate.dll +glob:nhibernate\build\ +glob:AssemblyInfo.cs Property changes on: branches/ReadOnlyCriteria/nhibernate ___________________________________________________________________ Modified: svn:mergeinfo - /branches/2.1.x/nhibernate:4690-4691,4696-4697,4711,4715-4716,4905-4908 + /branches/2.1.x/nhibernate:4690-4691,4696-4697,4711,4715-4716,4905-4908 /trunk/nhibernate:5306-5362 Modified: branches/ReadOnlyCriteria/nhibernate/ShowBuildMenu.bat =================================================================== --- branches/ReadOnlyCriteria/nhibernate/ShowBuildMenu.bat 2011-01-17 15:39:29 UTC (rev 5362) +++ branches/ReadOnlyCriteria/nhibernate/ShowBuildMenu.bat 2011-01-18 07:02:44 UTC (rev 5363) @@ -1,6 +1,5 @@ @echo off -set OLD_CD=%CD% -cd %~dp0 +pushd %~dp0 set NANT=Tools\nant\bin\NAnt.exe -t:net-3.5 @@ -17,9 +16,18 @@ echo F. Build NHibernate (Release) echo G. Build Release Package (Also runs tests and creates documentation) echo. -choice /C abcdefg +echo --- GRAMMAR --- +echo H. Grammar operations (related to Hql.g and HqlSqlWalker.g) +echo. +if exist %SYSTEMROOT%\System32\choice.exe ( goto prompt-choice ) +goto prompt-set + +:prompt-choice +choice /C:abcdefgh + if errorlevel 255 goto end +if errorlevel 8 goto grammar if errorlevel 7 goto build-release-package if errorlevel 6 goto build-release if errorlevel 5 goto build-debug @@ -29,6 +37,19 @@ if errorlevel 1 goto build-visual-studio if errorlevel 0 goto end +:prompt-set +set /p OPT=[A, B, C, D, E, F, G, H]? + +if /I "%OPT%"=="A" goto build-visual-studio +if /I "%OPT%"=="B" goto help-test-setup +if /I "%OPT%"=="C" goto help-larger-window +if /I "%OPT%"=="D" goto build-test +if /I "%OPT%"=="E" goto build-debug +if /I "%OPT%"=="F" goto build-release +if /I "%OPT%"=="G" goto build-release-package +if /I "%OPT%"=="H" goto grammar +goto prompt-set + :help-test-setup echo. echo 1. Install SQL Server 2008 (or use the database included with VS). @@ -88,6 +109,65 @@ %NANT% test goto end +:grammar +echo. +echo --- GRAMMAR --- +echo A. Regenerate HqlLexer.cs and HqlParser.cs from Hql.g. +echo B. Regenerate HqlSqlWalker.cs from HqlSqlWalker.g. +echo C. Regenerate Hql.g in debug mode. +echo D. Regenerate HqlSqlWalker.g in debug mode. +echo E. Quick instructions on using debug mode. +echo. + +if exist %SYSTEMROOT%\System32\choice.exe ( goto grammar-prompt-choice ) +goto grammar-prompt-set + +:grammar-prompt-choice +choice /C:abcde + +if errorlevel 255 goto end +if errorlevel 5 goto antlr-debug +if errorlevel 4 goto antlr-hqlsqlwalker-debug +if errorlevel 3 goto antlr-hql-debug +if errorlevel 2 goto antlr-hqlsqlwalker +if errorlevel 1 goto antlr-hql +if errorlevel 0 goto end + +:grammar-prompt-set +set /p OPT=[A, B, C, D, E]? + +if /I "%OPT%"=="A" goto antlr-hql +if /I "%OPT%"=="B" goto antlr-hqlsqlwalker +if /I "%OPT%"=="C" goto antlr-hql-debug +if /I "%OPT%"=="D" goto antlr-hqlsqlwalker-debug +if /I "%OPT%"=="E" goto antlr-debug +goto grammar-prompt-set + +:antlr-hql +call src\NHibernate\Hql\Ast\ANTLR\AntlrHql.bat +goto end + +:antlr-hqlsqlwalker +call src\NHibernate\Hql\Ast\ANTLR\AntlrHqlSqlWalker.bat +goto end + +:antlr-hql-debug +call src\NHibernate\Hql\Ast\ANTLR\AntlrHqlDebug.bat +goto end + +:antlr-hqlsqlwalker-debug +call src\NHibernate\Hql\Ast\ANTLR\AntlrHqlSqlWalkerDebug.bat +goto end + +:antlr-debug +echo To use the debug grammar: +echo 1. Create a unit test that runs the hql parser on the input you're interested in. +echo 2. Run the unit test. It will appear to stall. +echo 3. Download and run AntlrWorks. +echo 4. Choose "Debug Remote" and allow the default ports. +echo 5. You should now be connected and able to step through your grammar. +goto end + :end -cd %OLD_CD% +popd pause Property changes on: branches/ReadOnlyCriteria/nhibernate/Tools/Antlr ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:logregex + NH-\d+ Deleted: branches/ReadOnlyCriteria/nhibernate/Tools/Antlr/antlr-3.2.jar =================================================================== (Binary files differ) Copied: branches/ReadOnlyCriteria/nhibernate/Tools/Antlr/antlr-3.2.jar (from rev 5362, trunk/nhibernate/Tools/Antlr/antlr-3.2.jar) =================================================================== (Binary files differ) Modified: branches/ReadOnlyCriteria/nhibernate/build-common/common-project.xml =================================================================== --- branches/ReadOnlyCriteria/nhibernate/build-common/common-project.xml 2011-01-17 15:39:29 UTC (rev 5362) +++ branches/ReadOnlyCriteria/nhibernate/build-common/common-project.xml 2011-01-18 07:02:44 UTC (rev 5363) @@ -108,6 +108,7 @@ output="${bin.dir}/${project::get-name()}.dll" doc="${bin.dir}/${project::get-name()}.xml" if="${sign}" + optimize="${build.release}" > <nowarn> <warning number="1591" /> <!-- No XML comment for publicly visible member --> @@ -124,6 +125,7 @@ output="${bin.dir}/${project::get-name()}.dll" doc="${bin.dir}/${project::get-name()}.xml" unless="${sign}" + optimize="${build.release}" > <nowarn> <warning number="1591" /> <!-- No XML comment for publicly visible member --> Modified: branches/ReadOnlyCriteria/nhibernate/build-common/common.xml =================================================================== --- branches/ReadOnlyCriteria/nhibernate/build-common/common.xml 2011-01-17 15:39:29 UTC (rev 5362) +++ branches/ReadOnlyCriteria/nhibernate/build-common/common.xml 2011-01-18 07:02:44 UTC (rev 5363) @@ -84,7 +84,7 @@ effectively SP0). --> - <property name="project.version" value="3.0.0.GA" overwrite="false" /> + <property name="project.version" value="3.0.1.GA" overwrite="false" /> <!-- Compute short project version (major.minor) using a regex --> <regex input="${project.version}" pattern="^(?'shortversion'\d+\.\d+)" /> Modified: branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/basic_mapping.xml =================================================================== --- branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/basic_mapping.xml 2011-01-17 15:39:29 UTC (rev 5362) +++ branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/basic_mapping.xml 2011-01-18 07:02:44 UTC (rev 5363) @@ -225,7 +225,7 @@ <callout arearefs="class2"> <para> <literal>table</literal>(optional - defaults to the unqualified class name): The name of its database table. - </para> + </para> </callout> <callout arearefs="class3"> <para> @@ -1739,8 +1739,7 @@ insert="true|false" upate="true|false" access="field|property|nosetter|ClassName" - optimistic-lock="true|false" -> + optimistic-lock="true|false"> <property ...../> <many-to-one .... /> @@ -1805,6 +1804,113 @@ </sect2> + <sect2 id="mapping-declaration-properties"> + <title>properties</title> + + <para> + The <literal><properties></literal> element allows the + definition of a named, logical grouping of the properties of a class. + The most important use of the construct is that it allows a combination + of properties to be the target of a <literal>property-ref</literal>. It + is also a convenient way to define a multi-column unique constraint. For + example: + </para> + + <programlistingco> + <areaspec> + <area coords="2 60" id="properties1" /> + <area coords="3 60" id="properties2" /> + <area coords="4 60" id="properties3" /> + <area coords="5 60" id="properties4" /> + <area coords="6 60" id="properties5" /> + </areaspec> + + <programlisting><![CDATA[<properties + name="logicalName" + insert="true|false" + update="true|false" + optimistic-lock="true|false" + unique="true|false"> + + <property .../> + <many-to-one .../> + ........ +</properties>]]></programlisting> + + <calloutlist> + <callout arearefs="properties1"> + <para> + <literal>name</literal>: the logical name of the grouping. + It is <emphasis>not</emphasis> an actual property name. + </para> + </callout> + + <callout arearefs="properties2"> + <para> + <literal>insert</literal>: do the mapped columns appear in + SQL <literal>INSERTs</literal>? + </para> + </callout> + + <callout arearefs="properties3"> + <para> + <literal>update</literal>: do the mapped columns appear in + SQL <literal>UPDATEs</literal>? + </para> + </callout> + + <callout arearefs="properties4"> + <para> + <literal>optimistic-lock</literal> (optional - defaults to + <literal>true</literal>): specifies that updates to these + properties either do or do not require acquisition of the + optimistic lock. It determines if a version increment should occur + when these properties are dirty. + </para> + </callout> + + <callout arearefs="properties5"> + <para> + <literal>unique</literal> (optional - defaults to + <literal>false</literal>): specifies that a unique constraint + exists upon all mapped columns of the component. + </para> + </callout> + </calloutlist> + </programlistingco> + + <para> + For example, if we have the following + <literal><![CDATA[<properties>]]></literal> mapping: + </para> + + <programlisting role="XML"><![CDATA[<class name="Person"> + <id name="personNumber" /> + <properties name="name" unique="true" update="false"> + <property name="firstName" /> + <property name="lastName" /> + <property name="initial" /> + </properties> +</class>]]></programlisting> + + <para> + You might have some legacy data association that refers to this + unique key of the <literal>Person</literal> table, instead of to the + primary key: + </para> + + <programlisting role="XML"><![CDATA[<many-to-one name="owner" class="Person" property-ref="name"> + <column name="firstName" /> + <column name="lastName" /> + <column name="initial" /> +</many-to-one>]]></programlisting> + + <para> + The use of this outside the context of mapping legacy data is not + recommended. + </para> + </sect2> + <sect2 id="mapping-declaration-subclass"> <title>subclass</title> @@ -1830,6 +1936,7 @@ dynamic-insert="true|false"> <property .... /> + <properties .... /> ..... </subclass>]]></programlisting> <calloutlist> @@ -1899,6 +2006,7 @@ <key .... > <property .... /> + <properties .... /> ..... </joined-subclass>]]></programlisting> <calloutlist> @@ -2003,6 +2111,7 @@ node="element-name"> <property .... /> + <properties .... /> ..... </union-subclass>]]></programlisting> <calloutlist> Modified: branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/configuration.xml =================================================================== --- branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/configuration.xml 2011-01-17 15:39:29 UTC (rev 5362) +++ branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/configuration.xml 2011-01-18 07:02:44 UTC (rev 5363) @@ -568,7 +568,32 @@ </para> </entry> </row> - <row> + <row> + <entry> + <literal>hbm2ddl.keywords</literal> + </entry> + <entry> + Automatically import <literal>reserved/keywords</literal> from the database when the + <literal>ISessionFactory</literal> is created. + <para> + <emphasis role="strong">none :</emphasis> + disable any operation regarding RDBMS KeyWords + </para> + <para> + <emphasis role="strong">keywords :</emphasis> + imports all RDBMS KeyWords where the <literal>Dialect</literal> can provide the implementation of <literal>IDataBaseSchema</literal>. + </para> + <para> + <emphasis role="strong">auto-quote :</emphasis> + imports all RDBMS KeyWords and auto-quote all table-names/column-names . + </para> + <para> + <emphasis role="strong">eg.</emphasis> + <literal>none</literal> | <literal>keywords</literal> | <literal>auto-quote</literal> + </para> + </entry> + </row> + <row> <entry> <literal>use_proxy_validator</literal> </entry> Modified: branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/manipulating_data.xml =================================================================== --- branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/manipulating_data.xml 2011-01-17 15:39:29 UTC (rev 5362) +++ branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/manipulating_data.xml 2011-01-18 07:02:44 UTC (rev 5363) @@ -633,14 +633,14 @@ </itemizedlist> <para> - The last case can be avoided by using <literal>SaveOrUpdateCopy(Object o)</literal>. This method + The last case can be avoided by using <literal>Merge(Object o)</literal>. This method copies the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. The method returns the persistent instance. If the given instance is unsaved or does not exist in the database, NHibernate will save it and return it as a newly persistent instance. Otherwise, the given instance does not become associated with the session. In most applications with detached objects, you need both methods, <literal>SaveOrUpdate()</literal> - and <literal>SaveOrUpdateCopy()</literal>. + and <literal>Merge()</literal>. </para> </sect2> Modified: branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/performance.xml =================================================================== --- branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/performance.xml 2011-01-17 15:39:29 UTC (rev 5362) +++ branches/ReadOnlyCriteria/nhibernate/doc/reference/modules/performance.xml 2011-01-18 07:02:44 UTC (rev 5363) @@ -481,7 +481,7 @@ <listitem> <para> You may also attach a previously loaded object to a new <literal>ISession</literal> - with <literal>SaveOrUpdateCopy()</literal> or <literal>Lock()</literal> before + with <literal>Merge()</literal> or <literal>Lock()</literal> before accessing uninitialized collections (or other proxies). No, NHibernate does not, and certainly <emphasis>should</emphasis> not do this automatically, since it would introduce ad hoc transaction semantics! Modified: branches/ReadOnlyCriteria/nhibernate/lib/net/3.5/Remotion.Data.Linq.dll =================================================================== (Binary files differ) Copied: branches/ReadOnlyCriteria/nhibernate/lib/net/3.5/Remotion.Data.Linq.pdb (from rev 5362, trunk/nhibernate/lib/net/3.5/Remotion.Data.Linq.pdb) =================================================================== (Binary files differ) Copied: branches/ReadOnlyCriteria/nhibernate/lib/net/3.5/Remotion.Data.Linq.xml (from rev 5362, trunk/nhibernate/lib/net/3.5/Remotion.Data.Linq.xml) =================================================================== --- branches/ReadOnlyCriteria/nhibernate/lib/net/3.5/Remotion.Data.Linq.xml (rev 0) +++ branches/ReadOnlyCriteria/nhibernate/lib/net/3.5/Remotion.Data.Linq.xml 2011-01-18 07:02:44 UTC (rev 5363) @@ -0,0 +1,1253 @@ +<?xml version="1.0" encoding="utf-8"?><doc><assembly> + <name>Remotion.Data.Linq</name> + </assembly><members><member name="T:Remotion.Data.Linq.DefaultQueryProvider"><summary> + Represents a default implementation of <see cref="T:Remotion.Data.Linq.QueryProviderBase" /> that is automatically used by <see cref="T:Remotion.Data.Linq.QueryableBase`1" /> + unless a custom <see cref="T:System.Linq.IQueryProvider" /> is specified. The <see cref="T:Remotion.Data.Linq.DefaultQueryProvider" /> executes queries by parsing them into + an instance of type <see cref="T:Remotion.Data.Linq.QueryModel" />, which is then passed to an implementation of <see cref="T:Remotion.Data.Linq.IQueryExecutor" /> to obtain the + result set. + </summary></member><member name="T:Remotion.Data.Linq.QueryProviderBase"><summary> + Provides a default implementation of <see cref="T:System.Linq.IQueryProvider" /> that executes queries (subclasses of <see cref="T:Remotion.Data.Linq.QueryableBase`1" />) by + first parsing them into a <see cref="T:Remotion.Data.Linq.QueryModel" /> and then passing that to a given implementation of <see cref="T:Remotion.Data.Linq.IQueryExecutor" />. + Usually, <see cref="T:Remotion.Data.Linq.DefaultQueryProvider" /> should be used unless <see cref="M:Remotion.Data.Linq.QueryProviderBase.CreateQuery``1(System.Linq.Expressions.Expression)" /> must be manually implemented. + </summary></member><member name="M:Remotion.Data.Linq.QueryProviderBase.#ctor(Remotion.Data.Linq.IQueryExecutor)"><summary> + Initializes a new instance of <see cref="T:Remotion.Data.Linq.QueryProviderBase" /> using the default <see cref="T:Remotion.Data.Linq.Parsing.Structure.MethodCallExpressionNodeTypeRegistry" />. + </summary><param name="executor">The <see cref="T:Remotion.Data.Linq.IQueryExecutor" /> used to execute queries against a specific query backend.</param></member><member name="M:Remotion.Data.Linq.QueryProviderBase.#ctor(Remotion.Data.Linq.IQueryExecutor,Remotion.Data.Linq.Parsing.Structure.MethodCallExpressionNodeTypeRegistry)"><summary> + Initializes a new instance of <see cref="T:Remotion.Data.Linq.QueryProviderBase" /> using a custom <see cref="T:Remotion.Data.Linq.Parsing.Structure.MethodCallExpressionNodeTypeRegistry" />. Use this + constructor to specify a specific set of parsers to use when analyzing the query. + </summary><param name="executor">The <see cref="T:Remotion.Data.Linq.IQueryExecutor" /> used to execute queries against a specific query backend.</param><param name="nodeTypeRegistry">The <see cref="T:Remotion.Data.Linq.Parsing.Structure.MethodCallExpressionNodeTypeRegistry" /> containing the <see cref="T:System.Linq.Expressions.MethodCallExpression" /> + parsers that should be used when parsing queries.</param></member><member name="M:Remotion.Data.Linq.QueryProviderBase.CreateQuery(System.Linq.Expressions.Expression)"><summary> + Constructs an <see cref="T:System.Linq.IQueryable" /> object that can evaluate the query represented by a specified expression tree. This + method delegates to <see cref="M:Remotion.Data.Linq.QueryProviderBase.CreateQuery``1(System.Linq.Expressions.Expression)" />. + </summary><param name="expression">An expression tree that represents a LINQ query.</param></member><member name="M:Remotion.Data.Linq.QueryProviderBase.CreateQuery``1(System.Linq.Expressions.Expression)"><summary> + Constructs an <see cref="T:System.Linq.IQueryable`1" /> object that can evaluate the query represented by a specified expression tree. This method is + called by the standard query operators defined by the <see cref="T:System.Linq.Queryable" /> class. + </summary><param name="expression">An expression tree that represents a LINQ query.</param></member><member name="M:Remotion.Data.Linq.QueryProviderBase.Execute``1(System.Linq.Expressions.Expression)"><summary> + Executes the query defined by the specified expression by parsing it with a + <see cref="T:Remotion.Data.Linq.Parsing.Structure.QueryParser" /> and then running it through the <see cref="P:Remotion.Data.Linq.QueryProviderBase.Executor" />. + This method is invoked through the <see cref="T:System.Linq.IQueryProvider" /> interface by methods such as + <see cref="M:System.Linq.Queryable.First``1(System.Linq.IQueryable{``0})" /> and + <see cref="M:System.Linq.Queryable.Count``1(System.Linq.IQueryable{``0})" />, and it's also invoked by <see cref="T:Remotion.Data.Linq.QueryableBase`1" /> + when the <see cref="T:System.Linq.IQueryable`1" /> is enumerated. + </summary></member><member name="M:Remotion.Data.Linq.QueryProviderBase.GenerateQueryModel(System.Linq.Expressions.Expression)"><summary> + The method generates a <see cref="T:Remotion.Data.Linq.QueryModel" />. + </summary><param name="expression">The query as expression chain.</param></member><member name="P:Remotion.Data.Linq.QueryProviderBase.Executor"><summary> + Gets or sets the implementation of <see cref="T:Remotion.Data.Linq.IQueryExecutor" /> used to execute queries created via <see cref="M:Remotion.Data.Linq.QueryProviderBase.CreateQuery``1(System.Linq.Expressions.Expression)" />. + </summary></member><member name="P:Remotion.Data.Linq.QueryProviderBase.ExpressionTreeParser"><summary> + Gets the <see cref="P:Remotion.Data.Linq.QueryProviderBase.ExpressionTreeParser" /> used by this <see cref="T:Remotion.Data.Linq.QueryProviderBase" /> to parse LINQ <see cref="T:System.Linq.Expressions.Expression" /> + trees. + </summary></member><member name="M:Remotion.Data.Linq.DefaultQueryProvider.CreateQuery``1(System.Linq.Expressions.Expression)"><summary> + Creates a new <see cref="T:System.Linq.IQueryable" /> (of type <see cref="P:Remotion.Data.Linq.DefaultQueryProvider.QueryableType" /> with <typeparamref name="T" /> as its generic argument) that + represents the query defined by <paramref name="expression" /> and is able to enumerate its results. + </summary><param name="expression">An expression representing the query for which a <see cref="T:System.Linq.IQueryable`1" /> should be created.</param></member><member name="P:Remotion.Data.Linq.DefaultQueryProvider.QueryableType"><summary> + Gets the type of queryable created by this provider. This is the generic type definition of an implementation of <see cref="T:System.Linq.IQueryable`1" /> + (usually a subclass of <see cref="T:Remotion.Data.Linq.QueryableBase`1" />) with exactly one type argument. + </summary></member><member name="T:Remotion.Data.Linq.IQueryExecutor"><summary> + Constitutes the bridge between re-linq and a concrete query provider implementation. Concrete providers implement this interface + and <see cref="T:Remotion.Data.Linq.QueryProviderBase" /> calls the respective method of the interface implementation when a query is to be executed. + </summary></member><member name="M:Remotion.Data.Linq.IQueryExecutor.ExecuteScalar``1(Remotion.Data.Linq.QueryModel)"><summary> + Executes the given <paramref name="queryModel" /> as a scalar query, i.e. as a query returning a scalar value of type <typeparamref name="T" />. + The query ends with a scalar result operator, for example a <see cref="T:Remotion.Data.Linq.Clauses.ResultOperators.CountResultOperator" /> or a <see cref="T:Remotion.Data.Linq.Clauses.ResultOperators.SumResultOperator" />. + </summary><param name="queryModel">The <see cref="T:Remotion.Data.Linq.QueryModel" /> representing the query to be executed. Analyze this via an + <see cref="T:Remotion.Data.Linq.IQueryModelVisitor" />.</param></member><member name="M:Remotion.Data.Linq.IQueryExecutor.ExecuteSingle``1(Remotion.Data.Linq.QueryModel,System.Boolean)"><summary> + Executes the given <paramref name="queryModel" /> as a single object query, i.e. as a query returning a single object of type + <typeparamref name="T" />. + The query ends with a single result operator, for example a <see cref="T:Remotion.Data.Linq.Clauses.ResultOperators.FirstResultOperator" /> or a <see cref="T:Remotion.Data.Linq.Clauses.ResultOperators.SingleResultOperator" />. + </summary><param name="queryModel">The <see cref="T:Remotion.Data.Linq.QueryModel" /> representing the query to be executed. Analyze this via an + <see cref="T:Remotion.Data.Linq.IQueryModelVisitor" />.</param><param name="returnDefaultWhenEmpty">If <see langword="true" />, the executor must return a default value when its result set is empty; + if <see langword="false" />, it should throw an <see cref="T:System.InvalidOperationException" /> when its result set is empty.</param></member><member name="M:Remotion.Data.Linq.IQueryExecutor.ExecuteCollection``1(Remotion.Data.Linq.QueryModel)"><summary> + Executes the given <paramref name="queryModel" /> as a collection query, i.e. as a query returning objects of type <typeparamref name="T" />. + The query does not end with a scalar result operator, but it can end with a single result operator, for example + <see cref="T:Remotion.Data.Linq.Clauses.ResultOperators.SingleResultOperator" /> or <see cref="T:Remotion.Data.Linq.Clauses.ResultOperators.FirstResultOperator" />. In such a case, the returned enumerable must yield exactly + one object (or none if the last result operator allows empty result sets). + </summary><param name="queryModel">The <see cref="T:Remotion.Data.Linq.QueryModel" /> representing the query to be executed. Analyze this via an + <see cref="T:Remotion.Data.Linq.IQueryModelVisitor" />.</param></member><member name="T:Remotion.Data.Linq.IQueryModelVisitor"><summary> + Defines an interface for visiting the clauses of a <see cref="T:Remotion.Data.Linq.QueryModel" />. + </summary></member><member name="T:Remotion.Data.Linq.QueryableBase`1"><summary> + Acts as a common base class for <see cref="T:System.Linq.IQueryable`1" /> implementations based on re-linq. In a specific LINQ provider, a custom queryable + class should be derived from <see cref="T:Remotion.Data.Linq.QueryableBase`1" /> which supplies an implementation of <see cref="T:Remotion.Data.Linq.IQueryExecutor" /> that is used to + execute the query. This is then used as an entry point (the main data source) of a LINQ query. + </summary></member><member name="M:Remotion.Data.Linq.QueryableBase`1.#ctor(Remotion.Data.Linq.IQueryExecutor)"><summary> + Initializes a new instance of the <see cref="T:Remotion.Data.Linq.QueryableBase`1" /> class with a <see cref="T:Remotion.Data.Linq.DefaultQueryProvider" /> and the given + <paramref name="executor" />. This constructor should be used by subclasses to begin a new query. The <see cref="P:Remotion.Data.Linq.QueryableBase`1.Expression" /> generated by + this constructor is a <see cref="T:System.Linq.Expressions.ConstantExpression" /> pointing back to this <see cref="T:Remotion.Data.Linq.QueryableBase`1" />. + </summary><param name="executor">The <see cref="T:Remotion.Data.Linq.IQueryExecutor" /> used to execute the query represented by this <see cref="T:Remotion.Data.Linq.QueryableBase`1" />.</param></member><member name="M:Remotion.Data.Linq.QueryableBase`1.#ctor(System.Linq.IQueryProvider)"><summary> + Initializes a new instance of the <see cref="T:Remotion.Data.Linq.QueryableBase`1" /> class with a specific <see cref="T:System.Linq.IQueryProvider" />. This constructor + should only be used to begin a query when <see cref="T:Remotion.Data.Linq.DefaultQueryProvider" /> does not fit the requirements. + </summary><param name="provider">The provider used to execute the query represented by this <see cref="T:Remotion.Data.Linq.QueryableBase`1" /> and to construct + queries around this <see cref="T:Remotion.Data.Linq.QueryableBase`1" />.</param></member><member name="M:Remotion.Data.Linq.QueryableBase`1.#ctor(System.Linq.IQueryProvider,System.Linq.Expressions.Expression)"><summary> + Initializes a new instance of the <see cref="T:Remotion.Data.Linq.QueryableBase`1" /> class with a given <paramref name="provider" /> and + <paramref name="expression" />. A constructor with a matching signature must be exposed on subclasses because it is used by + <see cref="T:Remotion.Data.Linq.DefaultQueryProvider" /> to construct queries around this <see cref="T:Remotion.Data.Linq.QueryableBase`1" /> when a query method (e.g. of the + <see cref="T:System.Linq.Queryable" /> class) is called. + </summary><param name="provider">The provider used to execute the query represented by this <see cref="T:Remotion.Data.Linq.QueryableBase`1" /> and to construct + queries around this <see cref="T:Remotion.Data.Linq.QueryableBase`1" />.</param><param name="expression">The expression representing the query.</param></member><member name="M:Remotion.Data.Linq.QueryableBase`1.GetEnumerator"><summary> + Executes the query via the <see cref="P:Remotion.Data.Linq.QueryableBase`1.Provider" /> and returns an enumerator that iterates through the items returned by the query. + </summary></member><member name="P:Remotion.Data.Linq.QueryableBase`1.Expression"><summary> + Gets the expression tree that is associated with the instance of <see cref="T:System.Linq.IQueryable" />. This expression describes the + query represented by this <see cref="T:Remotion.Data.Linq.QueryableBase`1" />. + </summary></member><member name="P:Remotion.Data.Linq.QueryableBase`1.Provider"><summary> + Gets the query provider that is associated with this data source. The provider is used to execute the query. By default, a + <see cref="T:Remotion.Data.Linq.DefaultQueryProvider" /> is used that parses the query and passes it on to an implementation of <see cref="T:Remotion.Data.Linq.IQueryExecutor" />. + </summary></member><member name="P:Remotion.Data.Linq.QueryableBase`1.ElementType"><summary> + Gets the type of the element(s) that are returned when the expression tree associated with this instance of <see cref="T:System.Linq.IQueryable" /> is executed. + </summary></member><member name="T:Remotion.Data.Linq.QueryModel"><summary> + Provides an abstraction of an expression tree created for a LINQ query. <see cref="T:Remotion.Data.Linq.QueryModel" /> instances are passed to LINQ providers based + on re-linq via <see cref="T:Remotion.Data.Linq.IQueryExecutor" />, but you can also use <see cref="T:Remotion.Data.Linq.Parsing.Structure.QueryParser" /> to parse an expression tree by hand or construct + a <see cref="T:Remotion.Data.Linq.QueryModel" /> manually via its constructor. + </summary></member><member name="M:Remotion.Data.Linq.QueryModel.#ctor(Remotion.Data.Linq.Clauses.MainFromClause,Remotion.Data.Linq.Clauses.SelectClause)"><summary> + Initializes a new instance of <see cref="T:Remotion.Data.Linq.QueryModel" /> + </summary><param name="mainFromClause">The <see cref="T:Remotion.Data.Linq.Clauses.MainFromClause" /> of the query. This is the starting point of the query, generating items + that are filtered and projected by the query.</param><param name="selectClause">The <see cref="P:Remotion.Data.Linq.QueryModel.SelectClause" /> of the query. This is the end point of + the query, it defines what is actually returned for each of the items coming from the <see cref="P:Remotion.Data.Linq.QueryModel.MainFromClause" /> and passing the + <see cref="P:Remotion.Data.Linq.QueryModel.BodyClauses" />. After it, only the <see cref="P:Remotion.Data.Linq.QueryModel.ResultOperators" /> modify the result of the query.</param></member><member name="M:Remotion.Data.Linq.QueryModel.GetOutputDataInfo"><summary> + Gets an <see cref="T:Remotion.Data.Linq.Clauses.StreamedData.IStreamedDataInfo" /> object describing the data streaming out of this <see cref="T:Remotion.Data.Linq.QueryModel" />. If a query ends with + the <see cref="P:Remotion.Data.Linq.QueryModel.SelectClause" />, this corresponds to <see cref="M:Remotion.Data.Linq.Clauses.SelectClause.GetOutputDataInfo" />. If a query has + <see cref="P:Remotion.Data.Linq.QueryModel.ResultOperators" />, the data is further modified by those operators. + </summary></member><member name="M:Remotion.Data.Linq.QueryModel.GetUniqueIdentfierGenerator"><summary> + Gets the <see cref="T:Remotion.Data.Linq.UniqueIdentifierGenerator" /> which is used by the <see cref="T:Remotion.Data.Linq.QueryModel" />. + </summary></member><member name="M:Remotion.Data.Linq.QueryModel.Accept(Remotion.Data.Linq.IQueryModelVisitor)"><summary> + Accepts an implementation of <see cref="T:Remotion.Data.Linq.IQueryModelVisitor" /> or <see cref="T:Remotion.Data.Linq.QueryModelVisitorBase" />, as defined by the Visitor pattern. + </summary></member><member name="M:Remotion.Data.Linq.QueryModel.ToString"><summary> + Returns a <see cref="T:System.String" /> representation of this <see cref="T:Remotion.Data.Linq.QueryModel" />. + </summary></member><member name="M:Remotion.Data.Linq.Query... [truncated message content] |
From: <jul...@us...> - 2011-01-17 15:39:35
|
Revision: 5362 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5362&view=rev Author: julian-maughan Date: 2011-01-17 15:39:29 +0000 (Mon, 17 Jan 2011) Log Message: ----------- Deprecated ISession.SaveOrUpdateCopy methods - they are replaced by Merge methods which are functionally identical [ref. NH-2508] Modified Paths: -------------- trunk/nhibernate/doc/reference/modules/manipulating_data.xml trunk/nhibernate/doc/reference/modules/performance.xml trunk/nhibernate/releasenotes.txt trunk/nhibernate/src/NHibernate/Engine/CascadeStyle.cs trunk/nhibernate/src/NHibernate/Engine/CascadingAction.cs trunk/nhibernate/src/NHibernate/Event/IEventSource.cs trunk/nhibernate/src/NHibernate/ISession.cs trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs Modified: trunk/nhibernate/doc/reference/modules/manipulating_data.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/manipulating_data.xml 2011-01-17 15:04:02 UTC (rev 5361) +++ trunk/nhibernate/doc/reference/modules/manipulating_data.xml 2011-01-17 15:39:29 UTC (rev 5362) @@ -633,14 +633,14 @@ </itemizedlist> <para> - The last case can be avoided by using <literal>SaveOrUpdateCopy(Object o)</literal>. This method + The last case can be avoided by using <literal>Merge(Object o)</literal>. This method copies the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. The method returns the persistent instance. If the given instance is unsaved or does not exist in the database, NHibernate will save it and return it as a newly persistent instance. Otherwise, the given instance does not become associated with the session. In most applications with detached objects, you need both methods, <literal>SaveOrUpdate()</literal> - and <literal>SaveOrUpdateCopy()</literal>. + and <literal>Merge()</literal>. </para> </sect2> Modified: trunk/nhibernate/doc/reference/modules/performance.xml =================================================================== --- trunk/nhibernate/doc/reference/modules/performance.xml 2011-01-17 15:04:02 UTC (rev 5361) +++ trunk/nhibernate/doc/reference/modules/performance.xml 2011-01-17 15:39:29 UTC (rev 5362) @@ -481,7 +481,7 @@ <listitem> <para> You may also attach a previously loaded object to a new <literal>ISession</literal> - with <literal>SaveOrUpdateCopy()</literal> or <literal>Lock()</literal> before + with <literal>Merge()</literal> or <literal>Lock()</literal> before accessing uninitialized collections (or other proxies). No, NHibernate does not, and certainly <emphasis>should</emphasis> not do this automatically, since it would introduce ad hoc transaction semantics! Modified: trunk/nhibernate/releasenotes.txt =================================================================== --- trunk/nhibernate/releasenotes.txt 2011-01-17 15:04:02 UTC (rev 5361) +++ trunk/nhibernate/releasenotes.txt 2011-01-17 15:39:29 UTC (rev 5362) @@ -1,5 +1,8 @@ ** Known BREAKING CHANGES from NH3.0.0.GA to NH3.0.1.GA + ##### Design time ##### + * [NH-2481] - Deprecated: ISession.SaveOrUpdateCopy methods - use ISession.Merge methods instead + ##### Run time ##### * [NH-2481] - An exception will now be thrown when an entity references a transient entity and cascade="merge|all" is not configured on the association Modified: trunk/nhibernate/src/NHibernate/Engine/CascadeStyle.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/CascadeStyle.cs 2011-01-17 15:04:02 UTC (rev 5361) +++ trunk/nhibernate/src/NHibernate/Engine/CascadeStyle.cs 2011-01-17 15:39:29 UTC (rev 5362) @@ -153,7 +153,7 @@ { public override bool DoCascade(CascadingAction action) { - return action == CascadingAction.Merge; + return action == CascadingAction.Merge || action == CascadingAction.SaveUpdateCopy; } } Modified: trunk/nhibernate/src/NHibernate/Engine/CascadingAction.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/CascadingAction.cs 2011-01-17 15:04:02 UTC (rev 5361) +++ trunk/nhibernate/src/NHibernate/Engine/CascadingAction.cs 2011-01-17 15:39:29 UTC (rev 5362) @@ -1,3 +1,4 @@ +using System; using System.Collections; using Iesi.Collections; @@ -286,6 +287,7 @@ } } + [Obsolete("Replaced by MergeCascadingAction")] private class SaveUpdateCopyCascadingAction : CascadingAction { // for deprecated saveOrUpdateCopy() Modified: trunk/nhibernate/src/NHibernate/Event/IEventSource.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/IEventSource.cs 2011-01-17 15:04:02 UTC (rev 5361) +++ trunk/nhibernate/src/NHibernate/Event/IEventSource.cs 2011-01-17 15:39:29 UTC (rev 5362) @@ -1,3 +1,4 @@ +using System; using System.Collections; using Iesi.Collections; using NHibernate.Engine; @@ -32,10 +33,10 @@ void Refresh(object obj, IDictionary refreshedAlready); /// <summary> Cascade copy an entity instance</summary> + [Obsolete("Use Merge(string, object, IDictionary) instead")] void SaveOrUpdateCopy(string entityName, object obj, IDictionary copiedAlready); /// <summary> Cascade delete an entity instance</summary> void Delete(string entityName, object child, bool isCascadeDeleteEnabled, ISet transientEntities); } - } Modified: trunk/nhibernate/src/NHibernate/ISession.cs =================================================================== --- trunk/nhibernate/src/NHibernate/ISession.cs 2011-01-17 15:04:02 UTC (rev 5361) +++ trunk/nhibernate/src/NHibernate/ISession.cs 2011-01-17 15:39:29 UTC (rev 5362) @@ -420,7 +420,7 @@ /// The semantics of this method are defined by JSR-220. /// <param name="entityName">Name of the entity.</param> /// <param name="obj">a detached instance with state to be copied </param> - /// <returns> an updated persistent instance </returns> + /// <returns> an updated persistent instance </returns> /// </summary> /// <returns></returns> object Merge(string entityName, object obj); @@ -452,6 +452,7 @@ /// </summary> /// <param name="obj">a transient instance with state to be copied</param> /// <returns>an updated persistent instance</returns> + [Obsolete("Use Merge(object) instead")] object SaveOrUpdateCopy(object obj); /// <summary> @@ -465,6 +466,7 @@ /// <param name="obj">a persistent or transient instance with state to be copied</param> /// <param name="id">the identifier of the instance to copy to</param> /// <returns>an updated persistent instance</returns> + [Obsolete("No direct replacement. Use Merge instead.")] object SaveOrUpdateCopy(object obj, object id); /// <summary> Modified: trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2011-01-17 15:04:02 UTC (rev 5361) +++ trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2011-01-17 15:39:29 UTC (rev 5362) @@ -956,6 +956,7 @@ } /// <summary> Cascade copy an entity instance</summary> + [Obsolete("Use Merge(string, object, IDictionary) instead")] public void SaveOrUpdateCopy(string entityName, object obj, IDictionary copiedAlready) { using (new SessionIdLoggingContext(SessionId)) @@ -2103,11 +2104,7 @@ } } - /// <summary> - /// - /// </summary> - /// <param name="obj"></param> - /// <returns></returns> + [Obsolete("Use Merge(object) instead")] public object SaveOrUpdateCopy(object obj) { using (new SessionIdLoggingContext(SessionId)) @@ -2116,6 +2113,7 @@ } } + [Obsolete("No direct replacement. Use Merge instead.")] public object SaveOrUpdateCopy(object obj, object id) { using (new SessionIdLoggingContext(SessionId)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2011-01-17 15:04:11
|
Revision: 5361 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5361&view=rev Author: julian-maughan Date: 2011-01-17 15:04:02 +0000 (Mon, 17 Jan 2011) Log Message: ----------- Fixed merge failure when there is a transient entity reachable by multiple paths and at least one path does not cascade on merge [ref. NH-2481]. Port from Hibernate. Modified Paths: -------------- trunk/nhibernate/releasenotes.txt trunk/nhibernate/src/NHibernate/Event/Default/DefaultMergeEventListener.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate/Type/EntityType.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH479/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate/Event/Default/EventCache.cs trunk/nhibernate/src/NHibernate.Test/Cascade/A.cs trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/ trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/CascadeMergeToChildBeforeParent.hbm.xml trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/CascadeMergeToChildBeforeParentTest.cs trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/MultiPathCircleCascade.hbm.xml trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/MultiPathCircleCascadeTest.cs trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Node.cs trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Route.cs trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Tour.cs trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Transport.cs trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Vehicle.cs trunk/nhibernate/src/NHibernate.Test/Cascade/G.cs trunk/nhibernate/src/NHibernate.Test/Cascade/H.cs trunk/nhibernate/src/NHibernate.Test/Cascade/MultiPathCascade.hbm.xml trunk/nhibernate/src/NHibernate.Test/Cascade/MultiPathCascadeTest.cs Modified: trunk/nhibernate/releasenotes.txt =================================================================== --- trunk/nhibernate/releasenotes.txt 2011-01-17 05:55:48 UTC (rev 5360) +++ trunk/nhibernate/releasenotes.txt 2011-01-17 15:04:02 UTC (rev 5361) @@ -1,4 +1,8 @@ ** Known BREAKING CHANGES from NH3.0.0.GA to NH3.0.1.GA + + ##### Run time ##### + * [NH-2481] - An exception will now be thrown when an entity references a transient entity and cascade="merge|all" is not configured on the association + ##### Possible Breaking Changes ##### * [NH-2461] - Signature change for IQuery.SetParameterList @@ -10,7 +14,7 @@ ##### Run time ##### * [NH-2199] - null values in maps/dictionaries are no longer silenty ignored/deleted * [NH-1894] - SybaseAnywhereDialect has been removed, and replaced with SybaseASA9Dialect. - - Sybase Adaptive Server Enterprise (ASE) dialects removed. + - Sybase Adaptive Server Enterprise (ASE) dialects removed. ##### Possible Breaking Changes ##### * [NH-2251] - Signature change for GetLimitString in Dialect Modified: trunk/nhibernate/src/NHibernate/Event/Default/DefaultMergeEventListener.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/DefaultMergeEventListener.cs 2011-01-17 05:55:48 UTC (rev 5360) +++ trunk/nhibernate/src/NHibernate/Event/Default/DefaultMergeEventListener.cs 2011-01-17 15:04:02 UTC (rev 5361) @@ -1,6 +1,7 @@ using System; using System.Collections; +using Iesi.Collections.Generic; using NHibernate.Classic; using NHibernate.Engine; using NHibernate.Intercept; @@ -11,9 +12,8 @@ namespace NHibernate.Event.Default { - /// <summary> - /// Defines the default copy event listener used by hibernate for copying entities - /// in response to generated copy events. + /// <summary> + /// Defines the default event listener for handling of merge events generated from a session. /// </summary> [Serializable] public class DefaultMergeEventListener : AbstractSaveEventListener, IMergeEventListener @@ -32,16 +32,58 @@ protected override IDictionary GetMergeMap(object anything) { - return IdentityMap.Invert((IDictionary)anything); + return ((EventCache)anything).InvertMap(); } public virtual void OnMerge(MergeEvent @event) { - OnMerge(@event, IdentityMap.Instantiate(10)); + EventCache copyCache = new EventCache(); + + OnMerge(@event, copyCache); + + // TODO: iteratively get transient entities and retry merge until one of the following conditions: + // 1) transientCopyCache.size() == 0 + // 2) transientCopyCache.size() is not decreasing and copyCache.size() is not increasing + + // TODO: find out if retrying can add entities to copyCache (don't think it can...) + // For now, just retry once; throw TransientObjectException if there are still any transient entities + + IDictionary transientCopyCache = this.GetTransientCopyCache(@event, copyCache); + + if (transientCopyCache.Count > 0) + { + RetryMergeTransientEntities(@event, transientCopyCache, copyCache); + + // find any entities that are still transient after retry + transientCopyCache = this.GetTransientCopyCache(@event, copyCache); + + if (transientCopyCache.Count > 0) + { + ISet<string> transientEntityNames = new HashedSet<string>(); + + foreach (object transientEntity in transientCopyCache.Keys) + { + string transientEntityName = @event.Session.GuessEntityName(transientEntity); + + transientEntityNames.Add(transientEntityName); + + log.InfoFormat( + "transient instance could not be processed by merge: {0} [{1}]", + transientEntityName, + transientEntity.ToString()); + } + + throw new TransientObjectException("one or more objects is an unsaved transient instance - save transient instance(s) before merging: " + transientEntityNames); + } + } + + copyCache.Clear(); + copyCache = null; } - - public virtual void OnMerge(MergeEvent @event, IDictionary copyCache) + + public virtual void OnMerge(MergeEvent @event, IDictionary copiedAlready) { + EventCache copyCache = (EventCache)copiedAlready; IEventSource source = @event.Session; object original = @event.Original; @@ -54,7 +96,7 @@ if (li.IsUninitialized) { log.Debug("ignoring uninitialized proxy"); - @event.Result = source.Load(li.PersistentClass, li.Identifier); + @event.Result = source.Load(li.EntityName, li.Identifier); return; //EARLY EXIT! } else @@ -66,14 +108,20 @@ { entity = original; } - - if (copyCache.Contains(entity)) + + if (copyCache.Contains(entity) && copyCache.IsOperatedOn(entity)) { - log.Debug("already merged"); + log.Debug("already in merge process"); @event.Result = entity; } else { + if (copyCache.Contains(entity)) + { + log.Info("already in copyCache; setting in merge process"); + copyCache.SetOperatedOn(entity, true); + } + @event.Entity = entity; EntityState entityState = EntityState.Undefined; @@ -129,11 +177,12 @@ log.Debug("ignoring persistent instance"); //TODO: check that entry.getIdentifier().equals(requestedId) + object entity = @event.Entity; IEventSource source = @event.Session; IEntityPersister persister = source.GetEntityPersister(@event.EntityName, entity); - copyCache[entity] = entity; //before cascade! + ((EventCache)copyCache).Add(entity, entity, true); //before cascade! CascadeOnMerge(source, persister, entity, copyCache); CopyValues(persister, entity, entity, source, copyCache); @@ -143,45 +192,100 @@ protected virtual void EntityIsTransient(MergeEvent @event, IDictionary copyCache) { - log.Debug("merging transient instance"); + log.Info("merging transient instance"); object entity = @event.Entity; IEventSource source = @event.Session; IEntityPersister persister = source.GetEntityPersister(@event.EntityName, entity); string entityName = persister.EntityName; + + @event.Result = this.MergeTransientEntity(entity, entityName, @event.RequestedId, source, copyCache); + } + + private object MergeTransientEntity(object entity, string entityName, object requestedId, IEventSource source, IDictionary copyCache) + { + IEntityPersister persister = source.GetEntityPersister(entityName, entity); object id = persister.HasIdentifierProperty ? persister.GetIdentifier(entity, source.EntityMode) : null; + object copy = null; + + if (copyCache.Contains(entity)) + { + copy = copyCache[entity]; + persister.SetIdentifier(copy, id, source.EntityMode); + } + else + { + copy = source.Instantiate(persister, id); + ((EventCache)copyCache).Add(entity, copy, true); // before cascade! + } - object copy = persister.Instantiate(id, source.EntityMode); // should this be Session.instantiate(Persister, ...)? - copyCache[entity] = copy; //before cascade! - // cascade first, so that all unsaved objects get their // copy created before we actually copy //cascadeOnMerge(event, persister, entity, copyCache, Cascades.CASCADE_BEFORE_MERGE); base.CascadeBeforeSave(source, persister, entity, copyCache); CopyValues(persister, entity, copy, source, copyCache, ForeignKeyDirection.ForeignKeyFromParent); - //this bit is only *really* absolutely necessary for handling - //requestedId, but is also good if we merge multiple object - //graphs, since it helps ensure uniqueness - object requestedId = @event.RequestedId; - if (requestedId == null) + try { - SaveWithGeneratedId(copy, entityName, copyCache, source, false); + // try saving; check for non-nullable properties that are null or transient entities before saving + this.SaveTransientEntity(copy, entityName, requestedId, source, copyCache); } - else + catch (PropertyValueException ex) { - SaveWithRequestedId(copy, requestedId, entityName, copyCache, source); + string propertyName = ex.PropertyName; + object propertyFromCopy = persister.GetPropertyValue(copy, propertyName, source.EntityMode); + object propertyFromEntity = persister.GetPropertyValue(entity, propertyName, source.EntityMode); + IType propertyType = persister.GetPropertyType(propertyName); + EntityEntry copyEntry = source.PersistenceContext.GetEntry(copy); + + if (propertyFromCopy == null || !propertyType.IsEntityType) + { + log.InfoFormat("property '{0}.{1}' is null or not an entity; {1} =[{2}]", copyEntry.EntityName, propertyName, propertyFromCopy); + throw; + } + + if (!copyCache.Contains(propertyFromEntity)) + { + log.InfoFormat("property '{0}.{1}' from original entity is not in copyCache; {1} =[{2}]", copyEntry.EntityName, propertyName, propertyFromEntity); + throw; + } + + if (((EventCache)copyCache).IsOperatedOn(propertyFromEntity)) + { + log.InfoFormat("property '{0}.{1}' from original entity is in copyCache and is in the process of being merged; {1} =[{2}]", copyEntry.EntityName, propertyName, propertyFromEntity); + } + else + { + log.InfoFormat("property '{0}.{1}' from original entity is in copyCache and is not in the process of being merged; {1} =[{2}]", copyEntry.EntityName, propertyName, propertyFromEntity); + } + + // continue...; we'll find out if it ends up not getting saved later } - - // cascade first, so that all unsaved objects get their + + // cascade first, so that all unsaved objects get their // copy created before we actually copy base.CascadeAfterSave(source, persister, entity, copyCache); CopyValues(persister, entity, copy, source, copyCache, ForeignKeyDirection.ForeignKeyToParent); - @event.Result = copy; + return copy; } + + private void SaveTransientEntity(object entity, string entityName, object requestedId, IEventSource source, IDictionary copyCache) + { + // this bit is only *really* absolutely necessary for handling + // requestedId, but is also good if we merge multiple object + // graphs, since it helps ensure uniqueness + if (requestedId == null) + { + SaveWithGeneratedId(entity, entityName, copyCache, source, false); + } + else + { + SaveWithRequestedId(entity, requestedId, entityName, copyCache, source); + } + } protected virtual void EntityIsDetached(MergeEvent @event, IDictionary copyCache) { @@ -211,7 +315,7 @@ string previousFetchProfile = source.FetchProfile; source.FetchProfile = "merge"; - //we must clone embedded composite identifiers, or + //we must clone embedded composite identifiers, or //we will get back the same instance that we pass in object clonedIdentifier = persister.IdentifierType.DeepCopy(id, source.EntityMode, source.Factory); object result = source.Get(persister.EntityName, clonedIdentifier); @@ -220,7 +324,7 @@ if (result == null) { - //TODO: we should throw an exception if we really *know* for sure + //TODO: we should throw an exception if we really *know* for sure // that this is a detached instance, rather than just assuming //throw new StaleObjectStateException(entityName, id); @@ -237,7 +341,7 @@ return; } - copyCache[entity] = result; //before cascade! + ((EventCache)copyCache).Add(entity, result, true); //before cascade! object target = source.PersistenceContext.Unproxy(result); if (target == entity) @@ -258,7 +362,7 @@ throw new StaleObjectStateException(persister.EntityName, id); } - // cascade first, so that all unsaved objects get their + // cascade first, so that all unsaved objects get their // copy created before we actually copy CascadeOnMerge(source, persister, entity, copyCache); CopyValues(persister, entity, target, source, copyCache); @@ -357,8 +461,7 @@ persister.SetPropertyValues(target, copiedValues, source.EntityMode); } - protected virtual void CopyValues(IEntityPersister persister, object entity, object target, - ISessionImplementor source, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection) + protected virtual void CopyValues(IEntityPersister persister, object entity, object target, ISessionImplementor source, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection) { object[] copiedValues; @@ -383,7 +486,7 @@ persister.SetPropertyValues(target, copiedValues, source.EntityMode); } - /// <summary> + /// <summary> /// Perform any cascades needed as part of this copy event. /// </summary> /// <param name="source">The merge event being processed. </param> @@ -403,6 +506,92 @@ } } + /// <summary> + /// Determine which merged entities in the copyCache are transient. + /// </summary> + /// <param name="event"></param> + /// <param name="copyCache"></param> + /// <returns></returns> + /// <remarks>Should this method be on the EventCache class?</remarks> + protected EventCache GetTransientCopyCache(MergeEvent @event, EventCache copyCache) + { + EventCache transientCopyCache = new EventCache(); + + foreach(object entity in copyCache.Keys) + { + object entityCopy = copyCache[entity]; + + if (entityCopy is INHibernateProxy) + entityCopy = ((INHibernateProxy)entityCopy).HibernateLazyInitializer.GetImplementation(); + + // NH-specific: Disregard entities that implement ILifecycle and manage their own state - they + // don't have an EntityEntry, and we can't determine if they are transient or not + if (entityCopy is ILifecycle) + continue; + + EntityEntry copyEntry = @event.Session.PersistenceContext.GetEntry(entityCopy); + + if (copyEntry == null) + { + // entity name will not be available for non-POJO entities + // TODO: cache the entity name somewhere so that it is available to this exception + log.InfoFormat( + "transient instance could not be processed by merge: {0} [{1}]", + @event.Session.GuessEntityName(entityCopy), + entity); + + // merge did not cascade to this entity; it's in copyCache because a + // different entity has a non-nullable reference to it; + // this entity should not be put in transientCopyCache, because it was + // not included in the merge; + + throw new TransientObjectException( + "object is an unsaved transient instance - save the transient instance before merging: " + @event.Session.GuessEntityName(entityCopy)); + } + else if (copyEntry.Status == Status.Saving) + { + transientCopyCache.Add(entity, entityCopy, copyCache.IsOperatedOn(entity)); + } + else if (copyEntry.Status != Status.Loaded && copyEntry.Status != Status.ReadOnly) + { + throw new AssertionFailure( + String.Format( + "Merged entity does not have status set to MANAGED or READ_ONLY; {0} status = {1}", + entityCopy, + copyEntry.Status)); + } + } + return transientCopyCache; + } + + /// <summary> + /// Retry merging transient entities + /// </summary> + /// <param name="event"></param> + /// <param name="transientCopyCache"></param> + /// <param name="copyCache"></param> + protected void RetryMergeTransientEntities(MergeEvent @event, IDictionary transientCopyCache, EventCache copyCache) + { + // TODO: The order in which entities are saved may matter (e.g., a particular + // transient entity may need to be saved before other transient entities can + // be saved). + // Keep retrying the batch of transient entities until either: + // 1) there are no transient entities left in transientCopyCache + // or 2) no transient entities were saved in the last batch. + // For now, just run through the transient entities and retry the merge + + foreach(object entity in transientCopyCache.Keys) + { + object copy = transientCopyCache[entity]; + EntityEntry copyEntry = @event.Session.PersistenceContext.GetEntry(copy); + + if (entity == @event.Entity) + MergeTransientEntity(entity, copyEntry.EntityName, @event.RequestedId, @event.Session, copyCache); + else + MergeTransientEntity(entity, copyEntry.EntityName, copyEntry.Id, @event.Session, copyCache); + } + } + /// <summary> Cascade behavior is redefined by this subclass, disable superclass behavior</summary> protected override void CascadeAfterSave(IEventSource source, IEntityPersister persister, object entity, object anything) { Added: trunk/nhibernate/src/NHibernate/Event/Default/EventCache.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/EventCache.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Event/Default/EventCache.cs 2011-01-17 15:04:02 UTC (rev 5361) @@ -0,0 +1,186 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Iesi.Collections; +using NHibernate.Util; + +namespace NHibernate.Event.Default +{ + public class EventCache : IDictionary + { + private IDictionary entityToCopyMap = IdentityMap.Instantiate(10); + // key is an entity involved with the operation performed by the listener; + // value can be either a copy of the entity or the entity itself + + private IDictionary entityToOperatedOnFlagMap = IdentityMap.Instantiate(10); + // key is an entity involved with the operation performed by the listener; + // value is a flag indicating if the listener explicitly operates on the entity + + #region ICollection Implementation + + /// <summary> + /// Returns the number of entity-copy mappings in this EventCache + /// </summary> + public int Count + { + get { return entityToCopyMap.Count; } + } + + public bool IsSynchronized + { + get { return false; } + } + + public object SyncRoot + { + get { return this; } + } + + public void CopyTo(Array array, int index) + { + if (array == null) + throw new ArgumentNullException("array"); + if (index < 0) + throw new ArgumentOutOfRangeException("arrayIndex is less than 0"); + if (entityToCopyMap.Count + index + 1 > array.Length) + throw new ArgumentException("The number of elements in the source ICollection<T> is greater than the available space from arrayIndex to the end of the destination array."); + + entityToCopyMap.CopyTo(array, index); + } + + #endregion + + #region IEnumerable implementation + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)entityToCopyMap).GetEnumerator(); + } + + #endregion + + #region IDictionary implementation + + public object this[object key] + { + get + { + return entityToCopyMap[key]; + } + set + { + this.Add(key, value); + } + } + + public bool IsReadOnly + { + get { return false; } + } + + public bool IsFixedSize + { + get { return false; } + } + + public ICollection Keys + { + get { return entityToCopyMap.Keys; } + } + + public ICollection Values + { + get { return entityToCopyMap.Values; } + } + + public void Add(object key, object value) + { + if (key == null) + throw new ArgumentNullException("key"); + if (value == null) + throw new ArgumentNullException("value"); + + entityToCopyMap.Add(key, value); + entityToOperatedOnFlagMap.Add(key, false); + } + + public bool Contains(object key) + { + return entityToCopyMap.Contains(key); + } + + public void Remove(object key) + { + entityToCopyMap.Remove(key); + entityToOperatedOnFlagMap.Remove(key); + } + + public IDictionaryEnumerator GetEnumerator() + { + return entityToCopyMap.GetEnumerator(); + } + + public void Clear() + { + entityToCopyMap.Clear(); + entityToOperatedOnFlagMap.Clear(); + } + + #endregion + + /// <summary> + /// Associates the specified entity with the specified copy in this EventCache; + /// </summary> + /// <param name="entity"></param> + /// <param name="copy"></param> + /// <param name="isOperatedOn">indicates if the operation is performed on the entity</param> + public void Add(object entity, object copy, bool isOperatedOn) + { + if (entity == null) + throw new ArgumentNullException("null entities are not supported", "entity"); + if (copy == null) + throw new ArgumentNullException("null entity copies are not supported", "copy"); + + entityToCopyMap.Add(entity, copy); + entityToOperatedOnFlagMap.Add(entity, isOperatedOn); + } + + /// <summary> + /// Returns copy-entity mappings + /// </summary> + /// <returns></returns> + public IDictionary InvertMap() + { + return IdentityMap.Invert(entityToCopyMap); + } + + /// <summary> + /// Returns true if the listener is performing the operation on the specified entity. + /// </summary> + /// <param name="entity">Must be non-null and this EventCache must contain a mapping for this entity</param> + /// <returns></returns> + public bool IsOperatedOn(object entity) + { + if (entity == null) + throw new ArgumentNullException("null entities are not supported", "entity"); + + return (bool)entityToOperatedOnFlagMap[entity]; + } + + /// <summary> + /// Set flag to indicate if the listener is performing the operation on the specified entity. + /// </summary> + /// <param name="entity"></param> + /// <param name="isOperatedOn"></param> + public void SetOperatedOn(object entity, bool isOperatedOn) + { + if (entity == null) + throw new ArgumentNullException("null entities are not supported", "entity"); + + if (!entityToOperatedOnFlagMap.Contains(entity) || !entityToCopyMap.Contains(entity)) + throw new AssertionFailure("called EventCache.SetOperatedOn() for entity not found in EventCache"); + + entityToOperatedOnFlagMap[entity] = isOperatedOn; + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-01-17 05:55:48 UTC (rev 5360) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-01-17 15:04:02 UTC (rev 5361) @@ -165,6 +165,7 @@ <Compile Include="Engine\TypedValue.cs" /> <Compile Include="Engine\UnsavedValueFactory.cs" /> <Compile Include="Engine\Versioning.cs" /> + <Compile Include="Event\Default\EventCache.cs" /> <Compile Include="Exceptions\ADOExceptionHelper.cs" /> <Compile Include="Criterion\AbstractCriterion.cs" /> <Compile Include="Criterion\AndExpression.cs" /> Modified: trunk/nhibernate/src/NHibernate/Type/EntityType.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Type/EntityType.cs 2011-01-17 05:55:48 UTC (rev 5360) +++ trunk/nhibernate/src/NHibernate/Type/EntityType.cs 2011-01-17 15:04:02 UTC (rev 5361) @@ -243,7 +243,6 @@ return value; //special case ... this is the leaf of the containment graph, even though not immutable } - /// <summary></summary> public override bool IsMutable { get { return false; } @@ -251,8 +250,7 @@ public abstract bool IsOneToOne { get; } - public override object Replace(object original, object target, ISessionImplementor session, object owner, - IDictionary copyCache) + public override object Replace(object original, object target, ISessionImplementor session, object owner, IDictionary copyCache) { if (original == null) { @@ -269,17 +267,26 @@ { return target; } - object id = GetIdentifier(original, session); - if (id == null) + if (session.GetContextEntityIdentifier(original) == null && ForeignKeys.IsTransient(associatedEntityName, original, false, session)) { - throw new AssertionFailure("cannot copy a reference to an object with a null id"); + object copy = session.Factory.GetEntityPersister(associatedEntityName).Instantiate(null, session.EntityMode); + //TODO: should this be Session.instantiate(Persister, ...)? + copyCache.Add(original, copy); + return copy; } - id = GetIdentifierOrUniqueKeyType(session.Factory).Replace(id, null, session, owner, copyCache); - return ResolveIdentifier(id, session, owner); + else + { + object id = GetIdentifier(original, session); + if (id == null) + { + throw new AssertionFailure("non-transient entity has a null id"); + } + id = GetIdentifierOrUniqueKeyType(session.Factory).Replace(id, null, session, owner, copyCache); + return ResolveIdentifier(id, session, owner); + } } } - /// <summary></summary> public override bool IsAssociationType { get { return true; } @@ -612,4 +619,4 @@ } } -} +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Cascade/A.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Cascade/A.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Cascade/A.cs 2011-01-17 15:04:02 UTC (rev 5361) @@ -0,0 +1,58 @@ +using System; +using Iesi.Collections.Generic; + +namespace NHibernate.Test.Cascade +{ + public class A + { + private long id; + private string data; + private ISet<H> hs; // A 1 - * H + private G g; // A 1 - 1 G + + public A() + { + hs = new HashedSet<H>(); + } + + public A(string data) : this() + { + this.data = data; + } + + public virtual long Id + { + get { return id; } + set { id = value; } + } + + public virtual string Data + { + get { return data; } + set { data = value; } + } + + public virtual G G + { + get { return g; } + set { g = value; } + } + + public virtual ISet<H> Hs + { + get { return hs; } + set { hs = value; } + } + + public virtual void AddH(H h) + { + hs.Add(h); + h.A = this; + } + + public override string ToString() + { + return "A[" + id + ", " + data + "]"; + } + } +} \ No newline at end of file Property changes on: trunk/nhibernate/src/NHibernate.Test/Cascade/Circle ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:logregex + NH-\d+ Added: trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/CascadeMergeToChildBeforeParent.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/CascadeMergeToChildBeforeParent.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/CascadeMergeToChildBeforeParent.hbm.xml 2011-01-17 15:04:02 UTC (rev 5361) @@ -0,0 +1,139 @@ +<?xml version="1.0"?> +<hibernate-mapping + xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.Cascade.Circle"> + + <class name="Route" table="HB2_Route"> + + <id name="RouteId" type="long"> + <generator class="native" /> + </id> + + <version name="Version" column="VERS" type="long" /> + + <property name="Name" type="string" not-null="true" /> + + <set name="Nodes" inverse="true" cascade="persist,merge,refresh"> + <key column="RouteId" /> + <one-to-many class="Node" /> + </set> + + <set name="Vehicles" inverse="true" cascade="persist,merge,refresh"> + <key column="routeId" /> + <one-to-many class="Vehicle" /> + </set> + + </class> + + <class name="Tour" table="HB2_Tour"> + + <id name="TourId" type="long"> + <generator class="native" /> + </id> + + <version name="Version" column="VERS" type="long" /> + + <property name="Name" type="string" not-null="true" /> + + <set name="Nodes" inverse="true" lazy="true" cascade="merge,refresh"> + <key column="TourId" /> + <one-to-many class="Node" /> + </set> + + </class> + + <class name="Transport" table="HB2_Transport"> + + <id name="TransportId" type="long"> + <generator class="native" /> + </id> + + <version name="Version" column="VERS" type="long" /> + + <property name="Name" type="string" not-null="true" /> + + <many-to-one name="PickupNode" + column="PickupNodeId" + unique="true" + not-null="true" + cascade="merge,refresh" + lazy="false" /> + + <many-to-one name="DeliveryNode" + column="DeliveryNodeId" + unique="true" + not-null="true" + cascade="merge,refresh" + lazy="false" /> + + <many-to-one name="Vehicle" + column="VehicleId" + unique="false" + not-null="true" + cascade="none" + lazy="false" /> + + </class> + + <class name="Vehicle" table="HB2_Vehicle"> + + <id name="VehicleId" type="long"> + <generator class="native" /> + </id> + + <version name="Version" column="VERS" type="long" /> + + <property name="Name" /> + + <set name="Transports" inverse="false" lazy="true" cascade="merge,refresh"> + <key column="VehicleId" /> + <one-to-many class="Transport" not-found="exception" /> + </set> + + <many-to-one name="Route" + column="RouteId" + unique="false" + not-null="true" + cascade="none" + lazy="false" /> + + </class> + + <class name="Node" table="HB2_Node"> + + <id name="NodeId" type="long"> + <generator class="native" /> + </id> + + <version name="Version" column="VERS" type="long" /> + + <property name="Name" type="string" not-null="true" /> + + <set name="DeliveryTransports" inverse="true" lazy="true" cascade="merge,refresh"> + <key column="DeliveryNodeId" /> + <one-to-many class="Transport" /> + </set> + + <set name="PickupTransports" inverse="true" lazy="true" cascade="merge,refresh"> + <key column="PickupNodeId" /> + <one-to-many class="Transport" /> + </set> + + <many-to-one name="Route" + column="RouteId" + unique="false" + not-null="true" + cascade="none" + lazy="false" /> + + <many-to-one name="Tour" + column="TourId" + unique="false" + not-null="false" + cascade="merge,refresh" + lazy="false" /> + + </class> + +</hibernate-mapping> \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/CascadeMergeToChildBeforeParentTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/CascadeMergeToChildBeforeParentTest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/CascadeMergeToChildBeforeParentTest.cs 2011-01-17 15:04:02 UTC (rev 5361) @@ -0,0 +1,261 @@ +using System; +using System.Collections; +using System.Linq; +using NHibernate.Engine; +using NHibernate.Test; +using NUnit.Framework; + +namespace NHibernate.Test.Cascade.Circle +{ + /** + * The test case uses the following model: + * + * <- -> + * -- (N : 0,1) -- Tour + * | <- -> + * | -- (1 : N) -- (pickup) ---- + * -> | | | + * Route -- (1 : N) - Node Transport + * | | <- -> | | + * | -- (1 : N) -- (delivery) -- | + * | | + * | -> -> | + * -------- (1 : N) ---- Vehicle--(1 : N)------------ + * + * Arrows indicate the direction of cascade-merge. + */ + + [TestFixture] + public class CascadeMergeToChildBeforeParentTest : TestCase + { + protected override string MappingsAssembly + { + get { return "NHibernate.Test"; } + } + + protected override IList Mappings + { + get { return new[] { "Cascade.Circle.CascadeMergeToChildBeforeParent.hbm.xml" }; } + } + + [Test] + public void Merge() + { + using (ISession session = base.OpenSession()) + using (ITransaction transaction = session.BeginTransaction()) + { + Route route = new Route(); + route.Name = "routeA"; + session.Save(route); + transaction.Commit(); + } + + using (ISession session = base.OpenSession()) + using (ITransaction transaction = session.BeginTransaction()) + { + Route route = session.Get<Route>(1L); + route.TransientField = "sfnaouisrbn"; + + Tour tour = new Tour(); + tour.Name = "tourB"; + + Node pickupNode = new Node(); + pickupNode.Name = "pickupNodeB"; + + Node deliveryNode = new Node(); + deliveryNode.Name = "deliveryNodeB"; + + pickupNode.Route = route; + pickupNode.Tour = tour; + pickupNode.TransientField = "pickup node aaaaaaaaaaa"; + + deliveryNode.Route = route; + deliveryNode.Tour = tour; + deliveryNode.TransientField = "delivery node aaaaaaaaa"; + + tour.Nodes.Add(pickupNode); + tour.Nodes.Add(deliveryNode); + + route.Nodes.Add(pickupNode); + route.Nodes.Add(deliveryNode); + + Route mergedRoute = (Route)session.Merge(route); + + transaction.Commit(); + } + } + + // This test fails because the merge algorithm tries to save a + // transient child (transport) before cascade-merge gets its + // transient parent (vehicle); merge does not cascade from the + // child to the parent. + [Test] + public void MergeTransientChildBeforeTransientParent() + { + Route route = null; + + using (ISession session = base.OpenSession()) + using (ITransaction transaction = session.BeginTransaction()) + { + route = new Route(); + route.Name = "routeA"; + session.Save(route); + transaction.Commit(); + } + + using (ISession session = base.OpenSession()) + using (ITransaction transaction = session.BeginTransaction()) + { + route = session.Get<Route>(route.RouteId); + route.TransientField = "sfnaouisrbn"; + + Tour tour = new Tour(); + tour.Name = "tourB"; + + Transport transport = new Transport(); + transport.Name = "transportB"; + + Node pickupNode = new Node(); + pickupNode.Name = "pickupNodeB"; + + Node deliveryNode = new Node(); + deliveryNode.Name = "deliveryNodeB"; + + Vehicle vehicle = new Vehicle(); + vehicle.Name = "vehicleB"; + + pickupNode.Route = route; + pickupNode.Tour = tour; + pickupNode.PickupTransports.Add(transport); + pickupNode.TransientField = "pickup node aaaaaaaaaaa"; + + deliveryNode.Route = route; + deliveryNode.Tour = tour; + deliveryNode.DeliveryTransports.Add(transport); + deliveryNode.TransientField = "delivery node aaaaaaaaa"; + + tour.Nodes.Add(pickupNode); + tour.Nodes.Add(deliveryNode); + + route.Nodes.Add(pickupNode); + route.Nodes.Add(deliveryNode); + route.Vehicles.Add(vehicle); + + transport.PickupNode = pickupNode; + transport.DeliveryNode = deliveryNode; + transport.Vehicle = vehicle; + transport.TransientField = "aaaaaaaaaaaaaa"; + + vehicle.Transports.Add(transport); + vehicle.TransientField = "anewvalue"; + vehicle.Route = route; + + Route mergedRoute = (Route)session.Merge(route); + + transaction.Commit(); + } + } + + [Test] + public void MergeData3Nodes() + { + Route route = null; + + using (ISession session = base.OpenSession()) + using (ITransaction transaction = session.BeginTransaction()) + { + route = new Route(); + route.Name = "routeA"; + session.Save(route); + transaction.Commit(); + } + + using (ISession session = base.OpenSession()) + using (ITransaction transaction = session.BeginTransaction()) + { + route = session.Get<Route>(route.RouteId); + route.TransientField = "sfnaouisrbn"; + + Tour tour = new Tour(); + tour.Name = "tourB"; + + Transport transport1 = new Transport(); + transport1.Name = "TRANSPORT1"; + + Transport transport2 = new Transport(); + transport2.Name = "TRANSPORT2"; + + Node node1 = new Node(); + node1.Name = "NODE1"; + + Node node2 = new Node(); + node2.Name = "NODE2"; + + Node node3 = new Node(); + node3.Name = "NODE3"; + + Vehicle vehicle = new Vehicle(); + vehicle.Name = "vehicleB"; + + node1.Route = route; + node1.Tour = tour; + node1.PickupTransports.Add(transport1); + node1.TransientField = "node 1"; + + node2.Route = route; + node2.Tour = tour; + node2.DeliveryTransports.Add(transport1); + node2.PickupTransports.Add(transport2); + node2.TransientField = "node 2"; + + node3.Route = route; + node3.Tour = tour; + node3.DeliveryTransports.Add(transport2); + node3.TransientField = "node 3"; + + tour.Nodes.Add(node1); + tour.Nodes.Add(node2); + tour.Nodes.Add(node3); + + route.Nodes.Add(node1); + route.Nodes.Add(node2); + route.Nodes.Add(node3); + route.Vehicles.Add(vehicle); + + transport1.PickupNode = node1; + transport1.DeliveryNode = node2; + transport1.Vehicle = vehicle; + transport1.TransientField = "aaaaaaaaaaaaaa"; + + transport2.PickupNode = node2; + transport2.DeliveryNode = node3; + transport2.Vehicle = vehicle; + transport2.TransientField = "bbbbbbbbbbbbb"; + + vehicle.Transports.Add(transport1); + vehicle.Transports.Add(transport2); + vehicle.TransientField = "anewvalue"; + vehicle.Route = route; + + Route mergedRoute = (Route)session.Merge(route); + + transaction.Commit(); + } + } + + protected override void OnTearDown() + { + using (ISession session = base.OpenSession()) + using (ITransaction transaction = session.BeginTransaction()) + { + session.CreateQuery("delete from Transport").ExecuteUpdate(); + session.CreateQuery("delete from Vehicle").ExecuteUpdate(); + session.CreateQuery("delete from Node").ExecuteUpdate(); + session.CreateQuery("delete from Route").ExecuteUpdate(); + session.CreateQuery("delete from Tour").ExecuteUpdate(); + transaction.Commit(); + } + base.OnTearDown(); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/MultiPathCircleCascade.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/MultiPathCircleCascade.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/MultiPathCircleCascade.hbm.xml 2011-01-17 15:04:02 UTC (rev 5361) @@ -0,0 +1,95 @@ +<?xml version="1.0"?> +<hibernate-mapping + xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.Cascade.Circle"> + + <class name="Route" table="HB_Route"> + + <id name="RouteId" type="long"> + <generator class="native" /> + </id> + + <property name="Name" type="string" not-null="true" /> + + <set name="Nodes" inverse="true" cascade="persist,merge,refresh"> + <key column="RouteId" /> + <one-to-many class="Node" /> + </set> + + </class> + + <class name="Tour" table="HB_Tour"> + + <id name="TourId" type="long"> + <generator class="native" /> + </id> + + <property name="Name" type="string" not-null="true" /> + + <set name="Nodes" inverse="true" lazy="true" cascade="merge,refresh"> + <key column="TourId" /> + <one-to-many class="Node" /> + </set> + + </class> + + <class name="Transport" table="HB_Transport"> + + <id name="TransportId" type="long"> + <generator class="native" /> + </id> + + <property name="Name" type="string" not-null="true" /> + + <many-to-one name="PickupNode" + column="PickupNodeId" + unique="true" + not-null="true" + cascade="merge,refresh" + lazy="false" /> + + <many-to-one name="DeliveryNode" + column="DeliveryNodeId" + unique="true" + not-null="true" + cascade="merge,refresh" + lazy="false" /> + + </class> + + <class name="Node" table="HB_Node"> + + <id name="NodeId" type="long"> + <generator class="native" /> + </id> + + <property name="Name" type="string" not-null="true" /> + + <set name="DeliveryTransports" inverse="true" lazy="true" cascade="merge,refresh"> + <key column="DeliveryNodeId" /> + <one-to-many class="Transport" /> + </set> + + <set name="PickupTransports" inverse="true" lazy="true" cascade="merge,refresh"> + <key column="PickupNodeId" /> + <one-to-many class="Transport" /> + </set> + + <many-to-one name="Route" + column="RouteId" + unique="false" + not-null="true" + cascade="none" + lazy="false" /> + + <many-to-one name="Tour" + column="TourId" + unique="false" + not-null="false" + cascade="merge,refresh" + lazy="false" /> + + </class> + +</hibernate-mapping> \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/MultiPathCircleCascadeTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/MultiPathCircleCascadeTest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/MultiPathCircleCascadeTest.cs 2011-01-17 15:04:02 UTC (rev 5361) @@ -0,0 +1,440 @@ +using System; +using System.Collections; +using System.Linq; +using NHibernate.Engine; +using NHibernate.Test; +using NUnit.Framework; + +namespace NHibernate.Test.Cascade.Circle +{ + + /** + * The test case uses the following model: + * + * <- -> + * -- (N : 0,1) -- Tour + * | <- -> + * | -- (1 : N) -- (pickup) ---- + * -> | | | + * Route -- (1 : N) -- Node Transport + * | <- -> | + * -- (1 : N) -- (delivery) -- + * + * Arrows indicate the direction of cascade-merge. + * + * It reproduced the following issues: + * http://opensource.atlassian.com/projects/hibernate/browse/HHH-3046 + * http://opensource.atlassian.com/projects/hibernate/browse/HHH-3810 + * + * This tests that merge is cascaded properly from each entity. + * + * @author Pavol Zibrita, Gail Badner + */ + + [TestFixture] + public class MultiPathCircleCascadeTest : TestCase + { + protected override string MappingsAssembly + { + get { return "NHibernate.Test"; } + } + + protected override IList Mappings + { + get { return new[] { "Cascade.Circle.MultiPathCircleCascade.hbm.xml" }; } + } + + protected override void Configure(NHibernate.Cfg.Configuration configuration) + { + base.Configure(configuration); + configuration.SetProperty(NHibernate.Cfg.Environment.GenerateStatistics, "true"); + configuration.SetProperty(NHibernate.Cfg.Environment.BatchSize, "0"); + } + + [Test] + public void MergeEntityWithNonNullableTransientEntity() + { + Route route = this.GetUpdatedDetachedEntity(); + + Node node = route.Nodes.First(); + route.Nodes.Remove(node); + + Route routeNew = new Route(); + routeNew.Name = "new route"; + routeNew.Nodes.Add(node); + node.Route = routeNew; + + using (ISession session = base.OpenSession()) + using (ITransaction transaction = session.BeginTransaction()) + { + try + { + session.Merge(node); + Assert.Fail("should have thrown an exception"); + } + catch (Exception ex) + { + Assert.That(ex, Is.TypeOf(typeof(TransientObjectException))); + +// if (((SessionImplementor)session).Factory.Settings.isCheckNullability() ) { +// assertTrue( ex instanceof TransientObjectException ); +// } +// else { +// assertTrue( ex instanceof JDBCException ); +// } + } + finally + { + transaction.Rollback(); + } + } + } + + [Test] + public void MergeEntityWithNonNullableEntityNull() + { + Route route = GetUpdatedDetachedEntity(); + Node node = route.Nodes.First(); + route.Nodes.Remove(node); + node.Route = null; + + using (ISession session = base.OpenSession()) + using (ITransaction transaction = session.BeginTransaction()) + { + try + { + session.Merge(node); + Assert.Fail("should have thrown an exception"); + } + catch (Exception ex) + { + Assert.That(ex, Is.TypeOf(typeof(PropertyValueException))); + +// if ( ( ( SessionImplementor ) s ).getFactory().getSettings().isCheckNullability() ) { +// assertTrue( ex instanceof PropertyValueException ); +// } +// else { +// assertTrue( ex instanceof JDBCException ); +// } + } + finally + { + transaction.Rollback(); + } + } + } + + public void MergeEntityWithNonNullablePropSetToNull() + { + Route route = GetUpdatedDetachedEntity(); + Node node = route.Nodes.First(); + node.Name = null; + + using (ISession session = base.OpenSession()) + using (ITransaction transaction = session.BeginTransaction()) + { + try + { + session.Merge(route); + Assert.Fail("should have thrown an exception"); + } + catch (Exception ex) + { + Assert.That(ex, Is.TypeOf(typeof(PropertyValueException))); + +// if ( ( ( SessionImplementor ) s ).getFactory().getSettings().isCheckNullability() ) { +// assertTrue( ex instanceof PropertyValueException ); +// } +// else { +// assertTrue( ex instanceof JDBCException ); +// } + } + finally + { + transaction.Rollback(); + } + } + } + + [Test] + public void MergeRoute() + { + Route route = this.GetUpdatedDetachedEntity(); + + ClearCounts(); + + ISession s = base.OpenSession(); + s.BeginTransaction(); + s.Merge(route); + s.Transaction.Commit(); + s.Close(); + + AssertInsertCount(4); + AssertUpdateCount(1); + + s = base.OpenSession(); + s.BeginTransaction(); + route = s.Get<Route>(route.RouteId); + CheckResults(route, true); + s.Transaction.Commit(); + s.Close(); + } + + [Test] + public void MergePickupNode() + { + Route route = GetUpdatedDetachedEntity(); + + ClearCounts(); + + ISession s = OpenSession(); + s.BeginTransaction(); + + Node pickupNode = route.Nodes.First(n => n.Name == "pickupNodeB"); + pickupNode = (Node)s.Merge(pickupNode); + + s.Transaction.Commit(); + s.Close(); + + AssertInsertCount(4); + AssertUpdateCount(0); + + s = OpenSession(); + s.BeginTransaction(); + route = s.Get<Route>(route.RouteId); + CheckResults(route, false); + s.Transaction.Commit(); + s.Close(); + } + + [Test] + public void MergeDeliveryNode() + { + Route route = GetUpdatedDetachedEntity(); + + ClearCounts(); + + ISession s = OpenSession(); + s.BeginTransaction(); + + Node deliveryNode = route.Nodes.First(n => n.Name == "deliveryNodeB"); + deliveryNode = (Node)s.Merge(deliveryNode); + + s.Transaction.Commit(); + s.Close(); + + AssertInsertCount(4); + AssertUpdateCount(0); + + s = OpenSession(); + s.BeginTransaction(); + route = s.Get<Route>(route.RouteId); + CheckResults(route, false); + s.Transaction.Commit(); + s.Close(); + } + + [Test] + public void MergeTour() + { + Route route = GetUpdatedDetachedEntity(); + + ClearCounts(); + + ISession s = OpenSession(); + s.BeginTransaction(); + Tour tour = (Tour)s.Merge(route.Nodes.First().Tour); + s.Transaction.Commit(); + s.Close(); + + AssertInsertCount(4); + AssertUpdateCount(0); + + s = OpenSession(); + s.BeginTransaction(); + route = s.Get<Route>(route.RouteId); + CheckResults(route, false); + s.Transaction.Commit(); + s.Close(); + } + + [Test] + public void MergeTransport() + { + Route route = GetUpdatedDetachedEntity(); + + ClearCounts(); + + ISession s = OpenSession(); + s.BeginTransaction(); + + Node node = route.Nodes.First(); + Transport transport = null; + + if (node.PickupTransports.Count == 1) + transport = node.PickupTransports.First(); + else + transport = node.DeliveryTransports.First(); + + transport = (Transport)s.Merge(transport); + + s.Transaction.Commit(); + s.Close(); + + AssertInsertCount(4); + AssertUpdateCount(0); + + s = OpenSession(); + s.BeginTransaction(); + route = s.Get<Route>(route.RouteId); + CheckResults(route, false); + s.Transaction.Commit(); + s.Close(); + } + + private Route GetUpdatedDetachedEntity() + { + ISession s = OpenSession(); + s.BeginTransaction(); + + Route route = new Route(); + route.Name = "routeA"; + + s.Save(route); + s.Transaction.Commit(); + s.Close(); + + route.Name = "new routeA"; + route.TransientField = "sfnaouisrbn"; + + Tour tour = new Tour(); + tour.Name = "tourB"; + + Transport transport = new Transport(); + transport.Name = "transportB"; + + Node pickupNode = new Node(); + pickupNode.Name = "pickupNodeB"; + + Node deliveryNode = new Node(); + deliveryNode.Name = "deliveryNodeB"; + + pickupNode.Route = route; + pickupNode.Tour = tour; + pickupNode.PickupTransports.Add(transport); + pickupNode.TransientField = "pickup node aaaaaaaaaaa"; + + deliveryNode.Route = route; + deliveryNode.Tour = tour; + deliveryNode.DeliveryTransports.Add(transport); + deliveryNode.TransientField = "delivery node aaaaaaaaa"; + + tour.Nodes.Add(pickupNode); + tour.Nodes.Add(deliveryNode); + + route.Nodes.Add(pickupNode); + route.Nodes.Add(deliveryNode); + + transport.PickupNode = pickupNode; + transport.DeliveryNode = deliveryNode; + transport.TransientField = "aaaaaaaaaaaaaa"; + + return route; + } + + private void CheckResults(Route route, bool isRouteUpdated) + { + // since merge is not cascaded to route, this method needs to + // know whether route is expected to be updated + if (isRouteUpdated) + { + Assert.That(route.Name, Is.EqualTo("new routeA")); + } + + Assert.That(route.Nodes.Count, Is.EqualTo(2)); + Node deliveryNode = null; + Node pickupNode = null; + + foreach(Node node in route.Nodes) + { + if ("deliveryNodeB".Equals(node.Name)) + { + deliveryNode = node; + } + else if ("pickupNodeB".Equals(node.Name)) + { + pickupNode = node; + } + else + { + Assert.Fail("unknown node"); + } + } + + Assert.That(deliveryNode, Is.Not.Null); + Assert.That(deliveryNode.Route, Is.SameAs(route)); + Assert.That(deliveryNode.DeliveryTransports.Count, Is.EqualTo(1)); + Assert.That(deliveryNode.PickupTransports.Count, Is.EqualTo(0)); + Assert.That(deliveryNode.Tour, Is.Not.Null); + Assert.That(deliveryNode.TransientField, Is.EqualTo("node original value")); + + Assert.That(pickupNode, Is.Not.Null); + Assert.That(pickupNode.Route, Is.SameAs(route)); + Assert.That(pickupNode.DeliveryTransports.Count, Is.EqualTo(0)); + Assert.That(pickupNode.PickupTransports.Count, Is.EqualTo(1)); + Assert.That(pickupNode.Tour, Is.Not.Null); + Assert.That(pickupNode.TransientField, Is.EqualTo("node original value")); + + Assert.That(deliveryNode.NodeId.Equals(pickupNode.NodeId), Is.False); + Assert.That(deliveryNode.Tour, Is.SameAs(pickupNode.Tour)); + Assert.That(deliveryNode.DeliveryTransports.First(), Is.SameAs(pickupNode.PickupTransports.First())); + + Tour tour = deliveryNode.Tour; + Transport transport = deliveryNode.DeliveryTransports.First(); + + Assert.That(tour.Name, Is.EqualTo("tourB")); + Assert.That(tour.Nodes.Count, Is.EqualTo(2)); + Assert.That(tour.Nodes.Contains(deliveryNode), Is.True); + Assert.That(tour.Nodes.Contains(pickupNode), Is.True); + + Assert.That(transport.Name, Is.EqualTo("transportB")); + Assert.That(transport.DeliveryNode, Is.SameAs(deliveryNode)); + Assert.That(transport.PickupNode, Is.SameAs(pickupNode)); + Assert.That(transport.TransientField, Is.EqualTo("transport original value")); + } + + protected override void OnTearDown() + { + using (ISession session = base.OpenSession()) + using (ITransaction transaction = session.BeginTransaction()) + { + session.CreateQuery("delete from Transport").ExecuteUpdate(); + session.CreateQuery("delete from Node").ExecuteUpdate(); + session.CreateQuery("delete from Tour").ExecuteUpdate(); + session.CreateQuery("delete from Route").ExecuteUpdate(); + transaction.Commit(); + } + base.OnTearDown(); + } + + protected void ClearCounts() + { + sessions.Statistics.Clear(); + } + + protected void AssertInsertCount(long expected) + { + Assert.That(sessions.Statistics.EntityInsertCount, Is.EqualTo(expected), "unexpected insert count"); + } + + protected void AssertUpdateCount(long expected) + { + Assert.That(sessions.Statistics.EntityUpdateCount, Is.EqualTo(expected), "unexpected update count"); + } + + protected void AssertDeleteCount(long expected) + { + Assert.That(sessions.Statistics.EntityDeleteCount, Is.EqualTo(expected), "unexpected delete count"); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Node.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Node.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Node.cs 2011-01-17 15:04:02 UTC (rev 5361) @@ -0,0 +1,90 @@ +using System; +using System.Text; +using Iesi.Collections.Generic; + +namespace NHibernate.Test.Cascade.Circle +{ + public class Node + { + private long nodeId; + private long version; + private string name; + private ISet<Transport> deliveryTransports = new HashedSet<Transport>(); + private ISet<Transport> pickupTransports = new HashedSet<Transport>(); + private Route route = null; + private Tour tour; + private string transientField = "node original value"; + + public virtual long NodeId + { + get { return nodeId; } + set { nodeId = value; } + } + + public virtual long Version + { + get { return version; } + set { version = value; } + } + + public virtual string Name + { + get { return name; } + set { name = value; } + } + + public virtual ISet<Transport> DeliveryTransports + { + get { return deliveryTransports; } + set { deliveryTransports = value; } + } + + public virtual ISet<Transport> PickupTransports + { + get { return pickupTransports; } + set { pickupTransports = value; } + } + + public virtual Route Route + { + get { return route; } + set { route = value; } + } + + public virtual Tour Tour + { + get { return tour; } + set { tour = value; } + } + + public virtual string TransientField + { + get { return transientField; } + set { transientField = value; } + } + + public override string ToString() + { + var buffer = new StringBuilder(); + + buffer.AppendFormat("{0}, id: {1}", name, nodeId); + + if (route != null) + buffer.AppendFormat(" route name: {0}, tour name: {1}", route.Name, tour == null ? "null" : tour.Name); + + if (deliveryTransports != null) + { + foreach(Transport transport in deliveryTransports) + buffer.AppendFormat("Delivery Transports: {0}", transport.ToString()); + } + + if (route != null) + { + foreach(Transport transport in pickupTransports) + buffer.AppendFormat("Node: {0}", transport.ToString()); + } + + return buffer.ToString(); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Route.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Route.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Route.cs 2011-01-17 15:04:02 UTC (rev 5361) @@ -0,0 +1,67 @@ +using System; +using System.Text; +using Iesi.Collections.Generic; + +namespace NHibernate.Test.Cascade.Circle +{ + public class Route + { + private long routeId; + private long version; + private ISet<Node> nodes = new HashedSet<Node>(); + private ISet<Vehicle> vehicles = new HashedSet<Vehicle>(); + private string name; + private string transientField = null; + + public virtual long RouteId + { + get { return routeId; } + set { routeId = value; } + } + + public virtual long Version + { + get { return version; } + set { version = value; } + } + + public virtual ISet<Node> Nodes + { + get { return nodes; } + set { nodes = value; } + } + + public virtual ISet<Vehicle> Vehicles + { + get { return vehicles; } + set { vehicles = value; } + } + + public virtual string Name + { + get { return name; } + set { name = value; } + } + + public virtual string TransientField + { + get { return transientField; } + set { transientField = value; } + } + + public override string ToString() + { + var buffer = new StringBuilder(); + + buffer.AppendFormat("Route name: {0}, id: {1}, transientField: {2}", name, routeId, transientField); + + foreach(Node node in nodes) + buffer.AppendFormat("Node: {0}", node.ToString()); + + foreach(Vehicle vehicle in vehicles) + buffer.AppendFormat("Vehicle: {0}", vehicle.ToString()); + + return buffer.ToString(); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Tour.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Tour.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Tour.cs 2011-01-17 15:04:02 UTC (rev 5361) @@ -0,0 +1,37 @@ +using System; +using Iesi.Collections.Generic; + +namespace NHibernate.Test.Cascade.Circle +{ + public class Tour + { + private long tourId; + private long version; + private string name; + private ISet<Node> nodes = new HashedSet<Node>(); + + public virtual long TourId + { + get { return tourId; } + set { tourId = value; } + } + + public virtual long Version + { + get { return version; } + set { version = value; } + } + + public virtual string Name + { + get { return name; } + set { name = value; } + } + + public virtual ISet<Node> Nodes + { + get { return nodes; } + set { nodes = value; } + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Transport.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Transport.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Cascade/Circle/Transport.cs 2011-01-17 15:04:02 UTC (rev 5361) @@ -0,0 +1,63 @@ +using System; +using Iesi.Collections.Generic; + +namespace NHibernate.Test.Cascade.Circle +{ + public class Transport + { + private long transportId; + private long version; + private string name; + private Node pickupNode = null; + private Node deliveryNode = null; + private Vehicle vehicle; + private string transientField = "transport original value"; + + public virtual long TransportId + { + get { return transportId; } + set { transportId = value; } + } + + public virtual long Version + { + get { return version; } + set { version = value; } + } + + publi... [truncated message content] |
From: <pa...@us...> - 2011-01-17 05:55:54
|
Revision: 5360 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5360&view=rev Author: patearl Date: 2011-01-17 05:55:48 +0000 (Mon, 17 Jan 2011) Log Message: ----------- Linq: Fixed caching related to generic method calls. (NH-2433, Thanks to Dean Ward for patch.) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs 2011-01-17 04:39:24 UTC (rev 5359) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs 2011-01-17 05:55:48 UTC (rev 5360) @@ -1,6 +1,8 @@ using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Linq; using System.Linq.Expressions; +using System.Reflection; using System.Text; namespace NHibernate.Linq.Visitors @@ -42,7 +44,7 @@ { _string.Append(expression.Method.DeclaringType.Name); _string.Append("."); - _string.Append(expression.Method.Name); + VisitMethod(expression.Method); } else { @@ -85,7 +87,10 @@ } else { - _string.Append(expression.Value); + if (expression.Value == null) + _string.Append("NULL"); + else + _string.Append(expression.Value); } return base.VisitConstantExpression(expression); @@ -165,7 +170,7 @@ { VisitExpression(expression.Object); _string.Append('.'); - _string.Append(expression.Method.Name); + VisitMethod(expression.Method); _string.Append('('); VisitList(expression.Arguments, AppendCommas); _string.Append(')'); @@ -221,5 +226,16 @@ { return base.VisitUnknownExpression(expression); } + + private void VisitMethod(MethodInfo methodInfo) + { + _string.Append(methodInfo.Name); + if (methodInfo.IsGenericMethod) + { + _string.Append('['); + _string.Append(string.Join(",", methodInfo.GetGenericArguments().Select(a => a.FullName).ToArray())); + _string.Append(']'); + } + } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs 2011-01-17 04:39:24 UTC (rev 5359) +++ trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs 2011-01-17 05:55:48 UTC (rev 5360) @@ -169,6 +169,42 @@ } } + [Test] + public void Different_OfType_Returns_Different_Keys() + { + using (var session = OpenSession()) + { + Expression<Func<IEnumerable>> ofType1 = () => (from a in session.Query<Animal>().OfType<Cat>() where a.Pregnant select a.Id); + Expression<Func<IEnumerable>> ofType2 = () => (from a in session.Query<Animal>().OfType<Dog>() where a.Pregnant select a.Id); + + var nhOfType1 = new NhLinqExpression(ofType1.Body); + var nhOfType2 = new NhLinqExpression(ofType2.Body); + + Assert.AreNotEqual(nhOfType1.Key, nhOfType2.Key); + } + } + + [Test] + public void Different_Null_Returns_Different_Keys() + { + using (var session = OpenSession()) + { + string nullVariable = null; + string notNullVariable = "Hello"; + + Expression<Func<IEnumerable>> null1 = () => (from a in session.Query<Animal>() where a.Description == null select a); + Expression<Func<IEnumerable>> null2 = () => (from a in session.Query<Animal>() where a.Description == nullVariable select a); + Expression<Func<IEnumerable>> notNull = () => (from a in session.Query<Animal>() where a.Description == notNullVariable select a); + + var nhNull1 = new NhLinqExpression(null1.Body); + var nhNull2 = new NhLinqExpression(null2.Body); + var nhNotNull = new NhLinqExpression(notNull.Body); + + Assert.AreNotEqual(nhNull1.Key, nhNotNull.Key); + Assert.AreNotEqual(nhNull2.Key, nhNotNull.Key); + } + } + // TODO - different parameter names protected override IList Mappings This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-01-17 04:39:30
|
Revision: 5359 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5359&view=rev Author: patearl Date: 2011-01-17 04:39:24 +0000 (Mon, 17 Jan 2011) Log Message: ----------- Fixed indentation on a few lines. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Engine/ISessionImplementor.cs trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs Modified: trunk/nhibernate/src/NHibernate/Engine/ISessionImplementor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/ISessionImplementor.cs 2011-01-17 04:37:31 UTC (rev 5358) +++ trunk/nhibernate/src/NHibernate/Engine/ISessionImplementor.cs 2011-01-17 04:39:24 UTC (rev 5359) @@ -90,11 +90,11 @@ IList List(IQueryExpression queryExpression, QueryParameters parameters); /// <summary> - /// Create a new instance of <c>Query</c> for the given query expression - /// <param name="queryExpression">A hibernate query expression</param> - /// <returns>The query</returns> - /// </summary> - IQuery CreateQuery(IQueryExpression queryExpression); + /// Create a new instance of <c>Query</c> for the given query expression + /// <param name="queryExpression">A hibernate query expression</param> + /// <returns>The query</returns> + /// </summary> + IQuery CreateQuery(IQueryExpression queryExpression); void List(string query, QueryParameters parameters, IList results); Modified: trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs 2011-01-17 04:37:31 UTC (rev 5358) +++ trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs 2011-01-17 04:39:24 UTC (rev 5359) @@ -14,10 +14,10 @@ return new NhQueryable<T>(session as ISessionImplementor); } - public static IQueryable<T> Query<T>(this IStatelessSession session) - { - return new NhQueryable<T>(session as ISessionImplementor); - } + public static IQueryable<T> Query<T>(this IStatelessSession session) + { + return new NhQueryable<T>(session as ISessionImplementor); + } public static IQueryable<T> Cacheable<T>(this IQueryable<T> query) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-01-17 04:37:37
|
Revision: 5358 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5358&view=rev Author: patearl Date: 2011-01-17 04:37:31 +0000 (Mon, 17 Jan 2011) Log Message: ----------- Linq: Fixed query cache for "x is Type" operator. (NH-2459, thanks to Alex Baker for test.) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/Test.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/TrainingComponent.cs Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs 2011-01-17 04:00:30 UTC (rev 5357) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs 2011-01-17 04:37:31 UTC (rev 5358) @@ -198,7 +198,13 @@ protected override Expression VisitTypeBinaryExpression(TypeBinaryExpression expression) { - return base.VisitTypeBinaryExpression(expression); + _string.Append("IsType("); + VisitExpression(expression.Expression); + _string.Append(", "); + _string.Append(expression.TypeOperand.FullName); + _string.Append(")"); + + return expression; } protected override Expression VisitUnaryExpression(UnaryExpression expression) Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/Mappings.hbm.xml 2011-01-17 04:37:31 UTC (rev 5358) @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test" namespace="NHibernate.Test.NHSpecificTest.NH2459"> + + <class name="TrainingComponent" abstract="true" table="tblTrnNrt" discriminator-value="-1"> + <id name ="Id" column="NrtId"> + <generator class="guid"></generator> + </id> + <discriminator column="NrtObjectTypeId" type="int" /> + + <property name="Code" column="NationalCode" length="12"></property> + <property name="Title" column="NationalTitle" length="200"></property> + + </class> + + <subclass name="SkillSet" discriminator-value="1" extends="TrainingComponent"> + + </subclass> + + <subclass name="Qualification" discriminator-value="2" extends="TrainingComponent"> + + </subclass> + +</hibernate-mapping> + Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/Test.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/Test.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/Test.cs 2011-01-17 04:37:31 UTC (rev 5358) @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using log4net; +using log4net.Appender; +using log4net.Repository.Hierarchy; +using NHibernate.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2459 +{ + [TestFixture] + public class Test : BugTestCase + { + protected override void OnSetUp() + { + using (ISession session = OpenSession()) + { + SkillSet skillSet = new SkillSet() { Code = "123", Title = "Skill Set" }; + Qualification qualification = new Qualification() { Code = "124", Title = "Qualification" }; + + session.Save(skillSet); + session.Save(qualification); + session.Flush(); + } + } + + [Test] + public void IsTypeOperator() + { + using (ISession session = OpenSession()) + { + //first query is OK + IQueryable<TrainingComponent> query = session.Query<TrainingComponent>().Where(c => c is SkillSet); + Assert.That(!query.ToList().Any(c => !(c is SkillSet))); + + //Second time round the a cached version of the SQL for the query is used BUT the type parameter is not updated... + query = session.Query<TrainingComponent>().Where(c => c is Qualification); + Assert.That(!query.ToList().Any(c => !(c is Qualification))); + } + } + + protected override void OnTearDown() + { + using (ISession session = OpenSession()) + { + session.Delete("from TrainingComponent"); + session.Flush(); + } + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/TrainingComponent.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/TrainingComponent.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2459/TrainingComponent.cs 2011-01-17 04:37:31 UTC (rev 5358) @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NHibernate.Test.NHSpecificTest.NH2459 +{ + public class TrainingComponent + { + protected TrainingComponent() {} + public virtual Guid Id { get; set; } + public virtual string Code { get; set; } + public virtual string Title { get; set; } + } + + public class SkillSet : TrainingComponent { + + } + + public class Qualification : TrainingComponent { + + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-17 04:00:30 UTC (rev 5357) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-17 04:37:31 UTC (rev 5358) @@ -587,6 +587,8 @@ <Compile Include="NHSpecificTest\NH2420\MyTable.cs" /> <Compile Include="NHSpecificTest\NH2441\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2441\Model.cs" /> + <Compile Include="NHSpecificTest\NH2459\Test.cs" /> + <Compile Include="NHSpecificTest\NH2459\TrainingComponent.cs" /> <Compile Include="NHSpecificTest\NH2470\Class1Class2Classes.cs" /> <Compile Include="NHSpecificTest\NH2470\Class1Class2DTOs.cs" /> <Compile Include="NHSpecificTest\NH2470\Class1Class2Tests.cs" /> @@ -2381,6 +2383,7 @@ <EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" /> </ItemGroup> <ItemGroup> + <EmbeddedResource Include="NHSpecificTest\NH2459\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2412\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2280\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2203\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-01-17 04:00:37
|
Revision: 5357 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5357&view=rev Author: patearl Date: 2011-01-17 04:00:30 +0000 (Mon, 17 Jan 2011) Log Message: ----------- Linq: Generate left joins for order by clauses. (NH-2412) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Linq/ReWriters/AddLeftJoinsReWriter.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Customer.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Order.cs Modified: trunk/nhibernate/src/NHibernate/Linq/ReWriters/AddLeftJoinsReWriter.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/ReWriters/AddLeftJoinsReWriter.cs 2011-01-16 22:48:45 UTC (rev 5356) +++ trunk/nhibernate/src/NHibernate/Linq/ReWriters/AddLeftJoinsReWriter.cs 2011-01-17 04:00:30 UTC (rev 5357) @@ -1,10 +1,10 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq.Expressions; +using NHibernate.Linq.Visitors; using Remotion.Data.Linq; using Remotion.Data.Linq.Clauses; -namespace NHibernate.Linq.Visitors +namespace NHibernate.Linq.ReWriters { public class AddLeftJoinsReWriter : QueryModelVisitorBase { @@ -24,20 +24,37 @@ public override void VisitSelectClause(SelectClause selectClause, QueryModel queryModel) { - var joins = LeftJoinDetector.Detect(selectClause.Selector, new NameGenerator(queryModel), _sessionFactory); + selectClause.Selector = JoinReplacer(queryModel, selectClause.Selector); + } - if (joins.Joins.Count > 0) - { - selectClause.Selector = joins.Selector; + public override void VisitOrderByClause(OrderByClause orderByClause, QueryModel queryModel, int index) + { + foreach (Ordering ordering in orderByClause.Orderings) + { + ordering.Expression = JoinReplacer(queryModel, ordering.Expression); + } + } - queryModel.TransformExpressions(e => ExpressionSwapper.Swap(e, joins.ExpressionMap)); + private Expression JoinReplacer(QueryModel queryModel, Expression expression) + { + var joins = LeftJoinDetector.Detect(expression, new NameGenerator(queryModel), _sessionFactory); - foreach (var join in joins.Joins) - { - queryModel.BodyClauses.Add(join); - } - } - } + Expression result = expression; + + if (joins.Joins.Count > 0) + { + result = joins.Selector; + + queryModel.TransformExpressions(e => ExpressionSwapper.Swap(e, joins.ExpressionMap)); + + foreach (var join in joins.Joins) + { + queryModel.BodyClauses.Add(join); + } + } + + return result; + } } public class ExpressionSwapper : NhExpressionTreeVisitor Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Customer.cs (from rev 5344, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/A.cs) =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Customer.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Customer.cs 2011-01-17 04:00:30 UTC (rev 5357) @@ -0,0 +1,11 @@ +using System; +using System.Collections; + +namespace NHibernate.Test.NHSpecificTest.NH2412 +{ + public class Customer + { + public int? Id { get; set; } + public string Name { get; set; } + } +} Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Fixture.cs (from rev 5344, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/Fixture.cs) =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Fixture.cs 2011-01-17 04:00:30 UTC (rev 5357) @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NHibernate.Criterion; +using NHibernate.Linq; +using NHibernate.Linq.Functions; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2412 +{ + [TestFixture] + public class Fixture : BugTestCase + { + protected override void OnTearDown() + { + using (ISession s = sessions.OpenSession()) + { + s.Delete("from Order"); + s.Delete("from Customer"); + s.Flush(); + } + } + + [Test] + public void OrderByUsesLeftJoin() + { + ISession s = OpenSession(); + try + { + Customer c1 = new Customer {Name = "Allen"}; + s.Save(c1); + Customer c2 = new Customer {Name = "Bob"}; + s.Save(c2); + Customer c3 = new Customer {Name = "Charlie"}; + s.Save(c3); + + s.Save(new Order {Customer = c1}); + s.Save(new Order {Customer = c3}); + s.Save(new Order {Customer = c2}); + s.Save(new Order()); + + s.Flush(); + } + finally + { + s.Close(); + } + + s = OpenSession(); + try + { + var orders = s.Query<Order>().OrderBy(o => o.Customer.Name).ToList(); + Assert.AreEqual(4, orders.Count); + if (orders[0].Customer == null) + { + CollectionAssert.AreEqual(new[] {"Allen", "Bob", "Charlie"}, orders.Skip(1).Select(o => o.Customer.Name).ToArray()); + } + else + { + CollectionAssert.AreEqual(new[] { "Allen", "Bob", "Charlie" }, orders.Take(3).Select(o => o.Customer.Name).ToArray()); + } + } + finally + { + s.Close(); + } + } + } +} Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Mappings.hbm.xml (from rev 5344, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/Mappings.hbm.xml) =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Mappings.hbm.xml 2011-01-17 04:00:30 UTC (rev 5357) @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test" namespace="NHibernate.Test.NHSpecificTest.NH2412" default-lazy="false"> + <class name="Customer" table="customers"> + <id name="Id" column="id" unsaved-value="null"> + <generator class="native" /> + </id> + <property name="Name"/> + </class> + <class name="Order" table="orders"> + <id name="Id" column="id" unsaved-value="null"> + <generator class="native" /> + </id> + <many-to-one name="Customer" class="Customer" column="customerid"/> + </class> +</hibernate-mapping> Copied: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Order.cs (from rev 5344, trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2392/A.cs) =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Order.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2412/Order.cs 2011-01-17 04:00:30 UTC (rev 5357) @@ -0,0 +1,11 @@ +using System; +using System.Collections; + +namespace NHibernate.Test.NHSpecificTest.NH2412 +{ + public class Order + { + public int? Id { get; set; } + public Customer Customer { get; set; } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-16 22:48:45 UTC (rev 5356) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-17 04:00:30 UTC (rev 5357) @@ -579,6 +579,9 @@ <Compile Include="NHSpecificTest\NH2409\Message.cs" /> <Compile Include="NHSpecificTest\NH2409\MessageReading.cs" /> <Compile Include="NHSpecificTest\NH2409\User.cs" /> + <Compile Include="NHSpecificTest\NH2412\Order.cs" /> + <Compile Include="NHSpecificTest\NH2412\Customer.cs" /> + <Compile Include="NHSpecificTest\NH2412\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2420\DummyEnlistment.cs" /> <Compile Include="NHSpecificTest\NH2420\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2420\MyTable.cs" /> @@ -2378,6 +2381,7 @@ <EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" /> </ItemGroup> <ItemGroup> + <EmbeddedResource Include="NHSpecificTest\NH2412\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2280\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2203\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\BagWithLazyExtraAndFilter\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-01-16 22:48:52
|
Revision: 5356 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5356&view=rev Author: patearl Date: 2011-01-16 22:48:45 +0000 (Sun, 16 Jan 2011) Log Message: ----------- HQL: Fixed a bug relating to composite key SQL generation (NH-2280, Thanks Alex Baker). Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElement.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/InvalidSqlTest.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/Organisation.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/OrganisationCode.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElement.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElement.cs 2011-01-16 21:55:41 UTC (rev 5355) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/FromElement.cs 2011-01-16 22:48:45 UTC (rev 5356) @@ -459,7 +459,10 @@ } string result = StringHelper.Join(", ", cols); - return cols.Length == 1 ? result : "(" + result + ")"; + // There used to be code here that added parentheses if the number of columns was greater than one. + // This was causing invalid queries like select (c1, c2) from x. I couldn't think of a reason that + // parentheses would be wanted around a list of columns, so I removed them. + return result; } public void HandlePropertyBeingDereferenced(IType propertySource, string propertyName) Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/InvalidSqlTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/InvalidSqlTest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/InvalidSqlTest.cs 2011-01-16 22:48:45 UTC (rev 5356) @@ -0,0 +1,24 @@ +using System; + +using System.Globalization; +using System.IO; +using System.Linq; +using NHibernate.Dialect; +using NHibernate.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2280 +{ + [TestFixture] + public class InvalidSqlTest : BugTestCase + { + [Test] + public void CompositeKeyTest() + { + using (ISession session = OpenSession()) + { + session.Query<Organisation>().Where(o => o.Codes.Any(c => c.Key.Code == "1476")).ToList(); + } + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/Mappings.hbm.xml 2011-01-16 22:48:45 UTC (rev 5356) @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test" namespace="NHibernate.Test.NHSpecificTest.NH2280"> + <class name="Organisation" abstract="false" table="tblTrnOrganisation"> + <id name="OrganisationId"> + <generator class="guid"></generator> + </id> + <property name="LegalName" column="OrganisationLegalName"/> + <property name="Abn" /> + <property name="Acn" /> + + <set name="Codes" table="tblTrnRtoCode" cascade="all-delete-orphan" inverse="true" > + <key column="OrganisationId"/> + <one-to-many class="OrganisationCode"/> + </set> + </class> + + <class name="OrganisationCode" table="tblTrnRtoCode" dynamic-insert="true" dynamic-update="true"> + <composite-id class="NHibernate.Test.NHSpecificTest.NH2280.OrganisationCodeKey, NHibernate.Test" name="Key" > + <key-many-to-one column="OrganisationId" class="Organisation" name="Organisation"/> + <key-property column="RtoCode" name="Code"/> + <key-property column="RtoCodeStartDate" name="StartDate"/> + </composite-id> + <property name="EndDate" column="RtoCodeEndDate"/> + </class> +</hibernate-mapping> + Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/Organisation.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/Organisation.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/Organisation.cs 2011-01-16 22:48:45 UTC (rev 5356) @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Iesi.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH2280 +{ + public class Organisation + { + public virtual Guid OrganisationId { get; set; } + + public virtual ISet<OrganisationCode> Codes { get; protected internal set; } + + public virtual string LegalName { get; set; } + public virtual string Abn { get; set; } + public virtual string Acn { get; set; } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/OrganisationCode.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/OrganisationCode.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2280/OrganisationCode.cs 2011-01-16 22:48:45 UTC (rev 5356) @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; + +namespace NHibernate.Test.NHSpecificTest.NH2280 +{ + public class OrganisationCode + { + private OrganisationCodeKey key = new OrganisationCodeKey(); + + public virtual DateTime StartDate + { + get { return key.StartDate; } + set { key.StartDate = value; } + } + + public virtual string Code + { + get { return key.Code; } + set { key.Code = value; } + } + + public virtual OrganisationCodeKey Key + { + get { return key; } + protected set { key = value; } + } + + /// <summary> + /// Need comments for intellisense. + /// </summary> + public virtual Organisation Organisation + { + get { return key.Organisation; } + set { key.Organisation = value; } + } + + + public virtual DateTime? EndDate { get; set; } + + public override bool Equals(object obj) + { + var other = obj as OrganisationCodeKey; + if (other == null) + { + return false; + } + + return this.Code == other.Code && this.StartDate == other.StartDate; + } + + public override int GetHashCode() + { + return Code == null ? 0 : Code.GetHashCode() ^ StartDate.GetHashCode(); + } + + public override string ToString() + { + return Code; + } + } + + /// <summary> + /// blah blah blah + /// </summary> + [Serializable, + DebuggerDisplay("Organisation: {Organisation}, Code: {Code}, StartDate: {StartDate:d}")] + public class OrganisationCodeKey + { + public string Code { get; set; } + public DateTime StartDate { get; set; } + public Organisation Organisation { get; set; } + + public override bool Equals(object obj) + { + OrganisationCodeKey other = obj as OrganisationCodeKey; + if (other == null) + { + return false; + } + + return this.Organisation.OrganisationId == other.Organisation.OrganisationId && this.Code == other.Code && + this.StartDate == other.StartDate; + } + + public override int GetHashCode() + { + return (Organisation == null ? 0 : Organisation.GetHashCode()) ^ (Code == null ? 0 : Code.GetHashCode()) + ^ StartDate.GetHashCode(); + } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-16 21:55:41 UTC (rev 5355) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-16 22:48:45 UTC (rev 5356) @@ -521,6 +521,9 @@ <Compile Include="NHSpecificTest\NH2279\B.cs" /> <Compile Include="NHSpecificTest\NH2279\C.cs" /> <Compile Include="NHSpecificTest\NH2279\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2280\InvalidSqlTest.cs" /> + <Compile Include="NHSpecificTest\NH2280\Organisation.cs" /> + <Compile Include="NHSpecificTest\NH2280\OrganisationCode.cs" /> <Compile Include="NHSpecificTest\NH2287\Domain.cs" /> <Compile Include="NHSpecificTest\NH2287\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2288\Fixture.cs" /> @@ -2375,6 +2378,7 @@ <EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" /> </ItemGroup> <ItemGroup> + <EmbeddedResource Include="NHSpecificTest\NH2280\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2203\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\BagWithLazyExtraAndFilter\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2470\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-01-16 21:55:47
|
Revision: 5355 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5355&view=rev Author: patearl Date: 2011-01-16 21:55:41 +0000 (Sun, 16 Jan 2011) Log Message: ----------- Linq: Ignore duplicate joins when building expression map (NH2362). Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Linq/Visitors/LeftJoinDetector.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Fixture.cs Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/LeftJoinDetector.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/LeftJoinDetector.cs 2011-01-16 20:55:13 UTC (rev 5354) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/LeftJoinDetector.cs 2011-01-16 21:55:41 UTC (rev 5355) @@ -31,8 +31,9 @@ if (expression.Type.IsNonPrimitive() && IsEntity(expression.Type)) { var newExpr = AddJoin(expression); - _expressionMap.Add(expression, newExpr); - return newExpr; + if (!_expressionMap.ContainsKey(expression) || !_expressionMap[expression].Equals(newExpr)) // Second clause is sanity check. + _expressionMap.Add(expression, newExpr); + return newExpr; } return base.VisitMemberExpression(expression); Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Fixture.cs 2011-01-16 20:55:13 UTC (rev 5354) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Fixture.cs 2011-01-16 21:55:41 UTC (rev 5355) @@ -7,7 +7,6 @@ public class Fixture : BugTestCase { [Test] - [Ignore("Not working yet.")] public void CanParseMultipleGroupByAndSelect() { using (var session = OpenSession()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-01-16 20:55:20
|
Revision: 5354 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5354&view=rev Author: patearl Date: 2011-01-16 20:55:13 +0000 (Sun, 16 Jan 2011) Log Message: ----------- Linq: Fixed group by on multiple keys. Added more group by tests. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessGroupBy.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/GroupByTests.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2011-01-16 20:48:51 UTC (rev 5353) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2011-01-16 20:55:13 UTC (rev 5354) @@ -321,9 +321,9 @@ return new HqlDirectionDescending(_factory); } - public HqlGroupBy GroupBy(HqlExpression expression) + public HqlGroupBy GroupBy(params HqlExpression[] expressions) { - return new HqlGroupBy(_factory, expression); + return new HqlGroupBy(_factory, expressions); } public HqlAll All() Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2011-01-16 20:48:51 UTC (rev 5353) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2011-01-16 20:55:13 UTC (rev 5354) @@ -786,7 +786,7 @@ public class HqlGroupBy : HqlStatement { - public HqlGroupBy(IASTFactory factory, HqlExpression expression) : base(HqlSqlWalker.GROUP, "group by", factory, expression) + public HqlGroupBy(IASTFactory factory, params HqlExpression[] expressions) : base(HqlSqlWalker.GROUP, "group by", factory, expressions) { } } Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessGroupBy.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessGroupBy.cs 2011-01-16 20:48:51 UTC (rev 5353) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessGroupBy.cs 2011-01-16 20:55:13 UTC (rev 5354) @@ -1,5 +1,8 @@ -using NHibernate.Hql.Ast; +using System.Collections.Generic; +using System.Linq.Expressions; +using NHibernate.Hql.Ast; using Remotion.Data.Linq.Clauses.ResultOperators; +using System.Linq; namespace NHibernate.Linq.Visitors.ResultOperatorProcessors { @@ -7,9 +10,15 @@ { public void Process(GroupResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) { - tree.AddGroupByClause(tree.TreeBuilder.GroupBy( - HqlGeneratorExpressionTreeVisitor.Visit(resultOperator.KeySelector, queryModelVisitor.VisitorParameters) - .AsExpression())); + IEnumerable<Expression> groupByKeys; + if (resultOperator.KeySelector is NewExpression) + groupByKeys = (resultOperator.KeySelector as NewExpression).Arguments; + else + groupByKeys = new[] {resultOperator.KeySelector}; + + IEnumerable<HqlExpression> hqlGroupByKeys = groupByKeys.Select(k => HqlGeneratorExpressionTreeVisitor.Visit(k, queryModelVisitor.VisitorParameters).AsExpression()); + + tree.AddGroupByClause(tree.TreeBuilder.GroupBy(hqlGroupByKeys.ToArray())); } } } \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/GroupByTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/GroupByTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Linq/ByMethod/GroupByTests.cs 2011-01-16 20:55:13 UTC (rev 5354) @@ -0,0 +1,120 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NHibernate.DomainModel.Northwind.Entities; +using NUnit.Framework; + +namespace NHibernate.Test.Linq.ByMethod +{ + [TestFixture] + public class GroupByTests : LinqTestCase + { + [Test] + public void SingleKeyGroupAndCount() + { + var orderCounts = db.Orders.GroupBy(o => o.Customer).Select(g => g.Count()).ToList(); + Assert.AreEqual(89, orderCounts.Count); + Assert.AreEqual(830, orderCounts.Sum()); + } + + [Test] + public void MultipleKeyGroupAndCount() + { + var orderCounts = db.Orders.GroupBy(o => new {o.Customer, o.Employee}).Select(g => g.Count()).ToList(); + Assert.AreEqual(464, orderCounts.Count); + Assert.AreEqual(830, orderCounts.Sum()); + } + + [Test] + [Ignore("Not working yet.")] + public void SingleKeyGrouping() + { + var orders = db.Orders.GroupBy(o => o.Customer).ToList(); + Assert.That(orders.Count, Is.EqualTo(830)); + CheckGrouping(orders, o => o.Customer); + } + + [Test] + [Ignore("Not working yet.")] + public void MultipleKeyGrouping() + { + var orders = db.Orders.GroupBy(o => new { o.Customer, o.Employee }).ToList(); + Assert.That(orders.Count, Is.EqualTo(830)); + + CheckGrouping( + orders.Select(g => new TupGrouping<Customer, Employee, Order>(g.Key.Customer, g.Key.Employee, g)), + o => o.Customer, + o => o.Employee); + } + + private void CheckGrouping<TKey, TElement>(IEnumerable<IGrouping<TKey, TElement>> groupedItems, Func<TElement, TKey> groupBy) + { + HashSet<object> used = new HashSet<object>(); + foreach (IGrouping<TKey, TElement> group in groupedItems) + { + Assert.IsFalse(used.Contains(group.Key)); + used.Add(group.Key); + + foreach (var item in group) + { + Assert.AreEqual(group.Key, groupBy(item)); + } + } + } + + private void CheckGrouping<TKey1, TKey2, TElement>(IEnumerable<TupGrouping<TKey1, TKey2, TElement>> groupedItems, Func<TElement, TKey1> groupBy1, Func<TElement, TKey2> groupBy2) + { + HashSet<object> used = new HashSet<object>(); + foreach (IGrouping<Tup<TKey1, TKey2>, TElement> group in groupedItems) + { + Assert.IsFalse(used.Contains(group.Key.Item1)); + used.Add(group.Key.Item1); + Assert.IsFalse(used.Contains(group.Key.Item2)); + used.Add(group.Key.Item2); + + foreach (var item in group) + { + Assert.AreEqual(group.Key.Item1, groupBy1(item)); + Assert.AreEqual(group.Key.Item2, groupBy2(item)); + } + } + } + + private class TupGrouping<TKey1, TKey2, TElement> : IGrouping<Tup<TKey1, TKey2>, TElement> + { + private IEnumerable<TElement> Elements { get; set; } + + public TupGrouping(TKey1 key1, TKey2 key2, IEnumerable<TElement> elements) + { + Key = new Tup<TKey1, TKey2>(key1, key2); + Elements = elements; + } + + public IEnumerator<TElement> GetEnumerator() + { + return Elements.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public Tup<TKey1, TKey2> Key { get; private set; } + } + + private class Tup<T1, T2> + { + public T1 Item1 { get; private set; } + public T2 Item2 { get; private set; } + + public Tup(T1 item1, T2 item2) + { + Item1 = item1; + Item2 = item2; + } + } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Fixture.cs 2011-01-16 20:48:51 UTC (rev 5353) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2362/Fixture.cs 2011-01-16 20:55:13 UTC (rev 5354) @@ -4,10 +4,10 @@ namespace NHibernate.Test.NHSpecificTest.NH2362 { - [Ignore("Not fixed yet.")] public class Fixture : BugTestCase { [Test] + [Ignore("Not working yet.")] public void CanParseMultipleGroupByAndSelect() { using (var session = OpenSession()) Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-16 20:48:51 UTC (rev 5353) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-01-16 20:55:13 UTC (rev 5354) @@ -427,6 +427,7 @@ <Compile Include="Linq\BinaryBooleanExpressionTests.cs" /> <Compile Include="Linq\BinaryExpressionOrdererTests.cs" /> <Compile Include="Linq\BooleanMethodExtensionExample.cs" /> + <Compile Include="Linq\ByMethod\GroupByTests.cs" /> <Compile Include="Linq\CasingTest.cs" /> <Compile Include="Linq\CollectionAssert.cs" /> <Compile Include="Linq\CustomExtensionsExample.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |