PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/Source/facebook.Linq/Linq/FacebookDataReader.cs

https://bitbucket.org/assaframan/facebooklinq
C# | 403 lines | 345 code | 53 blank | 5 comment | 50 complexity | 2697aefe881e5aa56a423f90a605b499 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Data;
  6. using System.Xml;
  7. using facebook.Utility;
  8. namespace facebook.Linq
  9. {
  10. internal class FacebookDataReader : IDataReader
  11. {
  12. public FacebookDataReader(string xml)
  13. {
  14. Xml = xml;
  15. doc = new XmlDocument();
  16. doc.LoadXml(xml);
  17. RootNode = doc.ChildNodes[1];
  18. if (RootNode.Name == "error_response")
  19. {
  20. throw ParseFacebookException();
  21. }
  22. if (!RootNode.Name.EndsWith("_response"))
  23. {
  24. throw new Exception("Unknown response XML");
  25. }
  26. }
  27. public int Count
  28. {
  29. get
  30. {
  31. return RootNode.ChildNodes.Count;
  32. }
  33. }
  34. private FacebookException ParseFacebookException()
  35. {
  36. string errorXml = "";
  37. string message = "";
  38. string requestXml = "";
  39. int errorCode = 0;
  40. for (var n = RootNode.FirstChild; n != null; n = n.NextSibling)
  41. {
  42. switch (n.Name)
  43. {
  44. case "error_code":
  45. errorCode = Int32.Parse(n.InnerText);
  46. break;
  47. case "error_xml":
  48. errorXml = n.InnerXml;
  49. break;
  50. case "error_msg":
  51. message = n.InnerText;
  52. break;
  53. case "request_args":
  54. requestXml = n.InnerXml;
  55. break;
  56. default:
  57. break;
  58. }
  59. }
  60. return new FacebookException(errorXml, errorCode, message, requestXml);
  61. }
  62. string Xml;
  63. XmlReader Reader;
  64. XmlDocument doc;
  65. XmlNode CurrentNode;
  66. XmlNode RootNode;
  67. #region IDataReader Members
  68. public void Close()
  69. {
  70. RootNode = null;
  71. CurrentNode = null;
  72. doc = null;
  73. //Reader.Close();
  74. //Reader = null;
  75. Xml = null;
  76. }
  77. public int Depth
  78. {
  79. get { throw new NotImplementedException(); }
  80. }
  81. public DataTable GetSchemaTable()
  82. {
  83. throw new NotImplementedException();
  84. }
  85. public bool IsClosed
  86. {
  87. get { return Reader != null; }
  88. }
  89. public bool NextResult()
  90. {
  91. if (CurrentNode == null)
  92. {
  93. if (RootNode != null)
  94. CurrentNode = RootNode.FirstChild;
  95. }
  96. else CurrentNode = CurrentNode.NextSibling;
  97. return CurrentNode != null;
  98. }
  99. public bool Read()
  100. {
  101. return NextResult();
  102. /*if (CurrentNode == null)
  103. return false;
  104. return (CurrentNode = CurrentNode.NextSibling) != null;*/
  105. }
  106. public int RecordsAffected
  107. {
  108. get { return 0; }
  109. }
  110. #endregion
  111. #region IDisposable Members
  112. public void Dispose()
  113. {
  114. Reader = null;
  115. Xml = null;
  116. }
  117. #endregion
  118. #region IDataRecord Members
  119. public int FieldCount
  120. {
  121. get { return 0; }
  122. }
  123. public bool GetBoolean(int i)
  124. {
  125. throw new NotImplementedException();
  126. }
  127. public byte GetByte(int i)
  128. {
  129. throw new NotImplementedException();
  130. }
  131. public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
  132. {
  133. throw new NotImplementedException();
  134. }
  135. public char GetChar(int i)
  136. {
  137. throw new NotImplementedException();
  138. }
  139. public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
  140. {
  141. throw new NotImplementedException();
  142. }
  143. public IDataReader GetData(int i)
  144. {
  145. throw new NotImplementedException();
  146. }
  147. public string GetDataTypeName(int i)
  148. {
  149. throw new NotImplementedException();
  150. }
  151. public DateTime GetDateTime(int i)
  152. {
  153. throw new NotImplementedException();
  154. }
  155. public decimal GetDecimal(int i)
  156. {
  157. throw new NotImplementedException();
  158. }
  159. public double GetDouble(int i)
  160. {
  161. throw new NotImplementedException();
  162. }
  163. public Type GetFieldType(int i)
  164. {
  165. throw new NotImplementedException();
  166. }
  167. public float GetFloat(int i)
  168. {
  169. throw new NotImplementedException();
  170. }
  171. public Guid GetGuid(int i)
  172. {
  173. throw new NotImplementedException();
  174. }
  175. public short GetInt16(int i)
  176. {
  177. throw new NotImplementedException();
  178. }
  179. public int GetInt32(int i)
  180. {
  181. throw new NotImplementedException();
  182. }
  183. public long GetInt64(int i)
  184. {
  185. throw new NotImplementedException();
  186. }
  187. public string GetName(int i)
  188. {
  189. throw new NotImplementedException();
  190. }
  191. public int GetOrdinal(string name)
  192. {
  193. throw new NotImplementedException();
  194. }
  195. public string GetString(int i)
  196. {
  197. throw new NotImplementedException();
  198. }
  199. public object GetValue(int i)
  200. {
  201. throw new NotImplementedException();
  202. }
  203. public int GetValues(object[] values)
  204. {
  205. throw new NotImplementedException();
  206. }
  207. public bool IsDBNull(int i)
  208. {
  209. throw new NotImplementedException();
  210. }
  211. public object this[string name]
  212. {
  213. get
  214. {
  215. for (var cn = CurrentNode.FirstChild; cn != null; cn = cn.NextSibling)
  216. {
  217. if (cn.Name == name)
  218. {
  219. return ConvertPropertyFromXml(CurrentNode.Name, name, cn.InnerText);
  220. }
  221. }
  222. return null;
  223. }
  224. }
  225. public object this[int i]
  226. {
  227. get { throw new NotImplementedException(); }
  228. }
  229. #endregion
  230. object ConvertPropertyFromXml(string objectName, string propertyName, string value)
  231. {
  232. if (objectName.StartsWith("app."))
  233. objectName = objectName.Substring(4);
  234. var td = KnownTypeData.GetTypeDataByTableName(objectName);
  235. if (td == null)
  236. return ConvertNativePropertyFromXml(objectName, propertyName, value);
  237. var pd = td.GetPropertyByFieldName(propertyName);
  238. var propType = pd.PropertyInfo.PropertyType;
  239. var uType = Nullable.GetUnderlyingType(propType);
  240. if (uType!=null && uType!=propType) //is nullable
  241. {
  242. if (value.IsNullOrEmpty())
  243. return null;
  244. propType = uType;
  245. }
  246. if (propType == typeof(Int64))
  247. {
  248. return ParseLong(value);
  249. }
  250. else if (propType == typeof(Decimal))
  251. {
  252. return ParseDecimal(value);
  253. }
  254. else if (propType == typeof(string))
  255. {
  256. return value;
  257. }
  258. else if (propType == typeof(bool))
  259. {
  260. return ParseBool(value);
  261. }
  262. else if (propType == typeof(DateTime))
  263. {
  264. return ParseFacebookDateTime(value);
  265. }
  266. else if (propType.IsEnum)
  267. {
  268. return ParseFacebookEnum(propType, value);
  269. }
  270. else
  271. throw new NotImplementedException();
  272. }
  273. private object ParseFacebookEnum(Type propType, string value)
  274. {
  275. if (value.IsNullOrEmpty())
  276. return ReflectionHelper.GetDefaultValue(propType);
  277. value = value.Split('_').StringConcat("");
  278. return Enum.Parse(propType, value, true);
  279. }
  280. private static long ParseLong(string value)
  281. {
  282. if (value.IsNullOrEmpty())
  283. return 0;
  284. return Int64.Parse(value);
  285. }
  286. private static decimal ParseDecimal(string value)
  287. {
  288. if (value.IsNullOrEmpty())
  289. return 0;
  290. return Decimal.Parse(value);
  291. }
  292. private object ConvertNativePropertyFromXml(string objectName, string propertyName, string value)
  293. {
  294. switch (objectName)
  295. {
  296. case "friend_info":
  297. switch (propertyName)
  298. {
  299. case "uid1":
  300. case "uid2":
  301. return ParseLong(value);
  302. }
  303. break;
  304. }
  305. throw new NotImplementedException();
  306. }
  307. private TypeData GetFacebookExtendedTypeData(string objectName)
  308. {
  309. switch (objectName)
  310. {
  311. case "friend_info":
  312. {
  313. return new TypeData { FqlTableName = "friend_info", Properties = new Dictionary<string, PropertyData> { { "uid1", new PropertyData { FqlFieldName = "uid1", IsLinqIdentity = false, PropertyInfo = null } } } };
  314. }
  315. default:
  316. throw new NotImplementedException();
  317. }
  318. }
  319. public static bool ParseBool(string value)
  320. {
  321. switch (value.ToLower())
  322. {
  323. case "true":
  324. case "yes":
  325. return true;
  326. case "false":
  327. case "no":
  328. return false;
  329. case "0":
  330. return false;
  331. default:
  332. {
  333. int n = 0;
  334. if (Int32.TryParse(value, out n))
  335. return n != 0;
  336. return false;
  337. }
  338. }
  339. }
  340. public static DateTime ParseFacebookDateTime(string s)
  341. {
  342. if (s.IsNullOrEmpty())
  343. return DateTime.MinValue;
  344. int i = 0;
  345. if (Int32.TryParse(s, out i))
  346. return DateHelper.ConvertDoubleToDate(Convert.ToDouble(i));
  347. return DateTime.Parse(s);
  348. }
  349. }
  350. }