Beispiel #1
0
        /// <summary>
        /// Writes a ZIP file to a stream, including the selected files from the static directory.
        /// </summary>
        /// <param name="directory">The static directory instance.</param>
        /// <param name="zipStream">The output stream.</param>
        /// <param name="searchPattern">
        /// Optionally specifies a file name pattern using standard file system wildcards
        /// like <b>[*]</b> and <b>[?]</b>.  This defaults to including all files.
        /// </param>
        /// <param name="searchOptions">Optionally perform a recursive search.  This defaults to
        /// <see cref="SearchOption.TopDirectoryOnly"/>.
        /// </param>
        /// <param name="zipOptions">
        /// Additional options that control things like whether the files are zipped within
        /// the parent directory or whether the files are assumed to contain UTF-8 text and
        /// that Windows style CRLF line endings are to be converted to Linux compatible LF
        /// endings.  You can combine options by bitwise ORing them.  This defaults to
        /// <see cref="StaticZipOptions.None"/>.
        /// </param>
        /// <remarks>
        /// <note>
        /// The current implementation loads the files into memory so this isn't really suitable
        /// for zipping very large files.
        /// </note>
        /// </remarks>
        public static void Zip(
            this IStaticDirectory directory,
            Stream zipStream,
            string searchPattern        = null,
            SearchOption searchOptions  = SearchOption.TopDirectoryOnly,
            StaticZipOptions zipOptions = StaticZipOptions.None)
        {
            Covenant.Requires <ArgumentNullException>(zipStream != null, nameof(zipStream));

            using (var zip = ZipFile.Create(zipStream))
            {
                zip.BeginUpdate();

                foreach (var file in directory.GetFiles(searchPattern, searchOptions))
                {
                    var relativePath = file.Path.Substring(directory.Path.Length + 1);

                    if ((zipOptions | StaticZipOptions.LinuxLineEndings) != 0)
                    {
                        var text = file.ReadAllText(Encoding.UTF8);

                        text = NeonHelper.ToLinuxLineEndings(text);

                        zip.Add(new StaticBytesDataSource(Encoding.UTF8.GetBytes(text)), relativePath);
                    }
                    else
                    {
                        zip.Add(new StaticBytesDataSource(file.ReadAllBytes()), relativePath);
                    }
                }

                zip.CommitUpdate();
            }
        }
Beispiel #2
0
        /// <summary>
        /// Constructs an instance that loads scripts from embedded resources.
        /// </summary>
        /// <param name="masterConnection">
        /// The master database connection to be used for creating the target database.  This connection must have been made for a Postgres
        /// superuser or a user with the <b>CREATEDB</b> privilege and must not reference a specific database.
        /// </param>
        /// <param name="databaseName">The database name to be used.</param>
        /// <param name="schemaDirectory">The embedded resource directory returned by a call to <see cref="NeonAssemblyExtensions.GetResourceFileSystem(Assembly, string)"/>.</param>
        /// <param name="variables">Optionally specifies script variables.</param>
        /// <exception cref="FileNotFoundException">
        /// Thrown if there's no directory at <see cref="scriptFolder"/> or when there's no
        /// <b>schema-0.script</b> file in the directory.
        /// </exception>
        public SchemaManager(NpgsqlConnection masterConnection, string databaseName, IStaticDirectory schemaDirectory, Dictionary <string, string> variables = null)
        {
            Covenant.Requires <ArgumentNullException>(masterConnection != null, nameof(masterConnection));
            Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(databaseName), nameof(databaseName));
            Covenant.Requires <ArgumentNullException>(schemaDirectory != null, nameof(schemaDirectory));

            this.masterConnection = masterConnection;
            this.targetConnection = null;
            this.databaseName     = databaseName;
            this.scriptFolder     = schemaDirectory.Path;

            // Initialize the variables dictionary.

            if (variables != null)
            {
                foreach (var item in variables)
                {
                    this.variables[item.Key] = item.Value;
                }
            }

            this.variables["database"] = databaseName;

            // List the script files and load them into a dictionary keyed by the schema version
            // parsed from the file name.  We'll also check for duplicate schema files that differ
            // only by leading zeros in the name.

            var versionToScript = new Dictionary <int, string>();
            var scriptNameRegex = new Regex(@"schema-(?<version>\d+).script$");

            foreach (var scriptFile in schemaDirectory.GetFiles("*.script"))
            {
                var scriptName = scriptFile.Name;
                var match      = scriptNameRegex.Match(scriptName);

                if (!match.Success)
                {
                    throw new SchemaManagerException($"Unexpected script file [{scriptFile}].");
                }

                var scriptVersion = int.Parse(match.Groups["version"].Value);

                if (versionToScript.ContainsKey(scriptVersion))
                {
                    throw new SchemaManagerException($"There are multiple script files for schema [version={scriptVersion}].");
                }

                versionToScript.Add(scriptVersion, LoadScript(scriptFile));
            }

            if (!versionToScript.ContainsKey(0))
            {
                throw new FileNotFoundException($"[schema-0.script] database creation script not found in: {Path.GetDirectoryName(scriptFolder)}");
            }

            this.versionToScript = versionToScript;
        }
Beispiel #3
0
        /// <summary>
        /// Creates a ZIP file, including the selected files from the static directory.
        /// </summary>
        /// <param name="directory">The static directory instance.</param>
        /// <param name="zipPath">Path to the output ZIP file.</param>
        /// <param name="searchPattern">
        /// Optionally specifies a file name pattern using standard file system wildcards
        /// like <b>[*]</b> and <b>[?]</b>.  This defaults to including all files.
        /// </param>
        /// <param name="searchOptions">Optionally perform a recursive search.  This defaults to
        /// <see cref="SearchOption.TopDirectoryOnly"/>.
        /// </param>
        /// <param name="zipOptions">
        /// Additional options that control things like whether the files are zipped within
        /// the parent directory or whether the files are assumed to contain UTF-8 text and
        /// that Windows style CRLF line endings are to be converted to Linux compatible LF
        /// endings.  You can combine options by bitwise ORing them.  This defaults to
        /// <see cref="StaticZipOptions.None"/>.
        /// </param>
        public static void Zip(
            this IStaticDirectory directory,
            string zipPath,
            string searchPattern        = null,
            SearchOption searchOptions  = SearchOption.TopDirectoryOnly,
            StaticZipOptions zipOptions = StaticZipOptions.None)
        {
            Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(zipPath), nameof(zipPath));

            using (var stream = new FileStream(zipPath, FileMode.CreateNew, FileAccess.ReadWrite))
            {
                Zip(directory, stream, searchPattern, searchOptions, zipOptions);
            }
        }
Beispiel #4
0
 /// <summary>
 /// Initializes a new instance of the DefaultPathUtility class.
 /// </summary>
 /// <param name="staticPath">Static path.</param>
 /// <param name="staticDirectory">Static directory.</param>
 /// <param name="staticFile">Static file.</param>
 public DefaultPathUtility(IStaticPath staticPath, IStaticDirectory staticDirectory, IStaticFile staticFile)
 {
     this.staticPath = staticPath;
     this.staticDirectory = staticDirectory;
     this.staticFile = staticFile;
 }