PageRenderTime 49ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Mapping/XmlMappingSource.cs

https://bitbucket.org/danipen/mono
C# | 1190 lines | 976 code | 88 blank | 126 comment | 105 complexity | 021abbf3c3db5672b0e10e48c5c4a2aa MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. #region MIT license
  2. //
  3. // MIT license
  4. //
  5. // Copyright (c) 2007-2008 Jiri Moudry, Stefan Klinger
  6. //
  7. // Permission is hereby granted, free of charge, to any person obtaining a copy
  8. // of this software and associated documentation files (the "Software"), to deal
  9. // in the Software without restriction, including without limitation the rights
  10. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. // copies of the Software, and to permit persons to whom the Software is
  12. // furnished to do so, subject to the following conditions:
  13. //
  14. // The above copyright notice and this permission notice shall be included in
  15. // all copies or substantial portions of the Software.
  16. //
  17. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. // THE SOFTWARE.
  24. //
  25. #endregion
  26. #region grammar
  27. /* ----------------
  28. default namespace = "http://schemas.microsoft.com/linqtosql/mapping/2007"
  29. grammar {
  30. start = element Database { Database }
  31. Database = {
  32. element Table { Table }*,
  33. element Function { Function }*,
  34. attribute Name { text }?,
  35. attribute Provider { text }?
  36. }
  37. Table = {
  38. element Type { Type },
  39. attribute Name { text }?,
  40. attribute Member { text }?
  41. }
  42. Type = {
  43. {
  44. element Column { Column }* |
  45. element Association { Association }*
  46. }*,
  47. element Type { Type }*,
  48. attribute Name { text },
  49. attribute InheritanceCode { text }?,
  50. attribute IsInheritanceDefault { boolean }?
  51. }
  52. Column = {
  53. attribute Name { text }?,
  54. attribute Member { text },
  55. attribute Storage { text }?,
  56. attribute DbType { text }?,
  57. attribute IsPrimaryKey { boolean }?,
  58. attribute IsDbGenerated { boolean }?,
  59. attribute CanBeNull { boolean }?,
  60. attribute UpdateCheck { UpdateCheck }?,
  61. attribute IsDiscriminator { boolean }?,
  62. attribute Expression { text }?,
  63. attribute IsVersion { boolean }?,
  64. attribute AutoSync { AutoSync}?
  65. }
  66. Association = {
  67. attribute Name { text }?,
  68. attribute Member { text },
  69. attribute Storage { text }?,
  70. attribute ThisKey { text }?,
  71. attribute OtherKey { text }?,
  72. attribute IsForeignKey { boolean }?,
  73. attribute IsUnique { boolean }?,
  74. attribute DeleteRule { text }?,
  75. attribute DeleteOnNull { boolean }?
  76. }
  77. Function = {
  78. element Parameter { Parameter }*,
  79. {
  80. element ElementType { Type }* |
  81. element Return { Return }
  82. },
  83. attribute Name { text }?,
  84. attribute Method { text },
  85. attribute IsComposable { boolean }?
  86. }
  87. Parameter = {
  88. attribute Name { text }?,
  89. attribute Parameter { text },
  90. attribute DbType { text }?,
  91. attribute Direction { ParameterDirection }?
  92. }
  93. Return = attribute DbType { text}?
  94. UpdateCheck = "Always" | "Never" | "WhenChanged"
  95. ParameterDirection = "In" | "Out" | "InOut"
  96. AutoSync = "Never" | "OnInsert" | "OnUpdate" | "Always" | "Default"
  97. }
  98. ---------------- */
  99. #endregion
  100. using System;
  101. using System.Collections.Generic;
  102. using System.Collections.ObjectModel;
  103. using System.IO;
  104. using System.Linq;
  105. using System.Reflection;
  106. using System.Xml;
  107. using DbLinq;
  108. using DbLinq.Schema.Dbml;
  109. using DbLinq.Util;
  110. #if MONO_STRICT
  111. namespace System.Data.Linq.Mapping
  112. #else
  113. namespace DbLinq.Data.Linq.Mapping
  114. #endif
  115. {
  116. public sealed class XmlMappingSource : System.Data.Linq.Mapping.MappingSource
  117. {
  118. DbmlDatabase db;
  119. XmlMappingSource(XmlReader reader)
  120. {
  121. db = new DbmlDatabase(reader);
  122. }
  123. public static XmlMappingSource FromReader(XmlReader reader)
  124. {
  125. return new XmlMappingSource(reader);
  126. }
  127. public static XmlMappingSource FromStream(Stream stream)
  128. {
  129. return FromReader(XmlReader.Create(stream));
  130. }
  131. public static XmlMappingSource FromUrl(string url)
  132. {
  133. return FromReader(XmlReader.Create(url));
  134. }
  135. public static XmlMappingSource FromXml(string xml)
  136. {
  137. return FromReader(XmlReader.Create(new StringReader(xml)));
  138. }
  139. protected override System.Data.Linq.Mapping.MetaModel CreateModel(System.Type dataContextType)
  140. {
  141. return new XmlMetaModel(this, db, dataContextType);
  142. }
  143. abstract class DbmlItem
  144. {
  145. public const string DbmlNamespace = "http://schemas.microsoft.com/linqtosql/mapping/2007";
  146. public void ReadEmptyContent(XmlReader r, string name)
  147. {
  148. if (r.IsEmptyElement)
  149. r.ReadStartElement(name, DbmlNamespace);
  150. else
  151. {
  152. r.ReadStartElement(name, DbmlNamespace);
  153. for (r.MoveToContent(); r.NodeType != XmlNodeType.EndElement; r.MoveToContent())
  154. {
  155. if (r.NamespaceURI != DbmlNamespace)
  156. r.Skip();
  157. throw UnexpectedItemError(r);
  158. }
  159. r.ReadEndElement();
  160. }
  161. }
  162. public bool GetBooleanAttribute(XmlReader r, string attributeName)
  163. {
  164. return string.Compare(r.GetAttribute(attributeName), "true", StringComparison.OrdinalIgnoreCase) == 0;
  165. }
  166. public UpdateCheck GetUpdateCheckAttribute(XmlReader r, string attributeName)
  167. {
  168. var s = r.GetAttribute(attributeName);
  169. return s != null ? (UpdateCheck)Enum.Parse(typeof(UpdateCheck), s) : default(UpdateCheck);
  170. }
  171. public AutoSync GetAutoSyncAttribute(XmlReader r, string attributeName)
  172. {
  173. var s = r.GetAttribute(attributeName);
  174. return s != null ? (AutoSync)Enum.Parse(typeof(AutoSync), s) : default(AutoSync);
  175. }
  176. public T GetEnumAttribute<T>(XmlReader r, string attributeName)
  177. {
  178. var s = r.GetAttribute(attributeName);
  179. return s != null ? (T)Enum.Parse(typeof(T), s) : default(T);
  180. }
  181. public XmlException UnexpectedItemError(XmlReader r)
  182. {
  183. return new XmlException(String.Format("Unexpected dbml element '{0}'", r.LocalName));
  184. }
  185. }
  186. class DbmlDatabase : DbmlItem
  187. {
  188. public string Name;
  189. public string Provider;
  190. public List<DbmlTable> Tables = new List<DbmlTable>();
  191. public List<DbmlFunction> Functions = new List<DbmlFunction>();
  192. public DbmlDatabase(XmlReader r)
  193. {
  194. r.MoveToContent();
  195. Name = r.GetAttribute("Name");
  196. Provider = r.GetAttribute("Provider");
  197. if (r.IsEmptyElement)
  198. r.ReadStartElement("Database", DbmlNamespace);
  199. else
  200. {
  201. r.ReadStartElement("Database", DbmlNamespace);
  202. for (r.MoveToContent(); r.NodeType != XmlNodeType.EndElement; r.MoveToContent())
  203. {
  204. if (r.NamespaceURI != DbmlNamespace)
  205. r.Skip();
  206. else
  207. {
  208. switch (r.LocalName)
  209. {
  210. case "Table":
  211. Tables.Add(new DbmlTable(r));
  212. break;
  213. case "Function":
  214. Functions.Add(new DbmlFunction(r));
  215. break;
  216. default:
  217. throw UnexpectedItemError(r);
  218. }
  219. }
  220. }
  221. r.ReadEndElement();
  222. }
  223. }
  224. }
  225. class DbmlTable : DbmlItem
  226. {
  227. public DbmlType Type;
  228. public string Name;
  229. public string Member;
  230. public DbmlTable(XmlReader r)
  231. {
  232. Name = r.GetAttribute("Name");
  233. Member = r.GetAttribute("Member");
  234. if (r.IsEmptyElement)
  235. r.ReadStartElement("Table", DbmlNamespace);
  236. else
  237. {
  238. r.ReadStartElement("Table", DbmlNamespace);
  239. for (r.MoveToContent(); r.NodeType != XmlNodeType.EndElement; r.MoveToContent())
  240. {
  241. if (r.NamespaceURI != DbmlNamespace)
  242. r.Skip();
  243. else
  244. {
  245. switch (r.LocalName)
  246. {
  247. case "Type":
  248. Type = new DbmlType(r);
  249. break;
  250. default:
  251. throw UnexpectedItemError(r);
  252. }
  253. }
  254. }
  255. r.ReadEndElement();
  256. }
  257. }
  258. }
  259. class DbmlType : DbmlItem
  260. {
  261. public List<DbmlColumn> Columns = new List<DbmlColumn>();
  262. public List<DbmlAssociation> Associations = new List<DbmlAssociation>();
  263. public List<DbmlType> Types = new List<DbmlType>();
  264. public string Name;
  265. public string InheritanceCode;
  266. public bool IsInheritanceDefault;
  267. public DbmlType(XmlReader r)
  268. {
  269. Name = r.GetAttribute("Name");
  270. InheritanceCode = r.GetAttribute("InheritanceCode");
  271. IsInheritanceDefault = GetBooleanAttribute(r, "IsInheritanceDefault");
  272. if (r.IsEmptyElement)
  273. r.ReadStartElement("Type", DbmlNamespace);
  274. else
  275. {
  276. r.ReadStartElement("Type", DbmlNamespace);
  277. for (r.MoveToContent(); r.NodeType != XmlNodeType.EndElement; r.MoveToContent())
  278. {
  279. if (r.NamespaceURI != DbmlNamespace)
  280. r.Skip();
  281. else
  282. {
  283. switch (r.LocalName)
  284. {
  285. case "Column":
  286. Columns.Add(new DbmlColumn(r));
  287. break;
  288. case "Association":
  289. Associations.Add(new DbmlAssociation(r));
  290. break;
  291. case "Type":
  292. Types.Add(new DbmlType(r));
  293. break;
  294. default:
  295. throw UnexpectedItemError(r);
  296. }
  297. }
  298. }
  299. r.ReadEndElement();
  300. }
  301. }
  302. }
  303. class DbmlMemberBase : DbmlItem
  304. {
  305. public string Name;
  306. public string Member;
  307. public string Storage;
  308. }
  309. class DbmlColumn : DbmlMemberBase
  310. {
  311. public string DbType;
  312. public bool IsPrimaryKey;
  313. public bool IsDbGenerated;
  314. public bool CanBeNull;
  315. public System.Data.Linq.Mapping.UpdateCheck UpdateCheck;
  316. public bool IsDiscriminator;
  317. public string Expression;
  318. public bool IsVersion;
  319. public System.Data.Linq.Mapping.AutoSync AutoSync;
  320. public DbmlColumn(XmlReader r)
  321. {
  322. Member = r.GetAttribute("Member");
  323. Name = r.GetAttribute("Name") ?? Member;
  324. Storage = r.GetAttribute("Storage");
  325. DbType = r.GetAttribute("DbType");
  326. IsPrimaryKey = GetBooleanAttribute(r, "IsPrimaryKey");
  327. IsDbGenerated = GetBooleanAttribute(r, "IsDbGenerated");
  328. CanBeNull = GetBooleanAttribute(r, "CanBeNull");
  329. UpdateCheck = GetEnumAttribute<System.Data.Linq.Mapping.UpdateCheck>(r, "UpdateCheck");
  330. IsDiscriminator = GetBooleanAttribute(r, "IsDiscriminator");
  331. Expression = r.GetAttribute("Expression");
  332. IsVersion = GetBooleanAttribute(r, "IsVersion");
  333. AutoSync = GetEnumAttribute<System.Data.Linq.Mapping.AutoSync>(r, "AutoSync");
  334. ReadEmptyContent(r, "Column");
  335. }
  336. }
  337. class DbmlAssociation : DbmlMemberBase
  338. {
  339. public string ThisKey;
  340. public string OtherKey;
  341. public bool IsForeignKey;
  342. public bool IsUnique;
  343. public string DeleteRule;
  344. public bool DeleteOnNull;
  345. public DbmlAssociation(XmlReader r)
  346. {
  347. Name = r.GetAttribute("Name");
  348. Member = r.GetAttribute("Member");
  349. Storage = r.GetAttribute("Storage");
  350. ThisKey = r.GetAttribute("ThisKey");
  351. OtherKey = r.GetAttribute("OtherKey");
  352. IsForeignKey = GetBooleanAttribute(r, "IsForeignKey");
  353. IsUnique = GetBooleanAttribute(r, "IsUnique");
  354. DeleteRule = r.GetAttribute("DeleteRule");
  355. DeleteOnNull = GetBooleanAttribute(r, "DeleteOnNull");
  356. ReadEmptyContent(r, "Association");
  357. }
  358. }
  359. class DbmlFunction : DbmlItem
  360. {
  361. public string Name;
  362. public string Method;
  363. public bool IsComposable;
  364. public List<DbmlParameter> Parameters = new List<DbmlParameter>();
  365. public List<DbmlType> ElementTypes = new List<DbmlType>();
  366. public DbmlReturn Return;
  367. public DbmlFunction(XmlReader r)
  368. {
  369. Name = r.GetAttribute("Name");
  370. Method = r.GetAttribute("Method");
  371. IsComposable = GetBooleanAttribute(r, "IsComposable");
  372. if (r.IsEmptyElement)
  373. r.ReadStartElement("Function", DbmlNamespace);
  374. else
  375. {
  376. r.ReadStartElement("Function", DbmlNamespace);
  377. for (r.MoveToContent(); r.NodeType != XmlNodeType.EndElement; r.MoveToContent())
  378. {
  379. if (r.NamespaceURI != DbmlNamespace)
  380. r.Skip();
  381. else
  382. {
  383. switch (r.LocalName)
  384. {
  385. case "Parameter":
  386. Parameters.Add(new DbmlParameter(r));
  387. break;
  388. case "ElementType":
  389. ElementTypes.Add(new DbmlType(r));
  390. break;
  391. case "Return":
  392. Return = new DbmlReturn(r);
  393. break;
  394. default:
  395. throw UnexpectedItemError(r);
  396. }
  397. }
  398. }
  399. r.ReadEndElement();
  400. }
  401. }
  402. }
  403. class DbmlParameter : DbmlItem
  404. {
  405. public string Name;
  406. public string Parameter;
  407. public string DbType;
  408. public ParameterDirection Direction;
  409. public DbmlParameter(XmlReader r)
  410. {
  411. Name = r.GetAttribute("Name");
  412. Parameter = r.GetAttribute("Parameter");
  413. DbType = r.GetAttribute("DbType");
  414. Direction = GetEnumAttribute<ParameterDirection>(r, "Direction");
  415. ReadEmptyContent(r, "Parameter");
  416. }
  417. }
  418. class DbmlReturn : DbmlItem
  419. {
  420. public string DbType;
  421. public DbmlReturn(XmlReader r)
  422. {
  423. DbType = r.GetAttribute("DbType");
  424. ReadEmptyContent(r, "Return");
  425. }
  426. }
  427. class XmlMetaModel : System.Data.Linq.Mapping.MetaModel
  428. {
  429. System.Data.Linq.Mapping.MappingSource source;
  430. DbmlDatabase d;
  431. System.Type context_type;
  432. System.Data.Linq.Mapping.MetaFunction[] functions;
  433. System.Data.Linq.Mapping.MetaTable[] tables;
  434. Dictionary<System.Type, XmlMetaType> types;
  435. public XmlMetaModel(System.Data.Linq.Mapping.MappingSource source, DbmlDatabase database, System.Type contextType)
  436. {
  437. this.source = source;
  438. this.d = database;
  439. this.context_type = contextType;
  440. RegisterTypes();
  441. }
  442. void RegisterTypes()
  443. {
  444. types = new Dictionary<System.Type, XmlMetaType>();
  445. foreach (var t in d.Tables)
  446. RegisterTypeAndDescendants(t.Type);
  447. }
  448. void RegisterTypeAndDescendants(DbmlType dt)
  449. {
  450. System.Type t = GetTypeFromName(dt.Name);
  451. if (t == null)
  452. throw new ArgumentException(String.Format("type '{0}' not found", dt.Name));
  453. if (types.ContainsKey(t))
  454. return;
  455. types.Add(t, new XmlMetaType(this, dt));
  456. foreach (var cdt in dt.Types)
  457. RegisterTypeAndDescendants(cdt);
  458. }
  459. public override System.Type ContextType
  460. {
  461. get { return context_type; }
  462. }
  463. public override string DatabaseName
  464. {
  465. get { return d.Name; }
  466. }
  467. public override System.Data.Linq.Mapping.MappingSource MappingSource
  468. {
  469. get { return source; }
  470. }
  471. public override System.Type ProviderType
  472. {
  473. get { return GetTypeFromName(d.Provider); }
  474. }
  475. public override System.Data.Linq.Mapping.MetaFunction GetFunction(MethodInfo method)
  476. {
  477. foreach (var f in GetFunctions())
  478. if (f.Method == method)
  479. return f;
  480. throw new ArgumentException(String.Format("Corresponding MetaFunction for method '{0}' was not found", method));
  481. }
  482. public override IEnumerable<System.Data.Linq.Mapping.MetaFunction> GetFunctions()
  483. {
  484. if (functions == null)
  485. {
  486. var l = new List<System.Data.Linq.Mapping.MetaFunction>();
  487. foreach (var f in d.Functions)
  488. l.Add(new XmlMetaFunction(this, f));
  489. functions = l.ToArray();
  490. }
  491. return functions;
  492. }
  493. public System.Type GetTypeFromName(string name)
  494. {
  495. string ns = context_type.Namespace;
  496. string full = !name.Contains('.') && !String.IsNullOrEmpty(ns) ? String.Concat(ns, ".", name) : name;
  497. var t = this.context_type.Assembly.GetType(full) ?? System.Type.GetType(full);
  498. if (t == null)
  499. throw new ArgumentException(String.Format("Type '{0}' was not found", full));
  500. return t;
  501. }
  502. public override System.Data.Linq.Mapping.MetaType GetMetaType(System.Type type)
  503. {
  504. if (!types.ContainsKey(type))
  505. throw new ArgumentException(String.Format("Type '{0}' is not found in the mapping", type));
  506. return types[type];
  507. }
  508. public override System.Data.Linq.Mapping.MetaTable GetTable(System.Type rowType)
  509. {
  510. foreach (var t in GetTables())
  511. if (t.RowType.Type == rowType)
  512. return t;
  513. //throw new ArgumentException(String.Format("Corresponding MetaTable for row type '{0}' was not found", rowType));
  514. return null;
  515. }
  516. public override IEnumerable<System.Data.Linq.Mapping.MetaTable> GetTables()
  517. {
  518. if (tables == null)
  519. {
  520. var l = new List<System.Data.Linq.Mapping.MetaTable>();
  521. foreach (var t in d.Tables)
  522. l.Add(new XmlMetaTable(this, t));
  523. tables = l.ToArray();
  524. }
  525. return tables;
  526. }
  527. }
  528. class XmlMetaParameter : System.Data.Linq.Mapping.MetaParameter
  529. {
  530. string dbtype, mapped_name;
  531. ParameterInfo pi;
  532. public XmlMetaParameter(DbmlParameter p, ParameterInfo parameterInfo)
  533. : this(p.DbType, p.Parameter, parameterInfo)
  534. {
  535. }
  536. public XmlMetaParameter(string dbType, string mappedName, ParameterInfo parameterInfo)
  537. {
  538. this.dbtype = dbType;
  539. this.mapped_name = mappedName;
  540. this.pi = parameterInfo;
  541. }
  542. public override string DbType { get { return dbtype; } }
  543. public override string MappedName { get { return mapped_name; } }
  544. public override string Name { get { return Parameter.Name; } }
  545. public override ParameterInfo Parameter { get { return pi; } }
  546. public override System.Type ParameterType { get { return pi.ParameterType; } }
  547. }
  548. class XmlMetaTable : System.Data.Linq.Mapping.MetaTable
  549. {
  550. public XmlMetaTable(XmlMetaModel model, DbmlTable table)
  551. {
  552. this.model = model;
  553. this.t = table;
  554. System.Type rt;
  555. if (t.Member != null)
  556. {
  557. foreach (var member in model.ContextType.GetMember(t.Member))
  558. {
  559. if (table_member != null)
  560. throw new ArgumentException(String.Format("The context type '{0}' contains non-identical member '{1}'", model.ContextType, t.Member));
  561. table_member = member;
  562. }
  563. if (table_member == null)
  564. table_member = GetFieldsAndProperties(model.ContextType).First(pi => pi.GetMemberType().IsGenericType &&
  565. pi.GetMemberType().GetGenericTypeDefinition() == typeof(Table<>) &&
  566. pi.GetMemberType().GetGenericArguments()[0] == model.GetTypeFromName(t.Type.Name));
  567. if (table_member == null)
  568. throw new ArgumentException(String.Format("The context type '{0}' does not contain member '{1}' which is specified in dbml", model.ContextType, t.Member));
  569. member_type = table_member.GetMemberType();
  570. if (member_type.GetGenericTypeDefinition() != typeof(Table<>))
  571. throw new ArgumentException(String.Format("The table member type was unexpected: '{0}'", member_type));
  572. rt = member_type.GetGenericArguments()[0];
  573. }
  574. else
  575. {
  576. rt = System.Type.GetType(t.Type.Name);
  577. }
  578. row_type = model.GetMetaType(rt);
  579. if (row_type == null)
  580. throw new ArgumentException(String.Format("MetaType for '{0}' was not found", rt));
  581. }
  582. static IEnumerable<MemberInfo> GetFieldsAndProperties(System.Type type)
  583. {
  584. foreach (var f in type.GetFields())
  585. yield return f;
  586. foreach (var p in type.GetProperties())
  587. yield return p;
  588. }
  589. XmlMetaModel model;
  590. DbmlTable t;
  591. MemberInfo table_member;
  592. System.Type member_type;
  593. System.Data.Linq.Mapping.MetaType row_type;
  594. [DbLinqToDo]
  595. public override MethodInfo DeleteMethod
  596. {
  597. get { throw new NotImplementedException(); }
  598. }
  599. [DbLinqToDo]
  600. public override MethodInfo InsertMethod
  601. {
  602. get { throw new NotImplementedException(); }
  603. }
  604. public override System.Data.Linq.Mapping.MetaModel Model { get { return model; } }
  605. public override System.Data.Linq.Mapping.MetaType RowType { get { return row_type; } }
  606. System.Type MemberType { get { return member_type; } }
  607. public override string TableName { get { return t.Name; } }
  608. [DbLinqToDo]
  609. public override MethodInfo UpdateMethod
  610. {
  611. get { throw new NotImplementedException(); }
  612. }
  613. // not used yet
  614. MethodInfo GetMethod(TableFunction f)
  615. {
  616. if (f == null)
  617. return null;
  618. foreach (var mf in model.GetFunctions())
  619. if (mf.Name == f.FunctionId)
  620. return mf.Method;
  621. return null;
  622. }
  623. }
  624. class XmlMetaType : System.Data.Linq.Mapping.MetaType
  625. {
  626. XmlMetaModel model;
  627. DbmlType t;
  628. ReadOnlyCollection<System.Data.Linq.Mapping.MetaAssociation> associations;
  629. System.Type runtime_type;
  630. ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> members, identity_members, persistent_members;
  631. public XmlMetaType(XmlMetaModel model, DbmlType type)
  632. {
  633. this.model = model;
  634. this.t = type;
  635. runtime_type = model.GetTypeFromName(t.Name);
  636. int i = 0;
  637. var l = new List<System.Data.Linq.Mapping.MetaDataMember>();
  638. l.AddRange(Array.ConvertAll<DbmlColumn, System.Data.Linq.Mapping.MetaDataMember>(
  639. t.Columns.ToArray(), c => new XmlColumnMetaDataMember(model, this, c, i++)));
  640. members = new ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember>(l);
  641. }
  642. public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaAssociation> Associations
  643. {
  644. get
  645. {
  646. if (associations == null)
  647. {
  648. var l = new List<System.Data.Linq.Mapping.MetaAssociation>();
  649. // FIXME: Ordinal?
  650. foreach (var a in t.Associations)
  651. l.Add(new XmlMetaAssociation(this, new XmlAssociationMetaDataMember(model, this, a, -1), a));
  652. associations = new ReadOnlyCollection<System.Data.Linq.Mapping.MetaAssociation>(l.ToArray());
  653. }
  654. return associations;
  655. }
  656. }
  657. public override bool CanInstantiate { get { return !runtime_type.IsAbstract; } }
  658. public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> DataMembers { get { return members; } }
  659. public override System.Data.Linq.Mapping.MetaDataMember DBGeneratedIdentityMember
  660. {
  661. get { return members.First(m => m.IsDbGenerated && m.IsPrimaryKey); }
  662. }
  663. [DbLinqToDo]
  664. public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaType> DerivedTypes
  665. {
  666. get { throw new NotImplementedException(); }
  667. }
  668. public override System.Data.Linq.Mapping.MetaDataMember Discriminator
  669. {
  670. get { return members.First(m => m.IsDiscriminator); }
  671. }
  672. public override bool HasAnyLoadMethod
  673. {
  674. get { return members.Any(m => m.LoadMethod != null); }
  675. }
  676. [DbLinqToDo]
  677. public override bool HasAnyValidateMethod
  678. {
  679. get { throw new NotImplementedException(); }
  680. }
  681. [DbLinqToDo]
  682. public override bool HasInheritance
  683. {
  684. get { throw new NotImplementedException(); }
  685. }
  686. public override bool HasInheritanceCode
  687. {
  688. get { return t.InheritanceCode != null; }
  689. }
  690. public override bool HasUpdateCheck { get { return members.Any(m => m.UpdateCheck != System.Data.Linq.Mapping.UpdateCheck.Never); } }
  691. public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> IdentityMembers
  692. {
  693. get
  694. {
  695. if (identity_members == null)
  696. {
  697. identity_members = new ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember>(
  698. members.TakeWhile(m => m.IsPrimaryKey).ToArray());
  699. }
  700. return identity_members;
  701. }
  702. }
  703. [DbLinqToDo]
  704. public override System.Data.Linq.Mapping.MetaType InheritanceBase
  705. {
  706. get { throw new NotImplementedException(); }
  707. }
  708. public override Object InheritanceCode { get { return t.InheritanceCode; } }
  709. [DbLinqToDo]
  710. public override System.Data.Linq.Mapping.MetaType InheritanceDefault
  711. {
  712. get { throw new NotImplementedException(); }
  713. }
  714. [DbLinqToDo]
  715. public override System.Data.Linq.Mapping.MetaType InheritanceRoot
  716. {
  717. get { throw new NotImplementedException(); }
  718. }
  719. [DbLinqToDo]
  720. public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaType> InheritanceTypes
  721. {
  722. get { throw new NotImplementedException(); }
  723. }
  724. [DbLinqToDo]
  725. public override bool IsEntity { get { return true; } }
  726. public override bool IsInheritanceDefault { get { return t.IsInheritanceDefault; } }
  727. public override System.Data.Linq.Mapping.MetaModel Model { get { return model; } }
  728. public override string Name { get { return t.Name; } }
  729. [DbLinqToDo]
  730. public override MethodInfo OnLoadedMethod
  731. {
  732. get { throw new NotImplementedException(); }
  733. }
  734. [DbLinqToDo]
  735. public override MethodInfo OnValidateMethod
  736. {
  737. get { throw new NotImplementedException(); }
  738. }
  739. public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> PersistentDataMembers
  740. {
  741. get
  742. {
  743. if (persistent_members == null)
  744. {
  745. persistent_members = new ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember>(
  746. members.TakeWhile(m => m.IsPersistent).ToArray());
  747. }
  748. return persistent_members;
  749. }
  750. }
  751. public override System.Data.Linq.Mapping.MetaTable Table { get { return model.GetTable(runtime_type); } }
  752. public override System.Type Type { get { return runtime_type; } }
  753. public override System.Data.Linq.Mapping.MetaDataMember VersionMember { get { return members.First(m => m.IsVersion); } }
  754. public override System.Data.Linq.Mapping.MetaDataMember GetDataMember(MemberInfo member)
  755. {
  756. //return members.First(m => m.Member == member);
  757. foreach (var m in members)
  758. if (m.Member == member || (m.Member.ToString() == member.ToString() && member.DeclaringType.IsAssignableFrom(m.Member.DeclaringType)))
  759. return m;
  760. throw new ArgumentException(String.Format("No corresponding metadata member for '{0}'", member));
  761. }
  762. public override System.Data.Linq.Mapping.MetaType GetInheritanceType(System.Type type)
  763. {
  764. return InheritanceTypes.First(t => t.Type == type);
  765. }
  766. [DbLinqToDo]
  767. public override System.Data.Linq.Mapping.MetaType GetTypeForInheritanceCode(object code)
  768. {
  769. throw new NotImplementedException();
  770. }
  771. }
  772. class XmlMetaAssociation : System.Data.Linq.Mapping.MetaAssociation
  773. {
  774. //XmlMetaType owner;
  775. DbmlAssociation a;
  776. ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> these_keys, other_keys;
  777. System.Data.Linq.Mapping.MetaDataMember member;
  778. public XmlMetaAssociation(XmlMetaType owner, XmlMetaDataMember member, DbmlAssociation a)
  779. {
  780. //this.owner = owner;
  781. this.member = member;
  782. this.a = a;
  783. SetupRelationship();
  784. }
  785. /// <summary>
  786. /// This function sets up the relationship information based on the attribute <see cref="XmlMetaModel"/>.
  787. /// </summary>
  788. private void SetupRelationship()
  789. {
  790. //Get the association target type
  791. System.Type targetType = member.Member.GetFirstInnerReturnType();
  792. var metaModel = ThisMember.DeclaringType.Model as XmlMetaModel;
  793. if (metaModel == null)
  794. {
  795. throw new InvalidOperationException("Internal Error: MetaModel is not a XmlMetaModel");
  796. }
  797. System.Data.Linq.Mapping.MetaTable otherTable = metaModel.GetTable(targetType);
  798. //Setup "this key"
  799. these_keys = GetKeys(a.ThisKey ?? String.Empty, ThisMember.DeclaringType);
  800. //Setup other key
  801. other_keys = GetKeys(a.OtherKey ?? String.Empty, otherTable.RowType);
  802. }
  803. //Seperator used for key lists
  804. private static readonly char[] STRING_SEPERATOR = new[] { ',' };
  805. /// <summary>
  806. /// Returns a list of keys from the given meta type based on the key list string.
  807. /// </summary>
  808. /// <param name="keyListString">The key list string.</param>
  809. /// <param name="parentType">Type of the parent.</param>
  810. /// <returns></returns>
  811. private static ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> GetKeys(string keyListString, System.Data.Linq.Mapping.MetaType parentType)
  812. {
  813. if (keyListString != null)
  814. {
  815. var thisKeyList = new List<System.Data.Linq.Mapping.MetaDataMember>();
  816. string[] keyNames = keyListString.Split(STRING_SEPERATOR, StringSplitOptions.RemoveEmptyEntries);
  817. foreach (string rawKeyName in keyNames)
  818. {
  819. string keyName = rawKeyName.Trim();
  820. //TODO: maybe speed the lookup up
  821. System.Data.Linq.Mapping.MetaDataMember key = (from dataMember in parentType.PersistentDataMembers
  822. where dataMember.Name == keyName
  823. select dataMember).SingleOrDefault();
  824. if (key == null)
  825. {
  826. string errorMessage = string.Format("Could not find key member '{0}' of key '{1}' on type '{2}'. The key may be wrong or the field or property on '{2}' has changed names.",
  827. keyName, keyListString, parentType.Type.Name);
  828. throw new InvalidOperationException(errorMessage);
  829. }
  830. thisKeyList.Add(key);
  831. }
  832. return new ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember>(thisKeyList);
  833. }
  834. else //Key is the primary key of this table
  835. {
  836. return parentType.IdentityMembers;
  837. }
  838. }
  839. public override bool DeleteOnNull { get { return a.DeleteOnNull; } }
  840. public override string DeleteRule { get { return a.DeleteRule; } }
  841. public override bool IsForeignKey { get { return a.IsForeignKey; } }
  842. [DbLinqToDo]
  843. public override bool IsMany
  844. {
  845. get { throw new NotImplementedException(); }
  846. }
  847. public override bool IsNullable { get { return member.Member.GetMemberType().IsNullable(); } }
  848. public override bool IsUnique { get { return a.IsUnique; } }
  849. public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> OtherKey { get { return other_keys; } }
  850. public override bool OtherKeyIsPrimaryKey { get { return OtherKey.All(m => m.IsPrimaryKey); } }
  851. [DbLinqToDo]
  852. public override System.Data.Linq.Mapping.MetaDataMember OtherMember
  853. {
  854. get { throw new NotImplementedException(); }
  855. }
  856. public override System.Data.Linq.Mapping.MetaType OtherType { get { return OtherMember.DeclaringType; } }
  857. public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> ThisKey { get { return these_keys; } }
  858. public override bool ThisKeyIsPrimaryKey { get { return ThisKey.All(m => m.IsPrimaryKey); } }
  859. public override System.Data.Linq.Mapping.MetaDataMember ThisMember { get { return member; } }
  860. }
  861. abstract class XmlMetaDataMember : System.Data.Linq.Mapping.MetaDataMember
  862. {
  863. internal XmlMetaModel model;
  864. internal XmlMetaType type;
  865. internal MemberInfo member, storage;
  866. System.Data.Linq.Mapping.MetaAccessor member_accessor, storage_accessor;
  867. int ordinal;
  868. protected XmlMetaDataMember(XmlMetaModel model, XmlMetaType type, string memberName, string storageName, int ordinal)
  869. {
  870. this.model = model;
  871. this.type = type;
  872. BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
  873. if (type.Type.GetMember(memberName, bf).Length == 0)
  874. throw new ArgumentException(String.Format("Specified member '{0}' was not found in type '{1}'", memberName, type.Name));
  875. if (type.Type.GetMember(storageName, bf).Length == 0)
  876. throw new ArgumentException(String.Format("Specified member '{0}' was not found in type '{1}'", storageName, type.Name));
  877. this.member = type.Type.GetMember(memberName, bf)[0];
  878. this.storage = type.Type.GetMember(storageName, bf)[0];
  879. this.ordinal = ordinal;
  880. }
  881. public override bool CanBeNull { get { return member.GetMemberType().IsNullable(); } }
  882. public override System.Data.Linq.Mapping.MetaType DeclaringType { get { return type; } }
  883. public override bool IsDeferred { get { return false; } }
  884. public override bool IsPersistent { get { return true; } }
  885. public override MemberInfo Member { get { return member; } }
  886. public override System.Data.Linq.Mapping.MetaAccessor MemberAccessor
  887. {
  888. get
  889. {
  890. if (member_accessor == null)
  891. member_accessor = new XmlMetaAccessor(this, Member);
  892. return member_accessor;
  893. }
  894. }
  895. public override int Ordinal { get { return ordinal; } }
  896. public override System.Data.Linq.Mapping.MetaAccessor StorageAccessor
  897. {
  898. get
  899. {
  900. if (storage_accessor == null)
  901. storage_accessor = new XmlMetaAccessor(this, StorageMember);
  902. return storage_accessor;
  903. }
  904. }
  905. public override MemberInfo StorageMember { get { return storage; } }
  906. public override System.Type Type { get { return member.GetMemberType(); } }
  907. public override bool IsDeclaredBy(System.Data.Linq.Mapping.MetaType type)
  908. {
  909. return this.type == type;
  910. }
  911. }
  912. class XmlColumnMetaDataMember : XmlMetaDataMember
  913. {
  914. DbmlColumn c;
  915. public XmlColumnMetaDataMember(XmlMetaModel model, XmlMetaType type, DbmlColumn column, int ordinal)
  916. : base(model, type, column.Member, column.Storage, ordinal)
  917. {
  918. this.c = column;
  919. }
  920. public override System.Data.Linq.Mapping.MetaAssociation Association { get { return null; } }
  921. public override System.Data.Linq.Mapping.AutoSync AutoSync { get { return (System.Data.Linq.Mapping.AutoSync)c.AutoSync; } }
  922. public override string DbType { get { return c.DbType; } }
  923. [DbLinqToDo]
  924. public override System.Data.Linq.Mapping.MetaAccessor DeferredSourceAccessor
  925. {
  926. get { throw new NotImplementedException(); }
  927. }
  928. [DbLinqToDo]
  929. public override System.Data.Linq.Mapping.MetaAccessor DeferredValueAccessor
  930. {
  931. get { throw new NotImplementedException(); }
  932. }
  933. public override string Expression { get { return c.Expression; } }
  934. public override bool IsAssociation { get { return false; } }
  935. public override bool IsDbGenerated { get { return c.IsDbGenerated; } }
  936. public override bool IsDiscriminator { get { return c.IsDiscriminator; } }
  937. public override bool IsPrimaryKey { get { return c.IsPrimaryKey; } }
  938. public override bool IsVersion { get { return c.IsVersion; } }
  939. [DbLinqToDo]
  940. public override MethodInfo LoadMethod
  941. {
  942. get
  943. {
  944. throw new NotImplementedException();
  945. }
  946. }
  947. public override string MappedName { get { return c.Name; } }
  948. public override string Name { get { return c.Member ?? c.Name; } }
  949. public override System.Data.Linq.Mapping.UpdateCheck UpdateCheck { get { return c.UpdateCheck; } }
  950. }
  951. class XmlAssociationMetaDataMember : XmlMetaDataMember
  952. {
  953. DbmlAssociation a;
  954. XmlMetaAssociation ma;
  955. public XmlAssociationMetaDataMember(XmlMetaModel model, XmlMetaType type, DbmlAssociation association, int ordinal)
  956. : base(model, type, association.Member, association.Storage, ordinal)
  957. {
  958. this.a = association;
  959. }
  960. public override System.Data.Linq.Mapping.MetaAssociation Association
  961. {
  962. get
  963. {
  964. if (ma == null)
  965. this.ma = new XmlMetaAssociation(type, this, a);
  966. return ma;
  967. }
  968. }
  969. public override System.Data.Linq.Mapping.AutoSync AutoSync { get { return System.Data.Linq.Mapping.AutoSync.Never; } }
  970. public override string DbType { get { return String.Empty; } }
  971. [DbLinqToDo]
  972. public override System.Data.Linq.Mapping.MetaAccessor DeferredSourceAccessor
  973. {
  974. get { throw new NotImplementedException(); }
  975. }
  976. [DbLinqToDo]
  977. public override System.Data.Linq.Mapping.MetaAccessor DeferredValueAccessor
  978. {
  979. get { throw new NotImplementedException(); }
  980. }
  981. public override string Expression { get { return String.Empty; } }
  982. public override bool IsAssociation { get { return true; } }
  983. public override bool IsDbGenerated { get { return false; } }
  984. public override bool IsDiscriminator { get { return false; } }
  985. [DbLinqToDo]
  986. public override bool IsPrimaryKey
  987. {
  988. get { throw new NotImplementedException(); }
  989. }
  990. [DbLinqToDo]
  991. public override bool IsVersion
  992. {
  993. get { throw new NotImplementedException(); }
  994. }
  995. [DbLinqToDo]
  996. public override MethodInfo LoadMethod
  997. {
  998. get
  999. {
  1000. throw new NotImplementedException();
  1001. }
  1002. }
  1003. public override string MappedName { get { return a.Member; } }
  1004. public override string Name { get { return a.Name; } }
  1005. public override System.Data.Linq.Mapping.UpdateCheck UpdateCheck
  1006. {
  1007. get
  1008. {
  1009. throw new NotImplementedException();
  1010. }
  1011. }
  1012. }
  1013. class XmlMetaAccessor : System.Data.Linq.Mapping.MetaAccessor
  1014. {
  1015. XmlMetaDataMember member;
  1016. MemberInfo member_info;
  1017. public XmlMetaAccessor(XmlMetaDataMember member, MemberInfo memberInfo)
  1018. {
  1019. this.member = member;
  1020. this.member_info = memberInfo;
  1021. }
  1022. public override System.Type Type
  1023. {
  1024. get { return member_info is FieldInfo ? ((FieldInfo)member_info).FieldType : ((PropertyInfo)member_info).PropertyType; }
  1025. }
  1026. [DbLinqToDo]
  1027. public override object GetBoxedValue(object instance)
  1028. {
  1029. throw new NotImplementedException();
  1030. }
  1031. [DbLinqToDo]
  1032. public override void SetBoxedValue(ref object instance, object value)
  1033. {
  1034. throw new NotImplementedException();
  1035. }
  1036. }
  1037. class XmlMetaFunction : System.Data.Linq.Mapping.MetaFunction
  1038. {
  1039. XmlMetaModel model;
  1040. DbmlFunction f;
  1041. MethodInfo method;
  1042. ReadOnlyCollection<System.Data.Linq.Mapping.MetaParameter> parameters;
  1043. ReadOnlyCollection<System.Data.Linq.Mapping.MetaType> result_types;
  1044. System.Data.Linq.Mapping.MetaParameter return_param;
  1045. public XmlMetaFunction(XmlMetaModel model, DbmlFunction function)
  1046. {
  1047. this.model = model;
  1048. this.f = function;
  1049. method = model.ContextType.GetMethod(function.Method);
  1050. return_param = new XmlMetaParameter(function.Return.DbType, String.Empty, method.ReturnParameter);
  1051. }
  1052. public override bool HasMultipleResults { get { return f.ElementTypes.Count > 0; } }
  1053. public override bool IsComposable { get { return f.IsComposable; } }
  1054. public override string MappedName { get { return f.Name; } }
  1055. public override MethodInfo Method { get { return method; } }
  1056. public override System.Data.Linq.Mapping.MetaModel Model { get { return model; } }
  1057. public override string Name { get { return f.Name; } }
  1058. public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaParameter> Parameters
  1059. {
  1060. get
  1061. {
  1062. if (parameters == null)
  1063. {
  1064. var l = new List<System.Data.Linq.Mapping.MetaParameter>();
  1065. int i = 0;
  1066. ParameterInfo[] mparams = method.GetParameters();
  1067. foreach (var p in f.Parameters)
  1068. l.Add(new XmlMetaParameter(p, mparams[i++]));
  1069. parameters = new ReadOnlyCollection<System.Data.Linq.Mapping.MetaParameter>(l);
  1070. }
  1071. return parameters;
  1072. }
  1073. }
  1074. public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaType> ResultRowTypes
  1075. {
  1076. get
  1077. {
  1078. if (result_types == null)
  1079. {
  1080. var l = new List<System.Data.Linq.Mapping.MetaType>();
  1081. foreach (var p in f.ElementTypes)
  1082. l.Add(model.GetMetaType(model.GetTypeFromName(p.Name)))

Large files files are truncated, but you can click here to view the full file