JsonDataSourceConnection.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. using FastReport.Utils.Json;
  2. using System;
  3. using System.Data;
  4. using System.Data.Common;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. namespace FastReport.Data.JsonConnection
  10. {
  11. /// <summary>
  12. /// FastReport json connection
  13. /// </summary>
  14. public partial class JsonDataSourceConnection : DataConnectionBase, IJsonProviderSourceConnection
  15. {
  16. #region Public Fields
  17. /// <summary>
  18. /// Name of json object table
  19. /// </summary>
  20. public const string TABLE_NAME = "JSON";
  21. #endregion Public Fields
  22. #region Private Fields
  23. private JsonArray jsonInternal = null;
  24. private JsonSchema jsonSchema = null;
  25. private string jsonSchemaString = "";
  26. private bool simpleStructure;
  27. #endregion Private Fields
  28. #region Internal Properties
  29. internal JsonArray Json
  30. {
  31. get
  32. {
  33. if (jsonInternal == null)
  34. InitConnection();
  35. return jsonInternal;
  36. }
  37. }
  38. internal JsonSchema JsonSchema
  39. {
  40. get
  41. {
  42. if (jsonSchema == null)
  43. InitConnection();
  44. return jsonSchema;
  45. }
  46. }
  47. internal bool SimpleStructure
  48. {
  49. get
  50. {
  51. return simpleStructure;
  52. }
  53. }
  54. #endregion Internal Properties
  55. #region Public Constructors
  56. /// <summary>
  57. /// Initialize a new instance
  58. /// </summary>
  59. public JsonDataSourceConnection()
  60. {
  61. IsSqlBased = false;
  62. }
  63. #endregion Public Constructors
  64. #region Public Methods
  65. /// <inheritdoc/>
  66. public override void CreateAllTables(bool initSchema)
  67. {
  68. bool found = false;
  69. foreach (Base b in Tables)
  70. {
  71. if (b is JsonTableDataSource)
  72. {
  73. (b as JsonTableDataSource).UpdateSchema = true;
  74. (b as JsonTableDataSource).InitSchema();
  75. found = true;
  76. break;
  77. }
  78. }
  79. if (!found)
  80. {
  81. JsonTableDataSource jsonDataSource = new JsonTableDataSource();
  82. string fixedTableName = TABLE_NAME;
  83. jsonDataSource.TableName = fixedTableName;
  84. if (Report != null)
  85. {
  86. jsonDataSource.Name = Report.Dictionary.CreateUniqueName(fixedTableName);
  87. jsonDataSource.Alias = Report.Dictionary.CreateUniqueAlias(jsonDataSource.Alias);
  88. }
  89. else
  90. jsonDataSource.Name = fixedTableName;
  91. jsonDataSource.Parent = this;
  92. jsonDataSource.InitSchema();
  93. jsonDataSource.Enabled = true;
  94. }
  95. // init table schema
  96. if (initSchema)
  97. {
  98. foreach (TableDataSource table in Tables)
  99. {
  100. table.InitSchema();
  101. }
  102. }
  103. }
  104. /// <inheritdoc/>
  105. public override void CreateRelations()
  106. {
  107. }
  108. /// <inheritdoc/>
  109. public override void CreateTable(TableDataSource source)
  110. {
  111. //throw new NotImplementedException();
  112. }
  113. /// <inheritdoc/>
  114. public override void DeleteTable(TableDataSource source)
  115. {
  116. //throw new NotImplementedException();
  117. }
  118. /// <inheritdoc/>
  119. public override void FillTableData(DataTable table, string selectCommand, CommandParameterCollection parameters)
  120. {
  121. }
  122. /// <inheritdoc/>
  123. public override void FillTableSchema(DataTable table, string selectCommand, CommandParameterCollection parameters)
  124. {
  125. }
  126. /// <inheritdoc/>
  127. public override string[] GetTableNames()
  128. {
  129. return new string[] { TABLE_NAME };
  130. }
  131. /// <inheritdoc/>
  132. public override string QuoteIdentifier(string value, DbConnection connection)
  133. {
  134. return value;
  135. }
  136. /// <inheritdoc/>
  137. public JsonBase GetJson(TableDataSource tableDataSource)
  138. {
  139. return Json;
  140. }
  141. #endregion Public Methods
  142. #region Protected Methods
  143. /// <inheritdoc/>
  144. protected override DataSet CreateDataSet()
  145. {
  146. throw new NotImplementedException();
  147. }
  148. /// <inheritdoc/>
  149. protected override void SetConnectionString(string value)
  150. {
  151. jsonInternal = null;
  152. base.SetConnectionString(value);
  153. }
  154. #endregion Protected Methods
  155. #region Private Methods
  156. private void InitConnection()
  157. {
  158. InitConnection(false);
  159. }
  160. private void InitConnection(bool rebuildSchema)
  161. {
  162. JsonDataSourceConnectionStringBuilder builder = new JsonDataSourceConnectionStringBuilder(ConnectionString);
  163. simpleStructure = builder.SimpleStructure;
  164. JsonBase obj = null;
  165. string jsonText = builder.Json.Trim();
  166. if (jsonText.Length > 0)
  167. {
  168. if (!(jsonText[0] == '{' || jsonText[0] == '['))
  169. {
  170. //using (WebClient client = new WebClient())
  171. //{
  172. // try
  173. // {
  174. // client.Encoding = Encoding.GetEncoding(builder.Encoding);
  175. // }
  176. // catch
  177. // {
  178. // client.Encoding = Encoding.UTF8;
  179. // }
  180. // jsonText = client.DownloadString(jsonText);
  181. //}
  182. ServicePointManager.Expect100Continue = true;
  183. ServicePointManager.SecurityProtocol = (SecurityProtocolType)(0xc0 | 0x300 | 0xc00);
  184. var req = WebRequest.Create(jsonText);
  185. req.Timeout = CommandTimeout * 1000;
  186. foreach (var header in builder.Headers)
  187. {
  188. req.Headers.Add(header.Key, header.Value);
  189. }
  190. using (var response = req.GetResponse() as HttpWebResponse)
  191. {
  192. Encoding encoding = Encoding.UTF8;
  193. try
  194. {
  195. encoding = Encoding.GetEncoding(response.CharacterSet);
  196. }
  197. catch
  198. {
  199. try
  200. {
  201. encoding = Encoding.GetEncoding(builder.Encoding);
  202. }
  203. catch { }
  204. }
  205. using (var responseStream = response.GetResponseStream())
  206. using (var reader = new System.IO.StreamReader(responseStream, encoding))
  207. jsonText = reader.ReadToEnd();
  208. }
  209. }
  210. obj = JsonBase.FromString(jsonText) as JsonBase;
  211. }
  212. string schema = builder.JsonSchema;
  213. // have to update schema
  214. if (schema != jsonSchemaString || jsonSchema == null || String.IsNullOrEmpty(jsonSchemaString))
  215. {
  216. JsonSchema schemaObj = null;
  217. if (String.IsNullOrEmpty(schema) || rebuildSchema)
  218. {
  219. if (obj != null)
  220. {
  221. schemaObj = JsonSchema.FromJson(obj);
  222. JsonObject child = new JsonObject();
  223. schemaObj.Save(child);
  224. jsonSchemaString = child.ToString();
  225. }
  226. }
  227. else
  228. {
  229. schemaObj = JsonSchema.Load(JsonBase.FromString(schema) as JsonObject);
  230. jsonSchemaString = schema;
  231. }
  232. if (schemaObj == null)
  233. {
  234. schemaObj = new JsonSchema();
  235. schemaObj.Type = "array";
  236. }
  237. if (schemaObj.Type != "array")
  238. {
  239. JsonSchema parentSchema = new JsonSchema();
  240. parentSchema.Items = schemaObj;
  241. parentSchema.Type = "array";
  242. schemaObj = parentSchema;
  243. }
  244. jsonSchema = schemaObj;
  245. }
  246. if (obj is JsonArray)
  247. {
  248. jsonInternal = obj as JsonArray;
  249. }
  250. else
  251. {
  252. JsonArray result = new JsonArray();
  253. if (obj != null)
  254. result.Add(obj);
  255. jsonInternal = result;
  256. }
  257. }
  258. #endregion Private Methods
  259. }
  260. }