Proxy.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. using System.Net;
  2. using System.Text;
  3. using Newtonsoft.Json;
  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 settings = new JsonSerializerSettings { Formatting = Formatting.Indented };
  105. var sRequest = JsonConvert.SerializeObject(request, settings);
  106. var array = Encoding.ASCII.GetBytes(sRequest);
  107. var remoterequest = WebRequest.Create(string.Format("http://{0}/query?format=json", URL));
  108. remoterequest.ContentType = "application/json";
  109. remoterequest.Method = "POST";
  110. remoterequest.ContentLength = array.Length;
  111. var dataStream = remoterequest.GetRequestStream();
  112. dataStream.Write(array, 0, array.Length);
  113. dataStream.Close();
  114. var remoteresponse = remoterequest.GetResponse();
  115. using (var stream = remoteresponse.GetResponseStream())
  116. {
  117. var reader = new StreamReader(stream, Encoding.UTF8);
  118. var responseString = reader.ReadToEnd();
  119. var response = (Response)JsonConvert.DeserializeObject(responseString, typeof(Response));
  120. if (response.Status.Equals("OK"))
  121. {
  122. Data.Clear();
  123. Data.AddRange(response.Data);
  124. return true;
  125. }
  126. return false;
  127. }
  128. }
  129. private object BlankValue(object value)
  130. {
  131. if (value == null)
  132. return value;
  133. if (value is string)
  134. return "";
  135. return Activator.CreateInstance(value.GetType());
  136. }
  137. public bool Synchronise(string table, Dictionary<string, object> criteria, Dictionary<string, object> fallbackcriteria,
  138. Dictionary<string, object> fields, string seqfield)
  139. {
  140. var bChangedKey = false;
  141. var bBlankKey = false;
  142. var bFallback = false;
  143. var newcriteria = new Dictionary<string, object>();
  144. foreach (var key in criteria.Keys)
  145. {
  146. if (criteria[key] == BlankValue(criteria[key]))
  147. bBlankKey = true;
  148. if (!fields[key].Equals(criteria[key]))
  149. bChangedKey = true;
  150. newcriteria[key] = fields[key];
  151. }
  152. CreateSelectSQL(table, fields.Keys.ToList(), newcriteria);
  153. var bNewExists = Execute() && Data.Count > 0;
  154. if (!bNewExists && fallbackcriteria != null)
  155. {
  156. CreateSelectSQL(table, fields.Keys.ToList(), fallbackcriteria);
  157. bNewExists = Execute() && Data.Count > 0;
  158. bFallback = bNewExists;
  159. }
  160. bool bOldExists;
  161. if (!bBlankKey)
  162. {
  163. if (bChangedKey)
  164. {
  165. CreateSelectSQL(table, fields.Keys.ToList(), criteria);
  166. bOldExists = Execute() && Data.Count > 0;
  167. }
  168. else
  169. {
  170. bOldExists = bNewExists;
  171. }
  172. }
  173. else
  174. {
  175. bOldExists = false;
  176. }
  177. if (!bNewExists)
  178. {
  179. if (!bOldExists)
  180. {
  181. if (!string.IsNullOrEmpty(seqfield))
  182. {
  183. CreateSelectSQL(table, new List<string> { "max(" + seqfield + ")+1" }, null);
  184. if (Execute())
  185. fields[seqfield] = Data.First()[0];
  186. }
  187. CreateInsertSQL(table, fields);
  188. }
  189. else
  190. {
  191. CreateUpdateSQL(table, fields, bFallback ? fallbackcriteria : criteria);
  192. }
  193. }
  194. else
  195. {
  196. CreateUpdateSQL(table, fields, bFallback ? fallbackcriteria : criteria);
  197. }
  198. return Execute();
  199. }
  200. }
  201. public class FoxproProxy : Proxy
  202. {
  203. protected override string SQLFormat(object value)
  204. {
  205. if (value == null)
  206. return "''";
  207. if (value is double)
  208. return value.ToString();
  209. if (value is int)
  210. return value.ToString();
  211. if (value is bool)
  212. return (bool)value ? ".t." : ".f.";
  213. if (value is DateTime)
  214. {
  215. var date = (DateTime)value;
  216. 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,
  217. date.Hour,
  218. date.Minute, date.Second, date.Millisecond);
  219. }
  220. if (value is string)
  221. return string.Format("'{0}'", value);
  222. //throw new Exception("Invalid Type: " + value.GetType().ToString() + " -> " + value.ToString());
  223. return string.Format("'{0}'", value);
  224. }
  225. }
  226. public class SQLServerProxy : Proxy
  227. {
  228. protected override string SQLFormat(object value)
  229. {
  230. if (value == null)
  231. return "''";
  232. if (value is double)
  233. return value.ToString();
  234. if (value is int)
  235. return value.ToString();
  236. if (value is bool)
  237. return (bool)value ? "1" : "0";
  238. if (value is DateTime)
  239. {
  240. var date = (DateTime)value;
  241. 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,
  242. date.Hour,
  243. date.Minute, date.Second, date.Millisecond);
  244. }
  245. if (value is string)
  246. return string.Format("'{0}'", value);
  247. //throw new Exception("Invalid Type: " + value.GetType().ToString() + " -> " + value.ToString());
  248. return string.Format("'{0}'", value);
  249. }
  250. }
  251. }