vcs4sql 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/vcs4sql/changelog.rb +62 -0
- data/lib/vcs4sql/exception.rb +56 -0
- data/lib/vcs4sql/sqlite/applied.rb +71 -0
- data/lib/vcs4sql/sqlite/expected.rb +88 -0
- data/lib/vcs4sql/sqlite/migration.rb +84 -0
- data/lib/vcs4sql/version.rb +26 -0
- data/lib/vcs4sql.rb +26 -0
- data/license.txt +21 -0
- data/readme.md +82 -0
- metadata +275 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 514b0d6b20284c233f1bdcbd43815030d98f967865cda2fc712b49902733ed25
|
4
|
+
data.tar.gz: 6a498449fcba20064c3a9e9e4225c21a04a7ad79bbc615872cab486ba4bf569a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f5e0e2ed9e342944673fbe52c392f3347caf558e4d121566ad641ad9d3535a5b52cf0d878fff7859e1e089fbb745d2f669c81cd90e29e3d809b11f9c6aa9f691
|
7
|
+
data.tar.gz: a3120154eb638f500e51ceec609bffa436107de283f1550ecc3cb37c21a6b14ac48c1b50db630a5fa33a9613c88ee66b2ccb8491fe8bcab1fd2b16fae7b62e3e
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# MIT License
|
2
|
+
#
|
3
|
+
# Copyright (c) 2020 Yurii Dubinka
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
#
|
23
|
+
|
24
|
+
require "sqlite3"
|
25
|
+
|
26
|
+
module Vcs4sql
|
27
|
+
class Changelog
|
28
|
+
attr_reader :id, :file, :version, :md5sum, :sql
|
29
|
+
|
30
|
+
def initialize(file, applied, version, md5sum, sql, id: 0)
|
31
|
+
@file = file
|
32
|
+
@applied = applied
|
33
|
+
@version = version
|
34
|
+
@md5sum = md5sum
|
35
|
+
@sql = sql
|
36
|
+
@id = id
|
37
|
+
end
|
38
|
+
|
39
|
+
# @todo #/DEV Raise the exception in case if
|
40
|
+
# - this.* are empty or null
|
41
|
+
# - conn is empty or null
|
42
|
+
def apply(conn)
|
43
|
+
# @todo #/DEV Wrap the sql's execution to separate blocks which will:
|
44
|
+
# - catch the error
|
45
|
+
# - provide the detailed description
|
46
|
+
# - populate the error code
|
47
|
+
conn.execute_batch @sql
|
48
|
+
conn.execute "insert /* ll.sqlid:#{__FILE__}:#{__method__} */
|
49
|
+
into changelog(file,version,md5sum,applied,sql)
|
50
|
+
values(?,?,?,?,?)",
|
51
|
+
@file, @version, @md5sum, @applied, @sql
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_s
|
55
|
+
"#{@version}: #{@file} #{@md5sum}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def matches(exist)
|
59
|
+
@md5sum == exist.md5sum
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# MIT License
|
2
|
+
#
|
3
|
+
# Copyright (c) 2020 Yurii Dubinka
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
|
23
|
+
module Vcs4sql
|
24
|
+
class Vcs4sqlError < StandardError
|
25
|
+
attr_reader :code
|
26
|
+
|
27
|
+
def initialize(code, msg)
|
28
|
+
super("#{code}: #{msg}")
|
29
|
+
@code = code
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class ChecksumMismatchError < Vcs4sqlError
|
34
|
+
def initialize(expected, applied)
|
35
|
+
msg = <<~MSG
|
36
|
+
Version '#{expected.version}' has checksum mismatch.
|
37
|
+
|
38
|
+
The possible root cause is that the file with migration, which was applied already, got changed recently.
|
39
|
+
As a workaround, you may change the md5sum in the database in case if these changes are minor
|
40
|
+
and don't affect the structure:
|
41
|
+
update changelog set md5sum='#{expected.md5sum}' where id=#{applied.id}
|
42
|
+
|
43
|
+
In case if changes are major and affect the database structure then they should be reverted
|
44
|
+
and introduce it as a new change.
|
45
|
+
|
46
|
+
Expected '#{expected.version}' version from '#{expected.file}' (#{expected.md5sum}) has SQL:
|
47
|
+
#{expected.sql}
|
48
|
+
.............................................................................................
|
49
|
+
Existing '#{applied.version}' version from '#{applied.file}' (#{applied.md5sum}) has SQL:
|
50
|
+
#{applied.sql}
|
51
|
+
.............................................................................................
|
52
|
+
MSG
|
53
|
+
super("vcs4sql-001", msg)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# MIT License
|
4
|
+
#
|
5
|
+
# Copyright (c) 2020 Yurii Dubinka
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
15
|
+
# copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
# SOFTWARE.
|
24
|
+
#
|
25
|
+
module Vcs4sql
|
26
|
+
module Sqlite
|
27
|
+
# The applied (existing) database change log.
|
28
|
+
class Applied
|
29
|
+
# @param [Object] conn the connection to the database.
|
30
|
+
# @param [String (frozen)] sql the query to fetch the change log from db.
|
31
|
+
def initialize(conn, sql: "select * from changelog order by version")
|
32
|
+
@conn = conn
|
33
|
+
@sql = sql
|
34
|
+
end
|
35
|
+
|
36
|
+
def empty?
|
37
|
+
changelog.empty?
|
38
|
+
end
|
39
|
+
|
40
|
+
# Ensure that applied change set has a change with particular version
|
41
|
+
def absent(version)
|
42
|
+
change(version).nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the details about applied change by version
|
46
|
+
# @param [Object] version the version of applied change
|
47
|
+
# @todo #/DEV Add verification of array usage over index.
|
48
|
+
# The changelog shouldn't be a null.
|
49
|
+
def change(version)
|
50
|
+
changelog[version]
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# Evaluate the applied database change log.
|
56
|
+
# @todo #/DEV Add verification that connection not a null, throw error
|
57
|
+
# with proper error code in order to explain the problem.
|
58
|
+
# Potentially we need to define the class with error codes.
|
59
|
+
def changelog
|
60
|
+
return @changelog if defined? @changelog
|
61
|
+
|
62
|
+
@changelog = @conn.query(@sql).map do |row|
|
63
|
+
Changelog.new(
|
64
|
+
row["file"], row["applied"], row["version"], row["md5sum"],
|
65
|
+
row["sql"], id: row["id"]
|
66
|
+
)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# MIT License
|
4
|
+
#
|
5
|
+
# Copyright (c) 2020 Yurii Dubinka
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
15
|
+
# copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
# SOFTWARE.
|
24
|
+
|
25
|
+
require_relative "../exception"
|
26
|
+
|
27
|
+
module Vcs4sql
|
28
|
+
module Sqlite
|
29
|
+
# The expected database change log.
|
30
|
+
# Contains all changes which should be applied to target database.
|
31
|
+
class Expected
|
32
|
+
def initialize(home, testdata)
|
33
|
+
@home = home
|
34
|
+
@nonprod = ->(f) { !testdata && (f.to_s.end_with? ".testdata.sql") }
|
35
|
+
end
|
36
|
+
|
37
|
+
# Apply all sql files one by one
|
38
|
+
# @param [Object] conn the connection to the database.
|
39
|
+
def apply_all(conn)
|
40
|
+
apply(-1, conn)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Apply sql files which weren't applied yet
|
44
|
+
# @param [Object] conn the connection to the database.
|
45
|
+
def apply_mismatch(existing, conn)
|
46
|
+
version = -1
|
47
|
+
changelog.each_with_index do |change, i|
|
48
|
+
break if existing.absent(i)
|
49
|
+
|
50
|
+
unless change.matches existing.change(i)
|
51
|
+
raise ChecksumMismatchError.new change, existing.change(i)
|
52
|
+
end
|
53
|
+
|
54
|
+
version = i
|
55
|
+
end
|
56
|
+
apply(version, conn)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# Apply sql files which weren't applied yet based on version
|
62
|
+
# @param [Integer] ver The latest applied version to the database
|
63
|
+
# @param [Object] conn the connection to the database.
|
64
|
+
def apply(ver, conn)
|
65
|
+
# @todo #/DEV Raise an exception in case if any of arguments are null or
|
66
|
+
# empty. Potentially we may add verification of the type, but this is
|
67
|
+
# optional.
|
68
|
+
changelog.select { |change| change.version > ver }.each do |change|
|
69
|
+
change.apply(conn)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def changelog
|
74
|
+
return @changelog if defined? @changelog
|
75
|
+
|
76
|
+
@changelog = Dir.glob("#{@home}/*.sql")
|
77
|
+
.select { |f| File.file? f }
|
78
|
+
.reject(&@nonprod)
|
79
|
+
.sort
|
80
|
+
.each_with_index.map do |f, i|
|
81
|
+
sql = File.read(f).to_s.tr "\r", " "
|
82
|
+
md5 = Digest::MD5.hexdigest sql
|
83
|
+
Changelog.new(f, Time.now.iso8601(6), i, md5, sql)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# MIT License
|
4
|
+
#
|
5
|
+
# Copyright (c) 2020 Yurii Dubinka
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
15
|
+
# copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
# SOFTWARE.
|
24
|
+
#
|
25
|
+
|
26
|
+
require "securerandom"
|
27
|
+
require "digest"
|
28
|
+
require "fileutils"
|
29
|
+
require_relative "../changelog"
|
30
|
+
require_relative "expected"
|
31
|
+
require_relative "applied"
|
32
|
+
|
33
|
+
# The database schema migration
|
34
|
+
#
|
35
|
+
# Author:: Yurii Dubinka (yurii.dubinka@gmail.com)
|
36
|
+
# Copyright:: Copyright (c) 2019-2020 Yurii Dubinka
|
37
|
+
# License:: MIT
|
38
|
+
module Vcs4sql
|
39
|
+
module Sqlite
|
40
|
+
class Migration
|
41
|
+
def initialize(file)
|
42
|
+
FileUtils.mkdir_p File.dirname(file)
|
43
|
+
@conn = SQLite3::Database.new file
|
44
|
+
@conn.results_as_hash = true
|
45
|
+
end
|
46
|
+
|
47
|
+
# @param home
|
48
|
+
# @param testdata
|
49
|
+
def upgrade(home, testdata=false)
|
50
|
+
install_vcs4sql
|
51
|
+
existing = Applied.new @conn
|
52
|
+
expected = Expected.new home, testdata
|
53
|
+
if existing.empty?
|
54
|
+
expected.apply_all @conn
|
55
|
+
else
|
56
|
+
expected.apply_mismatch existing, @conn
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def install_vcs4sql
|
63
|
+
# @todo #/DEV Lock the upgrade procedure in order to avoid the cases
|
64
|
+
# when multiple processes are going to modify/upgrade the same database
|
65
|
+
# schema. No concurrent upgrades is allowed so far.
|
66
|
+
@conn.execute_batch2 <<~SQL
|
67
|
+
create table if not exists changelog (
|
68
|
+
id integer primary key autoincrement,
|
69
|
+
file text not null,
|
70
|
+
applied timestamp default current_timestamp,
|
71
|
+
version integer unique not null,
|
72
|
+
md5sum text not null,
|
73
|
+
sql text not null
|
74
|
+
);
|
75
|
+
create table if not exists changeloglock (
|
76
|
+
id text primary key,
|
77
|
+
locked integer,
|
78
|
+
lockedby text
|
79
|
+
);
|
80
|
+
SQL
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# MIT License
|
2
|
+
#
|
3
|
+
# Copyright (c) 2020 Yurii Dubinka
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
#
|
23
|
+
|
24
|
+
module Vcs4sql
|
25
|
+
VERSION = "0.1.0".freeze
|
26
|
+
end
|
data/lib/vcs4sql.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# MIT License
|
2
|
+
#
|
3
|
+
# Copyright (c) 2020 Yurii Dubinka
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
#
|
23
|
+
|
24
|
+
module Vcs4sql
|
25
|
+
autoload :VERSION, "vcs4sql/version"
|
26
|
+
end
|
data/license.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020 Yurii Dubinka
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/readme.md
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/vcs4sql.svg)](https://rubygems.org/gems/vcs4sql)
|
2
|
+
[![License: MIT](https://img.shields.io/github/license/mashape/apistatus.svg)](./license.txt)
|
3
|
+
[![Commit activity](https://img.shields.io/github/commit-activity/y/dgroup/mbox4j.svg?style=flat-square)](https://github.com/dgroup/mbox4j/graphs/commit-activity)
|
4
|
+
[![Hits-of-Code](https://hitsofcode.com/github/dgroup/mbox4j)](https://hitsofcode.com/view/github/dgroup/mbox4j)
|
5
|
+
|
6
|
+
[![Build status circleci](https://circleci.com/gh/dgroup/vcs4sql.svg?style=shield)](https://circleci.com/gh/dgroup/vcs4sql)
|
7
|
+
[![Build Status travis](https://img.shields.io/travis/dgroup/vcs4sql.svg?label=travis)](https://travis-ci.org/dgroup/vcs4sql)
|
8
|
+
[![0pdd](http://www.0pdd.com/svg?name=dgroup/vcs4sql)](http://www.0pdd.com/p?name=dgroup/vcs4sql)
|
9
|
+
[![Dependency Status](https://requires.io/github/dgroup/vcs4sql/requirements.svg?branch=master)](https://requires.io/github/dgroup/vcs4sql/requirements/?branch=master)
|
10
|
+
[![Known Vulnerabilities](https://snyk.io/test/github/dgroup/vcs4sql/badge.svg)](https://snyk.io/org/dgroup/project/<TBD>/?tab=dependencies&vulns=vulnerable)
|
11
|
+
[![DevOps By Rultor.com](http://www.rultor.com/b/dgroup/vcs4sql)](http://www.rultor.com/p/dgroup/vcs4sql)
|
12
|
+
|
13
|
+
[![EO badge](http://www.elegantobjects.org/badge.svg)](http://www.elegantobjects.org/#principles)
|
14
|
+
[![SQ maintainability](https://sonarcloud.io/api/project_badges/measure?project=io.github.dgroup%3Avcs4sql&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=io.github.dgroup%3Avcs4sql)
|
15
|
+
[![Codebeat](https://codebeat.co/badges/<TBD>)](https://codebeat.co/projects/github-com-dgroup-vcs4sql-master)
|
16
|
+
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/<TBD>)](https://www.codacy.com/app/dgroup/vcs4sql?utm_source=github.com&utm_medium=referral&utm_content=dgroup/vcs4sql&utm_campaign=Badge_Grade)
|
17
|
+
[![Codecov](https://codecov.io/gh/dgroup/vcs4sql/branch/master/graph/badge.svg)](https://codecov.io/gh/dgroup/vcs4sql)
|
18
|
+
[![Code Climate](https://codeclimate.com/github/dgroup/vcs4sql/badges/gpa.svg)](https://codeclimate.com/github/dgroup/vcs4sql)
|
19
|
+
|
20
|
+
In the last few years, version control for database became best practice.
|
21
|
+
There are several implementations/ways for ruby, however, most of them are focused/dependent on particular
|
22
|
+
frameworks that restrict the migration outside the framework.
|
23
|
+
vcs4sql allows organizing version control for the database(s) in a simple, elegant and lightweight way without any dependencies on existing frameworks.
|
24
|
+
|
25
|
+
The main idea is to keep changes as simple as possible and be able to have full control of the database structure without hidden frameworks "magic".
|
26
|
+
Initial PoC is designed for [sqlite](https://www.sqlite.org).
|
27
|
+
---
|
28
|
+
|
29
|
+
- [Quick start](#quick-start)
|
30
|
+
- [Support](#support)
|
31
|
+
- [License](#license)
|
32
|
+
- [Code of conduct](#code-of-conduct)
|
33
|
+
- [Contribution guide](#contribution-guide)
|
34
|
+
|
35
|
+
### Quick start
|
36
|
+
|
37
|
+
```
|
38
|
+
$ gem install vcs4sql
|
39
|
+
```
|
40
|
+
```bash
|
41
|
+
# Define the database migration scripts
|
42
|
+
$ tree
|
43
|
+
.
|
44
|
+
├── bin
|
45
|
+
├── Gemfile
|
46
|
+
├── Guardfile
|
47
|
+
├── Rakefile
|
48
|
+
├── ...
|
49
|
+
│ ├── ...
|
50
|
+
├── sqlite.db
|
51
|
+
├── ...
|
52
|
+
└── upgrades
|
53
|
+
└── sqlite
|
54
|
+
├── 001-install-main-tables.sql
|
55
|
+
├── 002-add-missing-indexes.sql
|
56
|
+
├── 003-add-missing-foreigh-keys.sql
|
57
|
+
├── ...
|
58
|
+
└── 999.testdata.sql
|
59
|
+
```
|
60
|
+
```ruby
|
61
|
+
require "vcs4sql"
|
62
|
+
|
63
|
+
Vcs4sql::Sqlite::Migration.new "sqlite.db"
|
64
|
+
.upgrade "upgrades/sqlite"
|
65
|
+
```
|
66
|
+
The scripts will be executed in a natural order based on name, so far.
|
67
|
+
|
68
|
+
### Support
|
69
|
+
|
70
|
+
If you want to report a bug, or have ideas, feedback or questions about the gem, [let me know via GitHub issues](https://github.com/dgroup/vcs4sql/issues/new) and I will do my best to provide a helpful answer. Happy hacking!
|
71
|
+
|
72
|
+
### License
|
73
|
+
|
74
|
+
The gem is available as open source under the terms of the [MIT License](license.txt).
|
75
|
+
|
76
|
+
### Code of conduct
|
77
|
+
|
78
|
+
Everyone interacting in this project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](.github/CODE_OF_CONDUCT.md).
|
79
|
+
|
80
|
+
### Contribution guide
|
81
|
+
|
82
|
+
Pull requests are welcome!
|
metadata
ADDED
@@ -0,0 +1,275 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vcs4sql
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Yurii Dubinka
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-03-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '6.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '6.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: fileutils
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.4.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.4.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sqlite3
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.4.2
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.4.2
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: debase
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.2.4.1
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.2.4.1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: minitest
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '5.11'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '5.11'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: minitest-ci
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.4'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.4'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: minitest-reporters
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.3'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.3'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rake
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '13.0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '13.0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rubocop
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - '='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 0.78.0
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - '='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 0.78.0
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rubocop-minitest
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - '='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 0.5.1
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - '='
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 0.5.1
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: rubocop-performance
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - '='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 1.5.2
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - '='
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: 1.5.2
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: ruby-debug-ide
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: 0.7.0
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: 0.7.0
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: simplecov
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - "~>"
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: 0.17.1
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - "~>"
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: 0.17.1
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: xcop
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - "~>"
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '0.6'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - "~>"
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '0.6'
|
223
|
+
description: |-
|
224
|
+
In the last few years, version control for database became best practice.
|
225
|
+
There are several implementations/ways for ruby, however, most of them are focused/dependent on particular
|
226
|
+
frameworks that restrict the migration outside the framework.
|
227
|
+
vcs4sql allows organizing version control for the database(s) in a simple,
|
228
|
+
elegant way without any dependencies on existing frameworks.
|
229
|
+
email:
|
230
|
+
- yurii.dubinka@gmail.com
|
231
|
+
executables: []
|
232
|
+
extensions: []
|
233
|
+
extra_rdoc_files: []
|
234
|
+
files:
|
235
|
+
- lib/vcs4sql.rb
|
236
|
+
- lib/vcs4sql/changelog.rb
|
237
|
+
- lib/vcs4sql/exception.rb
|
238
|
+
- lib/vcs4sql/sqlite/applied.rb
|
239
|
+
- lib/vcs4sql/sqlite/expected.rb
|
240
|
+
- lib/vcs4sql/sqlite/migration.rb
|
241
|
+
- lib/vcs4sql/version.rb
|
242
|
+
- license.txt
|
243
|
+
- readme.md
|
244
|
+
homepage: https://github.com/dgroup/vcs4sql
|
245
|
+
licenses:
|
246
|
+
- MIT
|
247
|
+
metadata:
|
248
|
+
bug_tracker_uri: https://github.com/dgroup/vcs4sql/issues
|
249
|
+
changelog_uri: https://github.com/dgroup/vcs4sql/releases
|
250
|
+
source_code_uri: https://github.com/dgroup/vcs4sql
|
251
|
+
homepage_uri: https://github.com/dgroup/vcs4sql
|
252
|
+
post_install_message: |-
|
253
|
+
Thanks for installing vcs4sql '0.1.0'!
|
254
|
+
Stay in touch with the community in Telegram: https://t.me/lazyleads
|
255
|
+
Follow us on Twitter: https://twitter.com/lazylead
|
256
|
+
If you have any issues, report to our GitHub repo: https://github.com/dgroup/vcs4sql
|
257
|
+
rdoc_options: []
|
258
|
+
require_paths:
|
259
|
+
- lib
|
260
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
261
|
+
requirements:
|
262
|
+
- - ">="
|
263
|
+
- !ruby/object:Gem::Version
|
264
|
+
version: 2.6.5
|
265
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
266
|
+
requirements:
|
267
|
+
- - ">="
|
268
|
+
- !ruby/object:Gem::Version
|
269
|
+
version: '0'
|
270
|
+
requirements: []
|
271
|
+
rubygems_version: 3.0.3
|
272
|
+
signing_key:
|
273
|
+
specification_version: 4
|
274
|
+
summary: Organizing version control for the database(s) in a simple, elegant way.
|
275
|
+
test_files: []
|