Proxy.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. using System.Net;
  2. using System.Text;
  3. using InABox.Core;
  4. namespace InABox.DatabaseProxy
  5. {
  6. public abstract class Proxy
  7. {
  8. private string server;
  9. public Proxy()
  10. {
  11. Data = new List<List<object>>();
  12. }
  13. public string Server
  14. {
  15. get => server;
  16. set => GetServerSettings(value);
  17. }
  18. public string URL { get; private set; }
  19. public string UserID { get; private set; }
  20. public string Password { get; private set; }
  21. public string SQL { get; set; }
  22. public List<List<object>> Data { get; }
  23. private void GetServerSettings(string Name)
  24. {
  25. server = Name;
  26. URL = "";
  27. UserID = "";
  28. Password = "";
  29. var settings = ConfigurationManager.Configuration.GetConfig("credentials", server).Split(',');
  30. URL = settings.Length > 0 ? settings[0] : "";
  31. UserID = settings.Length > 1 ? settings[1] : "";
  32. Password = settings.Length > 2 ? settings[2] : "";
  33. }
  34. protected abstract string SQLFormat(object value);
  35. private List<string> BuildFieldValues(Dictionary<string, object> data)
  36. {
  37. var result = new List<string>();
  38. foreach (var key in data.Keys)
  39. result.Add(SQLFormat(data[key]));
  40. return result;
  41. }
  42. public void CreateInsertSQL(string table, Dictionary<string, object> data)
  43. {
  44. var values = BuildFieldValues(data);
  45. var result = string.Format(
  46. "insert into {0} ({1}) values ({2})",
  47. table,
  48. string.Join(",", data.Keys),
  49. string.Join(",", values)
  50. );
  51. SQL = result;
  52. }
  53. public void CreateUpdateSQL(string table, Dictionary<string, object> data, Dictionary<string, object> criteria)
  54. {
  55. var fields = new List<string>();
  56. foreach (var key in data.Keys)
  57. fields.Add(string.Format("{0}={1}", key, SQLFormat(data[key])));
  58. var keys = new List<string>();
  59. foreach (var key in criteria.Keys)
  60. keys.Add(string.Format("{0}={1}", key, SQLFormat(criteria[key])));
  61. var result = string.Format(
  62. "update {0} set {1} where ({2})",
  63. table,
  64. string.Join(", ", fields),
  65. string.Join(") and (", keys)
  66. );
  67. SQL = result;
  68. }
  69. public void CreateSelectSQL(string table, List<string> fields, Dictionary<string, object> criteria)
  70. {
  71. var keys = new List<string>();
  72. if (criteria != null)
  73. foreach (var key in criteria.Keys)
  74. keys.Add(string.Format("{0}={1}", key, SQLFormat(criteria[key])));
  75. else
  76. keys.Add("1=1");
  77. var result = string.Format(
  78. "select {1} from {0} where ({2})",
  79. table,
  80. string.Join(", ", fields),
  81. string.Join(") and (", keys)
  82. );
  83. SQL = result;
  84. }
  85. public void CreateDeleteSQL(string table, Dictionary<string, object> criteria)
  86. {
  87. var keys = new List<string>();
  88. foreach (var key in criteria.Keys)
  89. keys.Add(string.Format("{0}={1}", key, SQLFormat(criteria[key])));
  90. var result = string.Format(
  91. "delete from {0} where ({1})",
  92. table,
  93. string.Join(") and (", keys)
  94. );
  95. SQL = result;
  96. }
  97. public bool Execute()
  98. {
  99. Data.Clear();
  100. var request = new Request();
  101. request.Credentials.UserID = UserID;
  102. request.Credentials.Password = Password;
  103. request.SQL = SQL;
  104. var sRequest = Serialization.Serialize(request, indented: true);
  105. var array = Encoding.ASCII.GetBytes(sRequest);
  106. var remoterequest = WebRequest.Create(string.Format("http://{0}/query?format=json", URL));
  107. remoterequest.ContentType = "application/json";
  108. remoterequest.Method = "POST";
  109. remoterequest.ContentLength = array.Length;
  110. var dataStream = remoterequest.GetRequestStream();
  111. dataStream.Write(array, 0, array.Length);
  112. dataStream.Close();
  113. var remoteresponse = remoterequest.GetResponse();
  114. using (var stream = remoteresponse.GetResponseStream())
  115. {
  116. var reader = new StreamReader(stream, Encoding.UTF8);
  117. var responseString = reader.ReadToEnd();
  118. var response = Serialization.Deserialize<Response>(responseString);
  119. if (response.Status.Equals("OK"))
  120. {
  121. Data.Clear();
  122. Data.AddRange(response.Data);
  123. return true;
  124. }
  125. return false;
  126. }
  127. }
  128. private object BlankValue(object value)
  129. {
  130. if (value == null)
  131. return value;
  132. if (value is string)
  133. return "";
  134. return Activator.CreateInstance(value.GetType());
  135. }
  136. public bool Synchronise(string table, Dictionary<string, object> criteria, Dictionary<string, object> fallbackcriteria,
  137. Dictionary<string, object> fields, string seqfield)
  138. {
  139. var bChangedKey = false;
  140. var bBlankKey = false;
  141. var bFallback = false;
  142. var newcriteria = new Dictionary<string, object>();
  143. foreach (var key in criteria.Keys)
  144. {
  145. if (criteria[key] == BlankValue(criteria[key]))
  146. bBlankKey = true;
  147. if (!fields[key].Equals(criteria[key]))
  148. bChangedKey = true;
  149. newcriteria[key] = fields[key];
  150. }
  151. CreateSelectSQL(table, fields.Keys.ToList(), newcriteria);
  152. var bNewExists = Execute() && Data.Count > 0;
  153. if (!bNewExists && fallbackcriteria != null)
  154. {
  155. CreateSelectSQL(table, fields.Keys.ToList(), fallbackcriteria);
  156. bNewExists = Execute() && Data.Count > 0;
  157. bFallback = bNewExists;
  158. }
  159. bool bOldExists;
  160. if (!bBlankKey)
  161. {
  162. if (bChangedKey)
  163. {
  164. CreateSelectSQL(table, fields.Keys.ToList(), criteria);
  165. bOldExists = Execute() && Data.Count > 0;
  166. }
  167. else
  168. {
  169. bOldExists = bNewExists;
  170. }
  171. }
  172. else
  173. {
  174. bOldExists = false;
  175. }
  176. if (!bNewExists)
  177. {
  178. if (!bOldExists)
  179. {
  180. if (!string.IsNullOrEmpty(seqfield))
  181. {
  182. CreateSelectSQL(table, new List<string> { "max(" + seqfield + ")+1" }, null);
  183. if (Execute())
  184. fields[seqfield] = Data.First()[0];
  185. }
  186. CreateInsertSQL(table, fields);
  187. }
  188. else
  189. {
  190. CreateUpdateSQL(table, fields, bFallback ? fallbackcriteria : criteria);
  191. }
  192. }
  193. else
  194. {
  195. CreateUpdateSQL(table, fields, bFallback ? fallbackcriteria : criteria);
  196. }
  197. return Execute();
  198. }
  199. }
  200. public class FoxproProxy : Proxy
  201. {
  202. protected override string SQLFormat(object value)
  203. {
  204. if (value == null)
  205. return "''";
  206. if (value is double)
  207. return value.ToString();
  208. if (value is int)
  209. return value.ToString();
  210. if (value is bool)
  211. return (bool)value ? ".t." : ".f.";
  212. if (value is DateTime)
  213. {
  214. var date = (DateTime)value;
  215. return string.Format("CAST('{0:D4}-{1:D2}-{2:D2}T{3:D2}:{4:D2}:{5:D2}.{6:D3}' as DATETIME)", date.Year, date.Month, date.Day,
  216. date.Hour,
  217. date.Minute, date.Second, date.Millisecond);
  218. }
  219. if (value is string)
  220. return string.Format("'{0}'", value);
  221. //throw new Exception("Invalid Type: " + value.GetType().ToString() + " -> " + value.ToString());
  222. return string.Format("'{0}'", value);
  223. }
  224. }
  225. public class SQLServerProxy : Proxy
  226. {
  227. protected override string SQLFormat(object value)
  228. {
  229. if (value == null)
  230. return "''";
  231. if (value is double)
  232. return value.ToString();
  233. if (value is int)
  234. return value.ToString();
  235. if (value is bool)
  236. return (bool)value ? "1" : "0";
  237. if (value is DateTime)
  238. {
  239. var date = (DateTime)value;
  240. return string.Format("CAST('{0:D4}-{1:D2}-{2:D2}T{3:D2}:{4:D2}:{5:D2}.{6:D3}' as DATETIME)", date.Year, date.Month, date.Day,
  241. date.Hour,
  242. date.Minute, date.Second, date.Millisecond);
  243. }
  244. if (value is string)
  245. return string.Format("'{0}'", value);
  246. //throw new Exception("Invalid Type: " + value.GetType().ToString() + " -> " + value.ToString());
  247. return string.Format("'{0}'", value);
  248. }
  249. }
  250. }