Пример #1
0
        public override void ValidateSchema()
        {
            if (Info <T> .Configuration.IsReadOnly)
            {
                return;
            }

            //First step - check if the table is there.
            try
            {
                var tableName = SchemaElements[Categories.Table][Keys.Name];

                try
                {
                    var tableCount = QuerySingleValue <int>($"SELECT COUNT(*) FROM information_schema.tables WHERE table_name = '{tableName}'");
                    if (tableCount != 0)
                    {
                        return;
                    }
                }
                catch (Exception e)
                {
                    if (!_options.AttempSchemaSetup)
                    {
                        throw;
                    }

                    // if (e.Message.Contains("is not allowed") || e.Message.Contains("denied")) // Let's try Admin mode.
                    try
                    {
                        _useAdmin = true;
                        // Let's create a default database and user.
                        Execute("CREATE DATABASE IF NOT EXISTS Zen");
                        Execute("SET GLOBAL log_bin_trust_function_creators = 1");
                        Execute("CREATE USER IF NOT EXISTS 'zenMaster'@'localhost' IDENTIFIED BY 'ExtremelyWeakPassword'");
                        Execute("GRANT ALL PRIVILEGES ON Zen.* TO 'zenMaster'@'localhost' WITH GRANT OPTION");
                        Execute("FLUSH PRIVILEGES");
                        _useAdmin = false;
                    }
                    catch (Exception exception)
                    {
                        _useAdmin = false;
                        Console.WriteLine(exception);
                        throw;
                    }
                }

                Current.Log.Add("Initializing schema");

                var maskKeys = Masks.ToMemberDictionary();

                //Create sequence.
                var tableRender = new StringBuilder();

                tableRender.AppendLine("CREATE TABLE IF NOT EXISTS " + tableName + " (");

                var isFirst = true;

                foreach (var(name, memberDescriptor) in Settings.Members)
                {
                    var  pType = memberDescriptor.Type;
                    long size  = memberDescriptor.Size ?? Masks.DefaultTextSize;

                    var pSourceName = memberDescriptor.TargetName;

                    var pDestinyType       = "";
                    var pAutoSchema        = "";
                    var defaultDestinyType = $"VARCHAR ({Masks.DefaultTextSize})";
                    var pNullableSpec      = "";

                    if (pType.IsPrimitiveType())
                    {
                        if (pType.IsArray)
                        {
                            continue;
                        }
                        if (!(typeof(string) == pType) && typeof(IEnumerable).IsAssignableFrom(pType))
                        {
                            continue;
                        }
                        if (typeof(ICollection).IsAssignableFrom(pType))
                        {
                            continue;
                        }
                        if (typeof(IList).IsAssignableFrom(pType))
                        {
                            continue;
                        }
                        if (typeof(IDictionary).IsAssignableFrom(pType))
                        {
                            continue;
                        }

                        if (pType.BaseType != null && typeof(IList).IsAssignableFrom(pType.BaseType) && pType.BaseType.IsGenericType)
                        {
                            continue;
                        }

                        var isNullable = pType.IsNullable();

                        if (Settings.StorageKeyMemberName == memberDescriptor.SourceName)
                        {
                            isNullable = false;
                        }

                        var(key, value) = TypeDefinitionMap.FirstOrDefault(i => pType == i.Key);

                        if (key != null)
                        {
                            pDestinyType = value.Name;
                            if (value.DefaultValue != null)
                            {
                                pDestinyType += " DEFAULT " + value.DefaultValue;
                            }

                            if (name == Settings.KeyMemberName)
                            {
                                if (value.InlineAutoSchema != null)
                                {
                                    pAutoSchema = value.InlineAutoSchema;
                                }
                            }
                        }
                        else
                        {
                            pDestinyType = defaultDestinyType;
                        }

                        if (size > Masks.MaximumTextSize)
                        {
                            pDestinyType = Masks.TextOverflowType;
                        }
                        if (pType.IsEnum)
                        {
                            pDestinyType = Masks.EnumType;
                        }

                        //Rendering

                        if (!isNullable)
                        {
                            pNullableSpec = "NOT NULL";
                        }
                    }
                    else
                    {
                        pDestinyType  = Masks.TextOverflowType;
                        pNullableSpec = "";
                    }

                    if (!isFirst)
                    {
                        tableRender.Append(", " + Environment.NewLine);
                    }
                    else
                    {
                        isFirst = false;
                    }

                    tableRender.Append($"{Masks.LeftFieldDelimiter}{pSourceName}{Masks.RightFieldDelimiter} {pDestinyType} {pNullableSpec} {pAutoSchema}");
                }

                // Finally the PK.

                tableRender.AppendLine($"{Environment.NewLine}, PRIMARY KEY(`{Settings.Members[Settings.KeyMemberName].TargetName}`)");

                tableRender.AppendLine(");");

                var rendered = tableRender.ToString();

                rendered = maskKeys.ReplaceIn(rendered);

                Current.Log.Add("Creating table " + tableName);

                Current.Log.Add("---");
                Current.Log.Add(rendered);
                Execute(rendered);
                Current.Log.Add("---");

                foreach (var(name, creationStatement) in SchemaElements[Categories.Trigger])
                {
                    Current.Log.Add($"Creating {Categories.Trigger} {name}");
                    Execute(creationStatement);
                }

                //'Event' hook for post-schema initialization procedure:
                typeof(T).GetMethod("OnSchemaInitialization", BindingFlags.Public | BindingFlags.Static)?.Invoke(null, null);
            }
            catch (Exception e)
            {
                Current.Log.Warn("Schema render Error: " + e.Message);
                Current.Log.Add(e);
                throw;
            }
        }