private void LoadRequirements() { ApiRequirementsFile[] requirements = TryLoadConfigurationFiles <ApiRequirementsFile>(this.SourceFolderPath); var foundRequirements = requirements.FirstOrDefault(); if (null != foundRequirements) { Console.WriteLine("Using API requirements file: {0}", foundRequirements.SourcePath); this.Requirements = foundRequirements.ApiRequirements; } DocumentOutlineFile[] outlines = TryLoadConfigurationFiles <DocumentOutlineFile>(this.SourceFolderPath); var foundOutlines = outlines.FirstOrDefault(); if (null != foundOutlines) { Console.WriteLine("Using document structure file: {0}", foundOutlines.SourcePath); this.DocumentStructure = foundOutlines; } SchemaConfigFile[] schemaConfigs = TryLoadConfigurationFiles <SchemaConfigFile>(this.SourceFolderPath); var schemaConfig = schemaConfigs.FirstOrDefault(); if (schemaConfig != null) { Console.WriteLine($"Using schema config file: {schemaConfig.SourcePath}"); SchemaConfig = schemaConfig.SchemaConfig; } else { SchemaConfig = new SchemaConfig(); } }
public static void RouteForTableMeta(RouteResultset rrs, SchemaConfig schema, ISqlStatement ast, PartitionKeyVisitor visitor, string stmt) { var sql = stmt; if (visitor.IsSchemaTrimmed()) { sql = GenSql(ast, stmt); } var tables = visitor.GetMetaReadTable(); if (tables == null) { throw new ArgumentException(string.Format("route err: tables[] is null for meta read table: {0}", stmt)); } string[] dataNodes; if (tables.Length <= 0) { dataNodes = schema.MetaDataNodes; } else { if (tables.Length == 1) { dataNodes = new string[1]; dataNodes[0] = GetMetaReadDataNode(schema, tables[0]); } else { ICollection <string> dataNodeSet = new HashSet <string>(); foreach (var table in tables) { var dataNode = GetMetaReadDataNode(schema, table); dataNodeSet.Add(dataNode); } dataNodes = dataNodeSet.ToArray(); //dataNodes = new string[dataNodeSet.Count]; //IEnumerator<string> iter = dataNodeSet.GetEnumerator(); //for (int i = 0; i < dataNodes.Length; ++i) //{ // dataNodes[i] = iter.Current; //} } } var nodes = new RouteResultsetNode[dataNodes.Length]; rrs.Nodes = nodes; for (var i1 = 0; i1 < dataNodes.Length; ++i1) { nodes[i1] = new RouteResultsetNode(dataNodes[i1], sql); } }
/// <exception cref="System.Exception" /> public override void Route(SchemaConfig schema, int loop, string sql) { for (var i = 0; i < loop; ++i) { var lexer = new MySqlLexer(sql); var insert = new MySqlDmlInsertParser(lexer, new MySqlExprParser(lexer)).Insert(); } }
/// <exception cref="System.Exception" /> public override void Route(SchemaConfig schema, int loop, string sql) { for (var i = 0; i < loop; ++i) { var sb = new StringBuilder(sqlSize); insert.Accept(new MySqlOutputAstVisitor(sb)); sb.ToString(); } }
//protected override void AddCodeTable(IPageStyle style, Dictionary<string, CodeTable> codeTables) //{ // base.AddCodeTable(style, codeTables); // const string CodeName = "CodeSex"; // if (!codeTables.ContainsKey(CodeName)) // { // CodeTable ct = PlugInFactoryManager.CreateInstance<CodeTable>( // CodeTablePlugInFactory.REG_NAME, CodeName); // codeTables.Add(CodeName, ct); // } //} public static ITableSchemeEx CreateSchema() { SchemaConfig config = new SchemaConfig(); config.ReadXml(XML); ITableScheme scheme = config.Schema.CreateObject(); return(scheme.Convert <ITableSchemeEx>()); }
/// <exception cref="System.Exception" /> public override void Route(SchemaConfig schema, int loop, string sql) { for (var i = 0; i < loop; ++i) { var lexer = new MySqlLexer(sql); var select = new MySqlDmlSelectParser(lexer, new MySqlExprParser(lexer)).Select(); var visitor = new PartitionKeyVisitor(schema.Tables); select.Accept(visitor); } }
/// <exception cref="System.Exception" /> public override void Route(SchemaConfig schema, int loop, string sql) { for (var i = 0; i < loop; ++i) { // SQLLexer lexer = new SQLLexer(sql); // DmlSelectStatement select = new DmlSelectParser(lexer, new // SQLExprParser(lexer)).select(); // PartitionKeyVisitor visitor = new // PartitionKeyVisitor(schema.getTablesSpace()); // select.accept(visitor); // visitor.getColumnValue(); ServerRouter.Route(schema, sql, null, null); } }
private static string GetMetaReadDataNode(SchemaConfig schema, string table) { var dataNode = schema.DataNode; var tables = schema.Tables; TableConfig tc; if (tables != null && table != null && //TODO GetMetaReadDataNode table != null (tc = tables.GetValue(table)) != null) { var dn = tc.DataNodes; if (dn != null && dn.Length > 0) { dataNode = dn[0]; } } return(dataNode); }
private void LoadSchemas(XmlElement root) { var list = root.GetElementsByTagName("schema"); XmlElement schemaElement = null; IDictionary <string, TableConfig> tables = null; for (int i = 0, n = list.Count; i < n; i++) { schemaElement = (XmlElement)list.Item(i); var name = schemaElement.GetAttribute("name"); var dataNode = schemaElement.GetAttribute("dataNode"); // 在非空的情况下检查dataNode是否存在 if (dataNode != null && dataNode.Length != 0) { CheckDataNodeExists(dataNode); } else { dataNode = string.Empty; } // 确保非空 var group = "default"; if (schemaElement.HasAttribute("group")) { group = schemaElement.GetAttribute("group").Trim(); } tables = LoadTables(schemaElement); if (schemas.ContainsKey(name)) { throw new ConfigException("schema " + name + " duplicated!"); } var keepSqlSchema = false; if (schemaElement.HasAttribute("keepSqlSchema")) { keepSqlSchema = bool.Parse(schemaElement.GetAttribute("keepSqlSchema").Trim()); } schemas[name] = new SchemaConfig(name, dataNode, group, keepSqlSchema, tables); } }
/// <exception cref="System.SqlSyntaxErrorException" /> public static void RouteFromHint(object frontConn, SchemaConfig schema, RouteResultset rrs, int prefixIndex, string sql) { var hint = CobarHint.ParserCobarHint(sql, prefixIndex); var outputSql = hint.OutputSql; var replica = hint.Replica; var table = hint.Table; var dataNodes = hint.DataNodes; var partitionOperand = hint.PartitionOperand; TableConfig tableConfig = null; if (table == null || schema.Tables == null || (tableConfig = schema.Tables.GetValue(table)) == null) { // table not indicated var nodes = new RouteResultsetNode[1]; rrs.Nodes = nodes; if (dataNodes != null && !dataNodes.IsEmpty()) { var replicaIndex = dataNodes[0].Value; if (replicaIndex >= 0 && RouteResultsetNode.DefaultReplicaIndex != replicaIndex) { // replica index indicated in dataNodes references nodes[0] = new RouteResultsetNode(schema.DataNode, replicaIndex, outputSql); LogExplicitReplicaSet(frontConn, sql, rrs); return; } } nodes[0] = new RouteResultsetNode(schema.DataNode, replica, outputSql); if (replica != RouteResultsetNode.DefaultReplicaIndex) { LogExplicitReplicaSet(frontConn, sql, rrs); } return; } if (dataNodes != null && !dataNodes.IsEmpty()) { var nodes = new RouteResultsetNode[dataNodes.Count]; rrs.Nodes = nodes; var i = 0; var replicaSet = false; foreach (var pair in dataNodes) { var dataNodeName = tableConfig.DataNodes[pair.Key]; var replicaIndex = dataNodes[i].Value; if (replicaIndex >= 0 && RouteResultsetNode.DefaultReplicaIndex != replicaIndex) { replicaSet = true; nodes[i] = new RouteResultsetNode(dataNodeName, replicaIndex, outputSql); } else { replicaSet = replicaSet || (replica != RouteResultsetNode.DefaultReplicaIndex); nodes[i] = new RouteResultsetNode(dataNodeName, replica, outputSql); } ++i; } if (replicaSet) { LogExplicitReplicaSet(frontConn, sql, rrs); } return; } if (partitionOperand == null) { var tableDataNodes = tableConfig.DataNodes; var nodes = new RouteResultsetNode[tableDataNodes.Length]; rrs.Nodes = nodes; for (var i = 0; i < nodes.Length; ++i) { nodes[i] = new RouteResultsetNode(tableDataNodes[i], replica, outputSql); } return; } var cols = partitionOperand.Key; var vals = partitionOperand.Value; if (cols == null || vals == null) { throw new SqlSyntaxErrorException("${partitionOperand} is invalid: " + sql); } RuleConfig rule = null; var tr = tableConfig.Rule; var rules = tr == null ? null : tr.Rules; if (rules != null) { foreach (var r in rules) { var ruleCols = r.Columns; var match = true; foreach (var ruleCol in ruleCols) { match &= cols.Contains(ruleCol); } if (match) { rule = r; break; } } } var tableDataNodes1 = tableConfig.DataNodes; if (rule == null) { var nodes = new RouteResultsetNode[tableDataNodes1.Length]; rrs.Nodes = nodes; var replicaSet = false; for (var i = 0; i < tableDataNodes1.Length; ++i) { replicaSet = replicaSet || (replica != RouteResultsetNode.DefaultReplicaIndex); nodes[i] = new RouteResultsetNode(tableDataNodes1[i], replica, outputSql); } if (replicaSet) { LogExplicitReplicaSet(frontConn, sql, rrs); } return; } var destDataNodes = CalcHintDataNodes(rule, cols, vals, tableDataNodes1); var nodes1 = new RouteResultsetNode[destDataNodes.Count]; rrs.Nodes = nodes1; var i1 = 0; var replicaSet1 = false; foreach (var dataNode in destDataNodes) { replicaSet1 = replicaSet1 || (replica != RouteResultsetNode.DefaultReplicaIndex); nodes1[i1++] = new RouteResultsetNode(dataNode, replica, outputSql); } if (replicaSet1) { LogExplicitReplicaSet(frontConn, sql, rrs); } }
//private static readonly Logger Logger = Logger.GetLogger(typeof(ServerRouter)); public static RouteResultset Route(SchemaConfig schema, string stmt, string charset, object info) { var rrs = new RouteResultset(stmt); // 检查是否含有cobar hint var prefixIndex = HintRouter.IndexOfPrefix(stmt); if (prefixIndex >= 0) { HintRouter.RouteFromHint(info, schema, rrs, prefixIndex, stmt); return(rrs); } // 检查schema是否含有拆分库 if (schema.IsNoSharding) { if (schema.IsKeepSqlSchema) { var ast = SqlParserDelegate.Parse(stmt, charset ?? MySqlParser.DefaultCharset); var visitor = new PartitionKeyVisitor(schema.Tables); visitor.SetTrimSchema(schema.Name); ast.Accept(visitor); if (visitor.IsSchemaTrimmed()) { stmt = GenSql(ast, stmt); } } var nodes = new RouteResultsetNode[1]; nodes[0] = new RouteResultsetNode(schema.DataNode, stmt); rrs.Nodes = nodes; return(rrs); } // 生成和展开AST var ast1 = SqlParserDelegate.Parse(stmt, charset ?? MySqlParser.DefaultCharset); var visitor1 = new PartitionKeyVisitor(schema.Tables); visitor1.SetTrimSchema(schema.IsKeepSqlSchema ? schema.Name : null); ast1.Accept(visitor1); // 如果sql包含用户自定义的schema,则路由到default节点 if (schema.IsKeepSqlSchema && visitor1.IsCustomedSchema()) { if (visitor1.IsSchemaTrimmed()) { stmt = GenSql(ast1, stmt); } var nodes = new RouteResultsetNode[1]; nodes[0] = new RouteResultsetNode(schema.DataNode, stmt); rrs.Nodes = nodes; return(rrs); } // 元数据语句路由 if (visitor1.IsTableMetaRead()) { MetaRouter.RouteForTableMeta(rrs, schema, ast1, visitor1, stmt); if (visitor1.IsNeedRewriteField()) { rrs.Flag = RouteResultset.RewriteField; } return(rrs); } // 匹配规则 TableConfig matchedTable = null; RuleConfig rule = null; IDictionary <string, IList <object> > columnValues = null; var astExt = visitor1.GetColumnValue(); var tables = schema.Tables; foreach (var e in astExt) { var col2Val = e.Value; var tc = tables.GetValue(e.Key); if (tc == null) { continue; } if (matchedTable == null) { matchedTable = tc; } if (col2Val == null || col2Val.IsEmpty()) { continue; } var tr = tc.Rule; if (tr != null) { foreach (var rc in tr.Rules) { var match = true; foreach (var ruleColumn in rc.Columns) { match &= col2Val.ContainsKey(ruleColumn); } if (match) { columnValues = col2Val; rule = rc; matchedTable = tc; goto ft_break; } } } } ft_break: ; // 规则匹配处理,表级别和列级别。 if (matchedTable == null) { var sql = visitor1.IsSchemaTrimmed() ? GenSql(ast1, stmt) : stmt; var rn = new RouteResultsetNode[1]; if (string.Empty.Equals(schema.DataNode) && IsSystemReadSql(ast1)) { rn[0] = new RouteResultsetNode(schema.RandomDataNode, sql); } else { rn[0] = new RouteResultsetNode(schema.DataNode, sql); } rrs.Nodes = rn; return(rrs); } if (rule == null) { if (matchedTable.IsRuleRequired) { throw new ArgumentException(string.Format("route rule for table {0} is required: {1}", matchedTable.Name, stmt)); } var dataNodes = matchedTable.DataNodes; var sql = visitor1.IsSchemaTrimmed() ? GenSql(ast1, stmt) : stmt; var rn = new RouteResultsetNode[dataNodes.Length]; for (var i = 0; i < dataNodes.Length; ++i) { rn[i] = new RouteResultsetNode(dataNodes[i], sql); } rrs.Nodes = rn; SetGroupFlagAndLimit(rrs, visitor1); return(rrs); } // 规则计算 ValidateAst(ast1, matchedTable, rule, visitor1); var dnMap = RuleCalculate(matchedTable, rule, columnValues); if (dnMap == null || dnMap.IsEmpty()) { throw new ArgumentException("No target dataNode for rule " + rule); } // 判断路由结果是单库还是多库 if (dnMap.Count == 1) { var dataNode = matchedTable.DataNodes[dnMap.Keys.FirstOrDefault()]; //string dataNode = matchedTable.GetDataNodes()[dnMap.Keys.GetEnumerator().Current]; var sql = visitor1.IsSchemaTrimmed() ? GenSql(ast1, stmt) : stmt; var rn = new RouteResultsetNode[1]; rn[0] = new RouteResultsetNode(dataNode, sql); rrs.Nodes = rn; } else { var rn = new RouteResultsetNode[dnMap.Count]; if (ast1 is DmlInsertReplaceStatement) { var ir = (DmlInsertReplaceStatement)ast1; DispatchInsertReplace(rn, ir, rule.Columns, dnMap, matchedTable, stmt, visitor1); } else { DispatchWhereBasedStmt(rn, ast1, rule.Columns, dnMap, matchedTable, stmt, visitor1); } rrs.Nodes = rn; SetGroupFlagAndLimit(rrs, visitor1); } return(rrs); }
private void LoadRequirements() { ApiRequirementsFile[] requirements = TryLoadConfigurationFiles <ApiRequirementsFile>(this.SourceFolderPath); var foundRequirements = requirements.FirstOrDefault(); if (null != foundRequirements) { Console.WriteLine("Using API requirements file: {0}", foundRequirements.SourcePath); this.Requirements = foundRequirements.ApiRequirements; } MetadataValidationConfigFile[] documentsValidationConfigs = TryLoadConfigurationFiles <MetadataValidationConfigFile>(this.SourceFolderPath); var foundDocsconfigs = documentsValidationConfigs.FirstOrDefault(); if (null != foundDocsconfigs) { Console.WriteLine("Using Documents validation config file: {0}", foundDocsconfigs.SourcePath); this.MetadataValidationConfigs = foundDocsconfigs.MetadataValidationConfigs; } DocumentOutlineFile[] outlines = TryLoadConfigurationFiles <DocumentOutlineFile>(this.SourceFolderPath); var foundOutlines = outlines.FirstOrDefault(); if (null != foundOutlines) { Console.WriteLine("Using document structure file: {0}", foundOutlines.SourcePath); this.DocumentStructure = foundOutlines; } LinkValidationConfigFile[] linkConfigs = TryLoadConfigurationFiles <LinkValidationConfigFile>(this.SourceFolderPath); var foundLinkConfig = linkConfigs.FirstOrDefault(); if (foundLinkConfig != null) { Console.WriteLine($"Using link validation config file: {foundLinkConfig.SourcePath}"); this.LinkValidationConfig = foundLinkConfig; } SchemaConfigFile[] schemaConfigs = TryLoadConfigurationFiles <SchemaConfigFile>(this.SourceFolderPath); var schemaConfig = schemaConfigs.FirstOrDefault(); if (schemaConfig != null) { Console.WriteLine($"Using schema config file: {schemaConfig.SourcePath}"); SchemaConfig = schemaConfig.SchemaConfig; } else { SchemaConfig = new SchemaConfig(); } string indent = "".PadLeft(4); string[] requiredYamlHeaders = SchemaConfig.RequiredYamlHeaders; if (requiredYamlHeaders.Any()) { Console.WriteLine($"{indent}Required YAML headers: {requiredYamlHeaders.ComponentsJoinedByString(", ")}"); } else { Console.WriteLine($"{indent}Required YAML headers have not been set."); } List <string> treatErrorsAsWarningsWorkloads = SchemaConfig.TreatErrorsAsWarningsWorkloads; if (treatErrorsAsWarningsWorkloads.Any()) { Console.WriteLine($"{indent}Treating errors as warnings for: {treatErrorsAsWarningsWorkloads.ComponentsJoinedByString(", ")}"); } foldersToSkip = SchemaConfig.FoldersToSkip; filesToSkip = SchemaConfig.FilesToSkip; }
/// <exception cref="System.Exception" /> public abstract void Route(SchemaConfig schema, int loop, string sql);
//protected override void AddCodeTable(IPageStyle style, Dictionary<string, CodeTable> codeTables) //{ // base.AddCodeTable(style, codeTables); // const string CodeName = "CodeSex"; // if (!codeTables.ContainsKey(CodeName)) // { // CodeTable ct = PlugInFactoryManager.CreateInstance<CodeTable>( // CodeTablePlugInFactory.REG_NAME, CodeName); // codeTables.Add(CodeName, ct); // } //} public static ITableSchemeEx CreateSchema() { SchemaConfig config = new SchemaConfig(); config.ReadXml(XML); ITableScheme scheme = config.Schema.CreateObject(); return scheme.Convert<ITableSchemeEx>(); }
/// <summary> /// Helper method that converts a string value into a ParameterDataType instance /// </summary> /// <param name="value"></param> /// <param name="addErrorAction"></param> /// <returns></returns> public static ParameterDataType ParseParameterDataType(this string value, bool isCollection = false, Action <ValidationError> addErrorAction = null, ParameterDataType defaultValue = null) { const string collectionPrefix = "collection("; const string collectionOfPrefix = "collection of"; const string collectionSuffix = " collection"; if (value == null) { return(null); } if (value.StartsWith(collectionPrefix, StringComparison.OrdinalIgnoreCase)) { isCollection = true; value = value.Substring(collectionPrefix.Length).TrimEnd(')'); } else if (value.StartsWith(collectionOfPrefix, StringComparison.OrdinalIgnoreCase)) { isCollection = true; value = value.Substring(collectionOfPrefix.Length).TrimEnd(')'); } else if (value.EndsWith(collectionSuffix, StringComparison.OrdinalIgnoreCase)) { isCollection = true; value = value.Replace(collectionSuffix, string.Empty); } // Value could have markdown formatting in it, so we do some basic work to try and remove that if it exists if (value.IndexOf('[') != -1) { value = value.TextBetweenCharacters('[', ']'); } SimpleDataType simpleType = ParseSimpleTypeString(value.ToLowerInvariant()); if (simpleType != SimpleDataType.None) { return(new ParameterDataType(simpleType, isCollection)); } // some inferences for common descriptions ParameterDataType inferredType = null; if (value.IContains("etag")) { inferredType = ParameterDataType.String; } else if (value.IContains("timestamp")) { inferredType = ParameterDataType.DateTimeOffset; } else if (value.IContains("string")) { inferredType = ParameterDataType.String; } bool isEnum = false; if (value.IContains(" enum")) { isEnum = true; value = value.IReplace(" enum", string.Empty).Trim(); } if (inferredType != null) { if (isCollection) { inferredType = ParameterDataType.CollectionOfType(inferredType); } return(inferredType); } // if there aren't any spaces or special characters, assume we parsed the name of a type correctly. if (value.IndexOfAny(new[] { ' ', '/' }) == -1) { SchemaConfig config = DocSet.SchemaConfig; if (!(config?.NotLowerCamel?.Contains(value)).GetValueOrDefault()) { value = char.ToLowerInvariant(value[0]) + value.Substring(1); } if (value.IndexOf('.') == -1 && !string.IsNullOrEmpty(config?.DefaultNamespace)) { value = config.DefaultNamespace + "." + value; } return(new ParameterDataType(value, isCollection, isEnum)); } if (defaultValue != null) { return(defaultValue); } if (null != addErrorAction) { addErrorAction(new ValidationWarning(ValidationErrorCode.TypeConversionFailure, "Couldn't convert '{0}' into understood data type. Assuming Object type.", value)); } return(new ParameterDataType(value, isCollection)); }