PageRenderTime 56ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/Aurora/Framework/Services/IApplicationPlugin.cs

https://bitbucket.org/VirtualReality/aurora-sim
C# | 745 lines | 452 code | 102 blank | 191 comment | 27 complexity | 9f2188b53ca0e15027ae4ed7eb62c327 MD5 | raw file
  1. /*
  2. * Copyright (c) Contributors, http://aurora-sim.org/, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the Aurora-Sim Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System.Linq;
  28. using System.Collections.Generic;
  29. using System.Data;
  30. using Nini.Config;
  31. using Aurora.Framework;
  32. namespace Aurora.Framework
  33. {
  34. /// <summary>
  35. /// Aurora-Sim Application Plugin framework interface
  36. /// </summary>
  37. public interface IApplicationPlugin
  38. {
  39. /// <summary>
  40. /// Returns the plugin name
  41. /// </summary>
  42. /// <returns></returns>
  43. string Name { get; }
  44. /// <summary>
  45. /// Called before any other calls are made, before the console is setup, and before the HTTP server is ready
  46. /// </summary>
  47. /// <param name="simBase"></param>
  48. void PreStartup(ISimulationBase simBase);
  49. /// <summary>
  50. /// Initialize the Plugin
  51. /// </summary>
  52. /// <param name = "openSim">The Application instance</param>
  53. void Initialize(ISimulationBase simBase);
  54. /// <summary>
  55. /// Called when the application initialization is completed
  56. /// </summary>
  57. void PostInitialise();
  58. /// <summary>
  59. /// Called when the application loading is completed
  60. /// </summary>
  61. void Start();
  62. /// <summary>
  63. /// Called when the application loading is completed
  64. /// </summary>
  65. void PostStart();
  66. /// <summary>
  67. /// Close out the module
  68. /// </summary>
  69. void Close();
  70. /// <summary>
  71. /// The configuration has changed, make sure that everything is updated with the new info
  72. /// </summary>
  73. /// <param name = "m_config"></param>
  74. void ReloadConfiguration(IConfigSource m_config);
  75. }
  76. }
  77. namespace Aurora.Framework
  78. {
  79. public interface IGenericData
  80. {
  81. #region UPDATE
  82. /// <summary>
  83. /// UPDATE table SET values[i].key = values[i].value {magic happens with queryFilter here} [LIMIT start[, count]]
  84. /// </summary>
  85. /// <param name="table">table to update</param>
  86. /// <param name="values">dictionary of table fields and new values</param>
  87. /// <param name="incrementValues">dictionary of table fields and integer to increment by (use negative ints to decrement)</param>
  88. /// <param name="queryFilter">filter to control which rows get updated</param>
  89. /// <param name="start">LIMIT start or LIMIT start, count</param>
  90. /// <param name="count">LIMIT start, count</param>
  91. /// <returns></returns>
  92. bool Update(string table, Dictionary<string, object> values, Dictionary<string, int> incrementValues, QueryFilter queryFilter, uint? start, uint? count);
  93. #endregion
  94. #region SELECT
  95. /// <summary>
  96. /// SELECT string.join(", ", wantedValue) FROM table {magic happens with queryFilter here} {magic happens with sort here} [LIMIT start[, count]]
  97. /// </summary>
  98. /// <param name="wantedValue"></param>
  99. /// <param name="table"></param>
  100. /// <param name="queryFilter"></param>
  101. /// <param name="sort"></param>
  102. /// <param name="start"></param>
  103. /// <param name="count"></param>
  104. /// <returns></returns>
  105. List<string> Query(string[] wantedValue, string table, QueryFilter queryFilter, Dictionary<string, bool> sort, uint? start, uint? count);
  106. /// <summary>
  107. /// select 'wantedValue' from 'table' 'whereClause'
  108. /// </summary>
  109. List<string> QueryFullData(string whereClause, string table, string wantedValue);
  110. /// <summary>
  111. /// select 'wantedValue' from 'table' 'whereClause'
  112. /// </summary>
  113. DataReaderConnection QueryData(string whereClause, string table, string wantedValue);
  114. /// <summary>
  115. /// select 'wantedValue' from 'table' where 'keyRow' = 'keyValue'
  116. /// This gives the row names as well as the values
  117. /// </summary>
  118. Dictionary<string, List<string>> QueryNames(string[] keyRow, object[] keyValue, string table, string wantedValue);
  119. #region JOIN
  120. List<string> Query(string[] wantedValue, QueryTables tables, QueryFilter queryFilter, Dictionary<string, bool> sort, uint? start, uint? count);
  121. Dictionary<string, List<string>> QueryNames(string[] keyRow, object[] keyValue, QueryTables tables, string wantedValue);
  122. DataReaderConnection QueryData(string whereClause, QueryTables tables, string wantedValue);
  123. List<string> QueryFullData(string whereClause, QueryTables tables, string wantedValue);
  124. #endregion
  125. #endregion
  126. #region INSERT
  127. /// <summary>
  128. /// insert into 'table' values ('values')
  129. /// </summary>
  130. bool Insert(string table, object[] values);
  131. /// <summary>
  132. /// INSERT INTO table (row.Keys) VALUES(row.Values)
  133. /// </summary>
  134. /// <param name="table"></param>
  135. /// <param name="row"></param>
  136. /// <returns></returns>
  137. bool Insert(string table, Dictionary<string, object> row);
  138. /// <summary>
  139. /// Runs multiple Insert(table, value) calls in one run
  140. /// </summary>
  141. /// <param name="table"></param>
  142. /// <param name="values"></param>
  143. /// <returns></returns>
  144. bool InsertMultiple(string table, List<object[]> values);
  145. /// <summary>
  146. /// Inserts a row into the database
  147. /// insert into 'table' values ('values') ON DUPLICATE KEY UPDATE 'updateKey' = 'updateValue'
  148. /// </summary>
  149. /// <param name = "table">table name</param>
  150. /// <param name = "values">All values to be inserted in the correct table order</param>
  151. /// <param name = "updateKey">If a row is already existing, update this key</param>
  152. /// <param name = "updateValue">If a row is already existing, update this value</param>
  153. /// <returns></returns>
  154. bool Insert(string table, object[] values, string updateKey, object updateValue);
  155. /// <summary>
  156. /// Inserts rows selected from another table.
  157. /// </summary>
  158. /// <param name="tableA"></param>
  159. /// <param name="fieldsA"></param>
  160. /// <param name="tableB"></param>
  161. /// <param name="valuesB"></param>
  162. /// <returns></returns>
  163. bool InsertSelect(string tableA, string[] fieldsA, string tableB, string[] valuesB);
  164. #endregion
  165. #region REPLACE INTO
  166. /// <summary>
  167. /// REPLACE INTO table (row.Keys) VALUES(row.Values)
  168. /// </summary>
  169. /// <param name="table">table name</param>
  170. /// <param name="row"></param>
  171. /// <returns></returns>
  172. bool Replace(string table, Dictionary<string, object> row);
  173. #endregion
  174. #region DELETE
  175. /// <summary>
  176. /// delete from 'table' where 'key' < now()
  177. /// </summary>
  178. /// <param name = "table"></param>
  179. /// <param name = "keys"></param>
  180. /// <param name = "values"></param>
  181. /// <returns></returns>
  182. bool DeleteByTime(string table, string keys);
  183. /// <summary>
  184. /// DELETE FROM table WHERE {magic happens with queryFilter here}
  185. /// </summary>
  186. /// <param name="table">table name</param>
  187. /// <param name="queryFilter">filter for determining which rows to delete</param>
  188. /// <returns></returns>
  189. bool Delete(string table, QueryFilter queryFilter);
  190. #endregion
  191. /// <summary>
  192. /// Connects to the database and then performs migrations
  193. /// </summary>
  194. /// <param name = "connectionString"></param>
  195. void ConnectToDatabase(string connectionString, string migrationName, bool validateTables);
  196. /// <summary>
  197. /// Makes a copy of the IGenericData plugin
  198. /// </summary>
  199. /// <returns></returns>
  200. IGenericData Copy();
  201. /// <summary>
  202. /// Close the given database connection
  203. /// </summary>
  204. void CloseDatabase(DataReaderConnection connection);
  205. /// <summary>
  206. /// in the sql the strings will return joined fields
  207. /// </summary>
  208. /// <param name = "toConCat"></param>
  209. /// <returns></returns>
  210. string ConCat(string[] toConCat);
  211. }
  212. public class DataReaderConnection : System.IDisposable
  213. {
  214. public IDataReader DataReader;
  215. public object Connection;
  216. public void Dispose()
  217. {
  218. DataReader.Dispose();
  219. }
  220. }
  221. public class QueryFilter
  222. {
  223. public Dictionary<string, object> andFilters = new Dictionary<string, object>();
  224. public Dictionary<string, object> orFilters = new Dictionary<string, object>();
  225. public Dictionary<string, List<object>> orMultiFilters = new Dictionary<string, List<object>>();
  226. public Dictionary<string, string> andLikeFilters = new Dictionary<string, string>();
  227. public Dictionary<string, string> orLikeFilters = new Dictionary<string, string>();
  228. public Dictionary<string, List<string>> orLikeMultiFilters = new Dictionary<string, List<string>>();
  229. public Dictionary<string, uint> andBitfieldAndFilters = new Dictionary<string, uint>();
  230. public Dictionary<string, uint> orBitfieldAndFilters = new Dictionary<string, uint>();
  231. public Dictionary<string, uint> andBitfieldNandFilters = new Dictionary<string, uint>();
  232. public Dictionary<string, object> andGreaterThanFilters = new Dictionary<string, object>();
  233. public Dictionary<string, object> orGreaterThanFilters = new Dictionary<string, object>();
  234. public Dictionary<string, object> andGreaterThanEqFilters = new Dictionary<string, object>();
  235. public Dictionary<string, object> orGreaterThanEqFilters = new Dictionary<string, object>();
  236. public Dictionary<string, object> andLessThanFilters = new Dictionary<string, object>();
  237. public Dictionary<string, object> orLessThanFilters = new Dictionary<string, object>();
  238. public Dictionary<string, object> andLessThanEqFilters = new Dictionary<string, object>();
  239. public Dictionary<string, object> andNotFilters = new Dictionary<string, object>();
  240. public List<string> andIsNullFilters = new List<string>();
  241. public List<string> andIsNotNullFilters = new List<string>();
  242. // public List<QueryFilter> subFilters = new List<QueryFilter>();
  243. public uint Count
  244. {
  245. get
  246. {
  247. uint total = (uint)(
  248. andFilters.Count +
  249. orFilters.Count +
  250. orMultiFilters.Count +
  251. andLikeFilters.Count +
  252. orLikeFilters.Count +
  253. orLikeMultiFilters.Count +
  254. andBitfieldAndFilters.Count +
  255. orBitfieldAndFilters.Count +
  256. andBitfieldNandFilters.Count +
  257. andGreaterThanFilters.Count +
  258. orGreaterThanFilters.Count +
  259. andGreaterThanEqFilters.Count +
  260. orGreaterThanEqFilters.Count +
  261. andLessThanFilters.Count +
  262. orLessThanFilters.Count +
  263. andLessThanEqFilters.Count +
  264. andNotFilters.Count +
  265. andIsNullFilters.Count +
  266. andIsNotNullFilters.Count
  267. );
  268. // subFilters.ForEach(delegate(QueryFilter filter)
  269. // {
  270. // total += filter.Count;
  271. // });
  272. return total;
  273. }
  274. }
  275. private static string preparedKey(string key)
  276. {
  277. return key.Replace("`", "").Replace("(", "_").Replace(")", "").Replace(" ", "_").Replace("-", "minus").Replace("+", "add").Replace("/", "divide").Replace("*", "multiply").Replace("'", "").Replace(",", "").Replace(".","alias");
  278. }
  279. public string ToSQL(char prepared, out Dictionary<string, object> ps)
  280. {
  281. ps = new Dictionary<string, object>();
  282. Dictionary<string, object>[] pss = { ps };
  283. string query = "";
  284. List<string> parts;
  285. uint i = 0;
  286. bool had = false;
  287. if (Count > 0)
  288. {
  289. query += "(";
  290. #region equality
  291. parts = new List<string>();
  292. foreach (KeyValuePair<string, object> where in andFilters)
  293. {
  294. string key = prepared.ToString() + "where_AND_" + (++i) + preparedKey(where.Key);
  295. ps[key] = where.Value;
  296. parts.Add(string.Format("{0} = {1}", where.Key, key));
  297. }
  298. if (parts.Count > 0)
  299. {
  300. query += " (" + string.Join(" AND ", parts.ToArray()) + ")";
  301. had = true;
  302. }
  303. parts = new List<string>();
  304. foreach (KeyValuePair<string, object> where in orFilters)
  305. {
  306. string key = prepared.ToString() + "where_OR_" + (++i) + preparedKey(where.Key);
  307. ps[key] = where.Value;
  308. parts.Add(string.Format("{0} = {1}", where.Key, key));
  309. }
  310. if (parts.Count > 0)
  311. {
  312. query += (had ? " AND" : string.Empty) + " (" + string.Join(" OR ", parts.ToArray()) + ")";
  313. had = true;
  314. }
  315. parts = new List<string>();
  316. foreach (KeyValuePair<string, List<object>> where in orMultiFilters)
  317. {
  318. foreach (object value in where.Value)
  319. {
  320. string key = prepared.ToString() + "where_OR_" + (++i) + preparedKey(where.Key);
  321. ps[key] = value;
  322. parts.Add(string.Format("{0} = {1}", where.Key, key));
  323. }
  324. }
  325. if (parts.Count > 0)
  326. {
  327. query += (had ? " AND" : string.Empty) + " (" + string.Join(" OR ", parts.ToArray()) + ")";
  328. had = true;
  329. }
  330. parts = new List<string>();
  331. foreach (KeyValuePair<string, object> where in andNotFilters)
  332. {
  333. string key = prepared.ToString() + "where_AND_NOT_" + (++i) + preparedKey(where.Key);
  334. ps[key] = where.Value;
  335. parts.Add(string.Format("{0} != {1}", where.Key, key));
  336. }
  337. if (parts.Count > 0)
  338. {
  339. query += (had ? " AND" : string.Empty) + " (" + string.Join(" AND ", parts.ToArray()) + ")";
  340. had = true;
  341. }
  342. #endregion
  343. #region LIKE
  344. parts = new List<string>();
  345. foreach (KeyValuePair<string, string> where in andLikeFilters)
  346. {
  347. string key = prepared.ToString() + "where_ANDLIKE_" + (++i) + preparedKey(where.Key);
  348. ps[key] = where.Value;
  349. parts.Add(string.Format("{0} LIKE {1}", where.Key, key));
  350. }
  351. if (parts.Count > 0)
  352. {
  353. query += (had ? " AND" : string.Empty) + " (" + string.Join(" AND ", parts.ToArray()) + ")";
  354. had = true;
  355. }
  356. parts = new List<string>();
  357. foreach (KeyValuePair<string, string> where in orLikeFilters)
  358. {
  359. string key = prepared.ToString() + "where_ORLIKE_" + (++i) + preparedKey(where.Key);
  360. ps[key] = where.Value;
  361. parts.Add(string.Format("{0} LIKE {1}", where.Key, key));
  362. }
  363. if (parts.Count > 0)
  364. {
  365. query += (had ? " AND" : string.Empty) + " (" + string.Join(" OR ", parts.ToArray()) + ")";
  366. had = true;
  367. }
  368. parts = new List<string>();
  369. foreach (KeyValuePair<string, List<string>> where in orLikeMultiFilters)
  370. {
  371. foreach (string value in where.Value)
  372. {
  373. string key = prepared.ToString() + "where_ORLIKE_" + (++i) + preparedKey(where.Key);
  374. ps[key] = value;
  375. parts.Add(string.Format("{0} LIKE {1}", where.Key, key));
  376. }
  377. }
  378. if (parts.Count > 0)
  379. {
  380. query += (had ? " AND" : string.Empty) + " (" + string.Join(" OR ", parts.ToArray()) + ")";
  381. had = true;
  382. }
  383. #endregion
  384. #region bitfield &
  385. parts = new List<string>();
  386. foreach (KeyValuePair<string, uint> where in andBitfieldAndFilters)
  387. {
  388. string key = prepared.ToString() + "where_bAND_" + (++i) + preparedKey(where.Key);
  389. ps[key] = where.Value;
  390. parts.Add(string.Format("{0} & {1}", where.Key, key));
  391. }
  392. if (parts.Count > 0)
  393. {
  394. query += (had ? " AND" : string.Empty) + " (" + string.Join(" AND ", parts.ToArray()) + ")";
  395. had = true;
  396. }
  397. parts = new List<string>();
  398. foreach (KeyValuePair<string, uint> where in orBitfieldAndFilters)
  399. {
  400. string key = prepared.ToString() + "where_bOR_" + (++i) + preparedKey(where.Key);
  401. ps[key] = where.Value;
  402. parts.Add(string.Format("{0} & {1}", where.Key, key));
  403. }
  404. if (parts.Count > 0)
  405. {
  406. query += (had ? " AND" : string.Empty) + " (" + string.Join(" OR ", parts.ToArray()) + ")";
  407. had = true;
  408. }
  409. parts = new List<string>();
  410. foreach (KeyValuePair<string, uint> where in andBitfieldNandFilters)
  411. {
  412. string key = prepared.ToString() + "where_bNAND_" + (++i) + preparedKey(where.Key);
  413. ps[key] = where.Value;
  414. parts.Add(string.Format("({0} & {1}) = 0", where.Key, key));
  415. }
  416. if (parts.Count > 0)
  417. {
  418. query += (had ? " AND" : string.Empty) + " (" + string.Join(" AND ", parts.ToArray()) + ")";
  419. had = true;
  420. }
  421. #endregion
  422. #region greater than
  423. parts = new List<string>();
  424. foreach (KeyValuePair<string, object> where in andGreaterThanFilters)
  425. {
  426. string key = prepared.ToString() + "where_gtAND_" + (++i) + preparedKey(where.Key);
  427. ps[key] = float.Parse((where.Value).ToString());
  428. parts.Add(string.Format("{0} > {1}", where.Key, key));
  429. }
  430. if (parts.Count > 0)
  431. {
  432. query += (had ? " AND" : string.Empty) + " (" + string.Join(" AND ", parts.ToArray()) + ")";
  433. had = true;
  434. }
  435. parts = new List<string>();
  436. foreach (KeyValuePair<string, object> where in orGreaterThanFilters)
  437. {
  438. string key = prepared.ToString() + "where_gtOR_" + (++i) + preparedKey(where.Key);
  439. ps[key] = float.Parse((where.Value).ToString());
  440. parts.Add(string.Format("{0} > {1}", where.Key, key));
  441. }
  442. if (parts.Count > 0)
  443. {
  444. query += (had ? " AND" : string.Empty) + " (" + string.Join(" OR ", parts.ToArray()) + ")";
  445. had = true;
  446. }
  447. parts = new List<string>();
  448. foreach (KeyValuePair<string, object> where in andGreaterThanEqFilters)
  449. {
  450. string key = prepared.ToString() + "where_gteqAND_" + (++i) + preparedKey(where.Key);
  451. ps[key] = float.Parse((where.Value).ToString());
  452. parts.Add(string.Format("{0} >= {1}", where.Key, key));
  453. }
  454. if (parts.Count > 0)
  455. {
  456. query += (had ? " AND" : string.Empty) + " (" + string.Join(" AND ", parts.ToArray()) + ")";
  457. had = true;
  458. }
  459. parts = new List<string>();
  460. foreach (KeyValuePair<string, object> where in orGreaterThanEqFilters)
  461. {
  462. string key = prepared.ToString() + "where_gteqOR_" + (++i) + preparedKey(where.Key);
  463. ps[key] = float.Parse((where.Value).ToString());
  464. parts.Add(string.Format("{0} >= {1}", where.Key, key));
  465. }
  466. if (parts.Count > 0)
  467. {
  468. query += (had ? " AND" : string.Empty) + " (" + string.Join(" OR ", parts.ToArray()) + ")";
  469. had = true;
  470. }
  471. #endregion
  472. #region less than
  473. parts = new List<string>();
  474. foreach (KeyValuePair<string, object> where in andLessThanFilters)
  475. {
  476. string key = prepared.ToString() + "where_ltAND_" + (++i) + preparedKey(where.Key);
  477. ps[key] = float.Parse((where.Value).ToString());
  478. parts.Add(string.Format("{0} < {1}", where.Key, key));
  479. }
  480. if (parts.Count > 0)
  481. {
  482. query += (had ? " AND" : string.Empty) + " (" + string.Join(" AND ", parts.ToArray()) + ")";
  483. had = true;
  484. }
  485. parts = new List<string>();
  486. foreach (KeyValuePair<string, object> where in orLessThanFilters)
  487. {
  488. string key = prepared.ToString() + "where_ltOR_" + (++i) + preparedKey(where.Key);
  489. ps[key] = float.Parse((where.Value).ToString());
  490. parts.Add(string.Format("{0} < {1}", where.Key, key));
  491. }
  492. if (parts.Count > 0)
  493. {
  494. query += (had ? " AND" : string.Empty) + " (" + string.Join(" OR ", parts.ToArray()) + ")";
  495. had = true;
  496. }
  497. parts = new List<string>();
  498. foreach (KeyValuePair<string, object> where in andLessThanEqFilters)
  499. {
  500. string key = prepared.ToString() + "where_lteqAND_" + (++i) + preparedKey(where.Key);
  501. ps[key] = float.Parse((where.Value).ToString());
  502. parts.Add(string.Format("{0} <= {1}", where.Key, key));
  503. }
  504. if (parts.Count > 0)
  505. {
  506. query += (had ? " AND" : string.Empty) + " (" + string.Join(" AND ", parts.ToArray()) + ")";
  507. had = true;
  508. }
  509. #endregion
  510. #region NULL
  511. parts = new List<string>();
  512. foreach (string field in andIsNotNullFilters)
  513. {
  514. parts.Add(string.Format("{0} IS NOT NULL", field));
  515. }
  516. if (parts.Count > 0)
  517. {
  518. query += (had ? " AND" : string.Empty) + " (" + string.Join(" AND ", parts.ToArray()) + ")";
  519. had = true;
  520. }
  521. parts = new List<string>();
  522. foreach (string field in andIsNullFilters)
  523. {
  524. parts.Add(string.Format("{0} IS NULL", field));
  525. }
  526. if (parts.Count > 0)
  527. {
  528. query += (had ? " AND" : string.Empty) + " (" + string.Join(" AND ", parts.ToArray()) + ")";
  529. had = true;
  530. }
  531. #endregion
  532. // foreach (QueryFilter subFilter in subFilters)
  533. // {
  534. // Dictionary<string, object> sps;
  535. // query += (had ? " AND" : string.Empty) + subFilter.ToSQL(prepared, out sps, ref i);
  536. // pss[pss.Length] = sps;
  537. // if (subFilter.Count > 0)
  538. // {
  539. // had = true;
  540. // }
  541. // }
  542. query += ")";
  543. }
  544. pss.SelectMany(x => x).ToLookup(x => x.Key, x => x.Value).ToDictionary(x => x.Key, x => x.First());
  545. return query;
  546. }
  547. }
  548. public class Query2Type<T> : IDataTransferable
  549. {
  550. public static List<T> doQuery2Type(List<string> query)
  551. {
  552. return new List<T>(0);
  553. }
  554. public override void FromKVP(Dictionary<string, object> KVP)
  555. {
  556. FromOSD(Util.DictionaryToOSD(KVP));
  557. }
  558. public override Dictionary<string, object> ToKVP()
  559. {
  560. return Util.OSDToDictionary(ToOSD());
  561. }
  562. }
  563. public interface IAuroraDataPlugin
  564. {
  565. /// <summary>
  566. /// Returns the plugin name
  567. /// </summary>
  568. /// <returns></returns>
  569. string Name { get; }
  570. /// <summary>
  571. /// Starts the database plugin, performs migrations if needed
  572. /// </summary>
  573. /// <param name = "GenericData">The Database Plugin</param>
  574. /// <param name = "source">Config if more parameters are needed</param>
  575. /// <param name = "DefaultConnectionString">The connection string to use</param>
  576. void Initialize(IGenericData GenericData, IConfigSource source, IRegistryCore simBase, string DefaultConnectionString);
  577. }
  578. public class QueryTables
  579. {
  580. readonly List<QueryTable> tables = new List<QueryTable>();
  581. public void AddTable(QueryTable newTable)
  582. {
  583. tables.Add(newTable);
  584. }
  585. /// <summary>
  586. /// Add main table to select from
  587. /// </summary>
  588. /// <param name="Name"></param>
  589. /// <param name="Alias"></param>
  590. public void AddTable(string Name, string Alias)
  591. {
  592. AddTable(new QueryTable(){TableName = Name, TableAlias = Alias});
  593. }
  594. /// <summary>
  595. /// Add secondary table that joins to another table
  596. /// </summary>
  597. /// <param name="Name"></param>
  598. /// <param name="Alias"></param>
  599. /// <param name="jType"></param>
  600. /// <param name="toJoinOn"></param>
  601. public void AddTable(string Name, string Alias, JoinType jType, string[,] toJoinOn)
  602. {
  603. AddTable(new QueryTable() { JoinOn = toJoinOn, TableAlias = Alias, TableName = Name, TypeJoin = jType });
  604. }
  605. public string ToSQL()
  606. {
  607. string returnValue = "";
  608. foreach (QueryTable t in tables)
  609. {
  610. if (returnValue == "")
  611. returnValue = t.TableName + " AS " + t.TableAlias + " ";
  612. else
  613. {
  614. if (t.TypeJoin == JoinType.Inner)
  615. returnValue += " INNER JOIN " + t.TableName + " AS " + t.TableAlias + " ";
  616. else
  617. returnValue += " OUTER JOIN " + t.TableName + " AS " + t.TableAlias + " ";
  618. for (int loop = 0; loop < t.JoinOn.Length / 2; loop++)
  619. {
  620. if (loop != 0)
  621. returnValue += " AND ";
  622. else
  623. returnValue += " ON ";
  624. returnValue += t.JoinOn[loop, 0] + " = " + t.JoinOn[loop, 1];
  625. }
  626. }
  627. }
  628. return returnValue;
  629. }
  630. }
  631. public enum JoinType
  632. {
  633. Inner = 1,
  634. Left = 2
  635. }
  636. public class QueryTable
  637. {
  638. public string TableName { get; set; }
  639. public string TableAlias { get; set; }
  640. public JoinType TypeJoin { get; set; }
  641. public string[,] JoinOn { get; set; }
  642. }
  643. }