SqliteExtensions.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using MediaBrowser.Model.IO;
  5. using MediaBrowser.Model.Serialization;
  6. using SQLitePCL.pretty;
  7. using System.IO;
  8. namespace Emby.Server.Implementations.Data
  9. {
  10. public static class SqliteExtensions
  11. {
  12. public static void RunQueries(this SQLiteDatabaseConnection connection, string[] queries)
  13. {
  14. if (queries == null)
  15. {
  16. throw new ArgumentNullException("queries");
  17. }
  18. connection.RunInTransaction(conn =>
  19. {
  20. //foreach (var query in queries)
  21. //{
  22. // conn.Execute(query);
  23. //}
  24. conn.ExecuteAll(string.Join(";", queries));
  25. });
  26. }
  27. public static byte[] ToGuidBlob(this string str)
  28. {
  29. return ToGuidBlob(new Guid(str));
  30. }
  31. public static byte[] ToGuidBlob(this Guid guid)
  32. {
  33. return guid.ToByteArray();
  34. }
  35. public static Guid ReadGuidFromBlob(this IResultSetValue result)
  36. {
  37. return new Guid(result.ToBlob());
  38. }
  39. public static string ToDateTimeParamValue(this DateTime dateValue)
  40. {
  41. var kind = DateTimeKind.Utc;
  42. return (dateValue.Kind == DateTimeKind.Unspecified)
  43. ? DateTime.SpecifyKind(dateValue, kind).ToString(
  44. GetDateTimeKindFormat(kind),
  45. CultureInfo.InvariantCulture)
  46. : dateValue.ToString(
  47. GetDateTimeKindFormat(dateValue.Kind),
  48. CultureInfo.InvariantCulture);
  49. }
  50. private static string GetDateTimeKindFormat(
  51. DateTimeKind kind)
  52. {
  53. return (kind == DateTimeKind.Utc) ? _datetimeFormatUtc : _datetimeFormatLocal;
  54. }
  55. /// <summary>
  56. /// An array of ISO-8601 DateTime formats that we support parsing.
  57. /// </summary>
  58. private static string[] _datetimeFormats = new string[] {
  59. "THHmmssK",
  60. "THHmmK",
  61. "HH:mm:ss.FFFFFFFK",
  62. "HH:mm:ssK",
  63. "HH:mmK",
  64. "yyyy-MM-dd HH:mm:ss.FFFFFFFK", /* NOTE: UTC default (5). */
  65. "yyyy-MM-dd HH:mm:ssK",
  66. "yyyy-MM-dd HH:mmK",
  67. "yyyy-MM-ddTHH:mm:ss.FFFFFFFK",
  68. "yyyy-MM-ddTHH:mmK",
  69. "yyyy-MM-ddTHH:mm:ssK",
  70. "yyyyMMddHHmmssK",
  71. "yyyyMMddHHmmK",
  72. "yyyyMMddTHHmmssFFFFFFFK",
  73. "THHmmss",
  74. "THHmm",
  75. "HH:mm:ss.FFFFFFF",
  76. "HH:mm:ss",
  77. "HH:mm",
  78. "yyyy-MM-dd HH:mm:ss.FFFFFFF", /* NOTE: Non-UTC default (19). */
  79. "yyyy-MM-dd HH:mm:ss",
  80. "yyyy-MM-dd HH:mm",
  81. "yyyy-MM-ddTHH:mm:ss.FFFFFFF",
  82. "yyyy-MM-ddTHH:mm",
  83. "yyyy-MM-ddTHH:mm:ss",
  84. "yyyyMMddHHmmss",
  85. "yyyyMMddHHmm",
  86. "yyyyMMddTHHmmssFFFFFFF",
  87. "yyyy-MM-dd",
  88. "yyyyMMdd",
  89. "yy-MM-dd"
  90. };
  91. private static string _datetimeFormatUtc = _datetimeFormats[5];
  92. private static string _datetimeFormatLocal = _datetimeFormats[19];
  93. public static DateTime ReadDateTime(this IResultSetValue result)
  94. {
  95. var dateText = result.ToString();
  96. return DateTime.ParseExact(
  97. dateText, _datetimeFormats,
  98. DateTimeFormatInfo.InvariantInfo,
  99. DateTimeStyles.None).ToUniversalTime();
  100. }
  101. public static DateTime? TryReadDateTime(this IResultSetValue result)
  102. {
  103. var dateText = result.ToString();
  104. DateTime dateTimeResult;
  105. if (DateTime.TryParseExact(dateText, _datetimeFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out dateTimeResult))
  106. {
  107. return dateTimeResult.ToUniversalTime();
  108. }
  109. return null;
  110. }
  111. /// <summary>
  112. /// Serializes to bytes.
  113. /// </summary>
  114. /// <returns>System.Byte[][].</returns>
  115. /// <exception cref="System.ArgumentNullException">obj</exception>
  116. public static byte[] SerializeToBytes(this IJsonSerializer json, object obj)
  117. {
  118. if (obj == null)
  119. {
  120. throw new ArgumentNullException("obj");
  121. }
  122. using (var stream = new MemoryStream())
  123. {
  124. json.SerializeToStream(obj, stream);
  125. return stream.ToArray();
  126. }
  127. }
  128. public static void Attach(ManagedConnection db, string path, string alias)
  129. {
  130. var commandText = string.Format("attach @path as {0};", alias);
  131. using (var statement = db.PrepareStatement(commandText))
  132. {
  133. statement.TryBind("@path", path);
  134. statement.MoveNext();
  135. }
  136. }
  137. public static bool IsDBNull(this IReadOnlyList<IResultSetValue> result, int index)
  138. {
  139. return result[index].SQLiteType == SQLiteType.Null;
  140. }
  141. public static string GetString(this IReadOnlyList<IResultSetValue> result, int index)
  142. {
  143. return result[index].ToString();
  144. }
  145. public static bool GetBoolean(this IReadOnlyList<IResultSetValue> result, int index)
  146. {
  147. return result[index].ToBool();
  148. }
  149. public static int GetInt32(this IReadOnlyList<IResultSetValue> result, int index)
  150. {
  151. return result[index].ToInt();
  152. }
  153. public static long GetInt64(this IReadOnlyList<IResultSetValue> result, int index)
  154. {
  155. return result[index].ToInt64();
  156. }
  157. public static float GetFloat(this IReadOnlyList<IResultSetValue> result, int index)
  158. {
  159. return result[index].ToFloat();
  160. }
  161. public static Guid GetGuid(this IReadOnlyList<IResultSetValue> result, int index)
  162. {
  163. return result[index].ReadGuidFromBlob();
  164. }
  165. private static void CheckName(string name)
  166. {
  167. #if DEBUG
  168. //if (!name.IndexOf("@", StringComparison.OrdinalIgnoreCase) != 0)
  169. {
  170. throw new Exception("Invalid param name: " + name);
  171. }
  172. #endif
  173. }
  174. public static void TryBind(this IStatement statement, string name, double value)
  175. {
  176. IBindParameter bindParam;
  177. if (statement.BindParameters.TryGetValue(name, out bindParam))
  178. {
  179. bindParam.Bind(value);
  180. }
  181. else
  182. {
  183. CheckName(name);
  184. }
  185. }
  186. public static void TryBind(this IStatement statement, string name, string value)
  187. {
  188. IBindParameter bindParam;
  189. if (statement.BindParameters.TryGetValue(name, out bindParam))
  190. {
  191. if (value == null)
  192. {
  193. bindParam.BindNull();
  194. }
  195. else
  196. {
  197. bindParam.Bind(value);
  198. }
  199. }
  200. else
  201. {
  202. CheckName(name);
  203. }
  204. }
  205. public static void TryBind(this IStatement statement, string name, bool value)
  206. {
  207. IBindParameter bindParam;
  208. if (statement.BindParameters.TryGetValue(name, out bindParam))
  209. {
  210. bindParam.Bind(value);
  211. }
  212. else
  213. {
  214. CheckName(name);
  215. }
  216. }
  217. public static void TryBind(this IStatement statement, string name, float value)
  218. {
  219. IBindParameter bindParam;
  220. if (statement.BindParameters.TryGetValue(name, out bindParam))
  221. {
  222. bindParam.Bind(value);
  223. }
  224. else
  225. {
  226. CheckName(name);
  227. }
  228. }
  229. public static void TryBind(this IStatement statement, string name, int value)
  230. {
  231. IBindParameter bindParam;
  232. if (statement.BindParameters.TryGetValue(name, out bindParam))
  233. {
  234. bindParam.Bind(value);
  235. }
  236. else
  237. {
  238. CheckName(name);
  239. }
  240. }
  241. public static void TryBind(this IStatement statement, string name, Guid value)
  242. {
  243. IBindParameter bindParam;
  244. if (statement.BindParameters.TryGetValue(name, out bindParam))
  245. {
  246. bindParam.Bind(value.ToGuidBlob());
  247. }
  248. else
  249. {
  250. CheckName(name);
  251. }
  252. }
  253. public static void TryBind(this IStatement statement, string name, DateTime value)
  254. {
  255. IBindParameter bindParam;
  256. if (statement.BindParameters.TryGetValue(name, out bindParam))
  257. {
  258. bindParam.Bind(value.ToDateTimeParamValue());
  259. }
  260. else
  261. {
  262. CheckName(name);
  263. }
  264. }
  265. public static void TryBind(this IStatement statement, string name, long value)
  266. {
  267. IBindParameter bindParam;
  268. if (statement.BindParameters.TryGetValue(name, out bindParam))
  269. {
  270. bindParam.Bind(value);
  271. }
  272. else
  273. {
  274. CheckName(name);
  275. }
  276. }
  277. public static void TryBind(this IStatement statement, string name, byte[] value)
  278. {
  279. IBindParameter bindParam;
  280. if (statement.BindParameters.TryGetValue(name, out bindParam))
  281. {
  282. bindParam.Bind(value);
  283. }
  284. else
  285. {
  286. CheckName(name);
  287. }
  288. }
  289. public static void TryBindNull(this IStatement statement, string name)
  290. {
  291. IBindParameter bindParam;
  292. if (statement.BindParameters.TryGetValue(name, out bindParam))
  293. {
  294. bindParam.BindNull();
  295. }
  296. else
  297. {
  298. CheckName(name);
  299. }
  300. }
  301. public static void TryBind(this IStatement statement, string name, DateTime? value)
  302. {
  303. if (value.HasValue)
  304. {
  305. TryBind(statement, name, value.Value);
  306. }
  307. else
  308. {
  309. TryBindNull(statement, name);
  310. }
  311. }
  312. public static void TryBind(this IStatement statement, string name, Guid? value)
  313. {
  314. if (value.HasValue)
  315. {
  316. TryBind(statement, name, value.Value);
  317. }
  318. else
  319. {
  320. TryBindNull(statement, name);
  321. }
  322. }
  323. public static void TryBind(this IStatement statement, string name, double? value)
  324. {
  325. if (value.HasValue)
  326. {
  327. TryBind(statement, name, value.Value);
  328. }
  329. else
  330. {
  331. TryBindNull(statement, name);
  332. }
  333. }
  334. public static void TryBind(this IStatement statement, string name, int? value)
  335. {
  336. if (value.HasValue)
  337. {
  338. TryBind(statement, name, value.Value);
  339. }
  340. else
  341. {
  342. TryBindNull(statement, name);
  343. }
  344. }
  345. public static void TryBind(this IStatement statement, string name, float? value)
  346. {
  347. if (value.HasValue)
  348. {
  349. TryBind(statement, name, value.Value);
  350. }
  351. else
  352. {
  353. TryBindNull(statement, name);
  354. }
  355. }
  356. public static void TryBind(this IStatement statement, string name, bool? value)
  357. {
  358. if (value.HasValue)
  359. {
  360. TryBind(statement, name, value.Value);
  361. }
  362. else
  363. {
  364. TryBindNull(statement, name);
  365. }
  366. }
  367. public static IEnumerable<IReadOnlyList<IResultSetValue>> ExecuteQuery(
  368. this IStatement This)
  369. {
  370. while (This.MoveNext())
  371. {
  372. yield return This.Current;
  373. }
  374. }
  375. }
  376. }