PageRenderTime 35ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/Libraries/Source/NHibernate/Collection/PersistentArrayHolder.cs

https://github.com/enjoii/WCell
C# | 353 lines | 255 code | 42 blank | 56 comment | 26 complexity | 3e4ec508763d2ab04718ee122acc1cde MD5 | raw file
  1. using System;
  2. using System.Collections;
  3. using System.Data;
  4. using System.Diagnostics;
  5. using log4net;
  6. using NHibernate.DebugHelpers;
  7. using NHibernate.Engine;
  8. using NHibernate.Loader;
  9. using NHibernate.Persister.Collection;
  10. using NHibernate.Type;
  11. namespace NHibernate.Collection
  12. {
  13. /// <summary>
  14. /// A persistent wrapper for an array. lazy initialization is NOT supported
  15. /// </summary>
  16. [Serializable]
  17. [DebuggerTypeProxy(typeof(CollectionProxy))]
  18. public class PersistentArrayHolder : AbstractPersistentCollection
  19. {
  20. private static readonly ILog log = LogManager.GetLogger(typeof(PersistentArrayHolder));
  21. /// <summary>
  22. /// The <see cref="Array"/> that NHibernate is wrapping.
  23. /// </summary>
  24. private Array array;
  25. [NonSerialized]
  26. private System.Type elementClass;
  27. /// <summary>
  28. /// A temporary list that holds the objects while the PersistentArrayHolder is being
  29. /// populated from the database.
  30. /// </summary>
  31. [NonSerialized]
  32. private ArrayList tempList;
  33. public PersistentArrayHolder(ISessionImplementor session, object array) : base(session)
  34. {
  35. this.array = (Array) array;
  36. SetInitialized();
  37. }
  38. /// <summary>
  39. ///
  40. /// </summary>
  41. /// <param name="persister"></param>
  42. /// <returns></returns>
  43. protected override ICollection Snapshot(ICollectionPersister persister)
  44. {
  45. EntityMode entityMode = Session.EntityMode;
  46. int length = /*(array==null) ? temp.Count :*/ array.Length;
  47. Array result = System.Array.CreateInstance(persister.ElementClass, length);
  48. for (int i = 0; i < length; i++)
  49. {
  50. object elt = /*(array==null) ? temp[i] :*/ array.GetValue(i);
  51. try
  52. {
  53. result.SetValue(persister.ElementType.DeepCopy(elt, entityMode, persister.Factory), i);
  54. }
  55. catch (Exception e)
  56. {
  57. log.Error("Array element type error", e);
  58. throw new HibernateException("Array element type error", e);
  59. }
  60. }
  61. return result;
  62. }
  63. public override ICollection GetOrphans(object snapshot, string entityName)
  64. {
  65. object[] sn = (object[]) snapshot;
  66. object[] arr = (object[]) array;
  67. ArrayList result = new ArrayList(sn.Length);
  68. for (int i = 0; i < sn.Length; i++)
  69. {
  70. result.Add(sn[i]);
  71. }
  72. for (int i = 0; i < sn.Length; i++)
  73. {
  74. IdentityRemove(result, arr[i], entityName, Session);
  75. }
  76. return result;
  77. }
  78. public PersistentArrayHolder(ISessionImplementor session, ICollectionPersister persister)
  79. : base(session)
  80. {
  81. elementClass = persister.ElementClass;
  82. }
  83. /// <summary>
  84. ///
  85. /// </summary>
  86. public object Array
  87. {
  88. get { return array; }
  89. }
  90. /// <summary>
  91. ///
  92. /// </summary>
  93. /// <param name="collection"></param>
  94. /// <returns></returns>
  95. public override bool IsWrapper(object collection)
  96. {
  97. return array == collection;
  98. }
  99. public override bool EqualsSnapshot(ICollectionPersister persister)
  100. {
  101. IType elementType = persister.ElementType;
  102. Array snapshot = GetSnapshot() as Array;
  103. int xlen = snapshot.Length;
  104. if (xlen != array.Length)
  105. {
  106. return false;
  107. }
  108. for (int i = 0; i < xlen; i++)
  109. {
  110. if (elementType.IsDirty(snapshot.GetValue(i), array.GetValue(i), Session))
  111. {
  112. return false;
  113. }
  114. }
  115. return true;
  116. }
  117. /// <summary>
  118. ///
  119. /// </summary>
  120. /// <returns></returns>
  121. public ICollection Elements()
  122. {
  123. //if (array==null) return tempList;
  124. int length = array.Length;
  125. IList list = new ArrayList(length);
  126. for (int i = 0; i < length; i++)
  127. {
  128. list.Add(array.GetValue(i));
  129. }
  130. return list;
  131. }
  132. /// <summary>
  133. ///
  134. /// </summary>
  135. public override bool Empty
  136. {
  137. get { return false; }
  138. }
  139. public override object ReadFrom(IDataReader rs, ICollectionPersister role, ICollectionAliases descriptor, object owner)
  140. {
  141. object element = role.ReadElement(rs, owner, descriptor.SuffixedElementAliases, Session);
  142. int index = (int) role.ReadIndex(rs, descriptor.SuffixedIndexAliases, Session);
  143. for (int i = tempList.Count; i <= index; i++)
  144. {
  145. tempList.Add(null);
  146. }
  147. tempList[index] = element;
  148. return element;
  149. }
  150. /// <summary>
  151. ///
  152. /// </summary>
  153. /// <returns></returns>
  154. public override IEnumerable Entries()
  155. {
  156. return Elements();
  157. }
  158. /// <summary>
  159. /// Before <see cref="ReadFrom" /> is called the PersistentArrayHolder needs to setup
  160. /// a temporary list to hold the objects.
  161. /// </summary>
  162. public override void BeginRead()
  163. {
  164. base.BeginRead();
  165. tempList = new ArrayList();
  166. }
  167. /// <summary>
  168. /// Takes the contents stored in the temporary list created during <see cref="BeginRead" />
  169. /// that was populated during <see cref="ReadFrom" /> and write it to the underlying
  170. /// array.
  171. /// </summary>
  172. public override bool EndRead(ICollectionPersister persister)
  173. {
  174. SetInitialized();
  175. array = System.Array.CreateInstance(elementClass, tempList.Count);
  176. int index = 0;
  177. foreach (object element in tempList)
  178. {
  179. array.SetValue(element, index);
  180. index++;
  181. }
  182. tempList = null;
  183. return true;
  184. }
  185. public override void BeforeInitialize(ICollectionPersister persister)
  186. {
  187. }
  188. public override bool IsDirectlyAccessible
  189. {
  190. get { return true; }
  191. }
  192. /// <summary>
  193. /// Initializes this array holder from the cached values.
  194. /// </summary>
  195. /// <param name="persister">The CollectionPersister to use to reassemble the Array.</param>
  196. /// <param name="disassembled">The disassembled Array.</param>
  197. /// <param name="owner">The owner object.</param>
  198. public override void InitializeFromCache(ICollectionPersister persister, object disassembled, object owner)
  199. {
  200. object[] cached = (object[]) disassembled;
  201. array = System.Array.CreateInstance(persister.ElementClass, cached.Length);
  202. for (int i = 0; i < cached.Length; i++)
  203. {
  204. array.SetValue(persister.ElementType.Assemble(cached[i], Session, owner), i);
  205. }
  206. SetInitialized();
  207. }
  208. public override object Disassemble(ICollectionPersister persister)
  209. {
  210. int length = array.Length;
  211. object[] result = new object[length];
  212. for (int i = 0; i < length; i++)
  213. {
  214. result[i] = persister.ElementType.Disassemble(array.GetValue(i), Session, null);
  215. }
  216. return result;
  217. }
  218. /// <summary>
  219. /// Returns the user-visible portion of the NHibernate PersistentArrayHolder.
  220. /// </summary>
  221. /// <returns>
  222. /// The array that contains the data, not the NHibernate wrapper.
  223. /// </returns>
  224. public override object GetValue()
  225. {
  226. return array;
  227. }
  228. public override IEnumerable GetDeletes(IType elemType, bool indexIsFormula)
  229. {
  230. IList deletes = new ArrayList();
  231. Array sn = GetSnapshot() as Array;
  232. int snSize = sn.Length;
  233. int arraySize = array.Length;
  234. int end;
  235. if (snSize > arraySize)
  236. {
  237. for (int i = arraySize; i < snSize; i++)
  238. {
  239. deletes.Add(i);
  240. }
  241. end = arraySize;
  242. }
  243. else
  244. {
  245. end = snSize;
  246. }
  247. for (int i = 0; i < end; i++)
  248. {
  249. if (array.GetValue(i) == null && sn.GetValue(i) != null)
  250. {
  251. deletes.Add(i);
  252. }
  253. }
  254. return deletes;
  255. }
  256. public override bool NeedsInserting(object entry, int i, IType elemType)
  257. {
  258. Array sn = GetSnapshot() as Array;
  259. return array.GetValue(i) != null && (i >= sn.Length || sn.GetValue(i) == null);
  260. }
  261. public override bool NeedsUpdating(object entry, int i, IType elemType)
  262. {
  263. Array sn = GetSnapshot() as Array;
  264. return i < sn.Length &&
  265. sn.GetValue(i) != null &&
  266. array.GetValue(i) != null &&
  267. elemType.IsDirty(array.GetValue(i), sn.GetValue(i), Session);
  268. }
  269. public override object GetIndex(object entry, int i)
  270. {
  271. return i;
  272. }
  273. public override object GetElement(object entry)
  274. {
  275. return entry;
  276. }
  277. public override object GetSnapshotElement(object entry, int i)
  278. {
  279. Array sn = (Array) GetSnapshot();
  280. return sn.GetValue(i);
  281. }
  282. public override bool EntryExists(object entry, int i)
  283. {
  284. return entry != null;
  285. }
  286. public void CopyTo(Array array, int index)
  287. {
  288. this.array.CopyTo(array, index);
  289. }
  290. public int Count
  291. {
  292. get { return array.Length; }
  293. }
  294. public IEnumerator GetEnumerator()
  295. {
  296. return array.GetEnumerator();
  297. }
  298. public bool IsSynchronized
  299. {
  300. get { return false; }
  301. }
  302. public object SyncRoot
  303. {
  304. get { return this; }
  305. }
  306. public override IEnumerable Entries(ICollectionPersister persister)
  307. {
  308. return Elements();
  309. }
  310. }
  311. }