diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/AssemblyInitializer.cs b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/AssemblyInitializer.cs new file mode 100644 index 00000000..d1f54edd --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/AssemblyInitializer.cs @@ -0,0 +1,13 @@ +using FastReport.Utils; + + +namespace FastReport.Data +{ + public class CouchbaseAssemblyInitializer : AssemblyInitializerBase + { + public CouchbaseAssemblyInitializer() + { + RegisteredObjects.AddConnection(typeof(CouchbaseDataConnection)); + } + } +} \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseConnectionEditor.Designer.cs b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseConnectionEditor.Designer.cs new file mode 100644 index 00000000..dd5578bf --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseConnectionEditor.Designer.cs @@ -0,0 +1,175 @@ +namespace FastReport.Data +{ + partial class CouchbaseConnectionEditor + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.gbDatabase = new System.Windows.Forms.GroupBox(); + this.tbDatabase = new System.Windows.Forms.TextBox(); + this.lblDatabase = new System.Windows.Forms.Label(); + this.tbPassword = new System.Windows.Forms.TextBox(); + this.lblUserName = new System.Windows.Forms.Label(); + this.tbUserName = new System.Windows.Forms.TextBox(); + this.lblPassword = new System.Windows.Forms.Label(); + this.gbServer = new System.Windows.Forms.GroupBox(); + this.tbHost = new System.Windows.Forms.TextBox(); + this.lblHost = new System.Windows.Forms.Label(); + this.labelLine1 = new FastReport.Controls.LabelLine(); + this.gbDatabase.SuspendLayout(); + this.gbServer.SuspendLayout(); + this.SuspendLayout(); + // + // gbDatabase + // + this.gbDatabase.Controls.Add(this.tbDatabase); + this.gbDatabase.Controls.Add(this.lblDatabase); + this.gbDatabase.Location = new System.Drawing.Point(15, 12); + this.gbDatabase.Name = "gbDatabase"; + this.gbDatabase.Size = new System.Drawing.Size(308, 66); + this.gbDatabase.TabIndex = 0; + this.gbDatabase.TabStop = false; + this.gbDatabase.Text = "Database"; + // + // tbDatabase + // + this.tbDatabase.Location = new System.Drawing.Point(6, 33); + this.tbDatabase.Name = "tbDatabase"; + this.tbDatabase.Size = new System.Drawing.Size(296, 20); + this.tbDatabase.TabIndex = 0; + // + // lblDatabase + // + this.lblDatabase.AutoSize = true; + this.lblDatabase.Location = new System.Drawing.Point(6, 17); + this.lblDatabase.Name = "lblDatabase"; + this.lblDatabase.Size = new System.Drawing.Size(86, 13); + this.lblDatabase.TabIndex = 0; + this.lblDatabase.Text = "Database name:"; + // + // tbPassword + // + this.tbPassword.Location = new System.Drawing.Point(114, 93); + this.tbPassword.Name = "tbPassword"; + this.tbPassword.Size = new System.Drawing.Size(188, 20); + this.tbPassword.TabIndex = 2; + this.tbPassword.UseSystemPasswordChar = true; + // + // lblUserName + // + this.lblUserName.AutoSize = true; + this.lblUserName.Location = new System.Drawing.Point(6, 70); + this.lblUserName.Name = "lblUserName"; + this.lblUserName.Size = new System.Drawing.Size(62, 13); + this.lblUserName.TabIndex = 0; + this.lblUserName.Text = "User name:"; + // + // tbUserName + // + this.tbUserName.Location = new System.Drawing.Point(114, 67); + this.tbUserName.Name = "tbUserName"; + this.tbUserName.Size = new System.Drawing.Size(188, 20); + this.tbUserName.TabIndex = 1; + // + // lblPassword + // + this.lblPassword.AutoSize = true; + this.lblPassword.Location = new System.Drawing.Point(6, 96); + this.lblPassword.Name = "lblPassword"; + this.lblPassword.Size = new System.Drawing.Size(57, 13); + this.lblPassword.TabIndex = 0; + this.lblPassword.Text = "Password:"; + // + // gbServer + // + this.gbServer.Controls.Add(this.tbHost); + this.gbServer.Controls.Add(this.lblHost); + this.gbServer.Controls.Add(this.tbPassword); + this.gbServer.Controls.Add(this.lblUserName); + this.gbServer.Controls.Add(this.tbUserName); + this.gbServer.Controls.Add(this.lblPassword); + this.gbServer.Location = new System.Drawing.Point(15, 84); + this.gbServer.Name = "gbServer"; + this.gbServer.Size = new System.Drawing.Size(308, 126); + this.gbServer.TabIndex = 1; + this.gbServer.TabStop = false; + this.gbServer.Text = "Server"; + // + // tbHost + // + this.tbHost.Location = new System.Drawing.Point(9, 41); + this.tbHost.Name = "tbHost"; + this.tbHost.Size = new System.Drawing.Size(293, 20); + this.tbHost.TabIndex = 0; + // + // lblHost + // + this.lblHost.AutoSize = true; + this.lblHost.Location = new System.Drawing.Point(6, 25); + this.lblHost.Name = "lblHost"; + this.lblHost.Size = new System.Drawing.Size(33, 13); + this.lblHost.TabIndex = 0; + this.lblHost.Text = "Host:"; + // + // labelLine1 + // + this.labelLine1.Location = new System.Drawing.Point(15, 216); + this.labelLine1.Name = "labelLine1"; + this.labelLine1.Size = new System.Drawing.Size(308, 16); + this.labelLine1.TabIndex = 0; + // + // CouchbaseConnectionEditor + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.gbDatabase); + this.Controls.Add(this.gbServer); + this.Controls.Add(this.labelLine1); + this.Name = "CouchbaseConnectionEditor"; + this.Size = new System.Drawing.Size(336, 237); + this.gbDatabase.ResumeLayout(false); + this.gbDatabase.PerformLayout(); + this.gbServer.ResumeLayout(false); + this.gbServer.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox gbDatabase; + private System.Windows.Forms.TextBox tbDatabase; + private System.Windows.Forms.Label lblDatabase; + private System.Windows.Forms.TextBox tbPassword; + private System.Windows.Forms.Label lblUserName; + private System.Windows.Forms.TextBox tbUserName; + private System.Windows.Forms.Label lblPassword; + private System.Windows.Forms.GroupBox gbServer; + private System.Windows.Forms.TextBox tbHost; + private System.Windows.Forms.Label lblHost; + private Controls.LabelLine labelLine1; + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseConnectionEditor.cs b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseConnectionEditor.cs new file mode 100644 index 00000000..009e88b8 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseConnectionEditor.cs @@ -0,0 +1,72 @@ +using FastReport.Utils; +using FastReport.Data.ConnectionEditors; + +namespace FastReport.Data +{ + /// + /// Represents a Couchbase connection editor. + /// + public partial class CouchbaseConnectionEditor : ConnectionEditorBase + { + #region Fields + + private string FConnectionString; + + #endregion Fields + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public CouchbaseConnectionEditor() + { + InitializeComponent(); + Localize(); + } + + #endregion Constructors + + #region Private Methods + + private void Localize() + { + MyRes res = new MyRes("ConnectionEditors,Common"); + gbServer.Text = res.Get("ServerLogon"); + lblUserName.Text = res.Get("UserName"); + lblPassword.Text = res.Get("Password"); + gbDatabase.Text = res.Get("Database"); + lblDatabase.Text = res.Get("DatabaseName"); + + res = new MyRes("Export,Email"); + } + + #endregion Private Methods + + #region Protected Methods + + /// + protected override string GetConnectionString() + { + CouchbaseConnectionStringBuilder builder = new CouchbaseConnectionStringBuilder(); + builder.DatabaseName = tbDatabase.Text; + builder.Host = tbHost.Text; + builder.Username = tbUserName.Text; + builder.Password = tbPassword.Text; + return builder.ToString(); + } + + /// + protected override void SetConnectionString(string value) + { + FConnectionString = value; + CouchbaseConnectionStringBuilder builder = new CouchbaseConnectionStringBuilder(value); + tbDatabase.Text = builder.DatabaseName; + tbHost.Text = builder.Host; + tbUserName.Text = builder.Username; + tbPassword.Text = builder.Password; + } + + #endregion Protected Methods + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseConnectionEditor.resx b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseConnectionEditor.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseConnectionEditor.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseConnectionStringBuilder.cs b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseConnectionStringBuilder.cs new file mode 100644 index 00000000..f8dfb6cf --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseConnectionStringBuilder.cs @@ -0,0 +1,133 @@ +using System; +using System.Text; + +namespace FastReport.Data +{ + /// + /// Represents the CouchbaseDataConnection connection string builder. + /// + /// + /// Use this class to parse connection string returned by the CouchbaseDataConnection class. + /// + public class CouchbaseConnectionStringBuilder + { + #region Fields + + private string databaseName; + private string host; + private string username; + private string password; + private string connectionString; + + #endregion Fields + + #region Properties + + /// + /// Gets or sets the host. + /// + public string Host + { + get { return host; } + set { host = value; } + } + + /// + /// Gets or sets the username. + /// + public string Username + { + get { return username; } + set { username = value; } + } + + /// + /// Gets or sets the password. + /// + public string Password + { + get { return password; } + set { password = value; } + } + + /// + /// Gets or sets the database name. + /// + public string DatabaseName + { + get { return databaseName; } + set { databaseName = value; } + } + + #endregion Properties + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public CouchbaseConnectionStringBuilder() + { + connectionString = ""; + host = ""; + databaseName = ""; + username = ""; + password = ""; + } + + /// + /// Initializes a new instance of the class with a specified connection string. + /// + /// The connection string value. + public CouchbaseConnectionStringBuilder(string connectionString) + { + this.connectionString = connectionString; + string[] parts = connectionString.Split(';'); + if (parts[0].Contains("Url")) + { + host = parts[0].Replace("Url = ", ""); + } + for (int i = 1; i < parts.Length; i++) + { + if (parts[i].Contains("Database")) + { + databaseName = parts[i].Replace("Database=", ""); + } + if (parts[i].Contains("User")) + { + username = parts[i].Replace("User=", ""); + } + if (parts[i].Contains("Password")) + { + password = parts[i].Replace("Password=", ""); + } + } + } + + #endregion Constructors + + #region Public Methods + + /// + public override string ToString() + { + StringBuilder sb = new StringBuilder("Url = "); + sb.Append(host); + if (!String.IsNullOrEmpty(databaseName)) + { + sb.AppendFormat(";Database={0}", databaseName); + } + if (!String.IsNullOrEmpty(username)) + { + sb.AppendFormat(";User={0}", username); + } + if (!String.IsNullOrEmpty(password)) + { + sb.AppendFormat(";Password={0}", password); + } + return sb.ToString(); + } + + #endregion Public Methods + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseDataConnection.DesignExt.cs b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseDataConnection.DesignExt.cs new file mode 100644 index 00000000..5402db12 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseDataConnection.DesignExt.cs @@ -0,0 +1,30 @@ +using System; +using FastReport.Data.ConnectionEditors; + +namespace FastReport.Data +{ + /// + /// Represents a connection to Couchbase database. + /// + public partial class CouchbaseDataConnection + { + /// + public override Type GetConnectionType() + { + return typeof(CouchbaseDataConnection); + } + + /// + public override string GetConnectionId() + { + CouchbaseConnectionStringBuilder builder = new CouchbaseConnectionStringBuilder(ConnectionString); + return "Couchbase: " + builder.ToString(); + } + + /// + public override ConnectionEditorBase GetEditor() + { + return new CouchbaseConnectionEditor(); + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseDataConnection.cs b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseDataConnection.cs new file mode 100644 index 00000000..77ccfd81 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/CouchbaseDataConnection.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.ComponentModel; +using Couchbase; +using Couchbase.Configuration.Client; +using Couchbase.Authentication; +using Newtonsoft.Json.Linq; +using System.Text; + +namespace FastReport.Data +{ + /// + /// Represents a connection to Couchbase database. + /// + public partial class CouchbaseDataConnection : JsonDataConnection + { + #region Properties + + /// + /// Gets or sets the database name. + /// + [Category("Data")] + public string DatabaseName + { + get + { + CouchbaseConnectionStringBuilder builder = new CouchbaseConnectionStringBuilder(ConnectionString); + return builder.DatabaseName; + } + set + { + CouchbaseConnectionStringBuilder builder = new CouchbaseConnectionStringBuilder(ConnectionString); + builder.DatabaseName = value; + ConnectionString = builder.ToString(); + } + } + + /// + /// Gets or sets the host url. + /// + [Category("Data")] + public string Host + { + get + { + CouchbaseConnectionStringBuilder builder = new CouchbaseConnectionStringBuilder(ConnectionString); + return builder.Host; + } + set + { + CouchbaseConnectionStringBuilder builder = new CouchbaseConnectionStringBuilder(ConnectionString); + builder.Host = value; + ConnectionString = builder.ToString(); + } + } + + /// + /// Gets or sets the username. + /// + [Category("Data")] + public string Username + { + get + { + CouchbaseConnectionStringBuilder builder = new CouchbaseConnectionStringBuilder(ConnectionString); + return builder.Username; + } + set + { + CouchbaseConnectionStringBuilder builder = new CouchbaseConnectionStringBuilder(ConnectionString); + builder.Username = value; + ConnectionString = builder.ToString(); + } + } + + /// + /// Gets or sets the password. + /// + [Category("Data")] + public string Password + { + get + { + CouchbaseConnectionStringBuilder builder = new CouchbaseConnectionStringBuilder(ConnectionString); + return builder.Password; + } + set + { + CouchbaseConnectionStringBuilder builder = new CouchbaseConnectionStringBuilder(ConnectionString); + builder.Password = value; + ConnectionString = builder.ToString(); + } + } + + #endregion Properties + + #region Protected Methods + + /// + protected override DataSet CreateDataSet() + { + using (var cluster = new Cluster(new ClientConfiguration + { + Servers = new List { new Uri(Host) } + })) + { + var authenticator = new PasswordAuthenticator(Username, Password); + cluster.Authenticate(authenticator); + var bucket = cluster.OpenBucket(DatabaseName); + List entityNames = cluster.Query("select distinct `type` from `beer-sample`") + .Rows.Select(v => v.GetValue("type").ToString()).ToList(); + + StringBuilder json = new StringBuilder(); + json.Append("{\n"); + foreach (string name in entityNames) + { + json.Append("\"").Append(name).Append("\":\n["); + DataTable table = new DataTable(name); + + // get all rows of the table + var objects = cluster.Query($"select * from `{DatabaseName}` where type = \"{name}\"") + .Rows.ToList(); + foreach (var jobj in objects) + { + json.Append(jobj.GetValue(DatabaseName).ToString()); + if (jobj != objects.Last()) + json.Append(","); + } + json.Append("]\n"); + if (name != entityNames.Last()) + json.Append(","); + } + json.Append("}"); + var jsstring = json.ToString(); + JsonData = jsstring; + return base.CreateDataSet(); + } + } + + #endregion Protected Methods + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/FastReport.Data.Couchbase.csproj b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/FastReport.Data.Couchbase.csproj new file mode 100644 index 00000000..5ef9632a --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/FastReport.Data.Couchbase.csproj @@ -0,0 +1,96 @@ + + + + netstandard2.0;net4.5 + ../../../FastReport.Plugins.snk + true + Fast Reports Inc. + Fast Reports Inc. + https://www.fast-report.com/en/product/fast-report-net/license + https://www.fast-report.com/en/product/fast-report-net + Fast Reports Inc. + FastReport.Data.Couchbase + Represents a connection to Couchbase server for FastReport.Net. + FastReport.Data.Couchbase + https://www.fast-report.com/download/images/frlogo-big.png + reporting, Couchbase, connection, reports + 2018.2.2$(VersionSuffix) + 2018.2.2.0 + 2018.2.2.0 + Debug;Release; + FastReport.Data.Couchbase + FastReport.Data + + + + FRCORE; + + + + + + + + + + + + + + + + + + + + + false + + + False + ..\..\..\..\FastReport\bin\Release\FastReport.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UserControl + + + CouchbaseConnectionEditor.cs + + + + + CouchbaseConnectionEditor.cs + Designer + + + + \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/readme.txt b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/readme.txt new file mode 100644 index 00000000..eb47e4cf --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Couchbase/readme.txt @@ -0,0 +1,14 @@ +How to use it: +- execute the following code once at the application start: +FastReport.Utils.RegisteredObjects.AddConnection(typeof(CouchbaseDataConnection)); +- now you should be able to create a new Couchbase data source from Designer (.Net 4) or from code: +Report report = new Report(); +report.Load(@"YourReport.frx"); +//... +CouchbaseDataConnection con = new CouchbaseDataConnection(); +con.Host = "http://127.0.0.1:8091"; +con.DatabaseName = "beer-sample"; +con.Username = "username"; +con.Password = "userPass"; +conn.CreateAllTables(); +report.Dictionary.Connections.Add(conn); \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/AssemblyInitializer.cs b/Extras/Core/FastReport.Data/FastReport.Data.Json/AssemblyInitializer.cs new file mode 100644 index 00000000..5f70a795 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/AssemblyInitializer.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using FastReport.Utils; + +namespace FastReport.Data +{ + public class JsonAssemblyInitializer : AssemblyInitializerBase + { + public JsonAssemblyInitializer() + { + RegisteredObjects.AddConnection(typeof(JsonDataConnection)); + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/FastReport.Data.Json.csproj b/Extras/Core/FastReport.Data/FastReport.Data.Json/FastReport.Data.Json.csproj new file mode 100644 index 00000000..ed6aa733 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/FastReport.Data.Json.csproj @@ -0,0 +1,93 @@ + + + + netstandard2.0;net4;net4.5 + true + ../../../FastReport.Plugins.snk + true + Fast Reports Inc. + Fast Reports Inc. + https://www.fast-report.com/en/product/fast-report-net/license + https://www.fast-report.com/en/product/fast-report-net + Fast Reports Inc. + FastReport.Data.Json + Represents a connection to Json data for FastReport.Net. + FastReport.Data.Json + https://www.fast-report.com/download/images/frlogo-big.png + reporting, Json, connection, reports + 2018.3.11$(VersionSuffix) + 2018.3.11.0 + 2018.3.11.0 + Debug;Release; + FastReport.Data.Json + FastReport.Data + Fixed bug with Newtonsoft.Json.dll location + + + FRCORE; + + + + + + + + + + + + + + + + + + + + + + false + + + False + ..\..\..\..\FastReport\bin\Release\FastReport.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + UserControl + + + JsonConnectionEditor.cs + + + + + JsonConnectionEditor.cs + Designer + + + diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/CSharpCodeWriter.cs b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/CSharpCodeWriter.cs new file mode 100644 index 00000000..c8e56206 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/CSharpCodeWriter.cs @@ -0,0 +1,304 @@ +// Copyright © 2010 Xamasoft +// Licensed under the Microsoft Reciprocal License (MS-RL). See LICENSE.txt for license information. + +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace FastReport.JsonClassGenerator +{ + public class CSharpCodeWriter : ICodeWriter + { + public string FileExtension + { + get { return ".cs"; } + } + + public string DisplayName + { + get { return "C#"; } + } + + + private const string NoRenameAttribute = "[Obfuscation(Feature = \"renaming\", Exclude = true)]"; + private const string NoPruneAttribute = "[Obfuscation(Feature = \"trigger\", Exclude = false)]"; + + public string GetTypeName(JsonType type, IJsonClassGeneratorConfig config) + { + var arraysAsLists = !config.ExplicitDeserialization; + + switch (type.Type) + { + case JsonTypeEnum.Anything: return "object"; + case JsonTypeEnum.Array: return arraysAsLists ? "IList<" + GetTypeName(type.InternalType, config) + ">" : GetTypeName(type.InternalType, config) + "[]"; + case JsonTypeEnum.Dictionary: return "Dictionary"; + case JsonTypeEnum.Boolean: return "bool"; + case JsonTypeEnum.Float: return "double"; + case JsonTypeEnum.Integer: return "int"; + case JsonTypeEnum.Long: return "long"; + case JsonTypeEnum.Date: return "DateTime"; + case JsonTypeEnum.NonConstrained: return "object"; + case JsonTypeEnum.NullableBoolean: return "bool?"; + case JsonTypeEnum.NullableFloat: return "double?"; + case JsonTypeEnum.NullableInteger: return "int?"; + case JsonTypeEnum.NullableLong: return "long?"; + case JsonTypeEnum.NullableDate: return "DateTime?"; + case JsonTypeEnum.NullableSomething: return "object"; + case JsonTypeEnum.Object: return type.AssignedName; + case JsonTypeEnum.String: return "string"; + default: throw new System.NotSupportedException("Unsupported json type"); + } + } + + + private bool ShouldApplyNoRenamingAttribute(IJsonClassGeneratorConfig config) + { + return config.ApplyObfuscationAttributes && !config.ExplicitDeserialization && !config.UsePascalCase; + } + private bool ShouldApplyNoPruneAttribute(IJsonClassGeneratorConfig config) + { + return config.ApplyObfuscationAttributes && !config.ExplicitDeserialization && config.UseProperties; + } + + public void WriteFileStart(IJsonClassGeneratorConfig config, TextWriter sw) + { + if (config.UseNamespaces) + { + //XXX + //foreach (var line in JsonClassGenerator.FileHeader) + //{ + // sw.WriteLine("// " + line); + //} + //sw.WriteLine(); + sw.WriteLine("using System;"); + sw.WriteLine("using System.Collections.Generic;"); + if (ShouldApplyNoPruneAttribute(config) || ShouldApplyNoRenamingAttribute(config)) + sw.WriteLine("using System.Reflection;"); + if (!config.ExplicitDeserialization && config.UsePascalCase) + sw.WriteLine("using Newtonsoft.Json;"); + //sw.WriteLine("using Newtonsoft.Json.Linq;"); + if (config.ExplicitDeserialization) + sw.WriteLine("using JsonCSharpClassGenerator;"); + if (config.SecondaryNamespace != null && config.HasSecondaryClasses && !config.UseNestedClasses) + { + sw.WriteLine("using {0};", config.SecondaryNamespace); + } + } + + if (config.UseNestedClasses) + { + sw.WriteLine(" {0} class {1}", config.InternalVisibility ? "internal" : "public", config.MainClass); + sw.WriteLine(" {"); + } + } + + public void WriteFileEnd(IJsonClassGeneratorConfig config, TextWriter sw) + { + if (config.UseNestedClasses) + { + sw.WriteLine(" }"); + } + } + + + public void WriteNamespaceStart(IJsonClassGeneratorConfig config, TextWriter sw, bool root) + { + sw.WriteLine(); + sw.WriteLine("namespace {0}", root && !config.UseNestedClasses ? config.Namespace : (config.SecondaryNamespace ?? config.Namespace)); + sw.WriteLine("{"); + sw.WriteLine(); + } + + public void WriteNamespaceEnd(IJsonClassGeneratorConfig config, TextWriter sw, bool root) + { + sw.WriteLine("}"); + } + + public void WriteClass(IJsonClassGeneratorConfig config, TextWriter sw, JsonType type) + { + var visibility = config.InternalVisibility ? "internal" : "public"; + + + + if (config.UseNestedClasses) + { + if (!type.IsRoot) + { + if (ShouldApplyNoRenamingAttribute(config)) sw.WriteLine(" " + NoRenameAttribute); + if (ShouldApplyNoPruneAttribute(config)) sw.WriteLine(" " + NoPruneAttribute); + sw.WriteLine(" {0} class {1}", visibility, type.AssignedName); + sw.WriteLine(" {"); + } + } + else + { + if (ShouldApplyNoRenamingAttribute(config)) sw.WriteLine(" " + NoRenameAttribute); + if (ShouldApplyNoPruneAttribute(config)) sw.WriteLine(" " + NoPruneAttribute); + sw.WriteLine(" {0} class {1}", visibility, type.AssignedName); + sw.WriteLine(" {"); + } + + var prefix = config.UseNestedClasses && !type.IsRoot ? " " : " "; + + + var shouldSuppressWarning = config.InternalVisibility && !config.UseProperties && !config.ExplicitDeserialization; + if (shouldSuppressWarning) + { + sw.WriteLine("#pragma warning disable 0649"); + if (!config.UsePascalCase) sw.WriteLine(); + } + + if (type.IsRoot && config.ExplicitDeserialization) WriteStringConstructorExplicitDeserialization(config, sw, type, prefix); + + if (config.ExplicitDeserialization) + { + if (config.UseProperties) WriteClassWithPropertiesExplicitDeserialization(sw, type, prefix); + else WriteClassWithFieldsExplicitDeserialization(sw, type, prefix); + } + else + { + WriteClassMembers(config, sw, type, prefix); + } + + if (shouldSuppressWarning) + { + sw.WriteLine(); + sw.WriteLine("#pragma warning restore 0649"); + sw.WriteLine(); + } + + + if (config.UseNestedClasses && !type.IsRoot) + sw.WriteLine(" }"); + + if (!config.UseNestedClasses) + sw.WriteLine(" }"); + + sw.WriteLine(); + + + } + + + + private void WriteClassMembers(IJsonClassGeneratorConfig config, TextWriter sw, JsonType type, string prefix) + { + foreach (var field in type.Fields) + { + if (config.UsePascalCase || config.ExamplesInDocumentation) sw.WriteLine(); + + if (config.ExamplesInDocumentation) + { + sw.WriteLine(prefix + "/// "); + sw.WriteLine(prefix + "/// Examples: " + field.GetExamplesText()); + sw.WriteLine(prefix + "/// "); + } + + if (config.UsePascalCase) + { + + sw.WriteLine(prefix + "[JsonProperty(\"{0}\")]", field.JsonMemberName); + } + + if (config.UseProperties) + { + sw.WriteLine(prefix + "public {0} {1} {{ get; set; }}", field.Type.GetTypeName(), field.MemberName); + } + else + { + sw.WriteLine(prefix + "public {0} {1};", field.Type.GetTypeName(), field.MemberName); + } + } + + } + + + + + + + + #region Code for (obsolete) explicit deserialization + private void WriteClassWithPropertiesExplicitDeserialization(TextWriter sw, JsonType type, string prefix) + { + + sw.WriteLine(prefix + "private JObject __jobject;"); + sw.WriteLine(prefix + "public {0}(JObject obj)", type.AssignedName); + sw.WriteLine(prefix + "{"); + sw.WriteLine(prefix + " this.__jobject = obj;"); + sw.WriteLine(prefix + "}"); + sw.WriteLine(); + + foreach (var field in type.Fields) + { + + string variable = null; + if (field.Type.MustCache) + { + variable = "_" + char.ToLower(field.MemberName[0]) + field.MemberName.Substring(1); + sw.WriteLine(prefix + "[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]"); + sw.WriteLine(prefix + "private {0} {1};", field.Type.GetTypeName(), variable); + } + + + sw.WriteLine(prefix + "public {0} {1}", field.Type.GetTypeName(), field.MemberName); + sw.WriteLine(prefix + "{"); + sw.WriteLine(prefix + " get"); + sw.WriteLine(prefix + " {"); + if (field.Type.MustCache) + { + sw.WriteLine(prefix + " if ({0} == null)", variable); + sw.WriteLine(prefix + " {0} = {1};", variable, field.GetGenerationCode("__jobject")); + sw.WriteLine(prefix + " return {0};", variable); + } + else + { + sw.WriteLine(prefix + " return {0};", field.GetGenerationCode("__jobject")); + } + sw.WriteLine(prefix + " }"); + sw.WriteLine(prefix + "}"); + sw.WriteLine(); + + } + + } + + + private void WriteStringConstructorExplicitDeserialization(IJsonClassGeneratorConfig config, TextWriter sw, JsonType type, string prefix) + { + sw.WriteLine(); + sw.WriteLine(prefix + "public {1}(string json)", config.InternalVisibility ? "internal" : "public", type.AssignedName); + sw.WriteLine(prefix + " : this(JObject.Parse(json))"); + sw.WriteLine(prefix + "{"); + sw.WriteLine(prefix + "}"); + sw.WriteLine(); + } + + private void WriteClassWithFieldsExplicitDeserialization(TextWriter sw, JsonType type, string prefix) + { + + + sw.WriteLine(prefix + "public {0}(JObject obj)", type.AssignedName); + sw.WriteLine(prefix + "{"); + + foreach (var field in type.Fields) + { + sw.WriteLine(prefix + " this.{0} = {1};", field.MemberName, field.GetGenerationCode("obj")); + + } + + sw.WriteLine(prefix + "}"); + sw.WriteLine(); + + foreach (var field in type.Fields) + { + sw.WriteLine(prefix + "public readonly {0} {1};", field.Type.GetTypeName(), field.MemberName); + } + } + #endregion + + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/FieldInfo.cs b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/FieldInfo.cs new file mode 100644 index 00000000..da206279 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/FieldInfo.cs @@ -0,0 +1,76 @@ +// Copyright © 2010 Xamasoft +// Licensed under the Microsoft Reciprocal License (MS-RL). See LICENSE.txt for license information. + +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace FastReport.JsonClassGenerator +{ + public class FieldInfo + { + + public FieldInfo(IJsonClassGeneratorConfig generator, string jsonMemberName, JsonType type, bool usePascalCase, IList Examples) + { + this.generator = generator; + this.JsonMemberName = jsonMemberName; + this.MemberName = jsonMemberName; + if (usePascalCase) MemberName = JsonClassGenerator.ToTitleCase(MemberName); + this.Type = type; + this.Examples = Examples; + } + private IJsonClassGeneratorConfig generator; + public string MemberName { get; private set; } + public string JsonMemberName { get; private set; } + public JsonType Type { get; private set; } + public IList Examples { get; private set; } + + public string GetGenerationCode(string jobject) + { + var field = this; + if (field.Type.Type == JsonTypeEnum.Array) + { + var innermost = field.Type.GetInnermostType(); + return string.Format("({1})JsonClassHelper.ReadArray<{5}>(JsonClassHelper.GetJToken({0}, \"{2}\"), JsonClassHelper.{3}, typeof({6}))", + jobject, + field.Type.GetTypeName(), + field.JsonMemberName, + innermost.GetReaderName(), + -1, + innermost.GetTypeName(), + field.Type.GetTypeName() + ); + } + else if (field.Type.Type == JsonTypeEnum.Dictionary) + { + + return string.Format("({1})JsonClassHelper.ReadDictionary<{2}>(JsonClassHelper.GetJToken({0}, \"{3}\"))", + jobject, + field.Type.GetTypeName(), + field.Type.InternalType.GetTypeName(), + field.JsonMemberName, + field.Type.GetTypeName() + ); + } + else + { + return string.Format("JsonClassHelper.{1}(JsonClassHelper.GetJToken<{2}>({0}, \"{3}\"))", + jobject, + field.Type.GetReaderName(), + field.Type.GetJTokenType(), + field.JsonMemberName); + } + + } + + + + public string GetExamplesText() + { + return string.Join(", ", Examples.Take(5).Select(x => JsonConvert.SerializeObject(x)).ToArray()); + } + + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/ICodeWriter.cs b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/ICodeWriter.cs new file mode 100644 index 00000000..cb6531ff --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/ICodeWriter.cs @@ -0,0 +1,23 @@ +// Copyright © 2010 Xamasoft +// Licensed under the Microsoft Reciprocal License (MS-RL). See LICENSE.txt for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace FastReport.JsonClassGenerator +{ + public interface ICodeWriter + { + string FileExtension { get; } + string DisplayName { get; } + string GetTypeName(JsonType type, IJsonClassGeneratorConfig config); + void WriteClass(IJsonClassGeneratorConfig config, TextWriter sw, JsonType type); + void WriteFileStart(IJsonClassGeneratorConfig config, TextWriter sw); + void WriteFileEnd(IJsonClassGeneratorConfig config, TextWriter sw); + void WriteNamespaceStart(IJsonClassGeneratorConfig config, TextWriter sw, bool root); + void WriteNamespaceEnd(IJsonClassGeneratorConfig config, TextWriter sw, bool root); + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/IJsonClassGeneratorConfig.cs b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/IJsonClassGeneratorConfig.cs new file mode 100644 index 00000000..f4231bb6 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/IJsonClassGeneratorConfig.cs @@ -0,0 +1,30 @@ +// Copyright © 2010 Xamasoft +// Licensed under the Microsoft Reciprocal License (MS-RL). See LICENSE.txt for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace FastReport.JsonClassGenerator +{ + public interface IJsonClassGeneratorConfig + { + string Namespace { get; set; } + string SecondaryNamespace { get; set; } + bool UseProperties { get; set; } + bool InternalVisibility { get; set; } + bool ExplicitDeserialization { get; set; } + bool NoHelperClass { get; set; } + string MainClass { get; set; } + bool UsePascalCase { get; set; } + bool UseNestedClasses { get; set; } + bool ApplyObfuscationAttributes { get; set; } + bool SingleFile { get; set; } + ICodeWriter CodeWriter { get; set; } + bool HasSecondaryClasses { get; } + bool AlwaysUseNullableValues { get; set; } + bool UseNamespaces { get; } + bool ExamplesInDocumentation { get; set; } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/JsonClassGenerator.cs b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/JsonClassGenerator.cs new file mode 100644 index 00000000..e578124c --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/JsonClassGenerator.cs @@ -0,0 +1,330 @@ +// Copyright © 2010 Xamasoft +// Licensed under the Microsoft Reciprocal License (MS-RL). See LICENSE.txt for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System.IO; +#if !FRCORE +using System.Data.Entity.Design.PluralizationServices; +#endif +using System.Globalization; + + +namespace FastReport.JsonClassGenerator +{ + public class JsonClassGenerator : IJsonClassGeneratorConfig + { + + + public string Example { get; set; } + public string TargetFolder { get; set; } + public string Namespace { get; set; } + public string SecondaryNamespace { get; set; } + public bool UseProperties { get; set; } + public bool InternalVisibility { get; set; } + public bool ExplicitDeserialization { get; set; } + public bool NoHelperClass { get; set; } + public string MainClass { get; set; } + public bool UsePascalCase { get; set; } + public bool UseNestedClasses { get; set; } + public bool ApplyObfuscationAttributes { get; set; } + public bool SingleFile { get; set; } + public ICodeWriter CodeWriter { get; set; } + public TextWriter OutputStream { get; set; } + public bool AlwaysUseNullableValues { get; set; } + public bool ExamplesInDocumentation { get; set; } + +#if !FRCORE + private PluralizationService pluralizationService = PluralizationService.CreateService(new CultureInfo("en-us")); +#endif + + private bool used = false; + public bool UseNamespaces { get { return Namespace != null; } } + + public void GenerateClasses() + { + if (CodeWriter == null) CodeWriter = new CSharpCodeWriter(); + if (ExplicitDeserialization && !(CodeWriter is CSharpCodeWriter)) throw new ArgumentException("Explicit deserialization is obsolete and is only supported by the C# provider."); + + if (used) throw new InvalidOperationException("This instance of JsonClassGenerator has already been used. Please create a new instance."); + used = true; + + + var writeToDisk = TargetFolder != null; + if (writeToDisk && !Directory.Exists(TargetFolder)) Directory.CreateDirectory(TargetFolder); + + + JObject[] examples; + var example = Example.StartsWith("HTTP/") ? Example.Substring(Example.IndexOf("\r\n\r\n")) : Example; + using (var sr = new StringReader(example)) + using (var reader = new JsonTextReader(sr)) + { + var json = JToken.ReadFrom(reader); + if (json is JArray) + { + examples = ((JArray)json).Cast().ToArray(); + } + else if (json is JObject) + { + examples = new[] { (JObject)json }; + } + else + { + throw new Exception("Sample JSON must be either a JSON array, or a JSON object."); + } + } + + + Types = new List(); + Names.Add(MainClass); + var rootType = new JsonType(this, examples[0]); + rootType.IsRoot = true; + rootType.AssignName(MainClass); + GenerateClass(examples, rootType); + + if (writeToDisk) + { + //var parentFolder = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); + //if (writeToDisk && !NoHelperClass && ExplicitDeserialization) + // File.WriteAllBytes(Path.Combine(TargetFolder, "JsonClassHelper.cs"), Properties.Resources.JsonClassHelper); + //if (SingleFile) + //{ + // WriteClassesToFile(Path.Combine(TargetFolder, MainClass + CodeWriter.FileExtension), Types); + //} + //else + //{ + + // foreach (var type in Types) + // { + // var folder = TargetFolder; + // if (!UseNestedClasses && !type.IsRoot && SecondaryNamespace != null) + // { + // var s = SecondaryNamespace; + // if (s.StartsWith(Namespace + ".")) s = s.Substring(Namespace.Length + 1); + // folder = Path.Combine(folder, s); + // Directory.CreateDirectory(folder); + // } + // WriteClassesToFile(Path.Combine(folder, (UseNestedClasses && !type.IsRoot ? MainClass + "." : string.Empty) + type.AssignedName + CodeWriter.FileExtension), new[] { type }); + // } + //} + } + else if (OutputStream != null) + { + WriteClassesToFile(OutputStream, Types); + } + + } + + private void WriteClassesToFile(string path, IEnumerable types) + { + using (var sw = new StreamWriter(path, false, Encoding.UTF8)) + { + WriteClassesToFile(sw, types); + } + } + + private void WriteClassesToFile(TextWriter sw, IEnumerable types) + { + var inNamespace = false; + var rootNamespace = false; + + CodeWriter.WriteFileStart(this, sw); + foreach (var type in types) + { + if (UseNamespaces && inNamespace && rootNamespace != type.IsRoot && SecondaryNamespace != null) { CodeWriter.WriteNamespaceEnd(this, sw, rootNamespace); inNamespace = false; } + if (UseNamespaces && !inNamespace) { CodeWriter.WriteNamespaceStart(this, sw, type.IsRoot); inNamespace = true; rootNamespace = type.IsRoot; } + CodeWriter.WriteClass(this, sw, type); + } + if (UseNamespaces && inNamespace) CodeWriter.WriteNamespaceEnd(this, sw, rootNamespace); + CodeWriter.WriteFileEnd(this, sw); + } + + + private void GenerateClass(JObject[] examples, JsonType type) + { + var jsonFields = new Dictionary(); + var fieldExamples = new Dictionary>(); + + var first = true; + + foreach (var obj in examples) + { + foreach (var prop in obj.Properties()) + { + JsonType fieldType; + var currentType = new JsonType(this, prop.Value); + var propName = prop.Name; + if (jsonFields.TryGetValue(propName, out fieldType)) + { + + var commonType = fieldType.GetCommonType(currentType); + + jsonFields[propName] = commonType; + } + else + { + var commonType = currentType; + if (first) commonType = commonType.MaybeMakeNullable(this); + else commonType = commonType.GetCommonType(JsonType.GetNull(this)); + jsonFields.Add(propName, commonType); + fieldExamples[propName] = new List(); + } + var fe = fieldExamples[propName]; + var val = prop.Value; + if (val.Type == JTokenType.Null || val.Type == JTokenType.Undefined) + { + if (!fe.Contains(null)) + { + fe.Insert(0, null); + } + } + else + { + var v = val.Type == JTokenType.Array || val.Type == JTokenType.Object ? val : val.Value(); + if (!fe.Any(x => v.Equals(x))) + fe.Add(v); + } + } + first = false; + } + + if (UseNestedClasses) + { + foreach (var field in jsonFields) + { + Names.Add(field.Key.ToLower()); + } + } + + foreach (var field in jsonFields) + { + var fieldType = field.Value; + if (fieldType.Type == JsonTypeEnum.Object) + { + var subexamples = new List(examples.Length); + foreach (var obj in examples) + { + JToken value; + if (obj.TryGetValue(field.Key, out value)) + { + if (value.Type == JTokenType.Object) + { + subexamples.Add((JObject)value); + } + } + } + + fieldType.AssignName(CreateUniqueClassName(field.Key)); + GenerateClass(subexamples.ToArray(), fieldType); + } + + if (fieldType.InternalType != null && fieldType.InternalType.Type == JsonTypeEnum.Object) + { + var subexamples = new List(examples.Length); + foreach (var obj in examples) + { + JToken value; + if (obj.TryGetValue(field.Key, out value)) + { + if (value.Type == JTokenType.Array) + { + foreach (var item in (JArray)value) + { + if (!(item is JObject)) throw new NotSupportedException("Arrays of non-objects are not supported yet."); + subexamples.Add((JObject)item); + } + + } + else if (value.Type == JTokenType.Object) + { + foreach (var item in (JObject)value) + { + if (!(item.Value is JObject)) throw new NotSupportedException("Arrays of non-objects are not supported yet."); + + subexamples.Add((JObject)item.Value); + } + } + } + } + + field.Value.InternalType.AssignName(CreateUniqueClassNameFromPlural(field.Key)); + GenerateClass(subexamples.ToArray(), field.Value.InternalType); + } + } + + type.Fields = jsonFields.Select(x => new FieldInfo(this, x.Key, x.Value, UsePascalCase, fieldExamples[x.Key])).ToArray(); + + Types.Add(type); + + } + + public IList Types { get; private set; } + private HashSet Names = new HashSet(); + + private string CreateUniqueClassName(string name) + { + name = ToTitleCase(name); + + var finalName = name; + var i = 2; + while (Names.Any(x => x.Equals(finalName, StringComparison.OrdinalIgnoreCase))) + { + finalName = name + i.ToString(); + i++; + } + + Names.Add(finalName); + return finalName; + } + + private string CreateUniqueClassNameFromPlural(string plural) + { + plural = ToTitleCase(plural); + string name; +#if !FRCORE + name = pluralizationService.Singularize(plural); +#else + name = plural.Last() == 's' ? plural.Remove(plural.Length - 1) : plural; +#endif + return CreateUniqueClassName(name); + } + + + + internal static string ToTitleCase(string str) + { + var sb = new StringBuilder(str.Length); + var flag = true; + + for (int i = 0; i < str.Length; i++) + { + var c = str[i]; + if (char.IsLetterOrDigit(c)) + { + sb.Append(flag ? char.ToUpper(c) : c); + flag = false; + } + else + { + flag = true; + } + } + + return sb.ToString(); + } + + public bool HasSecondaryClasses + { + get { return Types.Count > 1; } + } + + public static readonly string[] FileHeader = new[] { + "Generated by Xamasoft JSON Class Generator", + "http://www.xamasoft.com/json-class-generator" + }; + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/JsonClassHelper.cs b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/JsonClassHelper.cs new file mode 100644 index 00000000..e627b26e --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/JsonClassHelper.cs @@ -0,0 +1,198 @@ +// Copyright © 2010 Xamasoft +// Licensed under the Microsoft Reciprocal License (MS-RL). See LICENSE.txt for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Newtonsoft.Json.Linq; + +namespace FastReport.JsonClassGenerator +{ + internal static class JsonClassHelper + { + + public static T GetJToken(JObject obj, string field) where T : JToken + { + JToken value; + if (obj.TryGetValue(field, out value)) return GetJToken(value); + else return null; + } + + private static T GetJToken(JToken token) where T : JToken + { + if (token == null) return null; + if (token.Type == JTokenType.Null) return null; + if (token.Type == JTokenType.Undefined) return null; + return (T)token; + } + + public static string ReadString(JToken token) + { + var value = GetJToken(token); + if (value == null) return null; + return (string)value.Value; + } + + + public static bool ReadBoolean(JToken token) + { + var value = GetJToken(token); + if (value == null) throw new Newtonsoft.Json.JsonSerializationException(); + return Convert.ToBoolean(value.Value); + + } + + public static bool? ReadNullableBoolean(JToken token) + { + var value = GetJToken(token); + if (value == null) return null; + return Convert.ToBoolean(value.Value); + } + + + public static int ReadInteger(JToken token) + { + var value = GetJToken(token); + if (value == null) throw new Newtonsoft.Json.JsonSerializationException(); + return Convert.ToInt32((long)value.Value); + + } + + public static int? ReadNullableInteger(JToken token) + { + var value = GetJToken(token); + if (value == null) return null; + return Convert.ToInt32((long)value.Value); + + } + + + + public static long ReadLong(JToken token) + { + var value = GetJToken(token); + if (value == null) throw new Newtonsoft.Json.JsonSerializationException(); + return Convert.ToInt64(value.Value); + + } + + public static long? ReadNullableLong(JToken token) + { + var value = GetJToken(token); + if (value == null) return null; + return Convert.ToInt64(value.Value); + } + + + public static double ReadFloat(JToken token) + { + var value = GetJToken(token); + if (value == null) throw new Newtonsoft.Json.JsonSerializationException(); + return Convert.ToDouble(value.Value); + + } + + public static double? ReadNullableFloat(JToken token) + { + var value = GetJToken(token); + if (value == null) return null; + return Convert.ToDouble(value.Value); + + } + + + + + public static DateTime ReadDate(JToken token) + { + var value = GetJToken(token); + if (value == null) throw new Newtonsoft.Json.JsonSerializationException(); + return Convert.ToDateTime(value.Value); + + } + + public static DateTime? ReadNullableDate(JToken token) + { + var value = GetJToken(token); + if (value == null) return null; + return Convert.ToDateTime(value.Value); + + } + + public static object ReadObject(JToken token) + { + var value = GetJToken(token); + if (value == null) return null; + if (value.Type == JTokenType.Object) return value; + if (value.Type == JTokenType.Array) return ReadArray(value, ReadObject); + + var jvalue = value as JValue; + if (jvalue != null) return jvalue.Value; + + return value; + } + + public static T ReadStronglyTypedObject(JToken token) where T : class + { + var value = GetJToken(token); + if (value == null) return null; + return (T)Activator.CreateInstance(typeof(T), new object[] { token }); + + } + + + public delegate T ValueReader(JToken token); + + + + public static T[] ReadArray(JToken token, ValueReader reader) + { + var value = GetJToken(token); + if (value == null) return null; + + var array = new T[value.Count]; + for (int i = 0; i < array.Length; i++) + { + array[i] = reader(value[i]); + } + return array; + + } + + + + public static Dictionary ReadDictionary(JToken token) + { + var value = GetJToken(token); + if (value == null) return null; + + var dict = new Dictionary(); + + return dict; + } + + public static Array ReadArray(JArray jArray, ValueReader reader, Type type) + { + if (jArray == null) return null; + + var elemType = type.GetElementType(); + + var array = Array.CreateInstance(elemType, jArray.Count); + for (int i = 0; i < array.Length; i++) + { + if (elemType.IsArray) + { + array.SetValue(ReadArray(GetJToken(jArray[i]), reader, elemType), i); + } + else + { + array.SetValue(reader(jArray[i]), i); + } + + } + return array; + + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/JsonType.cs b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/JsonType.cs new file mode 100644 index 00000000..dce60273 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/JsonType.cs @@ -0,0 +1,324 @@ +// Copyright © 2010 Xamasoft +// Licensed under the Microsoft Reciprocal License (MS-RL). See LICENSE.txt for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Newtonsoft.Json.Linq; +using System.Globalization; + +namespace FastReport.JsonClassGenerator +{ + public class JsonType + { + + + private JsonType(IJsonClassGeneratorConfig generator) + { + this.generator = generator; + } + + public JsonType(IJsonClassGeneratorConfig generator, JToken token) + : this(generator) + { + + Type = GetFirstTypeEnum(token); + + if (Type == JsonTypeEnum.Array) + { + var array = (JArray)token; + InternalType = GetCommonType(generator, array.ToArray()); + } + } + + internal static JsonType GetNull(IJsonClassGeneratorConfig generator) + { + return new JsonType(generator, JsonTypeEnum.NullableSomething); + } + + private IJsonClassGeneratorConfig generator; + + internal JsonType(IJsonClassGeneratorConfig generator, JsonTypeEnum type) + : this(generator) + { + this.Type = type; + } + + + public static JsonType GetCommonType(IJsonClassGeneratorConfig generator, JToken[] tokens) + { + + if (tokens.Length == 0) return new JsonType(generator, JsonTypeEnum.NonConstrained); + + var common = new JsonType(generator, tokens[0]).MaybeMakeNullable(generator); + + for (int i = 1; i < tokens.Length; i++) + { + var current = new JsonType(generator, tokens[i]); + common = common.GetCommonType(current); + } + + return common; + + } + + internal JsonType MaybeMakeNullable(IJsonClassGeneratorConfig generator) + { + if (!generator.AlwaysUseNullableValues) return this; + return this.GetCommonType(JsonType.GetNull(generator)); + } + + + public JsonTypeEnum Type { get; private set; } + public JsonType InternalType { get; private set; } + public string AssignedName { get; private set; } + + + public void AssignName(string name) + { + AssignedName = name; + } + + + + public bool MustCache + { + get + { + switch (Type) + { + case JsonTypeEnum.Array: return true; + case JsonTypeEnum.Object: return true; + case JsonTypeEnum.Anything: return true; + case JsonTypeEnum.Dictionary: return true; + case JsonTypeEnum.NonConstrained: return true; + default: return false; + } + } + } + + public string GetReaderName() + { + if (Type == JsonTypeEnum.Anything || Type == JsonTypeEnum.NullableSomething || Type == JsonTypeEnum.NonConstrained) + { + return "ReadObject"; + } + if (Type == JsonTypeEnum.Object) + { + return string.Format("ReadStronglyTypedObject<{0}>", AssignedName); + } + else if (Type == JsonTypeEnum.Array) + { + return string.Format("ReadArray<{0}>", InternalType.GetTypeName()); + } + else + { + return string.Format("Read{0}", Enum.GetName(typeof(JsonTypeEnum), Type)); + } + } + + public JsonType GetInnermostType() + { + if (Type != JsonTypeEnum.Array) throw new InvalidOperationException(); + if (InternalType.Type != JsonTypeEnum.Array) return InternalType; + return InternalType.GetInnermostType(); + } + + + public string GetTypeName() + { + return generator.CodeWriter.GetTypeName(this, generator); + } + + public string GetJTokenType() + { + switch (Type) + { + case JsonTypeEnum.Boolean: + case JsonTypeEnum.Integer: + case JsonTypeEnum.Long: + case JsonTypeEnum.Float: + case JsonTypeEnum.Date: + case JsonTypeEnum.NullableBoolean: + case JsonTypeEnum.NullableInteger: + case JsonTypeEnum.NullableLong: + case JsonTypeEnum.NullableFloat: + case JsonTypeEnum.NullableDate: + case JsonTypeEnum.String: + return "JValue"; + case JsonTypeEnum.Array: + return "JArray"; + case JsonTypeEnum.Dictionary: + return "JObject"; + case JsonTypeEnum.Object: + return "JObject"; + default: + return "JToken"; + + } + } + + public JsonType GetCommonType(JsonType type2) + { + var commonType = GetCommonTypeEnum(this.Type, type2.Type); + + if (commonType == JsonTypeEnum.Array) + { + if (type2.Type == JsonTypeEnum.NullableSomething) return this; + if (this.Type == JsonTypeEnum.NullableSomething) return type2; + var commonInternalType = InternalType.GetCommonType(type2.InternalType).MaybeMakeNullable(generator); + if (commonInternalType != InternalType) return new JsonType(generator, JsonTypeEnum.Array) { InternalType = commonInternalType }; + } + + + //if (commonType == JsonTypeEnum.Dictionary) + //{ + // var commonInternalType = InternalType.GetCommonType(type2.InternalType); + // if (commonInternalType != InternalType) return new JsonType(JsonTypeEnum.Dictionary) { InternalType = commonInternalType }; + //} + + + if (this.Type == commonType) return this; + return new JsonType(generator, commonType).MaybeMakeNullable(generator); + } + + + private static bool IsNull(JsonTypeEnum type) + { + return type == JsonTypeEnum.NullableSomething; + } + + + + private JsonTypeEnum GetCommonTypeEnum(JsonTypeEnum type1, JsonTypeEnum type2) + { + if (type1 == JsonTypeEnum.NonConstrained) return type2; + if (type2 == JsonTypeEnum.NonConstrained) return type1; + + switch (type1) + { + case JsonTypeEnum.Boolean: + if (IsNull(type2)) return JsonTypeEnum.NullableBoolean; + if (type2 == JsonTypeEnum.Boolean) return type1; + break; + case JsonTypeEnum.NullableBoolean: + if (IsNull(type2)) return type1; + if (type2 == JsonTypeEnum.Boolean) return type1; + break; + case JsonTypeEnum.Integer: + if (IsNull(type2)) return JsonTypeEnum.NullableInteger; + if (type2 == JsonTypeEnum.Float) return JsonTypeEnum.Float; + if (type2 == JsonTypeEnum.Long) return JsonTypeEnum.Long; + if (type2 == JsonTypeEnum.Integer) return type1; + break; + case JsonTypeEnum.NullableInteger: + if (IsNull(type2)) return type1; + if (type2 == JsonTypeEnum.Float) return JsonTypeEnum.NullableFloat; + if (type2 == JsonTypeEnum.Long) return JsonTypeEnum.NullableLong; + if (type2 == JsonTypeEnum.Integer) return type1; + break; + case JsonTypeEnum.Float: + if (IsNull(type2)) return JsonTypeEnum.NullableFloat; + if (type2 == JsonTypeEnum.Float) return type1; + if (type2 == JsonTypeEnum.Integer) return type1; + if (type2 == JsonTypeEnum.Long) return type1; + break; + case JsonTypeEnum.NullableFloat: + if (IsNull(type2)) return type1; + if (type2 == JsonTypeEnum.Float) return type1; + if (type2 == JsonTypeEnum.Integer) return type1; + if (type2 == JsonTypeEnum.Long) return type1; + break; + case JsonTypeEnum.Long: + if (IsNull(type2)) return JsonTypeEnum.NullableLong; + if (type2 == JsonTypeEnum.Float) return JsonTypeEnum.Float; + if (type2 == JsonTypeEnum.Integer) return type1; + break; + case JsonTypeEnum.NullableLong: + if (IsNull(type2)) return type1; + if (type2 == JsonTypeEnum.Float) return JsonTypeEnum.NullableFloat; + if (type2 == JsonTypeEnum.Integer) return type1; + if (type2 == JsonTypeEnum.Long) return type1; + break; + case JsonTypeEnum.Date: + if (IsNull(type2)) return JsonTypeEnum.NullableDate; + if (type2 == JsonTypeEnum.Date) return JsonTypeEnum.Date; + break; + case JsonTypeEnum.NullableDate: + if (IsNull(type2)) return type1; + if (type2 == JsonTypeEnum.Date) return type1; + break; + case JsonTypeEnum.NullableSomething: + if (IsNull(type2)) return type1; + if (type2 == JsonTypeEnum.String) return JsonTypeEnum.String; + if (type2 == JsonTypeEnum.Integer) return JsonTypeEnum.NullableInteger; + if (type2 == JsonTypeEnum.Float) return JsonTypeEnum.NullableFloat; + if (type2 == JsonTypeEnum.Long) return JsonTypeEnum.NullableLong; + if (type2 == JsonTypeEnum.Boolean) return JsonTypeEnum.NullableBoolean; + if (type2 == JsonTypeEnum.Date) return JsonTypeEnum.NullableDate; + if (type2 == JsonTypeEnum.Array) return JsonTypeEnum.Array; + if (type2 == JsonTypeEnum.Object) return JsonTypeEnum.Object; + break; + case JsonTypeEnum.Object: + if (IsNull(type2)) return type1; + if (type2 == JsonTypeEnum.Object) return type1; + if (type2 == JsonTypeEnum.Dictionary) throw new ArgumentException(); + break; + case JsonTypeEnum.Dictionary: + throw new ArgumentException(); + //if (IsNull(type2)) return type1; + //if (type2 == JsonTypeEnum.Object) return type1; + //if (type2 == JsonTypeEnum.Dictionary) return type1; + // break; + case JsonTypeEnum.Array: + if (IsNull(type2)) return type1; + if (type2 == JsonTypeEnum.Array) return type1; + break; + case JsonTypeEnum.String: + if (IsNull(type2)) return type1; + if (type2 == JsonTypeEnum.String) return type1; + break; + } + + return JsonTypeEnum.Anything; + + } + + private static bool IsNull(JTokenType type) + { + return type == JTokenType.Null || type == JTokenType.Undefined; + } + + + + private static JsonTypeEnum GetFirstTypeEnum(JToken token) + { + var type = token.Type; + if (type == JTokenType.Integer) + { + if ((long)((JValue)token).Value < int.MaxValue) return JsonTypeEnum.Integer; + else return JsonTypeEnum.Long; + + } + switch (type) + { + case JTokenType.Array: return JsonTypeEnum.Array; + case JTokenType.Boolean: return JsonTypeEnum.Boolean; + case JTokenType.Float: return JsonTypeEnum.Float; + case JTokenType.Null: return JsonTypeEnum.NullableSomething; + case JTokenType.Undefined: return JsonTypeEnum.NullableSomething; + case JTokenType.String: return JsonTypeEnum.String; + case JTokenType.Object: return JsonTypeEnum.Object; + case JTokenType.Date: return JsonTypeEnum.Date; + + default: return JsonTypeEnum.Anything; + + } + } + + + public IList Fields { get; internal set; } + public bool IsRoot { get; internal set; } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/JsonTypeEnum.cs b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/JsonTypeEnum.cs new file mode 100644 index 00000000..ea8806eb --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/JsonTypeEnum.cs @@ -0,0 +1,33 @@ +// Copyright © 2010 Xamasoft +// Licensed under the Microsoft Reciprocal License (MS-RL). See LICENSE.txt for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace FastReport.JsonClassGenerator +{ + public enum JsonTypeEnum + { + Anything, + String, + Boolean, + Integer, + Long, + Float, + Date, + NullableInteger, + NullableLong, + NullableFloat, + NullableBoolean, + NullableDate, + Object, + Array, + Dictionary, + NullableSomething, + NonConstrained + + + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/LICENSE.txt b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/LICENSE.txt new file mode 100644 index 00000000..3249fc97 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonClassGenerator/LICENSE.txt @@ -0,0 +1,33 @@ +Microsoft Reciprocal License (Ms-RL) + +This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. + +1. Definitions + +The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. + +A "contribution" is the original software, or any additions or changes to the software. + +A "contributor" is any person that distributes its contribution under this license. + +"Licensed patents" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights + +(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. + +(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. + +3. Conditions and Limitations + +(A) Reciprocal Grants- For any file you distribute that contains code from the software (in source code or binary format), you must provide recipients the source code to that file along with a copy of this license, which license will govern that file. You may license other files that are entirely your own work and do not contain code from the software under any terms you choose. + +(B) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. + +(C) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. + +(D) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. + +(E) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. + +(F) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonCompiler.cs b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonCompiler.cs new file mode 100644 index 00000000..4a45efce --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonCompiler.cs @@ -0,0 +1,64 @@ +using Microsoft.CSharp; +using System; +using System.CodeDom.Compiler; +using System.IO; +using System.Reflection; + +namespace FastReport.Json +{ + /* + HOW TO USE: + + var type = JsonCompiler.Compile(json); + var properties = type.GetProperties(); + var obj = JsonConvert.DeserializeObject(json, type); + + Report report = new Report(); + report.Load(@"C:\report.frx"); + + foreach (var prop in properties) + { + report.RegisterData((IList)prop.GetValue(obj, null), prop.Name); + } + */ + public class JsonCompiler + { + public static Type Compile(string json) + { + JsonClassGenerator.JsonClassGenerator gen = new JsonClassGenerator.JsonClassGenerator(); + gen.Example = json; + gen.UseProperties = true; + gen.Namespace = "__JSON__"; + gen.MainClass = "__JSON__"; + gen.UsePascalCase = true; + + string source = ""; + using (StringWriter sw = new StringWriter()) + { + gen.OutputStream = sw; + gen.GenerateClasses(); + sw.Flush(); + source = sw.ToString(); + } + + using (CSharpCodeProvider compiler = new CSharpCodeProvider()) + { + CompilerParameters parameters = new CompilerParameters() + { + GenerateInMemory = true + }; + string nLocation = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location); + string nPath = Path.Combine(nLocation, "Newtonsoft.Json.dll"); + parameters.ReferencedAssemblies.Add(nPath); +#if FRCORE + var mscorPath = compiler.GetReference("System.Private.CoreLib.dll").Display; + parameters.ReferencedAssemblies.Add(mscorPath); +#endif + + CompilerResults results = compiler.CompileAssemblyFromSource(parameters, source); + Type type = results.CompiledAssembly.GetType("__JSON__.__JSON__"); + return type; + } + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonConnectionEditor.cs b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonConnectionEditor.cs new file mode 100644 index 00000000..8eeaea0d --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonConnectionEditor.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using FastReport.Utils; + +namespace FastReport.Data.ConnectionEditors +{ + internal partial class JsonConnectionEditor : ConnectionEditorBase + { + private void Localize() + { + gbSelect.Text = Res.Get("ConnectionEditors,Common,Database"); + lblJsonPath.Text = Res.Get("ConnectionEditors,Json,Path"); + tbJsonPath.Image = Res.GetImage(1); + } + + private void tbFile_ButtonClick(object sender, EventArgs e) + { + using (OpenFileDialog dialog = new OpenFileDialog()) + { + if (dialog.ShowDialog() == DialogResult.OK) + tbJsonPath.Text = dialog.FileName; + } + } + + protected override string GetConnectionString() + { + JsonConnectionStringBuilder builder = new JsonConnectionStringBuilder(); + builder.Json = tbJsonPath.Text; + return builder.ToString(); + } + + protected override void SetConnectionString(string value) + { + JsonConnectionStringBuilder builder = new JsonConnectionStringBuilder(value); + tbJsonPath.Text = builder.Json; + } + + public JsonConnectionEditor() + { + InitializeComponent(); + Localize(); + } + } +} \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonConnectionEditor.designer.cs b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonConnectionEditor.designer.cs new file mode 100644 index 00000000..0d276025 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonConnectionEditor.designer.cs @@ -0,0 +1,84 @@ +namespace FastReport.Data.ConnectionEditors +{ + partial class JsonConnectionEditor + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.gbSelect = new System.Windows.Forms.GroupBox(); + this.tbJsonPath = new FastReport.Controls.TextBoxButton(); + this.lblJsonPath = new System.Windows.Forms.Label(); + this.gbSelect.SuspendLayout(); + this.SuspendLayout(); + // + // gbSelect + // + this.gbSelect.Controls.Add(this.lblJsonPath); + this.gbSelect.Controls.Add(this.tbJsonPath); + this.gbSelect.Location = new System.Drawing.Point(8, 4); + this.gbSelect.Name = "gbSelect"; + this.gbSelect.Size = new System.Drawing.Size(320, 77); + this.gbSelect.TabIndex = 1; + this.gbSelect.TabStop = false; + this.gbSelect.Text = "Select database file"; + // + // tbJsonPath + // + this.tbJsonPath.Image = null; + this.tbJsonPath.Location = new System.Drawing.Point(12, 40); + this.tbJsonPath.Name = "tbJsonPath"; + this.tbJsonPath.Size = new System.Drawing.Size(296, 21); + this.tbJsonPath.TabIndex = 2; + this.tbJsonPath.ButtonClick += new System.EventHandler(this.tbFile_ButtonClick); + // + // lblJsonPath + // + this.lblJsonPath.AutoSize = true; + this.lblJsonPath.Location = new System.Drawing.Point(12, 20); + this.lblJsonPath.Name = "lblJsonPath"; + this.lblJsonPath.Size = new System.Drawing.Size(78, 13); + this.lblJsonPath.TabIndex = 3; + this.lblJsonPath.Text = "Json file or url:"; + // + // JsonConnectionEditor + // + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.Controls.Add(this.gbSelect); + this.Name = "JsonConnectionEditor"; + this.Size = new System.Drawing.Size(336, 91); + this.gbSelect.ResumeLayout(false); + this.gbSelect.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox gbSelect; + private FastReport.Controls.TextBoxButton tbJsonPath; + private System.Windows.Forms.Label lblJsonPath; + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonConnectionEditor.resx b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonConnectionEditor.resx new file mode 100644 index 00000000..d58980a3 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonConnectionEditor.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonConnectionStringBuilder.cs b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonConnectionStringBuilder.cs new file mode 100644 index 00000000..fc5686e8 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonConnectionStringBuilder.cs @@ -0,0 +1,50 @@ +using System.Data.Common; + +namespace FastReport.Data +{ + /// + /// Represents the JsonDataConnection connection string builder. + /// + /// + /// Use this class to parse connection string returned by the JsonDataConnection class. + /// + public class JsonConnectionStringBuilder : DbConnectionStringBuilder + { + /// + /// Gets or sets the path to json. It can be a path to local file or URL. + /// + public string Json + { + get + { + object json; + if (TryGetValue("Json", out json)) + return (string)json; + return ""; + } + set + { + base["Json"] = value; + } + } + + /// + /// Initializes a new instance of the class with default settings. + /// + public JsonConnectionStringBuilder() + { + ConnectionString = ""; + } + + /// + /// Initializes a new instance of the class with + /// specified connection string. + /// + /// The connection string. + public JsonConnectionStringBuilder(string connectionString) + : base() + { + ConnectionString = connectionString; + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonDataConnection.DesignExt.cs b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonDataConnection.DesignExt.cs new file mode 100644 index 00000000..d0563711 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonDataConnection.DesignExt.cs @@ -0,0 +1,52 @@ +using System; +using System.Data; +using System.ComponentModel; +using FastReport.Data.ConnectionEditors; +using System.Data.Common; +using System.Net; +using FastReport.Json; +using Newtonsoft.Json; +using System.Collections; +using System.Text; + +namespace FastReport.Data +{ + /// + /// Represents a connection to json database. + /// + /// This example shows how to add a new connection to the report. + /// + /// Report report = new Report(); + /// JsonDataConnection conn = new JsonDataConnection(); + /// conn.Json = @"c:\data.txt"; + /// report.Dictionary.Connections.Add(conn); + /// conn.CreateAllTables(); + /// + /// + public partial class JsonDataConnection : DataConnectionBase + { + #region Public Methods + + /// + public override ConnectionEditorBase GetEditor() + { + return new JsonConnectionEditor(); + } + + /// + public override string GetConnectionId() + { + return "Json: " + Json; + } + + /// + public override void TestConnection() + { + using (DataSet dataset = CreateDataSet()) + { + } + } + + #endregion + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonDataConnection.cs b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonDataConnection.cs new file mode 100644 index 00000000..426a05fd --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/JsonDataConnection.cs @@ -0,0 +1,203 @@ +using System; +using System.Data; +using System.ComponentModel; +using System.Data.Common; +using System.Net; +using FastReport.Json; +using Newtonsoft.Json; +using System.Collections; +using System.Text; + +namespace FastReport.Data +{ + /// + /// Represents a connection to json database. + /// + /// This example shows how to add a new connection to the report. + /// + /// Report report = new Report(); + /// JsonDataConnection conn = new JsonDataConnection(); + /// conn.Json = @"c:\data.txt"; + /// report.Dictionary.Connections.Add(conn); + /// conn.CreateAllTables(); + /// + /// + public partial class JsonDataConnection : DataConnectionBase + { + private Encoding dataEncoding; + private string jsonData; + + #region Properties + + public string JsonData + { + get + { + if (string.IsNullOrEmpty(jsonData)) + using (WebClient webClient = new WebClient()) + { + webClient.Encoding = dataEncoding; + jsonData = webClient.DownloadString(Json); + } + return jsonData; + } + set { jsonData = value; } + } + /// + /// Gets or sets the path to json. It can be a path to local file or URL. + /// + [Category("Data")] + public string Json + { + get + { + JsonConnectionStringBuilder builder = new JsonConnectionStringBuilder(ConnectionString); + return builder.Json; + } + set + { + JsonConnectionStringBuilder builder = new JsonConnectionStringBuilder(ConnectionString); + builder.Json = value; + ConnectionString = builder.ToString(); + } + } + + /// + /// Gets or sets the data encoding value. + /// + [Browsable(false)] + public Encoding DataEncoding + { + get { return dataEncoding; } + set { dataEncoding = value; } + } + + #endregion + + #region Protected Methods + /// + protected override DataSet CreateDataSet() + { + DataSet dataset = base.CreateDataSet(); + + if (string.IsNullOrWhiteSpace(JsonData)) + throw new Exception("Data is empty."); + + if (JsonData.Trim().StartsWith("[")) + JsonData = "{\"Data\":" + JsonData + "}"; + + var type = JsonCompiler.Compile(JsonData); + var properties = type.GetProperties(); + var obj = JsonConvert.DeserializeObject(JsonData, type); + + foreach (var prop in properties) + { + IList list = prop.GetValue(obj, null) as IList; + if (list != null) + { + DataTable dataTable = ToDataTable(list); + dataTable.TableName = prop.Name; + dataset.Tables.Add(dataTable); + } + } + + return dataset; + } + + /// + protected override void SetConnectionString(string value) + { + DisposeDataSet(); + base.SetConnectionString(value); + } + #endregion + + #region Public Methods + /// + public override void FillTableSchema(DataTable table, string selectCommand, CommandParameterCollection parameters) + { + // do nothing + } + + /// + public override void FillTableData(DataTable table, string selectCommand, CommandParameterCollection parameters) + { + // do nothing + } + + /// + public override void CreateTable(TableDataSource source) + { + if (DataSet.Tables.Contains(source.TableName)) + { + source.Table = DataSet.Tables[source.TableName]; + base.CreateTable(source); + } + else + source.Table = null; + } + + /// + public override void DeleteTable(TableDataSource source) + { + // do nothing + } + + /// + public override string QuoteIdentifier(string value, DbConnection connection) + { + return value; + } + + /// + public override string[] GetTableNames() + { + string[] result = new string[DataSet.Tables.Count]; + for (int i = 0; i < DataSet.Tables.Count; i++) + { + result[i] = DataSet.Tables[i].TableName; + } + return result; + } + + #endregion + + DataTable ToDataTable(IList data) + { + DataTable table = new DataTable(); + + if (data == null || data.Count == 0) + return table; + + PropertyDescriptorCollection props = TypeDescriptor.GetProperties(data[0]); + + for (int i = 0; i < props.Count; i++) + { + PropertyDescriptor prop = props[i]; + table.Columns.Add(prop.Name, prop.PropertyType); + } + + object[] values = new object[props.Count]; + + foreach (object item in data) + { + for (int i = 0; i < values.Length; i++) + { + values[i] = props[i].GetValue(item); + } + table.Rows.Add(values); + } + + return table; + } + + /// + /// Initializes a new instance of the class with default settings. + /// + public JsonDataConnection() + { + IsSqlBased = false; + dataEncoding = Encoding.UTF8; + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Json/readme.txt b/Extras/Core/FastReport.Data/FastReport.Data.Json/readme.txt new file mode 100644 index 00000000..ba84ed19 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Json/readme.txt @@ -0,0 +1,11 @@ +How to use it: +- execute the following code once at the application start: +FastReport.Utils.RegisteredObjects.AddConnection(typeof(JsonDataConnection)); +- now you should be able to create a new Json data connection from code: +Report report = new Report(); +report.Load(@"YourReport.frx"); +//... +JsonDataConnection conn = new JsonDataConnection(); +conn.ConnectionString = "path to JSON file"; +conn.CreateAllTables(); +report.Dictionary.Connections.Add(conn); \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/AssemblyInitializer.cs b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/AssemblyInitializer.cs new file mode 100644 index 00000000..3c17670b --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/AssemblyInitializer.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using FastReport.Utils; + +namespace FastReport.Data +{ + public class MongoDBAssemblyInitializer : AssemblyInitializerBase + { + public MongoDBAssemblyInitializer() + { + RegisteredObjects.AddConnection(typeof(MongoDBDataConnection)); + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/FastReport.Data.MongoDB.csproj b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/FastReport.Data.MongoDB.csproj new file mode 100644 index 00000000..c284a571 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/FastReport.Data.MongoDB.csproj @@ -0,0 +1,100 @@ + + + + netstandard2.0;net4.5 + false + ../../../FastReport.Plugins.snk + true + Fast Reports Inc. + Fast Reports Inc. + https://www.fast-report.com/en/product/fast-report-net/license + https://www.fast-report.com/en/product/fast-report-net + Fast Reports Inc. + FastReport.Data.MongoDB + Represents a connection to MongoDB database for FastReport.Net. + FastReport.Data.MongoDB + https://www.fast-report.com/download/images/frlogo-big.png + reporting, MongoDB, connection, reports + 2018.2.2$(VersionSuffix) + 2018.2.2.0 + 2018.2.2.0 + Debug;Release; + FastReport.Data.MongoDB + FastReport.Data + + + + FRCORE; + + + + + + + + + + + + + + + + + + + + + + + + false + + + False + ..\..\..\..\FastReport\bin\Release\FastReport.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + UserControl + + + MongoDBConnectionEditor.cs + + + + + MongoDBConnectionEditor.cs + Designer + + + + + + + + + diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.Designer.cs b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.Designer.cs new file mode 100644 index 00000000..bcd2f76a --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.Designer.cs @@ -0,0 +1,228 @@ +namespace FastReport.Data +{ + partial class MongoDBConnectionEditor + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.gbDatabase = new System.Windows.Forms.GroupBox(); + this.lblDatabase = new System.Windows.Forms.Label(); + this.tbDatabase = new System.Windows.Forms.TextBox(); + this.btnAdvanced = new System.Windows.Forms.Button(); + this.tbUserName = new System.Windows.Forms.TextBox(); + this.tbPassword = new System.Windows.Forms.TextBox(); + this.lblUserName = new System.Windows.Forms.Label(); + this.lblPassword = new System.Windows.Forms.Label(); + this.gbServer = new System.Windows.Forms.GroupBox(); + this.lblPort = new System.Windows.Forms.Label(); + this.tbPort = new System.Windows.Forms.TextBox(); + this.lblHost = new System.Windows.Forms.Label(); + this.tbHost = new System.Windows.Forms.TextBox(); + this.label1 = new FastReport.Controls.LabelLine(); + this.cbUseSsl = new System.Windows.Forms.CheckBox(); + this.gbDatabase.SuspendLayout(); + this.gbServer.SuspendLayout(); + this.SuspendLayout(); + // + // gbDatabase + // + this.gbDatabase.Controls.Add(this.lblDatabase); + this.gbDatabase.Controls.Add(this.tbDatabase); + this.gbDatabase.Location = new System.Drawing.Point(8, 142); + this.gbDatabase.Name = "gbDatabase"; + this.gbDatabase.Size = new System.Drawing.Size(320, 76); + this.gbDatabase.TabIndex = 5; + this.gbDatabase.TabStop = false; + this.gbDatabase.Text = "Database"; + // + // lblDatabase + // + this.lblDatabase.AutoSize = true; + this.lblDatabase.Location = new System.Drawing.Point(12, 20); + this.lblDatabase.Name = "lblDatabase"; + this.lblDatabase.Size = new System.Drawing.Size(79, 19); + this.lblDatabase.TabIndex = 3; + this.lblDatabase.Text = "Database:"; + // + // tbDatabase + // + this.tbDatabase.Location = new System.Drawing.Point(12, 40); + this.tbDatabase.Name = "tbDatabase"; + this.tbDatabase.Size = new System.Drawing.Size(296, 27); + this.tbDatabase.TabIndex = 0; + // + // btnAdvanced + // + this.btnAdvanced.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnAdvanced.AutoSize = true; + this.btnAdvanced.Enabled = false; + this.btnAdvanced.Location = new System.Drawing.Point(226, 219); + this.btnAdvanced.Name = "btnAdvanced"; + this.btnAdvanced.Size = new System.Drawing.Size(103, 29); + this.btnAdvanced.TabIndex = 4; + this.btnAdvanced.Text = "Advanced..."; + this.btnAdvanced.UseVisualStyleBackColor = true; + this.btnAdvanced.Visible = false; + this.btnAdvanced.Click += new System.EventHandler(this.btnAdvanced_Click); + // + // tbUserName + // + this.tbUserName.Location = new System.Drawing.Point(81, 82); + this.tbUserName.Name = "tbUserName"; + this.tbUserName.Size = new System.Drawing.Size(227, 27); + this.tbUserName.TabIndex = 1; + // + // tbPassword + // + this.tbPassword.Location = new System.Drawing.Point(81, 106); + this.tbPassword.Name = "tbPassword"; + this.tbPassword.Size = new System.Drawing.Size(227, 27); + this.tbPassword.TabIndex = 2; + this.tbPassword.UseSystemPasswordChar = true; + // + // lblUserName + // + this.lblUserName.AutoSize = true; + this.lblUserName.Location = new System.Drawing.Point(12, 86); + this.lblUserName.Name = "lblUserName"; + this.lblUserName.Size = new System.Drawing.Size(91, 19); + this.lblUserName.TabIndex = 0; + this.lblUserName.Text = "User name:"; + // + // lblPassword + // + this.lblPassword.AutoSize = true; + this.lblPassword.Location = new System.Drawing.Point(12, 110); + this.lblPassword.Name = "lblPassword"; + this.lblPassword.Size = new System.Drawing.Size(82, 19); + this.lblPassword.TabIndex = 1; + this.lblPassword.Text = "Password:"; + // + // gbServer + // + this.gbServer.Controls.Add(this.lblPort); + this.gbServer.Controls.Add(this.tbPort); + this.gbServer.Controls.Add(this.lblHost); + this.gbServer.Controls.Add(this.tbHost); + this.gbServer.Controls.Add(this.tbUserName); + this.gbServer.Controls.Add(this.tbPassword); + this.gbServer.Controls.Add(this.lblUserName); + this.gbServer.Controls.Add(this.lblPassword); + this.gbServer.Location = new System.Drawing.Point(8, 3); + this.gbServer.Name = "gbServer"; + this.gbServer.Size = new System.Drawing.Size(320, 137); + this.gbServer.TabIndex = 7; + this.gbServer.TabStop = false; + this.gbServer.Text = "Server"; + // + // lblPort + // + this.lblPort.AutoSize = true; + this.lblPort.Location = new System.Drawing.Point(12, 53); + this.lblPort.Name = "lblPort"; + this.lblPort.Size = new System.Drawing.Size(44, 19); + this.lblPort.TabIndex = 6; + this.lblPort.Text = "Port:"; + // + // tbPort + // + this.tbPort.Location = new System.Drawing.Point(81, 50); + this.tbPort.Name = "tbPort"; + this.tbPort.Size = new System.Drawing.Size(227, 27); + this.tbPort.TabIndex = 5; + // + // lblHost + // + this.lblHost.AutoSize = true; + this.lblHost.Location = new System.Drawing.Point(12, 27); + this.lblHost.Name = "lblHost"; + this.lblHost.Size = new System.Drawing.Size(47, 19); + this.lblHost.TabIndex = 4; + this.lblHost.Text = "Host:"; + // + // tbHost + // + this.tbHost.Location = new System.Drawing.Point(81, 24); + this.tbHost.Name = "tbHost"; + this.tbHost.Size = new System.Drawing.Size(227, 27); + this.tbHost.TabIndex = 0; + // + // label1 + // + this.label1.Location = new System.Drawing.Point(8, 243); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(320, 17); + this.label1.TabIndex = 6; + // + // cbUseSsl + // + this.cbUseSsl.AutoSize = true; + this.cbUseSsl.Location = new System.Drawing.Point(20, 223); + this.cbUseSsl.Name = "cbUseSsl"; + this.cbUseSsl.Size = new System.Drawing.Size(86, 23); + this.cbUseSsl.TabIndex = 8; + this.cbUseSsl.Text = "Use Ssl"; + this.cbUseSsl.UseVisualStyleBackColor = true; + // + // MongoDBConnectionEditor + // + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 19F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.cbUseSsl); + this.Controls.Add(this.gbDatabase); + this.Controls.Add(this.btnAdvanced); + this.Controls.Add(this.gbServer); + this.Controls.Add(this.label1); + this.Name = "MongoDBConnectionEditor"; + this.Size = new System.Drawing.Size(504, 263); + this.gbDatabase.ResumeLayout(false); + this.gbDatabase.PerformLayout(); + this.gbServer.ResumeLayout(false); + this.gbServer.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.GroupBox gbDatabase; + private System.Windows.Forms.Label lblDatabase; + private System.Windows.Forms.TextBox tbDatabase; + private System.Windows.Forms.Button btnAdvanced; + private System.Windows.Forms.TextBox tbUserName; + private System.Windows.Forms.TextBox tbPassword; + private System.Windows.Forms.Label lblUserName; + private System.Windows.Forms.Label lblPassword; + private System.Windows.Forms.GroupBox gbServer; + private System.Windows.Forms.Label lblHost; + private System.Windows.Forms.TextBox tbHost; + private Controls.LabelLine label1; + private System.Windows.Forms.Label lblPort; + private System.Windows.Forms.TextBox tbPort; + private System.Windows.Forms.CheckBox cbUseSsl; + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.cs b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.cs new file mode 100644 index 00000000..ed19ce0d --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using FastReport.Data.ConnectionEditors; +using FastReport.Forms; +using MongoDB.Driver; +using FastReport.Utils; +using FastReport.Data; + +namespace FastReport.Data +{ + public partial class MongoDBConnectionEditor : ConnectionEditorBase + { + private string FConnectionString; + + private void btnAdvanced_Click(object sender, EventArgs e) + { + using (AdvancedConnectionPropertiesForm form = new AdvancedConnectionPropertiesForm()) + { + MongoUrlBuilder builder = new MongoUrlBuilder(ConnectionString); + // form.AdvancedProperties = builder; + if (form.ShowDialog() == DialogResult.OK) + ConnectionString = form.AdvancedProperties.ToString(); + } + } + + private void Localize() + { + MyRes res = new MyRes("ConnectionEditors,Common"); + + gbServer.Text = res.Get("ServerLogon"); + //lblHost.Text = res.Get("Server"); + lblUserName.Text = res.Get("UserName"); + lblPassword.Text = res.Get("Password"); + + gbDatabase.Text = res.Get("Database"); + lblDatabase.Text = res.Get("DatabaseName"); + btnAdvanced.Text = Res.Get("Buttons,Advanced"); + } + + protected override string GetConnectionString() + { + MongoUrlBuilder builder = new MongoUrlBuilder(); + if (!string.IsNullOrEmpty(FConnectionString)) + builder = new MongoUrlBuilder(FConnectionString); + builder.Server = new MongoServerAddress(tbHost.Text, int.Parse(tbPort.Text)); + if (!string.IsNullOrEmpty(tbUserName.Text) && !string.IsNullOrEmpty(tbPassword.Text)) + { + builder.Username = tbUserName.Text; + builder.Password = tbPassword.Text; + builder.UseSsl = cbUseSsl.Checked; + } + MongoDBDataConnection.dbName = builder.DatabaseName = tbDatabase.Text; + return builder.ToMongoUrl().Url; + } + + protected override void SetConnectionString(string value) + { + FConnectionString = value; + MongoUrlBuilder builder = new MongoUrlBuilder(); + if (!string.IsNullOrEmpty(value)) + builder = new MongoUrlBuilder(value); + + tbHost.Text = builder.Server.Host; + tbPort.Text = builder.Server.Port.ToString(); + tbUserName.Text = builder.Username; + tbPassword.Text = builder.Password; + tbDatabase.Text = builder.DatabaseName; + } + + public MongoDBConnectionEditor() + { + InitializeComponent(); + Localize(); + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.resx b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBConnectionEditor.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBDataConnection.DesignExt.cs b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBDataConnection.DesignExt.cs new file mode 100644 index 00000000..a0afe81b --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBDataConnection.DesignExt.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Data.Common; +using MongoDB.Driver; +using FastReport.Data.ConnectionEditors; +using System.Data; +using MongoDB.Bson; + +namespace FastReport.Data +{ + public partial class MongoDBDataConnection : DataConnectionBase + { + + public override Type GetConnectionType() + { + return typeof(MongoClient); + } + + public override string GetConnectionId() + { + MongoUrlBuilder builder = new MongoUrlBuilder(ConnectionString); + string info = ""; + try + { + info = builder.DatabaseName; + } + catch + { + } + return "MongoDB: " + info; + } + + public override ConnectionEditorBase GetEditor() + { + return new MongoDBConnectionEditor(); + } + + /// + public override void TestConnection() + { + MongoClient client = new MongoClient(ConnectionString); + var databases = client.ListDatabases();//.GetDatabase(dbName); + var doc = databases.First(); + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBDataConnection.cs b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBDataConnection.cs new file mode 100644 index 00000000..b43910f7 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/MongoDBDataConnection.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Data.Common; +using MongoDB.Driver; +using System.Data; +using MongoDB.Bson; +using FastReport.Data; + +namespace FastReport.Data +{ + public partial class MongoDBDataConnection : DataConnectionBase + { + public static string dbName = ""; + + #region Private Methods + private void ExecuteFillDataTable(BsonDocument doc, DataTable dt, DataRow dr, string parent) + { + List> arrays = new List>(); + foreach (string key in doc.Names) + { + object value = doc[key]; + string x; + if (value is BsonDocument) + { + string newParent = string.IsNullOrEmpty(parent) ? key : parent + "." + key; + ExecuteFillDataTable((BsonDocument)value, dt, dr, newParent); + } + else if (value is BsonArray) + arrays.Add(new KeyValuePair(key, (BsonArray)value)); + else if (value is BsonTimestamp) + x = doc[key].AsBsonTimestamp.ToLocalTime().ToString("s"); + else if (value is BsonNull) + x = string.Empty; + else + { + x = value.ToString(); + string colName = string.IsNullOrEmpty(parent) ? key : parent + "." + key; + if (!dt.Columns.Contains(colName)) + dt.Columns.Add(colName); + dr[colName] = value; + } + } + } + #endregion + + #region Protected Methods + + /// + protected DataTable CreateDataTable(DataTable table, bool allRows) + { + MongoClient client = new MongoClient(ConnectionString); + IMongoDatabase db = client.GetDatabase(table.TableName); + + var collection = db.GetCollection(table.TableName); + if (!allRows) + { + var documents = collection.Find(new BsonDocument()).First(); + DataRow dr = table.NewRow(); + ExecuteFillDataTable(documents, table, dr, string.Empty); + } + else + { + var documents = collection.Find(new BsonDocument()).ToList(); + foreach (var obj in documents) + { + DataRow dr = table.NewRow(); + ExecuteFillDataTable(obj, table, dr, string.Empty); + table.Rows.Add(dr); + } + } + return table; + } + + protected override string GetConnectionStringWithLoginInfo(string userName, string password) + { + MongoUrlBuilder builder = new MongoUrlBuilder(ConnectionString); + builder.Username = userName; + builder.Password = password; + return builder.ToString(); + } + #endregion + + #region Public Methods + + public override string[] GetTableNames() + { + List list = new List(); + + MongoClient client = new MongoClient(ConnectionString); + IMongoDatabase db = client.GetDatabase(dbName); + IAsyncCursor collections = db.ListCollections(); + foreach (var item in collections.ToList()) + { + list.Add(item[0].ToString()); + } + return list.ToArray(); + } + + public override string QuoteIdentifier(string value, DbConnection connection) + { + return value; + } + + /// + public override void FillTableSchema(DataTable table, string selectCommand, + CommandParameterCollection parameters) + { + CreateDataTable(table, false); + } + + /// + public override void FillTableData(DataTable table, string selectCommand, + CommandParameterCollection parameters) + { + CreateDataTable(table, true); + } + #endregion + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/readme.txt b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/readme.txt new file mode 100644 index 00000000..214853ca --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MongoDB/readme.txt @@ -0,0 +1,11 @@ +How to use it: +- execute the following code once at the application start: +FastReport.Utils.RegisteredObjects.AddConnection(typeof(MongoDBDataConnection)); +- now you should be able to create a new MongoDB data connection from code: +Report report = new Report(); +report.Load(@"YourReport.frx"); +//... +MongoDBDataConnection conn = new MongoDBDataConnection(); +conn.ConnectionString = "your connection string"; +conn.CreateAllTables(); +report.Dictionary.Connections.Add(conn); \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MsSql/AssemblyInitializer.cs b/Extras/Core/FastReport.Data/FastReport.Data.MsSql/AssemblyInitializer.cs new file mode 100644 index 00000000..af8d4bda --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MsSql/AssemblyInitializer.cs @@ -0,0 +1,12 @@ +using FastReport.Utils; + +namespace FastReport.Data +{ + public class MsSqlAssemblyInitializer : AssemblyInitializerBase + { + public MsSqlAssemblyInitializer() + { + RegisteredObjects.AddConnection(typeof(MsSqlDataConnection)); + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MsSql/FastReport.Data.MsSql.csproj b/Extras/Core/FastReport.Data/FastReport.Data.MsSql/FastReport.Data.MsSql.csproj new file mode 100644 index 00000000..c37f7147 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MsSql/FastReport.Data.MsSql.csproj @@ -0,0 +1,47 @@ + + + netstandard2.0 + true + ../../../FastReport.Plugins.snk + true + Fast Reports Inc. + Fast Reports Inc. + https://www.fast-report.com/en/product/fast-report-net/license + https://www.fast-report.com/en/product/fast-report-net + Fast Reports Inc. + FastReport.Data.MsSql + Represents a connection to MS SQL database for FastReport.Net + FastReport.Data.MsSql + https://www.fast-report.com/download/images/frlogo-big.png + reporting, mssql, connection, reports, core + 2018.2.3$(VersionSuffix) + 2018.2.4.0 + 2018.2.0.0 + Debug;Release; + FastReport.Data.MsSql + FastReport.Data + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MsSql/readme.txt b/Extras/Core/FastReport.Data/FastReport.Data.MsSql/readme.txt new file mode 100644 index 00000000..92a44f1e --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MsSql/readme.txt @@ -0,0 +1,11 @@ +How to use it: +- execute the following code once at the application start: +FastReport.Utils.RegisteredObjects.AddConnection(typeof(MsSqlDataConnection)); +- now you should be able to create a new MySQL data connection from code: +Report report = new Report(); +report.Load(@"YourReport.frx"); +//... +MySqlDataConnection conn = new MySqlDataConnection(); +conn.ConnectionString = "your connection string"; +conn.CreateAllTables(); +report.Dictionary.Connections.Add(conn); \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MySql/AssemblyInitializer.cs b/Extras/Core/FastReport.Data/FastReport.Data.MySql/AssemblyInitializer.cs new file mode 100644 index 00000000..7ba8bbc5 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MySql/AssemblyInitializer.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using FastReport.Utils; + +namespace FastReport.Data +{ + public class MySqlAssemblyInitializer : AssemblyInitializerBase + { + public MySqlAssemblyInitializer() + { + RegisteredObjects.AddConnection(typeof(MySqlDataConnection)); + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MySql/FastReport.Data.MySql.csproj b/Extras/Core/FastReport.Data/FastReport.Data.MySql/FastReport.Data.MySql.csproj new file mode 100644 index 00000000..ebf6c4ff --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MySql/FastReport.Data.MySql.csproj @@ -0,0 +1,91 @@ + + + netstandard2.0;net4 + true + ../../../FastReport.Plugins.snk + true + Fast Reports Inc. + Fast Reports Inc. + https://www.fast-report.com/en/product/fast-report-net/license + https://www.fast-report.com/en/product/fast-report-net + Fast Reports Inc. + FastReport.Data.MySql + Represents a connection to My SQL database for FastReport.Net. + FastReport.Data.MySql + https://www.fast-report.com/download/images/frlogo-big.png + reporting, mysql, connection, reports + 2018.2.2$(VersionSuffix) + 2018.2.2.0 + 2018.2.0.0 + Debug;Release; + FastReport.Data.MySql + FastReport.Data + + + + + + + + + + + + + + + + + + + + + + + false + + + False + ..\..\..\..\FastReport\bin\Release\FastReport.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UserControl + + + MySqlConnectionEditor.cs + + + + + MySqlConnectionEditor.cs + Designer + + + diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MySql/MySqlConnectionEditor.Designer.cs b/Extras/Core/FastReport.Data/FastReport.Data.MySql/MySqlConnectionEditor.Designer.cs new file mode 100644 index 00000000..157f198e --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MySql/MySqlConnectionEditor.Designer.cs @@ -0,0 +1,191 @@ +namespace FastReport.Data +{ + public partial class MySqlConnectionEditor + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnAdvanced = new System.Windows.Forms.Button(); + this.gbDatabase = new System.Windows.Forms.GroupBox(); + this.lblDatabase = new System.Windows.Forms.Label(); + this.tbPassword = new System.Windows.Forms.TextBox(); + this.tbUserName = new System.Windows.Forms.TextBox(); + this.lblPassword = new System.Windows.Forms.Label(); + this.lblUserName = new System.Windows.Forms.Label(); + this.label1 = new FastReport.Controls.LabelLine(); + this.gbServer = new System.Windows.Forms.GroupBox(); + this.lblServer = new System.Windows.Forms.Label(); + this.tbServer = new System.Windows.Forms.TextBox(); + this.tbDatabase = new System.Windows.Forms.TextBox(); + this.gbDatabase.SuspendLayout(); + this.gbServer.SuspendLayout(); + this.SuspendLayout(); + // + // btnAdvanced + // + this.btnAdvanced.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnAdvanced.AutoSize = true; + this.btnAdvanced.Location = new System.Drawing.Point(252, 220); + this.btnAdvanced.Name = "btnAdvanced"; + this.btnAdvanced.Size = new System.Drawing.Size(77, 23); + this.btnAdvanced.TabIndex = 0; + this.btnAdvanced.Text = "Advanced..."; + this.btnAdvanced.UseVisualStyleBackColor = true; + this.btnAdvanced.Click += new System.EventHandler(this.btnAdvanced_Click); + // + // gbDatabase + // + this.gbDatabase.Controls.Add(this.lblDatabase); + this.gbDatabase.Controls.Add(this.tbDatabase); + this.gbDatabase.Location = new System.Drawing.Point(8, 136); + this.gbDatabase.Name = "gbDatabase"; + this.gbDatabase.Size = new System.Drawing.Size(320, 76); + this.gbDatabase.TabIndex = 1; + this.gbDatabase.TabStop = false; + this.gbDatabase.Text = "Database"; + // + // lblDatabase + // + this.lblDatabase.AutoSize = true; + this.lblDatabase.Location = new System.Drawing.Point(12, 20); + this.lblDatabase.Name = "lblDatabase"; + this.lblDatabase.Size = new System.Drawing.Size(57, 13); + this.lblDatabase.TabIndex = 3; + this.lblDatabase.Text = "Database:"; + // + // tbPassword + // + this.tbPassword.Location = new System.Drawing.Point(120, 96); + this.tbPassword.Name = "tbPassword"; + this.tbPassword.Size = new System.Drawing.Size(188, 20); + this.tbPassword.TabIndex = 2; + this.tbPassword.UseSystemPasswordChar = true; + // + // tbUserName + // + this.tbUserName.Location = new System.Drawing.Point(120, 72); + this.tbUserName.Name = "tbUserName"; + this.tbUserName.Size = new System.Drawing.Size(188, 20); + this.tbUserName.TabIndex = 1; + // + // lblPassword + // + this.lblPassword.AutoSize = true; + this.lblPassword.Location = new System.Drawing.Point(12, 100); + this.lblPassword.Name = "lblPassword"; + this.lblPassword.Size = new System.Drawing.Size(57, 13); + this.lblPassword.TabIndex = 1; + this.lblPassword.Text = "Password:"; + // + // lblUserName + // + this.lblUserName.AutoSize = true; + this.lblUserName.Location = new System.Drawing.Point(12, 76); + this.lblUserName.Name = "lblUserName"; + this.lblUserName.Size = new System.Drawing.Size(62, 13); + this.lblUserName.TabIndex = 0; + this.lblUserName.Text = "User name:"; + // + // label1 + // + this.label1.Location = new System.Drawing.Point(8, 244); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(320, 17); + this.label1.TabIndex = 2; + // + // gbServer + // + this.gbServer.Controls.Add(this.lblServer); + this.gbServer.Controls.Add(this.tbServer); + this.gbServer.Controls.Add(this.tbUserName); + this.gbServer.Controls.Add(this.tbPassword); + this.gbServer.Controls.Add(this.lblUserName); + this.gbServer.Controls.Add(this.lblPassword); + this.gbServer.Location = new System.Drawing.Point(8, 4); + this.gbServer.Name = "gbServer"; + this.gbServer.Size = new System.Drawing.Size(320, 128); + this.gbServer.TabIndex = 3; + this.gbServer.TabStop = false; + this.gbServer.Text = "Server"; + // + // lblServer + // + this.lblServer.AutoSize = true; + this.lblServer.Location = new System.Drawing.Point(12, 20); + this.lblServer.Name = "lblServer"; + this.lblServer.Size = new System.Drawing.Size(72, 13); + this.lblServer.TabIndex = 4; + this.lblServer.Text = "Server name:"; + // + // tbServer + // + this.tbServer.Location = new System.Drawing.Point(12, 40); + this.tbServer.Name = "tbServer"; + this.tbServer.Size = new System.Drawing.Size(296, 20); + this.tbServer.TabIndex = 0; + // + // tbDatabase + // + this.tbDatabase.Location = new System.Drawing.Point(12, 40); + this.tbDatabase.Name = "tbDatabase"; + this.tbDatabase.Size = new System.Drawing.Size(296, 20); + this.tbDatabase.TabIndex = 0; + // + // PostgresConnectionEditor + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.gbServer); + this.Controls.Add(this.label1); + this.Controls.Add(this.gbDatabase); + this.Controls.Add(this.btnAdvanced); + this.Name = "PostgresConnectionEditor"; + this.Size = new System.Drawing.Size(336, 263); + this.gbDatabase.ResumeLayout(false); + this.gbDatabase.PerformLayout(); + this.gbServer.ResumeLayout(false); + this.gbServer.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnAdvanced; + private System.Windows.Forms.GroupBox gbDatabase; + private System.Windows.Forms.Label lblDatabase; + private System.Windows.Forms.TextBox tbPassword; + private System.Windows.Forms.TextBox tbUserName; + private System.Windows.Forms.Label lblPassword; + private System.Windows.Forms.Label lblUserName; + private FastReport.Controls.LabelLine label1; + private System.Windows.Forms.GroupBox gbServer; + private System.Windows.Forms.Label lblServer; + private System.Windows.Forms.TextBox tbServer; + private System.Windows.Forms.TextBox tbDatabase; + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MySql/MySqlConnectionEditor.cs b/Extras/Core/FastReport.Data/FastReport.Data.MySql/MySqlConnectionEditor.cs new file mode 100644 index 00000000..8d86fd3f --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MySql/MySqlConnectionEditor.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using FastReport.Data.ConnectionEditors; +using FastReport.Forms; +using FastReport.Utils; +using MySql.Data.MySqlClient; + +namespace FastReport.Data +{ + public partial class MySqlConnectionEditor : ConnectionEditorBase + { + private string FConnectionString; + + private void btnAdvanced_Click(object sender, EventArgs e) + { + using (AdvancedConnectionPropertiesForm form = new AdvancedConnectionPropertiesForm()) + { + MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder(ConnectionString); + form.AdvancedProperties = builder; + if (form.ShowDialog() == DialogResult.OK) + ConnectionString = form.AdvancedProperties.ToString(); + } + } + + private void Localize() + { + MyRes res = new MyRes("ConnectionEditors,Common"); + + gbServer.Text = res.Get("ServerLogon"); + lblServer.Text = res.Get("Server"); + lblUserName.Text = res.Get("UserName"); + lblPassword.Text = res.Get("Password"); + + gbDatabase.Text = res.Get("Database"); + lblDatabase.Text = res.Get("DatabaseName"); + btnAdvanced.Text = Res.Get("Buttons,Advanced"); + } + + protected override string GetConnectionString() + { + MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder(FConnectionString); + + builder.Server = tbServer.Text; + builder.UserID = tbUserName.Text; + builder.Password = tbPassword.Text; + builder.Database = tbDatabase.Text; + + return builder.ToString(); + } + + protected override void SetConnectionString(string value) + { + FConnectionString = value; + MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder(value); + + tbServer.Text = builder.Server; + tbUserName.Text = builder.UserID; + tbPassword.Text = builder.Password; + tbDatabase.Text = builder.Database; + } + + public MySqlConnectionEditor() + { + InitializeComponent(); + Localize(); + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MySql/MySqlConnectionEditor.resx b/Extras/Core/FastReport.Data/FastReport.Data.MySql/MySqlConnectionEditor.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MySql/MySqlConnectionEditor.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MySql/MySqlDataConnection.DesignExt.cs b/Extras/Core/FastReport.Data/FastReport.Data.MySql/MySqlDataConnection.DesignExt.cs new file mode 100644 index 00000000..e0500e73 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MySql/MySqlDataConnection.DesignExt.cs @@ -0,0 +1,33 @@ +using System; +using FastReport.Data.ConnectionEditors; +using MySql.Data.MySqlClient; + +namespace FastReport.Data +{ + public partial class MySqlDataConnection + { + public override Type GetParameterType() + { + return typeof(MySqlDbType); + } + + public override string GetConnectionId() + { + MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder(ConnectionString); + string info = ""; + try + { + info = builder.Database; + } + catch + { + } + return "MySQL: " + info; + } + + public override ConnectionEditorBase GetEditor() + { + return new MySqlConnectionEditor(); + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MySql/MySqlDataConnection.cs b/Extras/Core/FastReport.Data/FastReport.Data.MySql/MySqlDataConnection.cs new file mode 100644 index 00000000..406b35ae --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MySql/MySqlDataConnection.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Data.Common; +using MySql.Data.MySqlClient; +using System.Data; + +namespace FastReport.Data +{ + public partial class MySqlDataConnection : DataConnectionBase + { + private void GetDBObjectNames(string name, List list) + { + DataTable schema = null; + string databaseName = ""; + DbConnection connection = GetConnection(); + try + { + OpenConnection(connection); + MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder(ConnectionString); + schema = connection.GetSchema(name); + databaseName = builder.Database; + } + finally + { + DisposeConnection(connection); + } + foreach (DataRow row in schema.Rows) + { + if (String.IsNullOrEmpty(databaseName) || String.Compare(row["TABLE_SCHEMA"].ToString(), databaseName) == 0) + list.Add(row["TABLE_NAME"].ToString()); + } + } + + public override string[] GetTableNames() + { + List list = new List(); + GetDBObjectNames("Tables", list); + GetDBObjectNames("Views", list); + return list.ToArray(); + } + + public override string QuoteIdentifier(string value, DbConnection connection) + { + return "`" + value + "`"; + } + + protected override string GetConnectionStringWithLoginInfo(string userName, string password) + { + MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder(ConnectionString); + + builder.UserID = userName; + builder.Password = password; + + return builder.ToString(); + } + + public override Type GetConnectionType() + { + return typeof(MySqlConnection); + } + + public override DbDataAdapter GetAdapter(string selectCommand, DbConnection connection, + CommandParameterCollection parameters) + { + MySqlDataAdapter adapter = new MySqlDataAdapter(selectCommand, connection as MySqlConnection); + foreach (CommandParameter p in parameters) + { + MySqlParameter parameter = adapter.SelectCommand.Parameters.Add(p.Name, (MySqlDbType)p.DataType, p.Size); + parameter.Value = p.Value; + } + return adapter; + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.MySql/readme.txt b/Extras/Core/FastReport.Data/FastReport.Data.MySql/readme.txt new file mode 100644 index 00000000..82e83409 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.MySql/readme.txt @@ -0,0 +1,11 @@ +How to use it: +- execute the following code once at the application start: +FastReport.Utils.RegisteredObjects.AddConnection(typeof(MySqlDataConnection)); +- now you should be able to create a new MySQL data source from Designer (.Net 4) or from code: +Report report = new Report(); +report.Load(@"YourReport.frx"); +//... +MySqlDataConnection conn = new MySqlDataConnection(); +conn.ConnectionString = "your connection string"; +conn.CreateAllTables(); +report.Dictionary.Connections.Add(conn); \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.OracleODPCore/AssemblyInitializer.cs b/Extras/Core/FastReport.Data/FastReport.Data.OracleODPCore/AssemblyInitializer.cs new file mode 100644 index 00000000..3fb0c428 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.OracleODPCore/AssemblyInitializer.cs @@ -0,0 +1,12 @@ +using FastReport.Utils; + +namespace FastReport.Data +{ + public class OracleODPCoreAssemblyInitializer : AssemblyInitializerBase + { + public OracleODPCoreAssemblyInitializer() + { + RegisteredObjects.AddConnection(typeof(OracleDataConnection)); + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.OracleODPCore/FastReport.Data.OracleODPCore.csproj b/Extras/Core/FastReport.Data/FastReport.Data.OracleODPCore/FastReport.Data.OracleODPCore.csproj new file mode 100644 index 00000000..35ed2ba1 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.OracleODPCore/FastReport.Data.OracleODPCore.csproj @@ -0,0 +1,43 @@ + + + netcoreapp2.0 + true + ../../../FastReport.Plugins.snk + true + Fast Reports Inc. + Fast Reports Inc. + https://www.fast-report.com/en/product/fast-report-net/license + https://www.fast-report.com/en/product/fast-report-net + Fast Reports Inc. + FastReport.Data.OracleODPCore + Represents a connection to Oracle database for FastReport.Net. + FastReport.Data.OracleODPCore + https://www.fast-report.com/download/images/frlogo-big.png + reporting, oracle, core, connection, reports + 2018.3.29$(VersionSuffix) + 2018.3.29.0 + 2018.3.29.0 + Debug;Release; + FastReport.Data.OracleODPCore + FastReport.Data + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.OracleODPCore/FastReport.Data.OracleODPCore.sln b/Extras/Core/FastReport.Data/FastReport.Data.OracleODPCore/FastReport.Data.OracleODPCore.sln new file mode 100644 index 00000000..ca9f6df4 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.OracleODPCore/FastReport.Data.OracleODPCore.sln @@ -0,0 +1,65 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27703.2042 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastReport.Data.OracleODPCore", "FastReport.Data.OracleODPCore.csproj", "{7B86832D-F0BB-4B7B-9AB8-844EC5477DCE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastReportWebCore.MVC", "..\..\..\..\Demos\Core\FastReportWebCore.MVC\FastReportWebCore.MVC\FastReportWebCore.MVC.csproj", "{2FD10CEE-3D6F-4FEE-A5AF-E445F2474E53}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastReportCore", "..\..\..\..\FastReport.Core\FastReport.Core.csproj", "{B3C8DAE9-396E-4A5F-A987-92197EAC1068}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Academic|Any CPU = Academic|Any CPU + Basic|Any CPU = Basic|Any CPU + Debug|Any CPU = Debug|Any CPU + Demo|Any CPU = Demo|Any CPU + Release|Any CPU = Release|Any CPU + WinForms|Any CPU = WinForms|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7B86832D-F0BB-4B7B-9AB8-844EC5477DCE}.Academic|Any CPU.ActiveCfg = Debug|Any CPU + {7B86832D-F0BB-4B7B-9AB8-844EC5477DCE}.Academic|Any CPU.Build.0 = Debug|Any CPU + {7B86832D-F0BB-4B7B-9AB8-844EC5477DCE}.Basic|Any CPU.ActiveCfg = Debug|Any CPU + {7B86832D-F0BB-4B7B-9AB8-844EC5477DCE}.Basic|Any CPU.Build.0 = Debug|Any CPU + {7B86832D-F0BB-4B7B-9AB8-844EC5477DCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7B86832D-F0BB-4B7B-9AB8-844EC5477DCE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7B86832D-F0BB-4B7B-9AB8-844EC5477DCE}.Demo|Any CPU.ActiveCfg = Debug|Any CPU + {7B86832D-F0BB-4B7B-9AB8-844EC5477DCE}.Demo|Any CPU.Build.0 = Debug|Any CPU + {7B86832D-F0BB-4B7B-9AB8-844EC5477DCE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7B86832D-F0BB-4B7B-9AB8-844EC5477DCE}.Release|Any CPU.Build.0 = Release|Any CPU + {7B86832D-F0BB-4B7B-9AB8-844EC5477DCE}.WinForms|Any CPU.ActiveCfg = Debug|Any CPU + {7B86832D-F0BB-4B7B-9AB8-844EC5477DCE}.WinForms|Any CPU.Build.0 = Debug|Any CPU + {2FD10CEE-3D6F-4FEE-A5AF-E445F2474E53}.Academic|Any CPU.ActiveCfg = Debug|Any CPU + {2FD10CEE-3D6F-4FEE-A5AF-E445F2474E53}.Academic|Any CPU.Build.0 = Debug|Any CPU + {2FD10CEE-3D6F-4FEE-A5AF-E445F2474E53}.Basic|Any CPU.ActiveCfg = Debug|Any CPU + {2FD10CEE-3D6F-4FEE-A5AF-E445F2474E53}.Basic|Any CPU.Build.0 = Debug|Any CPU + {2FD10CEE-3D6F-4FEE-A5AF-E445F2474E53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2FD10CEE-3D6F-4FEE-A5AF-E445F2474E53}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2FD10CEE-3D6F-4FEE-A5AF-E445F2474E53}.Demo|Any CPU.ActiveCfg = Debug|Any CPU + {2FD10CEE-3D6F-4FEE-A5AF-E445F2474E53}.Demo|Any CPU.Build.0 = Debug|Any CPU + {2FD10CEE-3D6F-4FEE-A5AF-E445F2474E53}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2FD10CEE-3D6F-4FEE-A5AF-E445F2474E53}.Release|Any CPU.Build.0 = Release|Any CPU + {2FD10CEE-3D6F-4FEE-A5AF-E445F2474E53}.WinForms|Any CPU.ActiveCfg = Debug|Any CPU + {2FD10CEE-3D6F-4FEE-A5AF-E445F2474E53}.WinForms|Any CPU.Build.0 = Debug|Any CPU + {B3C8DAE9-396E-4A5F-A987-92197EAC1068}.Academic|Any CPU.ActiveCfg = Academic|Any CPU + {B3C8DAE9-396E-4A5F-A987-92197EAC1068}.Academic|Any CPU.Build.0 = Academic|Any CPU + {B3C8DAE9-396E-4A5F-A987-92197EAC1068}.Basic|Any CPU.ActiveCfg = Basic|Any CPU + {B3C8DAE9-396E-4A5F-A987-92197EAC1068}.Basic|Any CPU.Build.0 = Basic|Any CPU + {B3C8DAE9-396E-4A5F-A987-92197EAC1068}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B3C8DAE9-396E-4A5F-A987-92197EAC1068}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B3C8DAE9-396E-4A5F-A987-92197EAC1068}.Demo|Any CPU.ActiveCfg = Demo|Any CPU + {B3C8DAE9-396E-4A5F-A987-92197EAC1068}.Demo|Any CPU.Build.0 = Demo|Any CPU + {B3C8DAE9-396E-4A5F-A987-92197EAC1068}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B3C8DAE9-396E-4A5F-A987-92197EAC1068}.Release|Any CPU.Build.0 = Release|Any CPU + {B3C8DAE9-396E-4A5F-A987-92197EAC1068}.WinForms|Any CPU.ActiveCfg = WinForms|Any CPU + {B3C8DAE9-396E-4A5F-A987-92197EAC1068}.WinForms|Any CPU.Build.0 = WinForms|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {16A578B6-6410-482B-9A91-F5B248FBBF99} + EndGlobalSection +EndGlobal diff --git a/Extras/Core/FastReport.Data/FastReport.Data.OracleODPCore/OracleDataConnection.cs b/Extras/Core/FastReport.Data/FastReport.Data.OracleODPCore/OracleDataConnection.cs new file mode 100644 index 00000000..74032ab9 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.OracleODPCore/OracleDataConnection.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Data; +using System.Data.Common; +using Oracle.ManagedDataAccess.Client; + +namespace FastReport.Data +{ + public class OracleDataConnection : DataConnectionBase + { + private void GetDBObjectNames(string name, string columnName, List list) + { + DataTable schema = null; + DbConnection connection = GetConnection(); + try + { + OpenConnection(connection); + OracleConnectionStringBuilder builder = new OracleConnectionStringBuilder(connection.ConnectionString); + schema = connection.GetSchema(name, new string[] { builder.UserID.ToUpper(), null }); + } + finally + { + DisposeConnection(connection); + } + + foreach (DataRow row in schema.Rows) + { + string tableName = row[columnName].ToString(); + string schemaName = row["OWNER"].ToString(); + if (String.Compare(schemaName, "SYSTEM") == 0) + list.Add(tableName); + else + list.Add(schemaName + ".\"" + tableName + "\""); + } + } + + public override string[] GetTableNames() + { + List list = new List(); + GetDBObjectNames("Tables", "TABLE_NAME", list); + GetDBObjectNames("Views", "VIEW_NAME", list); + return list.ToArray(); + } + + public override string QuoteIdentifier(string value, DbConnection connection) + { + // already quoted? keep in mind GetDBObjectNames and non-SYSTEM schema! + if (!value.EndsWith("\"")) + value = "\"" + value + "\""; + return value; + } + + protected override string GetConnectionStringWithLoginInfo(string userName, string password) + { + OracleConnectionStringBuilder builder = new OracleConnectionStringBuilder(ConnectionString); + + builder.UserID = userName; + builder.Password = password; + + return builder.ToString(); + } + + public override Type GetConnectionType() + { + return typeof(OracleConnection); + } + + public override DbDataAdapter GetAdapter(string selectCommand, DbConnection connection, + CommandParameterCollection parameters) + { + OracleDataAdapter adapter = new OracleDataAdapter(selectCommand, connection as OracleConnection); + adapter.SelectCommand.BindByName = true; + + foreach (CommandParameter p in parameters) + { + OracleDbType parType = (OracleDbType)p.DataType; + OracleParameter parameter = adapter.SelectCommand.Parameters.Add(p.Name, parType, p.Size); + parameter.Value = p.Value; + + // if we have refcursor parameter, set its direction to output, and also + // modify the command type to CommandType.StoredProcedure. The selectCommand must contain + // the stored proc name only. + if (parType == OracleDbType.RefCursor) + { + parameter.Direction = ParameterDirection.Output; + adapter.SelectCommand.CommandType = CommandType.StoredProcedure; + } + } + + return adapter; + } + + public override Type GetParameterType() + { + return typeof(OracleDbType); + } + + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.OracleODPCore/readme.txt b/Extras/Core/FastReport.Data/FastReport.Data.OracleODPCore/readme.txt new file mode 100644 index 00000000..084415a5 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.OracleODPCore/readme.txt @@ -0,0 +1,13 @@ +How to use it: +- execute the following code once at the application start: +FastReport.Utils.RegisteredObjects.AddConnection(typeof(OracleDataConnection)); +- now you should be able to create a new Oracle data source: +Report report = new Report(); +report.Load(@"YourReport.frx"); +//... +OracleDataConnection conn = new OracleDataConnection(); +conn.ConnectionString = "your connection string"; +conn.CreateAllTables(); +report.Dictionary.Connections.Add(conn); +- or reassign report connection string: +report.Dictionary.Connections[0].ConnectionString = "your connection string"; \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Postgres/AssemblyInitializer.cs b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/AssemblyInitializer.cs new file mode 100644 index 00000000..d8e60cd4 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/AssemblyInitializer.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using FastReport.Utils; + +namespace FastReport.Data +{ + public class PostgresAssemblyInitializer : AssemblyInitializerBase + { + public PostgresAssemblyInitializer() + { + RegisteredObjects.AddConnection(typeof(PostgresDataConnection)); + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Postgres/FastReport.Data.Postgres.csproj b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/FastReport.Data.Postgres.csproj new file mode 100644 index 00000000..af2fde0d --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/FastReport.Data.Postgres.csproj @@ -0,0 +1,96 @@ + + + net4;netstandard2.0 + true + ../../../FastReport.Plugins.snk + true + Fast Reports Inc. + Fast Reports Inc. + https://www.fast-report.com/en/product/fast-report-net/license + https://www.fast-report.com/en/product/fast-report-net + Fast Reports Inc. + FastReport.Data.Postgres + Represents a connection to PostgreSQL database for FastReport.Net. + FastReport.Data.Postgres + https://www.fast-report.com/download/images/frlogo-big.png + reporting, postgres, connection, reports + 2018.3.46$(VersionSuffix) + 2018.3.46.0 + 2018.3.46.0 + Debug;Release; + FastReport.Data.Postgres + FastReport.Data + added system schemas filter + + + FRCORE; + + + + + + + + + + + + + + + + + + + + + + + false + + + False + ..\..\..\..\FastReport\bin\$(Configuration)\FastReport.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PostgresConnectionEditor.cs + + + + + PostgresConnectionEditor.cs + Designer + + + + + UserControl + + + \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Postgres/FastReport.OpenSource.Data.Postgres.csproj b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/FastReport.OpenSource.Data.Postgres.csproj new file mode 100644 index 00000000..5117299c --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/FastReport.OpenSource.Data.Postgres.csproj @@ -0,0 +1,49 @@ + + + net452;netstandard2.0 + true + ../../../FastReport.Plugins.snk + true + Fast Reports Inc. + Fast Reports Inc. + https://github.com/FastReports/FastReport/blob/master/LICENSE.md + https://www.fast-report.com/en/product/fast-report-net + https://github.com/FastReports/FastReport + Fast Reports Inc. + FastReport.Data.Postgres + Represents a connection to PostgreSQL database for FastReport.Net. + FastReport.OpenSource.Data.Postgres + https://www.fast-report.com/download/images/frlogo-big.png + reporting, postgres, connection, reports + 2018.3.46$(VersionSuffix) + 1.0.0 + Debug;Release; + FastReport.Data.Postgres + FastReport.Data + added system schemas filter + + + FRCORE; + + + + + + + + + + + + + + + + + + + + UserControl + + + \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Postgres/PostgresConnectionEditor.Designer.cs b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/PostgresConnectionEditor.Designer.cs new file mode 100644 index 00000000..d3ef8a76 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/PostgresConnectionEditor.Designer.cs @@ -0,0 +1,206 @@ +namespace FastReport.Data +{ + partial class PostgresConnectionEditor + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnAdvanced = new System.Windows.Forms.Button(); + this.gbDatabase = new System.Windows.Forms.GroupBox(); + this.cbxDatabase = new System.Windows.Forms.ComboBox(); + this.lblDatabase = new System.Windows.Forms.Label(); + this.tbPassword = new System.Windows.Forms.TextBox(); + this.tbUserName = new System.Windows.Forms.TextBox(); + this.lblPassword = new System.Windows.Forms.Label(); + this.lblUserName = new System.Windows.Forms.Label(); + this.label1 = new FastReport.Controls.LabelLine(); + this.gbServer = new System.Windows.Forms.GroupBox(); + this.lblServer = new System.Windows.Forms.Label(); + this.tbServer = new System.Windows.Forms.TextBox(); + this.enableSystemSchemasCb = new System.Windows.Forms.CheckBox(); + this.gbDatabase.SuspendLayout(); + this.gbServer.SuspendLayout(); + this.SuspendLayout(); + // + // btnAdvanced + // + this.btnAdvanced.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnAdvanced.AutoSize = true; + this.btnAdvanced.Location = new System.Drawing.Point(252, 220); + this.btnAdvanced.Name = "btnAdvanced"; + this.btnAdvanced.Size = new System.Drawing.Size(77, 23); + this.btnAdvanced.TabIndex = 0; + this.btnAdvanced.Text = "Advanced..."; + this.btnAdvanced.UseVisualStyleBackColor = true; + this.btnAdvanced.Click += new System.EventHandler(this.btnAdvanced_Click); + // + // gbDatabase + // + this.gbDatabase.Controls.Add(this.cbxDatabase); + this.gbDatabase.Controls.Add(this.lblDatabase); + this.gbDatabase.Location = new System.Drawing.Point(8, 136); + this.gbDatabase.Name = "gbDatabase"; + this.gbDatabase.Size = new System.Drawing.Size(320, 76); + this.gbDatabase.TabIndex = 1; + this.gbDatabase.TabStop = false; + this.gbDatabase.Text = "Database"; + // + // cbxDatabase + // + this.cbxDatabase.FormattingEnabled = true; + this.cbxDatabase.Location = new System.Drawing.Point(12, 40); + this.cbxDatabase.Name = "cbxDatabase"; + this.cbxDatabase.Size = new System.Drawing.Size(296, 21); + this.cbxDatabase.TabIndex = 3; + this.cbxDatabase.DropDown += new System.EventHandler(this.cbxDatabase_DropDown); + // + // lblDatabase + // + this.lblDatabase.AutoSize = true; + this.lblDatabase.Location = new System.Drawing.Point(12, 20); + this.lblDatabase.Name = "lblDatabase"; + this.lblDatabase.Size = new System.Drawing.Size(57, 13); + this.lblDatabase.TabIndex = 3; + this.lblDatabase.Text = "Database:"; + // + // tbPassword + // + this.tbPassword.Location = new System.Drawing.Point(120, 96); + this.tbPassword.Name = "tbPassword"; + this.tbPassword.Size = new System.Drawing.Size(188, 20); + this.tbPassword.TabIndex = 2; + this.tbPassword.UseSystemPasswordChar = true; + // + // tbUserName + // + this.tbUserName.Location = new System.Drawing.Point(120, 72); + this.tbUserName.Name = "tbUserName"; + this.tbUserName.Size = new System.Drawing.Size(188, 20); + this.tbUserName.TabIndex = 1; + // + // lblPassword + // + this.lblPassword.AutoSize = true; + this.lblPassword.Location = new System.Drawing.Point(12, 100); + this.lblPassword.Name = "lblPassword"; + this.lblPassword.Size = new System.Drawing.Size(57, 13); + this.lblPassword.TabIndex = 1; + this.lblPassword.Text = "Password:"; + // + // lblUserName + // + this.lblUserName.AutoSize = true; + this.lblUserName.Location = new System.Drawing.Point(12, 76); + this.lblUserName.Name = "lblUserName"; + this.lblUserName.Size = new System.Drawing.Size(62, 13); + this.lblUserName.TabIndex = 0; + this.lblUserName.Text = "User name:"; + // + // label1 + // + this.label1.Location = new System.Drawing.Point(8, 244); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(320, 17); + this.label1.TabIndex = 2; + // + // gbServer + // + this.gbServer.Controls.Add(this.lblServer); + this.gbServer.Controls.Add(this.tbServer); + this.gbServer.Controls.Add(this.tbUserName); + this.gbServer.Controls.Add(this.tbPassword); + this.gbServer.Controls.Add(this.lblUserName); + this.gbServer.Controls.Add(this.lblPassword); + this.gbServer.Location = new System.Drawing.Point(8, 4); + this.gbServer.Name = "gbServer"; + this.gbServer.Size = new System.Drawing.Size(320, 128); + this.gbServer.TabIndex = 3; + this.gbServer.TabStop = false; + this.gbServer.Text = "Server"; + // + // lblServer + // + this.lblServer.AutoSize = true; + this.lblServer.Location = new System.Drawing.Point(12, 20); + this.lblServer.Name = "lblServer"; + this.lblServer.Size = new System.Drawing.Size(72, 13); + this.lblServer.TabIndex = 4; + this.lblServer.Text = "Server name:"; + // + // tbServer + // + this.tbServer.Location = new System.Drawing.Point(12, 40); + this.tbServer.Name = "tbServer"; + this.tbServer.Size = new System.Drawing.Size(296, 20); + this.tbServer.TabIndex = 0; + // + // enableSystemSchemasCb + // + this.enableSystemSchemasCb.AutoSize = true; + this.enableSystemSchemasCb.Location = new System.Drawing.Point(23, 225); + this.enableSystemSchemasCb.Name = "enableSystemSchemasCb"; + this.enableSystemSchemasCb.Size = new System.Drawing.Size(139, 17); + this.enableSystemSchemasCb.TabIndex = 4; + this.enableSystemSchemasCb.Text = "Enable system schemas"; + this.enableSystemSchemasCb.UseVisualStyleBackColor = true; + // + // PostgresConnectionEditor + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.enableSystemSchemasCb); + this.Controls.Add(this.gbServer); + this.Controls.Add(this.label1); + this.Controls.Add(this.gbDatabase); + this.Controls.Add(this.btnAdvanced); + this.Name = "PostgresConnectionEditor"; + this.Size = new System.Drawing.Size(336, 263); + this.gbDatabase.ResumeLayout(false); + this.gbDatabase.PerformLayout(); + this.gbServer.ResumeLayout(false); + this.gbServer.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnAdvanced; + private System.Windows.Forms.GroupBox gbDatabase; + private System.Windows.Forms.Label lblDatabase; + private System.Windows.Forms.TextBox tbPassword; + private System.Windows.Forms.TextBox tbUserName; + private System.Windows.Forms.Label lblPassword; + private System.Windows.Forms.Label lblUserName; + private FastReport.Controls.LabelLine label1; + private System.Windows.Forms.GroupBox gbServer; + private System.Windows.Forms.ComboBox cbxDatabase; + private System.Windows.Forms.Label lblServer; + private System.Windows.Forms.TextBox tbServer; + private System.Windows.Forms.CheckBox enableSystemSchemasCb; + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Postgres/PostgresConnectionEditor.cs b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/PostgresConnectionEditor.cs new file mode 100644 index 00000000..7900af35 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/PostgresConnectionEditor.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using FastReport.Data.ConnectionEditors; +using FastReport.Forms; +using FastReport.Utils; +using Npgsql; + +namespace FastReport.Data +{ + public partial class PostgresConnectionEditor : ConnectionEditorBase + { + private string FConnectionString; + + private void cbxDatabase_DropDown(object sender, EventArgs e) + { + cbxDatabase.Items.Clear(); + + try + { + NpgsqlConnectionStringBuilder builder = new NpgsqlConnectionStringBuilder(ConnectionString); + builder.Database = "template1"; + using (NpgsqlConnection connection = new NpgsqlConnection(builder.ToString())) + { + connection.Open(); + NpgsqlDataReader dr = new NpgsqlCommand("SELECT datname FROM pg_database WHERE datallowconn = 't'", connection).ExecuteReader(); + while (dr.Read()) + { + cbxDatabase.Items.Add(dr["datname"]); + } + } + } + catch + { + } + } + + private void btnAdvanced_Click(object sender, EventArgs e) + { + using (AdvancedConnectionPropertiesForm form = new AdvancedConnectionPropertiesForm()) + { + NpgsqlConnectionStringBuilder builder = new NpgsqlConnectionStringBuilder(ConnectionString); + form.AdvancedProperties = builder; + if (form.ShowDialog() == DialogResult.OK) + ConnectionString = form.AdvancedProperties.ToString(); + } + } + + private void Localize() + { + MyRes res = new MyRes("ConnectionEditors,Common"); + + gbServer.Text = res.Get("ServerLogon"); + lblServer.Text = res.Get("Server"); + lblUserName.Text = res.Get("UserName"); + lblPassword.Text = res.Get("Password"); + + gbDatabase.Text = res.Get("Database"); + lblDatabase.Text = res.Get("DatabaseName"); + btnAdvanced.Text = Res.Get("Buttons,Advanced"); + } + + protected override string GetConnectionString() + { + NpgsqlConnectionStringBuilder builder = new NpgsqlConnectionStringBuilder(FConnectionString); + + builder.Host = tbServer.Text; + builder.UserName = tbUserName.Text; + builder.Password = tbPassword.Text; + builder.Database = cbxDatabase.Text; + PostgresDataConnection.EnableSystemSchemas = enableSystemSchemasCb.Checked; + return builder.ToString(); + } + + protected override void SetConnectionString(string value) + { + enableSystemSchemasCb.Checked = PostgresDataConnection.EnableSystemSchemas; + FConnectionString = value; + NpgsqlConnectionStringBuilder builder = new NpgsqlConnectionStringBuilder(value); + + tbServer.Text = builder.Host; + tbUserName.Text = builder.UserName; + tbPassword.Text = builder.Password; + cbxDatabase.Text = builder.Database; + } + + public PostgresConnectionEditor() + { + InitializeComponent(); + Localize(); + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Postgres/PostgresConnectionEditor.resx b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/PostgresConnectionEditor.resx new file mode 100644 index 00000000..d58980a3 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/PostgresConnectionEditor.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Postgres/PostgresDataConnection.DesignExt.cs b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/PostgresDataConnection.DesignExt.cs new file mode 100644 index 00000000..4e860285 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/PostgresDataConnection.DesignExt.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Data.Common; +using FastReport.Data.ConnectionEditors; +using Npgsql; +using NpgsqlTypes; +using System.Data; +using FastReport.Data.ConnectionEditors; + +namespace FastReport.Data +{ + public partial class PostgresDataConnection + { + public override Type GetParameterType() + { + return typeof(NpgsqlDbType); + } + + public override string GetConnectionId() + { + NpgsqlConnectionStringBuilder builder = new NpgsqlConnectionStringBuilder(ConnectionString); + string info = ""; + try + { + info = builder.Database; + } + catch + { + } + return "Postgres: " + info; + } + + public override ConnectionEditorBase GetEditor() + { + PostgresConnectionEditor editor = new PostgresConnectionEditor(); + return editor; + } + } +} \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Postgres/PostgresDataConnection.cs b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/PostgresDataConnection.cs new file mode 100644 index 00000000..a87aae86 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/PostgresDataConnection.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Data.Common; +using Npgsql; +using NpgsqlTypes; +using System.Data; + +namespace FastReport.Data +{ + public partial class PostgresDataConnection : DataConnectionBase + { + /// + /// Specified, system schemas should be shown or not + /// + public static bool EnableSystemSchemas { get; set; } + + private void GetDBObjectNames(string name, List list) + { + DataTable schema = null; + DbConnection connection = GetConnection(); + try + { + OpenConnection(connection); + schema = connection.GetSchema("Tables", new string[] { null, "", null, name }); //not only public + } + finally + { + DisposeConnection(connection); + } + + foreach (DataRow row in schema.Rows) + { + string schemaName = row["TABLE_SCHEMA"].ToString(); + if (!EnableSystemSchemas && (schemaName == "pg_catalog" || schemaName == "information_schema")) + continue; + list.Add(schemaName + "." + "\"" + row["TABLE_NAME"].ToString() + "\""); + } + } + + public override string[] GetTableNames() + { + List list = new List(); + GetDBObjectNames("BASE TABLE", list); + GetDBObjectNames("VIEW", list); + if (list.Count == 0) + { + string selectCommand = + "SELECT n.nspname as \"Schema\", " + + "c.relname as \"Name\", " + + "CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 's' THEN 'special' WHEN 'f' THEN 'foreign table' END as \"Type\", " + + "pg_catalog.pg_get_userbyid(c.relowner) as \"Owner\" " + + "FROM pg_catalog.pg_class c " + + "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace " + + "WHERE c.relkind IN ('r', 'v', '') " + + "AND n.nspname <> 'pg_catalog' " + + "AND n.nspname <> 'information_schema' " + + "AND n.nspname !~'^pg_toast' " + + "AND pg_catalog.pg_table_is_visible(c.oid) " + + "ORDER BY 1,2; "; + + DataSet dataset = new DataSet(); + + DbConnection connection = GetConnection(); + try + { + OpenConnection(connection); + NpgsqlDataAdapter adapter = new NpgsqlDataAdapter(selectCommand, connection as NpgsqlConnection); + adapter.Fill(dataset); + + if (dataset.Tables.Count > 0) + foreach (DataRow row in dataset.Tables[0].Rows) + { + list.Add(row["Name"].ToString()); + } + } + finally + { + DisposeConnection(connection); + } + + } + return list.ToArray(); + } + + public override string QuoteIdentifier(string value, DbConnection connection) + { + return value; + } + + protected override string GetConnectionStringWithLoginInfo(string userName, string password) + { + NpgsqlConnectionStringBuilder builder = new NpgsqlConnectionStringBuilder(ConnectionString); +#if FRCORE + builder.Username = userName; +#else + builder.UserName = userName; +#endif + builder.Password = password; + + return builder.ToString(); + } + + public override Type GetConnectionType() + { + return typeof(NpgsqlConnection); + } + + public override DbDataAdapter GetAdapter(string selectCommand, DbConnection connection, + CommandParameterCollection parameters) + { + NpgsqlDataAdapter adapter = new NpgsqlDataAdapter(selectCommand, connection as NpgsqlConnection); + foreach (CommandParameter p in parameters) + { + NpgsqlParameter parameter = adapter.SelectCommand.Parameters.Add(p.Name, (NpgsqlDbType)p.DataType, p.Size); + parameter.Value = p.Value; + } + return adapter; + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.Postgres/readme.txt b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/readme.txt new file mode 100644 index 00000000..9d778353 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.Postgres/readme.txt @@ -0,0 +1,11 @@ +How to use it: +- execute the following code once at the application start: +FastReport.Utils.RegisteredObjects.AddConnection(typeof(PostgresDataConnection)); +- now you should be able to create a new PostgreSQL data source from Designer (.Net 4) or from code: +Report report = new Report(); +report.Load(@"YourReport.frx"); +//... +PostgresDataConnection conn = new PostgresDataConnection(); +conn.ConnectionString = "your connection string"; +conn.CreateAllTables(); +report.Dictionary.Connections.Add(conn); \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/AssemblyInitializer.cs b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/AssemblyInitializer.cs new file mode 100644 index 00000000..196cd6cd --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/AssemblyInitializer.cs @@ -0,0 +1,13 @@ +using FastReport.Utils; + + +namespace FastReport.Data +{ + public class RavenDBAssemblyInitializer : AssemblyInitializerBase + { + public RavenDBAssemblyInitializer() + { + RegisteredObjects.AddConnection(typeof(RavenDBDataConnection)); + } + } +} \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/FastReport.Data.RavenDB.csproj b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/FastReport.Data.RavenDB.csproj new file mode 100644 index 00000000..a75cca3c --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/FastReport.Data.RavenDB.csproj @@ -0,0 +1,102 @@ + + + + + net4.7;netstandard2.0 + ../../../FastReport.Plugins.snk + true + Fast Reports Inc. + Fast Reports Inc. + https://www.fast-report.com/en/product/fast-report-net/license + https://www.fast-report.com/en/product/fast-report-net + Fast Reports Inc. + FastReport.Data.RavenDB + Represents a connection to RavenDB database for FastReport.Net. + FastReport.Data.RavenDB + https://www.fast-report.com/download/images/frlogo-big.png + reporting, RavenDB, connection, reports + 2018.2.2$(VersionSuffix) + 2018.2.2.0 + 2018.2.2.0 + Debug;Release; + FastReport.Data.RavenDB + FastReport.Data + + + + FRCORE; + + + + + + + + + + + + + + + + + + + + + + false + + + False + ..\..\..\..\FastReport\bin\Release\FastReport.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UserControl + + + RavenDBConnectionEditor.cs + + + + + RavenDBConnectionEditor.cs + Designer + + + + diff --git a/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBConnectionEditor.Designer.cs b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBConnectionEditor.Designer.cs new file mode 100644 index 00000000..7a9a49d2 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBConnectionEditor.Designer.cs @@ -0,0 +1,179 @@ +namespace FastReport.Data +{ + partial class RavenDBConnectionEditor + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.tbCertificatePath = new FastReport.Controls.TextBoxButton(); + + this.gbDatabase = new System.Windows.Forms.GroupBox(); + this.tbDatabase = new System.Windows.Forms.TextBox(); + this.lblDatabase = new System.Windows.Forms.Label(); + this.tbPassword = new System.Windows.Forms.TextBox(); + this.lblUserName = new System.Windows.Forms.Label(); + // this.tbCertificatePath = new System.Windows.Forms.TextBox(); + this.lblPassword = new System.Windows.Forms.Label(); + this.gbServer = new System.Windows.Forms.GroupBox(); + this.tbHost = new System.Windows.Forms.TextBox(); + this.lblHost = new System.Windows.Forms.Label(); + this.labelLine1 = new FastReport.Controls.LabelLine(); + this.gbDatabase.SuspendLayout(); + this.gbServer.SuspendLayout(); + this.SuspendLayout(); + // + // gbDatabase + // + this.gbDatabase.Controls.Add(this.tbDatabase); + this.gbDatabase.Controls.Add(this.lblDatabase); + this.gbDatabase.Location = new System.Drawing.Point(15, 12); + this.gbDatabase.Name = "gbDatabase"; + this.gbDatabase.Size = new System.Drawing.Size(308, 66); + this.gbDatabase.TabIndex = 0; + this.gbDatabase.TabStop = false; + this.gbDatabase.Text = "Database"; + // + // tbDatabase + // + this.tbDatabase.Location = new System.Drawing.Point(6, 33); + this.tbDatabase.Name = "tbDatabase"; + this.tbDatabase.Size = new System.Drawing.Size(296, 27); + this.tbDatabase.TabIndex = 0; + // + // lblDatabase + // + this.lblDatabase.AutoSize = true; + this.lblDatabase.Location = new System.Drawing.Point(6, 17); + this.lblDatabase.Name = "lblDatabase"; + this.lblDatabase.Size = new System.Drawing.Size(123, 19); + this.lblDatabase.TabIndex = 0; + this.lblDatabase.Text = "Database name:"; + // + // tbPassword + // + this.tbPassword.Location = new System.Drawing.Point(133, 93); + this.tbPassword.Name = "tbPassword"; + this.tbPassword.Size = new System.Drawing.Size(169, 27); + this.tbPassword.TabIndex = 2; + this.tbPassword.UseSystemPasswordChar = true; + // + // lblUserName + // + this.lblUserName.AutoSize = true; + this.lblUserName.Location = new System.Drawing.Point(6, 70); + this.lblUserName.Name = "lblUserName"; + this.lblUserName.Size = new System.Drawing.Size(121, 19); + this.lblUserName.TabIndex = 0; + this.lblUserName.Text = "Certificate path:"; + // + // tbCertificatePath + // + this.tbCertificatePath.Image = null; + this.tbCertificatePath.Location = new System.Drawing.Point(133, 67); + this.tbCertificatePath.Name = "tbCertificatePath"; + this.tbCertificatePath.Size = new System.Drawing.Size(169, 27); + this.tbCertificatePath.TabIndex = 1; + this.tbCertificatePath.ButtonClick += new System.EventHandler(this.tbCertificatePath_ButtonClick); + // + // lblPassword + // + this.lblPassword.AutoSize = true; + this.lblPassword.Location = new System.Drawing.Point(6, 96); + this.lblPassword.Name = "lblPassword"; + this.lblPassword.Size = new System.Drawing.Size(82, 19); + this.lblPassword.TabIndex = 0; + this.lblPassword.Text = "Password:"; + // + // gbServer + // + this.gbServer.Controls.Add(this.tbHost); + this.gbServer.Controls.Add(this.lblHost); + this.gbServer.Controls.Add(this.tbPassword); + this.gbServer.Controls.Add(this.lblUserName); + this.gbServer.Controls.Add(this.tbCertificatePath); + this.gbServer.Controls.Add(this.lblPassword); + this.gbServer.Location = new System.Drawing.Point(15, 84); + this.gbServer.Name = "gbServer"; + this.gbServer.Size = new System.Drawing.Size(308, 126); + this.gbServer.TabIndex = 1; + this.gbServer.TabStop = false; + this.gbServer.Text = "Server"; + // + // tbHost + // + this.tbHost.Location = new System.Drawing.Point(9, 41); + this.tbHost.Name = "tbHost"; + this.tbHost.Size = new System.Drawing.Size(293, 27); + this.tbHost.TabIndex = 0; + // + // lblHost + // + this.lblHost.AutoSize = true; + this.lblHost.Location = new System.Drawing.Point(6, 25); + this.lblHost.Name = "lblHost"; + this.lblHost.Size = new System.Drawing.Size(47, 19); + this.lblHost.TabIndex = 0; + this.lblHost.Text = "Host:"; + // + // labelLine1 + // + this.labelLine1.Location = new System.Drawing.Point(15, 216); + this.labelLine1.Name = "labelLine1"; + this.labelLine1.Size = new System.Drawing.Size(308, 16); + this.labelLine1.TabIndex = 0; + // + // RavenDBConnectionEditor + // + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 19F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.gbDatabase); + this.Controls.Add(this.gbServer); + this.Controls.Add(this.labelLine1); + this.Name = "RavenDBConnectionEditor"; + this.Size = new System.Drawing.Size(504, 237); + this.gbDatabase.ResumeLayout(false); + this.gbDatabase.PerformLayout(); + this.gbServer.ResumeLayout(false); + this.gbServer.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + private FastReport.Controls.TextBoxButton tbCertificatePath; + private System.Windows.Forms.GroupBox gbDatabase; + private System.Windows.Forms.TextBox tbDatabase; + private System.Windows.Forms.Label lblDatabase; + private System.Windows.Forms.TextBox tbPassword; + private System.Windows.Forms.Label lblUserName; + // private System.Windows.Forms.TextBox tbCertificatePath; + private System.Windows.Forms.Label lblPassword; + private System.Windows.Forms.GroupBox gbServer; + private System.Windows.Forms.TextBox tbHost; + private System.Windows.Forms.Label lblHost; + private Controls.LabelLine labelLine1; + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBConnectionEditor.cs b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBConnectionEditor.cs new file mode 100644 index 00000000..82537d10 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBConnectionEditor.cs @@ -0,0 +1,84 @@ +using FastReport.Utils; +using FastReport.Data.ConnectionEditors; +using System; +using System.Windows.Forms; + +namespace FastReport.Data +{ + /// + /// Represents a RavenDB connection editor. + /// + public partial class RavenDBConnectionEditor : ConnectionEditorBase + { + #region Fields + + private string FConnectionString; + + #endregion Fields + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public RavenDBConnectionEditor() + { + InitializeComponent(); + Localize(); + } + + #endregion Constructors + + #region Private Methods + + private void Localize() + { + MyRes res = new MyRes("ConnectionEditors,Common"); + gbServer.Text = res.Get("ServerLogon"); + //lblUserName.Text = res.Get("UserName"); + lblPassword.Text = res.Get("Password"); + gbDatabase.Text = res.Get("Database"); + lblDatabase.Text = res.Get("DatabaseName"); + tbCertificatePath.Image = Res.GetImage(1); + res = new MyRes("Export,Email"); + } + + #endregion Private Methods + + #region Protected Methods + + /// + protected override string GetConnectionString() + { + RavenDBConnectionStringBuilder builder = new RavenDBConnectionStringBuilder(); + builder.DatabaseName = tbDatabase.Text; + builder.Host = tbHost.Text; + builder.CertificatePath = tbCertificatePath.Text; + builder.Password = tbPassword.Text; + return builder.ToString(); + } + + /// + protected override void SetConnectionString(string value) + { + FConnectionString = value; + RavenDBConnectionStringBuilder builder = new RavenDBConnectionStringBuilder(value); + tbDatabase.Text = builder.DatabaseName; + tbHost.Text = builder.Host; + tbCertificatePath.Text = builder.CertificatePath; + tbPassword.Text = builder.Password; + } + + #endregion Protected Methods + + private void tbCertificatePath_ButtonClick(object sender, EventArgs e) + { + using (OpenFileDialog dialog = new OpenFileDialog()) + { + dialog.Filter = "Certificate files (*.pfx)|*.pfx"; + if (dialog.ShowDialog() == DialogResult.OK) + tbCertificatePath.Text = dialog.FileName; + } + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBConnectionEditor.resx b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBConnectionEditor.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBConnectionEditor.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBConnectionStringBuilder.cs b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBConnectionStringBuilder.cs new file mode 100644 index 00000000..3ca8a709 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBConnectionStringBuilder.cs @@ -0,0 +1,133 @@ +using System; +using System.Text; + +namespace FastReport.Data +{ + /// + /// Represents the RavenDBDataConnection connection string builder. + /// + /// + /// Use this class to parse connection string returned by the RavenDBDataConnection class. + /// + public class RavenDBConnectionStringBuilder + { + #region Fields + + private string databaseName; + private string host; + private string certificatePath; + private string password; + private string connectionString; + + #endregion Fields + + #region Properties + + /// + /// Gets or sets the host. + /// + public string Host + { + get { return host; } + set { host = value; } + } + + /// + /// Gets or sets the username. + /// + public string CertificatePath + { + get { return certificatePath; } + set { certificatePath = value; } + } + + /// + /// Gets or sets the password. + /// + public string Password + { + get { return password; } + set { password = value; } + } + + /// + /// Gets or sets the database name. + /// + public string DatabaseName + { + get { return databaseName; } + set { databaseName = value; } + } + + #endregion Properties + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public RavenDBConnectionStringBuilder() + { + connectionString = ""; + host = ""; + databaseName = ""; + certificatePath = ""; + password = ""; + } + + /// + /// Initializes a new instance of the class with a specified connection string. + /// + /// The connection string value. + public RavenDBConnectionStringBuilder(string connectionString) + { + this.connectionString = connectionString; + string[] parts = connectionString.Split(';'); + if (parts[0].Contains("Url")) + { + host = parts[0].Replace("Url = ", ""); + } + for (int i = 1; i < parts.Length; i++) + { + if (parts[i].Contains("Database")) + { + databaseName = parts[i].Replace("Database=", ""); + } + if (parts[i].Contains("User")) + { + certificatePath = parts[i].Replace("User=", ""); + } + if (parts[i].Contains("Password")) + { + password = parts[i].Replace("Password=", ""); + } + } + } + + #endregion Constructors + + #region Public Methods + + /// + public override string ToString() + { + StringBuilder sb = new StringBuilder("Url = "); + sb.Append(host); + if (!String.IsNullOrEmpty(databaseName)) + { + sb.AppendFormat(";Database={0}", databaseName); + } + if (!String.IsNullOrEmpty(certificatePath)) + { + sb.AppendFormat(";User={0}", certificatePath); + } + if (!String.IsNullOrEmpty(password)) + { + sb.AppendFormat(";Password={0}", password); + } + return sb.ToString(); + } + + #endregion Public Methods + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBDataConnection.DesignExt.cs b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBDataConnection.DesignExt.cs new file mode 100644 index 00000000..a88bbadd --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBDataConnection.DesignExt.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using FastReport.Data.ConnectionEditors; +using Raven.Client; +using Raven.Client.Documents; +using System.Net; +using System.ComponentModel; +//using Raven.Json.Linq; +//using Raven.Imports.Newtonsoft.Json.Linq; +using Raven.Client.Documents.Session; + +namespace FastReport.Data +{ + /// + /// Represents a connection to RavenDB database. + /// + public partial class RavenDBDataConnection : DataConnectionBase + { + /// + public override Type GetConnectionType() + { + return typeof(RavenDBDataConnection); + } + + /// + public override string GetConnectionId() + { + RavenDBConnectionStringBuilder builder = new RavenDBConnectionStringBuilder(ConnectionString); + return "RavenDB: " + builder.ToString(); + } + + /// + public override ConnectionEditorBase GetEditor() + { + return new RavenDBConnectionEditor(); + } + + /// + public override void TestConnection() + { + IDocumentStore store = this.Certificate == null ? new DocumentStore() + { + Urls = new string[] { Host }, + Database = DatabaseName + } + : new DocumentStore() + { + Urls = new string[] { Host }, + Database = DatabaseName, + Certificate = this.Certificate + }; + + store.Initialize(); + IDocumentSession session = store.OpenSession(); + store.Dispose(); + + //using (var store = new DocumentStore()) + //{ + // store.Url = Host; + // if (!string.IsNullOrEmpty(DatabaseName)) + // store.DefaultDatabase = DatabaseName; + // if (!string.IsNullOrEmpty(Username) || !string.IsNullOrEmpty(Password)) + // store.Credentials = new NetworkCredential(Username, Password); + // store.Initialize(); + // IDocumentSession session = store.OpenSession(); + //} + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBDataConnection.cs b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBDataConnection.cs new file mode 100644 index 00000000..310c3e98 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/RavenDBDataConnection.cs @@ -0,0 +1,308 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using Raven.Client; +using Raven.Client.Documents; +using System.Net; +using System.ComponentModel; +using Raven.Client.Documents.Session; +using Sparrow.Json; +using Newtonsoft.Json.Linq; +using Raven.Client.Documents.Operations.Indexes; +using Raven.Client.Documents.Operations; +using System.Security.Cryptography.X509Certificates; + +namespace FastReport.Data +{ + /// + /// Represents a connection to RavenDB database. + /// + public partial class RavenDBDataConnection : DataConnectionBase + { + private X509Certificate2 certificate; + + //public string CertificatePath { get; set; } //= @"C:\Users\alexe\Downloads\RavenDB-4.0.2-windows-x64\raven1337.Cluster.Settings\admin.client.certificate.raven1337.pfx"; + + + #region Properties + public X509Certificate2 Certificate + { + get + { + if (!string.IsNullOrEmpty(CertificatePath)) + { + if (!string.IsNullOrEmpty(this.Password)) + certificate = new X509Certificate2(CertificatePath, Password); + else + certificate = new X509Certificate2(CertificatePath); + } + return certificate; + } + set + { + certificate = value; + } + } + + /// + /// Gets or sets the certificate path. + /// + [Category("Data")] + public string CertificatePath + { + get + { + RavenDBConnectionStringBuilder builder = new RavenDBConnectionStringBuilder(ConnectionString); + return builder.CertificatePath; + } + set + { + RavenDBConnectionStringBuilder builder = new RavenDBConnectionStringBuilder(ConnectionString); + builder.CertificatePath = value; + ConnectionString = builder.ToString(); + } + } + + /// + /// Gets or sets the certificate password. + /// + [Category("Data")] + public string Password + { + get + { + RavenDBConnectionStringBuilder builder = new RavenDBConnectionStringBuilder(ConnectionString); + return builder.Password; + } + set + { + RavenDBConnectionStringBuilder builder = new RavenDBConnectionStringBuilder(ConnectionString); + builder.Password = value; + ConnectionString = builder.ToString(); + } + } + + /// + /// Gets or sets the database name. + /// + [Category("Data")] + public string DatabaseName + { + get + { + RavenDBConnectionStringBuilder builder = new RavenDBConnectionStringBuilder(ConnectionString); + return builder.DatabaseName; + } + set + { + RavenDBConnectionStringBuilder builder = new RavenDBConnectionStringBuilder(ConnectionString); + builder.DatabaseName = value; + ConnectionString = builder.ToString(); + } + } + + /// + /// Gets or sets the host url. + /// + [Category("Data")] + public string Host + { + get + { + RavenDBConnectionStringBuilder builder = new RavenDBConnectionStringBuilder(ConnectionString); + return builder.Host; + } + set + { + RavenDBConnectionStringBuilder builder = new RavenDBConnectionStringBuilder(ConnectionString); + builder.Host = value; + ConnectionString = builder.ToString(); + } + } + + #endregion Properties + + #region Protected Methods + + /// + protected override DataSet CreateDataSet() + { + DataSet dataset = base.CreateDataSet(); + + IDocumentStore store = this.Certificate == null ? new DocumentStore() + { + Urls = new string[] { Host }, + Database = DatabaseName + } + : new DocumentStore() + { + Urls = new string[] { Host }, + Database = DatabaseName, + Certificate = this.Certificate + }; + + //using strt { + store.Initialize(); + using (IDocumentSession session = store.OpenSession()) + { + var operation = new GetCollectionStatisticsOperation(); + var ress = store.Maintenance.Send(operation); + List entityNames = ress.Collections.Select(c => c.Key).ToList(); + foreach (string name in entityNames) + { + DataTable table = new DataTable(name); + + #region Local Functions + void AddColumn(string colName, Type colType) + { + try + { + + DataColumn column = new DataColumn(); + column.ColumnName = colName; + column.DataType = colType ?? typeof(string); + table.Columns.Add(column); + } + catch (Exception ex) + { + + } + } + + Type GetSimpleType(Type columnType) + { + try + { + if (columnType == typeof(LazyStringValue)) + columnType = typeof(string); + else if (columnType == typeof(LazyNumberValue)) + { + + } + return columnType; + } + catch (Exception ex) + { + + } + return typeof(string); + } + #endregion + + // get all rows of the table + BlittableJsonReaderObject[] objects = session.Advanced.LoadStartingWith(name, null, 0, Int32.MaxValue); + if (objects.Count() > 0) + { + //create table columns + var properties = objects[0].GetPropertyNames(); + foreach (var prop in properties) + { + try + { + var item = objects[0][prop]; + Type columnType = item?.GetType() ?? typeof(string); + //columns + if (columnType != typeof(BlittableJsonReaderObject)) + { + columnType = GetSimpleType(columnType); + AddColumn(prop, columnType); + } + //subcolumns + else if (columnType == typeof(BlittableJsonReaderArray)) + { + + } + else + { + var complexItem = (item as BlittableJsonReaderObject); + var subproperties = complexItem.GetPropertyNames(); + foreach (var subprop in subproperties) + { + var subitem = complexItem[subprop]; + columnType = GetSimpleType(subprop.GetType() ?? typeof(string)); + AddColumn($"{prop}.{subprop}", columnType); + } + } + } + catch (Exception ex) + { + + } + } + // add table rows + foreach (var obj in objects) + { + DataRow row = table.NewRow(); + // add row cells + for (int i = 0; i < table.Columns.Count; i++) + { + if (table.Columns[i].ColumnName.Contains(".")) + { + string[] parts = table.Columns[i].ColumnName.Split(".".ToCharArray()); + var value = obj[parts[0]]; + + if (value is BlittableJsonReaderObject) + { + var subvalue = (value as BlittableJsonReaderObject)[parts[1]]; + row[i] = subvalue; + } + } + else + { + var value = obj[table.Columns[i].ColumnName]; + row[i] = value; + } + } + table.Rows.Add(row); + } + dataset.Tables.Add(table); + } + } + + } + store.Dispose(); + return dataset; + //using end } + + } + +#endregion Protected Methods + +#region Public Methods + + /// + public override void CreateTable(TableDataSource source) + { + if (DataSet.Tables.Contains(source.TableName)) + { + source.Table = DataSet.Tables[source.TableName]; + base.CreateTable(source); + } + else + { + source.Table = null; + } + } + + /// + public override string[] GetTableNames() + { + string[] result = new string[DataSet.Tables.Count]; + for (int i = 0; i < DataSet.Tables.Count; i++) + { + result[i] = DataSet.Tables[i].TableName; + } + return result; + } + + /// + public override string QuoteIdentifier(string value, DbConnection connection) + { + return value; + } + +#endregion Public Methods + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/readme.txt b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/readme.txt new file mode 100644 index 00000000..0695dbe0 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.RavenDB/readme.txt @@ -0,0 +1,14 @@ +How to use it: +- execute the following code once at the application start: +FastReport.Utils.RegisteredObjects.AddConnection(typeof(RavenDBDataConnection)); +- now you should be able to create a new RavenDB data source from Designer (.Net 4) or from code: +Report report = new Report(); +report.Load(@"YourReport.frx"); +//... +RavenDBDataConnection conn = new RavenDBDataConnection(); +conn.Host = "https://a.ravenhost.development.run:80"; +conn.DatabaseName = "SampleDatabase"; +conn.CertificatePath = @"C:\certificate.pfx"; +conn.Password = "password"; +conn.CreateAllTables(); +report.Dictionary.Connections.Add(conn); \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.SQLite/AssemblyInitializer.cs b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/AssemblyInitializer.cs new file mode 100644 index 00000000..68c78561 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/AssemblyInitializer.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using FastReport.Utils; + +namespace FastReport.Data +{ + public class SQLiteAssemblyInitializer : AssemblyInitializerBase + { + public SQLiteAssemblyInitializer() + { + RegisteredObjects.AddConnection(typeof(SQLiteDataConnection)); + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.SQLite/FastReport.Data.SQLite.csproj b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/FastReport.Data.SQLite.csproj new file mode 100644 index 00000000..6d910013 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/FastReport.Data.SQLite.csproj @@ -0,0 +1,92 @@ + + + + netstandard2.0;net4 + true + ../../../FastReport.Plugins.snk + true + Fast Reports Inc. + Fast Reports Inc. + https://www.fast-report.com/en/product/fast-report-net/license + https://www.fast-report.com/en/product/fast-report-net + Fast Reports Inc. + FastReport.Data.SQLite + Represents a connection to SQLite database for FastReport.Net. + FastReport.Data.SQLite + https://www.fast-report.com/download/images/frlogo-big.png + reporting, SQLite, connection, reports + 2018.2.2$(VersionSuffix) + 2018.2.2.0 + 2018.2.2.0 + Debug;Release; + FastReport.Data.SQLite + FastReport.Data + + + + FRCORE;;DEBUG;NETSTANDARD2_0 + + + + + + + + + + + + + + + + + + + + false + + + False + ..\..\..\..\FastReport\bin\Release\FastReport.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UserControl + + + SQLiteConnectionEditor.cs + + + + + SQLiteConnectionEditor.cs + Designer + + + diff --git a/Extras/Core/FastReport.Data/FastReport.Data.SQLite/SQLiteConnectionEditor.Designer.cs b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/SQLiteConnectionEditor.Designer.cs new file mode 100644 index 00000000..71d7767f --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/SQLiteConnectionEditor.Designer.cs @@ -0,0 +1,122 @@ +namespace FastReport.Data +{ + partial class SQLiteConnectionEditor + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnAdvanced = new System.Windows.Forms.Button(); + this.gbDatabase = new System.Windows.Forms.GroupBox(); + this.btBrowse = new System.Windows.Forms.Button(); + this.lblDataSource = new System.Windows.Forms.Label(); + this.tbDataSource = new System.Windows.Forms.TextBox(); + this.label1 = new FastReport.Controls.LabelLine(); + this.gbDatabase.SuspendLayout(); + this.SuspendLayout(); + // + // btnAdvanced + // + this.btnAdvanced.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnAdvanced.AutoSize = true; + this.btnAdvanced.Location = new System.Drawing.Point(252, 220); + this.btnAdvanced.Name = "btnAdvanced"; + this.btnAdvanced.Size = new System.Drawing.Size(77, 23); + this.btnAdvanced.TabIndex = 0; + this.btnAdvanced.Text = "Advanced..."; + this.btnAdvanced.UseVisualStyleBackColor = true; + this.btnAdvanced.Click += new System.EventHandler(this.btnAdvanced_Click); + // + // gbDatabase + // + this.gbDatabase.Controls.Add(this.btBrowse); + this.gbDatabase.Controls.Add(this.lblDataSource); + this.gbDatabase.Controls.Add(this.tbDataSource); + this.gbDatabase.Location = new System.Drawing.Point(8, 3); + this.gbDatabase.Name = "gbDatabase"; + this.gbDatabase.Size = new System.Drawing.Size(320, 211); + this.gbDatabase.TabIndex = 1; + this.gbDatabase.TabStop = false; + this.gbDatabase.Text = "Database"; + // + // btBrowse + // + this.btBrowse.Location = new System.Drawing.Point(270, 45); + this.btBrowse.Name = "btBrowse"; + this.btBrowse.Size = new System.Drawing.Size(32, 21); + this.btBrowse.TabIndex = 4; + this.btBrowse.Text = ".."; + this.btBrowse.UseVisualStyleBackColor = true; + this.btBrowse.Click += new System.EventHandler(this.btBrowse_Click); + // + // lblDataSource + // + this.lblDataSource.AutoSize = true; + this.lblDataSource.Location = new System.Drawing.Point(6, 29); + this.lblDataSource.Name = "lblDataSource"; + this.lblDataSource.Size = new System.Drawing.Size(67, 13); + this.lblDataSource.TabIndex = 3; + this.lblDataSource.Text = "DataSource:"; + // + // tbDataSource + // + this.tbDataSource.Location = new System.Drawing.Point(9, 45); + this.tbDataSource.Name = "tbDataSource"; + this.tbDataSource.Size = new System.Drawing.Size(255, 20); + this.tbDataSource.TabIndex = 0; + // + // label1 + // + this.label1.Location = new System.Drawing.Point(8, 244); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(320, 17); + this.label1.TabIndex = 2; + // + // SQLiteConnectionEditor + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.label1); + this.Controls.Add(this.gbDatabase); + this.Controls.Add(this.btnAdvanced); + this.Name = "SQLiteConnectionEditor"; + this.Size = new System.Drawing.Size(336, 263); + this.gbDatabase.ResumeLayout(false); + this.gbDatabase.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnAdvanced; + private System.Windows.Forms.GroupBox gbDatabase; + private System.Windows.Forms.Label lblDataSource; + private FastReport.Controls.LabelLine label1; + private System.Windows.Forms.TextBox tbDataSource; + private System.Windows.Forms.Button btBrowse; + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.SQLite/SQLiteConnectionEditor.cs b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/SQLiteConnectionEditor.cs new file mode 100644 index 00000000..2627880e --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/SQLiteConnectionEditor.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using FastReport.Data.ConnectionEditors; +using FastReport.Forms; +using FastReport.Utils; +using System.Data.SQLite; + +namespace FastReport.Data +{ + public partial class SQLiteConnectionEditor : ConnectionEditorBase + { + private string FConnectionString; + + private void btnAdvanced_Click(object sender, EventArgs e) + { + using (AdvancedConnectionPropertiesForm form = new AdvancedConnectionPropertiesForm()) + { + SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder(ConnectionString); + form.AdvancedProperties = builder; + if (form.ShowDialog() == DialogResult.OK) + ConnectionString = form.AdvancedProperties.ToString(); + } + } + + private void Localize() + { + MyRes res = new MyRes("ConnectionEditors,Odbc"); + + lblDataSource.Text = res.Get("DataSource"); + + res = new MyRes("ConnectionEditors,Common"); + + gbDatabase.Text = res.Get("Database"); + btnAdvanced.Text = Res.Get("Buttons,Advanced"); + } + + protected override string GetConnectionString() + { + SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder(FConnectionString); + + builder.DataSource = tbDataSource.Text; + + return builder.ToString(); + } + + protected override void SetConnectionString(string value) + { + FConnectionString = value; + SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder(value); + + tbDataSource.Text = builder.DataSource; + } + + public SQLiteConnectionEditor() + { + InitializeComponent(); + Localize(); + } + + private void btBrowse_Click(object sender, EventArgs e) + { + using (OpenFileDialog dlg = new OpenFileDialog()) + { + dlg.Filter = "*.db3|*.db3|*.*|*.*"; + if (dlg.ShowDialog() == DialogResult.OK) + tbDataSource.Text = dlg.FileName; + } + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.SQLite/SQLiteConnectionEditor.resx b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/SQLiteConnectionEditor.resx new file mode 100644 index 00000000..19dc0dd8 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/SQLiteConnectionEditor.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.SQLite/SQLiteDataConnection.DesignExt.cs b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/SQLiteDataConnection.DesignExt.cs new file mode 100644 index 00000000..76784828 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/SQLiteDataConnection.DesignExt.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Data.Common; +using FastReport.Data.ConnectionEditors; +using System.Data.SQLite; + +namespace FastReport.Data +{ + public partial class SQLiteDataConnection + { + public override string GetConnectionId() + { + SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder(ConnectionString); + string info = ""; + try + { + info = builder.DataSource ?? String.Empty; + } + catch + { + } + return "SQLite: " + info; + } + + public override ConnectionEditorBase GetEditor() + { + return new SQLiteConnectionEditor(); + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.SQLite/SQLiteDataConnection.cs b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/SQLiteDataConnection.cs new file mode 100644 index 00000000..aab2e2bc --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/SQLiteDataConnection.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Data.Common; +using System.Data; +using FastReport.Data; +#if FRCORE +using System.Linq; +using Microsoft.Data.Sqlite; +#else +using System.Data.SQLite; +#endif + +namespace FastReport.Data +{ + public partial class SQLiteDataConnection : DataConnectionBase + { + private void GetDBObjectNames(string name, List list) + { + DataTable schema = null; + DbConnection connection = GetConnection(); + try + { + OpenConnection(connection); + schema = connection.GetSchema(name); + } + finally + { + DisposeConnection(connection); + } + foreach (DataRow row in schema.Rows) + { + list.Add(row["TABLE_NAME"].ToString()); + } + } + + public override string[] GetTableNames() + { + List list = new List(); + GetDBObjectNames("Tables", list); + GetDBObjectNames("Views", list); + return list.ToArray(); + } + + public override string QuoteIdentifier(string value, DbConnection connection) + { + return "`" + value + "`"; + } + + protected override string GetConnectionStringWithLoginInfo(string userName, string password) + { +#if FRCORE + SqliteConnectionStringBuilder builder = new SqliteConnectionStringBuilder(ConnectionString); +#else + SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder(ConnectionString); + builder.Password = password; +#endif + + return builder.ToString(); + } + + public override Type GetConnectionType() + { +#if FRCORE + return typeof(SqliteConnection); +#else + return typeof(SQLiteConnection); +#endif + } + +#if !FRCORE + public override DbDataAdapter GetAdapter(string selectCommand, DbConnection connection, + CommandParameterCollection parameters) + { + SQLiteDataAdapter adapter = new SQLiteDataAdapter(selectCommand, connection as SQLiteConnection); + foreach (CommandParameter p in parameters) + { + SQLiteParameter parameter = adapter.SelectCommand.Parameters.Add(p.Name, (DbType)p.DataType, p.Size); + parameter.Value = p.Value; + } + return adapter; + } +#else + + public new SqliteConnection GetConnection() => new SqliteConnection(ConnectionString); + + private string PrepareSelectCommand(string selectCommand, string tableName, DbConnection connection) + { + if (String.IsNullOrEmpty(selectCommand)) + { + selectCommand = "select * from " + QuoteIdentifier(tableName, connection); + } + return selectCommand; + } + + private IEnumerable GetColumns(SqliteDataReader reader) + { + for (int i = 0; i < reader.FieldCount; i++) + { + yield return new DataColumn(reader.GetName(i), reader.GetFieldType(i)); + } + } + + public override void FillTableSchema(DataTable table, string selectCommand, + CommandParameterCollection parameters) + { + SqliteConnection conn = GetConnection(); + try + { + OpenConnection(conn); + + // prepare select command + selectCommand = PrepareSelectCommand(selectCommand, table.TableName, conn); + + SqliteCommand command = conn.CreateCommand(); + command.CommandText = selectCommand; + + // read the table schema + using (SqliteDataReader reader = command.ExecuteReader()) + { + var clmns = GetColumns(reader); + table.Columns.AddRange(clmns.ToArray()); + } + } + finally + { + DisposeConnection(conn); + } + } + + public override void FillTableData(DataTable table, string selectCommand, + CommandParameterCollection parameters) + { + SqliteConnection conn = GetConnection(); + try + { + OpenConnection(conn); + + // prepare select command + selectCommand = PrepareSelectCommand(selectCommand, table.TableName, conn); + + SqliteCommand command = conn.CreateCommand(); + command.CommandText = selectCommand; + command.CommandTimeout = CommandTimeout; + + // read the table + using (SqliteDataReader reader = command.ExecuteReader()) + { + table.Clear(); + while (reader.Read()) + { + var newRow = table.Rows.Add(); + foreach (DataColumn col in table.Columns) + { + newRow[col.ColumnName] = reader[col.ColumnName]; + } + } + } + } + finally + { + DisposeConnection(conn); + } + } +#endif + + public override Type GetParameterType() + { + return typeof(DbType); + } + } +} diff --git a/Extras/Core/FastReport.Data/FastReport.Data.SQLite/readme.txt b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/readme.txt new file mode 100644 index 00000000..bc6b2ffe --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.SQLite/readme.txt @@ -0,0 +1,11 @@ +How to use it: +- execute the following code once at the application start: +FastReport.Utils.RegisteredObjects.AddConnection(typeof(SQLiteDataConnection)); +- now you should be able to create a new SQLite data source from Designer (.Net 4) or from code: +Report report = new Report(); +report.Load(@"YourReport.frx"); +//... +SQLiteDataConnection conn = new SQLiteDataConnection(); +conn.ConnectionString = "your connection string"; +conn.CreateAllTables(); +report.Dictionary.Connections.Add(conn); \ No newline at end of file diff --git a/Extras/Core/FastReport.Data/FastReport.Data.sln b/Extras/Core/FastReport.Data/FastReport.Data.sln new file mode 100644 index 00000000..976213b6 --- /dev/null +++ b/Extras/Core/FastReport.Data/FastReport.Data.sln @@ -0,0 +1,55 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2027 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastReport.Data.MsSql", "FastReport.Data.MsSql\FastReport.Data.MsSql.csproj", "{00C4F5E9-E580-4D3A-9AD5-961AA8BEAC13}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastReport.Data.MySql", "FastReport.Data.MySql\FastReport.Data.MySql.csproj", "{2F557F54-6836-44D8-B279-2CEAD6834D74}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastReport.Data.SQLite", "FastReport.Data.SQLite\FastReport.Data.SQLite.csproj", "{163D31BF-E81B-4CF8-BC19-F41F3B77FE83}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastReport.Data.Postgres", "FastReport.Data.Postgres\FastReport.Data.Postgres.csproj", "{3BB02EC3-A96F-42DC-803A-948066D43B69}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastReport.Data.Json", "FastReport.Data.Json\FastReport.Data.Json.csproj", "{C58DD653-F4F4-47A5-A52F-4F151A31F190}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FastReport.Data.MongoDB", "FastReport.Data.MongoDB\FastReport.Data.MongoDB.csproj", "{9BA8F49F-6BD7-42EA-9914-8BFF239A0C20}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {00C4F5E9-E580-4D3A-9AD5-961AA8BEAC13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00C4F5E9-E580-4D3A-9AD5-961AA8BEAC13}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00C4F5E9-E580-4D3A-9AD5-961AA8BEAC13}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00C4F5E9-E580-4D3A-9AD5-961AA8BEAC13}.Release|Any CPU.Build.0 = Release|Any CPU + {2F557F54-6836-44D8-B279-2CEAD6834D74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2F557F54-6836-44D8-B279-2CEAD6834D74}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2F557F54-6836-44D8-B279-2CEAD6834D74}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2F557F54-6836-44D8-B279-2CEAD6834D74}.Release|Any CPU.Build.0 = Release|Any CPU + {163D31BF-E81B-4CF8-BC19-F41F3B77FE83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {163D31BF-E81B-4CF8-BC19-F41F3B77FE83}.Debug|Any CPU.Build.0 = Debug|Any CPU + {163D31BF-E81B-4CF8-BC19-F41F3B77FE83}.Release|Any CPU.ActiveCfg = Release|Any CPU + {163D31BF-E81B-4CF8-BC19-F41F3B77FE83}.Release|Any CPU.Build.0 = Release|Any CPU + {3BB02EC3-A96F-42DC-803A-948066D43B69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3BB02EC3-A96F-42DC-803A-948066D43B69}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3BB02EC3-A96F-42DC-803A-948066D43B69}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3BB02EC3-A96F-42DC-803A-948066D43B69}.Release|Any CPU.Build.0 = Release|Any CPU + {C58DD653-F4F4-47A5-A52F-4F151A31F190}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C58DD653-F4F4-47A5-A52F-4F151A31F190}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C58DD653-F4F4-47A5-A52F-4F151A31F190}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C58DD653-F4F4-47A5-A52F-4F151A31F190}.Release|Any CPU.Build.0 = Release|Any CPU + {9BA8F49F-6BD7-42EA-9914-8BFF239A0C20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9BA8F49F-6BD7-42EA-9914-8BFF239A0C20}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9BA8F49F-6BD7-42EA-9914-8BFF239A0C20}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9BA8F49F-6BD7-42EA-9914-8BFF239A0C20}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C3B2B0A0-D152-4CF3-AD41-1B32D582011F} + EndGlobalSection +EndGlobal diff --git a/FastReport.Base/AssemblyInitializer.cs b/FastReport.Base/AssemblyInitializer.cs index 71a881e1..90b9b445 100644 --- a/FastReport.Base/AssemblyInitializer.cs +++ b/FastReport.Base/AssemblyInitializer.cs @@ -72,10 +72,10 @@ public AssemblyInitializer() RegisteredObjects.Add(typeof(OverlayBand), "", 166, "Objects,Bands,Overlay"); // report objects - RegisteredObjects.Add(typeof(TextObject), "ReportPage", 102); - RegisteredObjects.Add(typeof(PictureObject), "ReportPage", 103); + RegisteredObjects.Add(typeof(TextObject), "ReportPage", 102, 1); + RegisteredObjects.Add(typeof(PictureObject), "ReportPage", 103, 2); - RegisteredObjects.AddCategory("ReportPage,Shapes", 106, "Objects,Shapes"); + RegisteredObjects.AddCategory("ReportPage,Shapes", 106, 4, "Objects,Shapes"); RegisteredObjects.Add(typeof(LineObject), "ReportPage,Shapes", 105, "Objects,Shapes,Line", 0, true); RegisteredObjects.Add(typeof(LineObject), "ReportPage,Shapes", 107, "Objects,Shapes,DiagonalLine", 1, true); RegisteredObjects.Add(typeof(LineObject), "ReportPage,Shapes", 150, "Objects,Shapes,DiagonalLine", 2, true); @@ -93,25 +93,25 @@ public AssemblyInitializer() RegisteredObjects.Add(typeof(PolygonObject), "ReportPage,Shapes", 243, "Objects,Shapes,Hexagon", 0x60); RegisteredObjects.Add(typeof(PolygonObject), "ReportPage,Shapes", 244, "Objects,Shapes,Heptagon", 0x70); RegisteredObjects.Add(typeof(PolygonObject), "ReportPage,Shapes", 245, "Objects,Shapes,Octagon", 0x80); - RegisteredObjects.Add(typeof(SubreportObject), "ReportPage", 104); + RegisteredObjects.Add(typeof(SubreportObject), "ReportPage", 104, 5); - RegisteredObjects.Add(typeof(TableObject), "ReportPage", 127); + RegisteredObjects.Add(typeof(TableObject), "ReportPage", 127, 6); RegisteredObjects.Add(typeof(TableColumn), "", 215); RegisteredObjects.Add(typeof(TableRow), "", 216); RegisteredObjects.Add(typeof(TableCell), "", 214); - RegisteredObjects.Add(typeof(MatrixObject), "ReportPage", 142); - RegisteredObjects.Add(typeof(CrossViewObject), "ReportPage", 247); + RegisteredObjects.Add(typeof(MatrixObject), "ReportPage", 142, 7); + RegisteredObjects.Add(typeof(CrossViewObject), "ReportPage", 247, 8); - RegisteredObjects.AddCategory("ReportPage,Barcodes", 123, "Objects,BarcodeObject"); + RegisteredObjects.AddCategory("ReportPage,Barcodes", 123, 9, "Objects,BarcodeObject"); for (int i = 0; i <= Barcodes.Items.Length - 1; i++) RegisteredObjects.Add(typeof(BarcodeObject), "ReportPage,Barcodes", -1, "ComponentMenu,Barcode,Barcodes,Barcode" + i, i); - RegisteredObjects.Add(typeof(CheckBoxObject), "ReportPage", 124); + RegisteredObjects.Add(typeof(CheckBoxObject), "ReportPage", 124, 10); - RegisteredObjects.Add(typeof(ZipCodeObject), "ReportPage", 129); - RegisteredObjects.Add(typeof(CellularTextObject), "ReportPage", 121); + RegisteredObjects.Add(typeof(ZipCodeObject), "ReportPage", 129, 14); + RegisteredObjects.Add(typeof(CellularTextObject), "ReportPage", 121, 15); - RegisteredObjects.AddCategory("ReportPage,Gauge", 140, "Objects,Gauge"); + RegisteredObjects.AddCategory("ReportPage,Gauge", 140, 17, "Objects,Gauge"); RegisteredObjects.Add(typeof(LinearGauge), "ReportPage,Gauge", -1, "Objects,Gauge,Linear", 0, false); RegisteredObjects.Add(typeof(SimpleGauge), "ReportPage,Gauge", -1, "Objects,Gauge,Simple", 0, false); RegisteredObjects.Add(typeof(RadialGauge), "ReportPage,Gauge", -1, "Objects,Gauge,Radial", 0, false); @@ -120,7 +120,7 @@ public AssemblyInitializer() // RegisteredObjects.Add(typeof(CrossBandObject), "ReportPage", 11, "Cross-band line", 0); // RegisteredObjects.Add(typeof(CrossBandObject), "ReportPage", 11, "Cross-band rectangle", 1); - RegisteredObjects.Add(typeof(HtmlObject), "ReportPage", 246); + RegisteredObjects.Add(typeof(HtmlObject), "ReportPage", 246, 18); // exports diff --git a/FastReport.Base/Utils/RegisteredObjects.cs b/FastReport.Base/Utils/RegisteredObjects.cs index 973591da..7f70661d 100644 --- a/FastReport.Base/Utils/RegisteredObjects.cs +++ b/FastReport.Base/Utils/RegisteredObjects.cs @@ -157,6 +157,16 @@ internal void Update(Object obj, Bitmap image, int imageIndex, string text, int MultiInsert = multiInsert; } + internal void Update(Object obj, Bitmap image, int imageIndex, int buttonIndex, string text, int flags, + bool multiInsert) + { + fObject = obj; + UpdateDesign(obj, image, imageIndex, buttonIndex, text, flags, multiInsert); + Text = text; + Flags = flags; + MultiInsert = multiInsert; + } + #endregion internal ObjectInfo() @@ -211,19 +221,30 @@ public static ObjectInfo Objects #endregion #region Private Methods + private static void RegisterType(Type type) { FTypes[type.Name] = type; } - private static void InternalAdd(Object obj, string category, Bitmap image, int imageIndex, string text, - int flags, bool multiInsert) + private static void InternalAdd(Object obj, string category, Bitmap image, int imageIndex, string text, int flags, + bool multiInsert) { ObjectInfo item = FObjects.FindOrCreate(category); item.Update(obj, image, imageIndex, text, flags, multiInsert); if (obj is Type) RegisterType(obj as Type); } + + private static void InternalAdd(Object obj, string category, Bitmap image, int imageIndex, int buttonIndex, + string text, int flags, bool multiInsert) + { + ObjectInfo item = FObjects.FindOrCreate(category); + item.Update(obj, image, imageIndex, buttonIndex, text, flags, multiInsert); + if (obj is Type) + RegisterType(obj as Type); + } + #endregion #region Public Methods @@ -252,6 +273,11 @@ internal static void AddCategory(string category, int imageIndex, string text) InternalAdd(null, category, null, imageIndex, text, 0, false); } + internal static void AddCategory(string category, int imageIndex, int buttonIndex, string text) + { + InternalAdd(null, category, null, imageIndex, buttonIndex, text, 0, false); + } + /// /// Registers a category that may contain several report objects. /// @@ -383,6 +409,18 @@ public static void Add(Type obj, string category, int imageIndex) InternalAdd(obj, category + ",", null, imageIndex, "", 0, false); } + /// + /// Registers an object in the specified category. + /// + /// Type of object to register. + /// Name of category to register in. + /// Index of image for object's button. + /// Index of object's button in toolbar. + public static void Add(Type obj, string category, int imageIndex, int buttonIndex) + { + InternalAdd(obj, category + ",", null, imageIndex, buttonIndex, "", 0, false); + } + internal static void Add(Type obj, string category, int imageIndex, string text) { InternalAdd(obj, category + ",", null, imageIndex, text, 0, false); diff --git a/FastReport.Base/Utils/TextRenderer.cs b/FastReport.Base/Utils/TextRenderer.cs index cd5d27c6..95557b5e 100644 --- a/FastReport.Base/Utils/TextRenderer.cs +++ b/FastReport.Base/Utils/TextRenderer.cs @@ -557,7 +557,9 @@ public void WrapLines() charsFit = MeasureString(text); string textFit = text.Substring(0, charsFit).TrimEnd(new char[] { ' ' }); lines.Add(new Line(textFit, this, originalCharIndex)); - text = text.Substring(charsFit); + text = text.Substring(charsFit) + // Fix for linux system + .TrimStart(' '); originalCharIndex += charsFit; } } diff --git a/FastReport.OpenSource.sln b/FastReport.OpenSource.sln index 03bde5f7..c12c0967 100644 --- a/FastReport.OpenSource.sln +++ b/FastReport.OpenSource.sln @@ -15,6 +15,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastReportCore.MVC", "Demos EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Demos", "Demos", "{8E9E75EB-2ABC-4CC1-8AA0-C11DEE54A152}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extras", "Extras", "{CCF32DAC-85D9-43D4-A4A7-72626A13D806}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Connections", "Connections", "{898AF8DC-11C3-4640-B60C-5D8CBF2F29CF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastReport.OpenSource.Data.Postgres", "Extras\Core\FastReport.Data\FastReport.Data.Postgres\FastReport.OpenSource.Data.Postgres.csproj", "{DADF1C79-7C33-4059-B71F-C3D91EA90436}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Academic|Any CPU = Academic|Any CPU @@ -74,6 +80,16 @@ Global {FC7C0236-7420-4881-9808-5AFD08310B76}.Release|Any CPU.Build.0 = Release|Any CPU {FC7C0236-7420-4881-9808-5AFD08310B76}.WinForms|Any CPU.ActiveCfg = Debug|Any CPU {FC7C0236-7420-4881-9808-5AFD08310B76}.WinForms|Any CPU.Build.0 = Debug|Any CPU + {DADF1C79-7C33-4059-B71F-C3D91EA90436}.Academic|Any CPU.ActiveCfg = Debug|Any CPU + {DADF1C79-7C33-4059-B71F-C3D91EA90436}.Academic|Any CPU.Build.0 = Debug|Any CPU + {DADF1C79-7C33-4059-B71F-C3D91EA90436}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DADF1C79-7C33-4059-B71F-C3D91EA90436}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DADF1C79-7C33-4059-B71F-C3D91EA90436}.Demo|Any CPU.ActiveCfg = Debug|Any CPU + {DADF1C79-7C33-4059-B71F-C3D91EA90436}.Demo|Any CPU.Build.0 = Debug|Any CPU + {DADF1C79-7C33-4059-B71F-C3D91EA90436}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DADF1C79-7C33-4059-B71F-C3D91EA90436}.Release|Any CPU.Build.0 = Release|Any CPU + {DADF1C79-7C33-4059-B71F-C3D91EA90436}.WinForms|Any CPU.ActiveCfg = Debug|Any CPU + {DADF1C79-7C33-4059-B71F-C3D91EA90436}.WinForms|Any CPU.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -81,6 +97,8 @@ Global GlobalSection(NestedProjects) = preSolution {F1DE0844-F78B-4367-A2AA-4CE1029F2BAE} = {8E9E75EB-2ABC-4CC1-8AA0-C11DEE54A152} {FC7C0236-7420-4881-9808-5AFD08310B76} = {8E9E75EB-2ABC-4CC1-8AA0-C11DEE54A152} + {898AF8DC-11C3-4640-B60C-5D8CBF2F29CF} = {CCF32DAC-85D9-43D4-A4A7-72626A13D806} + {DADF1C79-7C33-4059-B71F-C3D91EA90436} = {898AF8DC-11C3-4640-B60C-5D8CBF2F29CF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DFBB1F5B-F03E-4BCB-AFEE-A45A2C4D5BB8} diff --git a/FastReport.OpenSource/Utils/RegisteredObjects.Core.cs b/FastReport.OpenSource/Utils/RegisteredObjects.Core.cs index f51f31b3..dc96398e 100644 --- a/FastReport.OpenSource/Utils/RegisteredObjects.Core.cs +++ b/FastReport.OpenSource/Utils/RegisteredObjects.Core.cs @@ -17,7 +17,20 @@ partial class ObjectInfo /// private void UpdateDesign(object obj, Bitmap image, int imageIndex, string text, int flags, bool multiInsert) { + } + /// + /// Does nothing. + /// + /// + /// + /// + /// + /// + /// + /// + private void UpdateDesign(object obj, Bitmap image, int imageIndex, int ButtonIndex, string text, int flags, bool multiInsert) + { } #endregion Private Methods diff --git a/Tools/pack.bat b/Tools/pack.bat index d2940297..28005e21 100644 --- a/Tools/pack.bat +++ b/Tools/pack.bat @@ -15,24 +15,36 @@ for %%x in (%*) do ( IF [%%x] == [--version] ( SET "VERSION=0.0.0" ) ) +rem Directories: SET "PROP=/p:SolutionDir=%~dp0..\;SolutionFileName=FastReport.OpenSource.sln;Version=!VERSION!" SET "FR=FastReport.OpenSource\FastReport.OpenSource.csproj" SET "WEB=FastReport.Core.Web\FastReport.Web.csproj" +SET "DATA=Extras\Core\FastReport.Data" + +rem Connections +SET "POSTGRES=FastReport.Data.Postgres\FastReport.OpenSource.Data.Postgres.csproj" + +SET "OUTPUT=%~dp0..\..\fr_nuget" + pushd %~dp0.. IF "!WITH_OUT_DEBUG!"=="false" ( -dotnet clean !FR! -c Debug "!PROP!-debug" -dotnet clean !WEB! -c Debug "!PROP!-debug" +dotnet clean !FR! -c Debug "!PROP!-debug" +dotnet clean !WEB! -c Debug "!PROP!-debug" +dotnet clean !DATA!\!POSTGRES! -c Debug "!PROP!-debug" -dotnet pack !FR! -c Debug "!PROP!-debug" -o ../../fr_nuget --include-symbols --include-source -dotnet pack !WEB! -c Debug "!PROP!-debug" -o ../../fr_nuget --include-symbols --include-source +dotnet pack !FR! -c Debug "!PROP!-debug" -o "!OUTPUT!" --include-symbols --include-source +dotnet pack !WEB! -c Debug "!PROP!-debug" -o "!OUTPUT!" --include-symbols --include-source +dotnet pack !DATA!\!POSTGRES! -c Debug "!PROP!-debug" -o "!OUTPUT!" --include-symbols --include-source ) -dotnet clean !FR! -c Release "!PROP!" -dotnet clean !WEB! -c Release "!PROP!" - -dotnet pack !FR! -c Release "!PROP!" -o ../../fr_nuget -dotnet pack !WEB! -c Release "!PROP!" -o ../../fr_nuget +dotnet clean !FR! -c Release "!PROP!" +dotnet clean !WEB! -c Release "!PROP!" +dotnet clean !DATA!\!POSTGRES! -c Release "!PROP!" + +dotnet pack !FR! -c Release "!PROP!" -o "!OUTPUT!" +dotnet pack !WEB! -c Release "!PROP!" -o "!OUTPUT!" +dotnet pack !DATA!\!POSTGRES! -c Release "!PROP!" -o "!OUTPUT!" popd \ No newline at end of file