123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491 |
- using FastReport.Data;
- using FastReport.Forms;
- using FastReport.Utils;
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Data.Common;
- using System.Windows.Forms;
- namespace FastReport.FastQueryBuilder
- {
- internal class Core
- {
- private IQueryDesigner queryDesigner;
- private DataBase dataBase;
- private DialogResult dialogResult;
- private Query query = new Query();
- // unstable features
- private bool unstableFeatures;
- private bool unstableFeaturesForce;
- public Core(IQueryDesigner qd, DataBase db)
- {
- unstableFeatures = true;
- dataBase = db;
- queryDesigner = qd;
- queryDesigner.OnOk += OnOk;
- queryDesigner.OnCancel += OnCancel;
- queryDesigner.OnGetTableList += OnGetTableList;
- queryDesigner.OnAddTable += OnAddTable;
- queryDesigner.OnGenerateSQL += OnGenerateSQL;
- queryDesigner.OnRunSQL += OnRunSQL;
- queryDesigner.Fields = query.SelectedFields;
- queryDesigner.Groups = query.GroupedFields;
- queryDesigner.Links = query.LinkList;
- }
- public bool UseJoin { get; set; } = true;
- public DialogResult DesignQuery()
- {
- queryDesigner.DesignQuery();
- return dialogResult;
- }
- private void OnOk(object sender, EventArgs e)
- {
- dialogResult = DialogResult.OK;
- queryDesigner.Close();
- }
- private void OnCancel(object sender, EventArgs e)
- {
- dialogResult = DialogResult.Cancel;
- queryDesigner.Close();
- }
- private void OnGetTableList(object sender, EventArgs e)
- {
- queryDesigner.DoFillTableList(dataBase.TableList);
- }
- private Table FindTable(List<Table> list, string tableName)
- {
- foreach (Table table in list)
- {
- if (table.Name == tableName)
- return table;
- }
- return null;
- }
- private void OnAddTable(object sender, AddTableEventArgs e)
- {
- Table tbl = (Table)e.table.Clone();
- tbl.Alias = GetUniqueAlias(tbl, e.alias);
- query.TableList.Add(tbl);
- var tv = queryDesigner.DoAddTable(tbl, e.position);
- tv.OnAddLink += OnAddLink;
- tv.OnSelectField += OnSelectField;
- tv.OnDeleteTable += OnDeleteTable;
- e.tableView = tv;
- }
- private Field FindSelectedField(SqlParser.FieldStruct fs)
- {
- foreach (Field f in query.SelectedFields)
- {
- if ((f.Table.Alias == fs.Table || f.Table.Name == fs.Table) && FieldEqFieldStruct(f, fs))
- {
- return f;
- }
- }
- return null;
- }
- private Field FindField(SqlParser.FieldStruct fs)
- {
- foreach (Table t in query.TableList)
- {
- if (t.Name == fs.Table || t.Alias == fs.Table)
- {
- foreach (Field f in t.FieldList)
- {
- if (FieldEqFieldStruct(f, fs))
- return f;
- }
- }
- }
- return null;
- }
- private bool FieldEqFieldStruct(Field f, SqlParser.FieldStruct fs)
- {
- return f.Name == fs.Name ||
- !String.IsNullOrEmpty(f.Alias) && f.Alias == fs.Name ||
- !String.IsNullOrEmpty(fs.Alias) && f.Name == fs.Alias ||
- !String.IsNullOrEmpty(f.Alias) && !String.IsNullOrEmpty(fs.Alias) && f.Alias == fs.Alias;
- }
- private bool hasDuplicate(string alias)
- {
- foreach (Table t in query.TableList)
- {
- if (t.Alias == alias)
- return true;
- }
- return false;
- }
- private string GetUniqueAlias(Table tbl, string al)
- {
- if (string.IsNullOrEmpty(al))
- {
- al = tbl.Name[0].ToString().ToUpper();
- if (al[0] < 'A' || al[0] > 'Z')
- al = "A";
- }
- int n = 1;
- while (hasDuplicate(al))
- {
- al = tbl.Name[0] + n.ToString();
- n++;
- }
- return al;
- }
- private void OnDeleteTable(object sender, AddTableEventArgs e)
- {
- for (int i = query.SelectedFields.Count - 1; i >= 0; i--)
- {
- if (query.SelectedFields[i].Table == e.table)
- query.SelectedFields.RemoveAt(i);
- }
- query.DeleteTable(e.table);
- queryDesigner.Fields = query.SelectedFields;
- }
- private void OnAddLink(object sender, AddLinkEventArgs e)
- {
- Link lnk;
- if (LinkHasFrom(query.LinkList, e.fieldTo.Table))
- lnk = new Link(e.fieldTo, e.fieldFrom);
- else
- lnk = new Link(e.fieldFrom, e.fieldTo);
- if (LinkHas(query.LinkList, lnk))
- return;
- if (!e.useDefaults)
- {
- lnk.Join = e.joinType;
- lnk.Where = e.whereType;
- }
- else
- {
- lnk.Join = UseJoin ? QueryEnums.JoinTypes.InnerJoin : QueryEnums.JoinTypes.Where;
- lnk.Where = QueryEnums.WhereTypes.Equal;
- }
- query.LinkList.Add(lnk);
- }
- private bool LinkHas(List<Link> list, Link lnk)
- {
- foreach (Link link in list)
- {
- if (link.From == lnk.From && link.To == lnk.To)
- return true;
- }
- return false;
- }
- private bool LinkHasFrom(List<Link> list, Table from)
- {
- foreach (Link link in list)
- {
- if (link.From.Table == from)
- return true;
- }
- return false;
- }
- private void OnSelectField(object sender, CheckFieldEventArgs e)
- {
- if (e.value)
- {
- query.SelectedFields.Add(e.field);
- }
- else
- {
- query.SelectedFields.Remove(e.field);
- }
- queryDesigner.Fields = query.SelectedFields;
- }
- private void OnGenerateSQL(object sender, EventArgs e)
- {
- var sqlGen = new SQLGenerator(query);
- sqlGen.qch = dataBase.GetQuotationChars();
- queryDesigner.SQLText = sqlGen.getSql();
- #region Debug
- //queryDesigner.SQLText += "\n\n\n\n/*Tables:\n";
- //foreach (Table tbl in query.TableList)
- //{
- // queryDesigner.SQLText += tbl.Name + "\n";
- //}
- //queryDesigner.SQLText += "\nLinks:\n";
- //foreach (Link lnk in query.LinkList)
- //{
- // queryDesigner.SQLText += lnk.From.Table + ":" + lnk.From.Name + " => " + lnk.To.Table + ":" + lnk.To.Name + "\n";
- //}
- //queryDesigner.SQLText += "\nFields:\n";
- //foreach (Field fld in query.SelectedFields)
- //{
- // queryDesigner.SQLText += fld.Table.ToString() + '.' + fld.Name + "\n";
- //}
- //queryDesigner.SQLText += "*/";
- #endregion
- }
- private void OnRunSQL(object sender, EventArgs e)
- {
- var sqlGen = new SQLGenerator(query);
- sqlGen.qch = dataBase.GetQuotationChars();
- string sql = string.IsNullOrEmpty(queryDesigner.SQLText) ? sqlGen.getSql() : queryDesigner.SQLText;
- DataTable table = new DataTable();
- DataConnectionBase dataConnection = dataBase.dataBase;
- DbConnection conn = dataConnection.GetConnection();
- try
- {
- dataConnection.OpenConnection(conn);
- using (DbDataAdapter adapter = dataConnection.GetAdapter(sql, conn, new CommandParameterCollection(null)))
- {
- table.Clear();
- adapter.Fill(table);
- }
- }
- finally
- {
- dataConnection.DisposeConnection(conn);
- }
- queryDesigner.DataSource = table;
- }
- public string GetSql()
- {
- if (string.IsNullOrEmpty(queryDesigner.SQLText))
- OnGenerateSQL(null, null);
- return queryDesigner.SQLText;
- }
- public void SetSql(string sql)
- {
- if (unstableFeatures && !string.IsNullOrEmpty(sql))
- {
- var parser = new SqlParser(sql);
- parser.qch = dataBase.GetQuotationChars();
- var tableViews = new List<ITableView>();
- try
- {
- parser.Parse();
- List<Table> tables = dataBase.TableList;
- // add tables
- foreach (SqlParser.TableStruct t in parser.Tables)
- {
- if (!unstableFeatures)
- break;
- Table table = FindTable(tables, t.Name);
- if (table != null)
- {
- var args = new AddTableEventArgs(table, System.Drawing.Point.Empty, t.Alias);
- OnAddTable(queryDesigner, args);
- tableViews.Add(args.tableView);
- }
- else
- {
- ShowError(new FormatException("Table " + t.Name + " is not found!"));
- }
- }
- if (unstableFeatures)
- {
- // select fields
- foreach (SqlParser.FieldStruct fs in parser.Fields)
- {
- if (!unstableFeatures)
- break;
- string tableName = fs.Table;
- foreach (ITableView tv in tableViews)
- {
- if (!unstableFeatures)
- break;
- Table tbl = tv.Table;
- if (tbl.Name == tableName || tbl.Alias == tableName)
- {
- if (!tv.SelectCheckBox(fs.Name, fs.Func, fs.Alias))
- ShowError(new FormatException("Field " + fs.Name + " is not found!"));
- break;
- }
- }
- }
- foreach (SqlParser.FieldStruct fs in parser.Where)
- {
- if (!unstableFeatures)
- break;
- Field f = FindSelectedField(fs);
- if (f == null)
- {
- ShowError(new FormatException("Field " + fs.Name + " is not found!"));
- }
- else
- {
- f.Filter = fs.Filter;
- }
- }
- foreach (SqlParser.FieldStruct fs in parser.Groups)
- {
- if (!unstableFeatures)
- break;
- Field f = FindSelectedField(fs);
- if (f == null)
- {
- ShowError(new FormatException("Field " + fs.Name + " is not found!"));
- }
- else
- {
- f.Group = true;
- query.GroupedFields.Add(f);
- }
- }
- foreach (SqlParser.FieldStruct fs in parser.Orders)
- {
- if (!unstableFeatures)
- break;
- Field f = FindSelectedField(fs);
- if (f == null)
- {
- ShowError(new FormatException("Field " + fs.Name + " is not found!"));
- }
- else
- {
- switch (fs.SortType)
- {
- case SortTypes.Asc:
- f.Order = "Asc";
- break;
- case SortTypes.Desc:
- f.Order = "Desc";
- break;
- }
- }
- }
- }
- if (unstableFeatures)
- {
- foreach (SqlParser.LinkStruct ls in parser.Links)
- {
- if (!unstableFeatures)
- break;
- Field fieldFrom = FindField(ls.One);
- Field fieldTo = FindField(ls.Two);
- if (fieldFrom == null)
- {
- ShowError(new FormatException("Field " + ls.One + " is not found!"));
- }
- if (fieldTo == null)
- {
- ShowError(new FormatException("Field " + ls.Two + " is not found!"));
- }
- if (fieldFrom != null && fieldTo != null)
- OnAddLink(queryDesigner, new AddLinkEventArgs(fieldFrom, fieldTo, ls.JoinType, ls.WhereType));
- }
- }
- if (unstableFeatures && !unstableFeaturesForce)
- {
- var sqlGen = new SQLGenerator(query);
- sqlGen.qch = dataBase.GetQuotationChars();
- string newSql = sqlGen.getSql();
- var lexerOld = new SqlLexer(sql, sqlGen.qch);
- var lexerNew = new SqlLexer(newSql, sqlGen.qch);
- var tokensOld = lexerOld.Parse();
- var tokensNew = lexerNew.Parse();
- bool isSqlEquals = true;
- if (tokensOld.Count != tokensNew.Count)
- {
- isSqlEquals = false;
- }
- else
- {
- for (int i = 0; i < tokensOld.Count; i++)
- {
- if (!tokensOld[i].Equals(tokensNew[i]))
- {
- isSqlEquals = false;
- break;
- }
- }
- }
- if (!isSqlEquals)
- ShowError(new Exception("Sql is not equals"));
- }
- if (!unstableFeatures)
- {
- query.LinkList.Clear();
- query.SelectedFields.Clear();
- query.GroupedFields.Clear();
- query.TableList.Clear();
- queryDesigner.Clear();
- queryDesigner.Fields = query.SelectedFields;
- }
- }
- catch (Exception e)
- {
- ShowError(e);
- }
- }
- }
- private void ShowError(Exception e)
- {
- #if DEBUG
- ExceptionForm form = new ExceptionForm(e);
- form.ShowDialog();
- #endif
- if (unstableFeatures && !unstableFeaturesForce)
- {
- switch (MessageBox.Show(Res.Get("Forms,QueryBuilder,QueryIsCorrupted"),
- Res.Get("Forms,QueryBuilder,QueryIsCorruptedTitle"),
- MessageBoxButtons.YesNo, MessageBoxIcon.Warning))
- {
- case DialogResult.Yes:
- unstableFeaturesForce = true;
- break;
- case DialogResult.No:
- unstableFeatures = false;
- break;
- }
- }
- }
- }
- }
|