model_schema 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/Rakefile +4 -4
- data/bin/dump_model_schema +1 -117
- data/lib/model_schema.rb +1 -0
- data/lib/model_schema/dumper.rb +120 -0
- data/lib/model_schema/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce3974d23c633c3c0b29f1d6021698608f864181
|
4
|
+
data.tar.gz: 8cdf340a4c88a594b67c50bd8a54086ae73ea97b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 820a8b272b36b86dade6aa32423b8b1842478e34ec63cfd43b4c97a507cd3ca8e0cbb3d3a276e04607c3792692c42894bf9084f11865207980173b186f1e1e96
|
7
|
+
data.tar.gz: e77ba585c336618e522a56159b7da45d03b69877b63a5b9ce61037e595f664040e7d7e0f03eeef72873a472029e4033b95dbce4972e89087581e186fff19b370
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# ModelSchema [](https://travis-ci.org/karthikv/model_schema)
|
2
2
|
ModelSchema lets you annotate a [Sequel](https://github.com/jeremyevans/sequel/)
|
3
|
-
Model with its expected schema
|
4
|
-
a Sequel Model file that looks like this:
|
3
|
+
Model with its expected schema and immediately identify inconsistencies.
|
4
|
+
Instead of seeing a Sequel Model file that looks like this:
|
5
5
|
|
6
6
|
```rb
|
7
7
|
class User < Sequel::Model(:users)
|
data/Rakefile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
3
|
|
4
4
|
Rake::TestTask.new(:test) do |t|
|
5
|
-
t.libs <<
|
6
|
-
t.libs <<
|
5
|
+
t.libs << 'test'
|
6
|
+
t.libs << 'lib'
|
7
7
|
t.test_files = FileList['test/**/*_test.rb']
|
8
8
|
end
|
9
9
|
|
data/bin/dump_model_schema
CHANGED
@@ -1,121 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'bundler/setup'
|
3
3
|
require 'model_schema'
|
4
|
-
require 'slop'
|
5
4
|
|
6
|
-
|
7
|
-
LEADING_WHITESPACE_REGEX = /^\s*/
|
8
|
-
|
9
|
-
# Parses options and then dumps the model schema.
|
10
|
-
def main(args)
|
11
|
-
opts = {}
|
12
|
-
opts[:tabbing] = 2
|
13
|
-
|
14
|
-
parser = OptionParser.new do |p|
|
15
|
-
p.banner = "Usage: dump_model_schema [options]"
|
16
|
-
|
17
|
-
p.on('-m', '--model MODEL', 'Model file to dump schema in') do |model|
|
18
|
-
opts[:model] = model
|
19
|
-
end
|
20
|
-
|
21
|
-
p.on('-c', '--connection CONNECTION',
|
22
|
-
'Connection string for database') do |connection|
|
23
|
-
opts[:connection] = connection
|
24
|
-
end
|
25
|
-
|
26
|
-
p.on('-t', '--tabbing TABBING', Integer,
|
27
|
-
'Number of spaces for tabbing, or 0 for hard tabs') do |tabbing|
|
28
|
-
opts[:tabbing] = tabbing
|
29
|
-
end
|
30
|
-
|
31
|
-
p.on('-v', '--version', 'Print version') do
|
32
|
-
puts ModelSchema::VERSION
|
33
|
-
exit
|
34
|
-
end
|
35
|
-
|
36
|
-
p.on('-h', '--help', 'Print help') do
|
37
|
-
puts parser
|
38
|
-
exit
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
parser.parse(args)
|
43
|
-
|
44
|
-
# model and connection are required
|
45
|
-
abort 'Must provide a model file with -m or --model.' if !opts[:model]
|
46
|
-
abort 'Must provide a connection string with -c or --connection.' if !opts[:connection]
|
47
|
-
|
48
|
-
dump_model_schema(opts)
|
49
|
-
end
|
50
|
-
|
51
|
-
# Dumps the model schema based on the given options (see option parsing above).
|
52
|
-
def dump_model_schema(opts)
|
53
|
-
model_info = parse_model_file(opts[:model])
|
54
|
-
abort "Couldn't find class that extends Sequel::Model" if !model_info
|
55
|
-
|
56
|
-
db = Sequel.connect(opts[:connection])
|
57
|
-
db.extension(:schema_dumper)
|
58
|
-
|
59
|
-
klass = Class.new(Sequel::Model(model_info[:table_name]))
|
60
|
-
klass.db = db
|
61
|
-
|
62
|
-
# dump table generator given by model_schema
|
63
|
-
generator = klass.send(:table_generator)
|
64
|
-
commands = [generator.dump_columns, generator.dump_constraints,
|
65
|
-
generator.dump_indexes].reject{|s| s == ''}.join("\n\n")
|
66
|
-
|
67
|
-
# account for indentation
|
68
|
-
tab = opts[:tabbing] == 0 ? "\t" : ' ' * opts[:tabbing]
|
69
|
-
schema_indentation = model_info[:indentation] + tab
|
70
|
-
command_indentation = schema_indentation + tab
|
71
|
-
|
72
|
-
commands = commands.lines.map {|l| l == "\n" ? l : command_indentation + l}.join
|
73
|
-
commands = commands.gsub('=>', ' => ')
|
74
|
-
|
75
|
-
dump_lines = ["#{schema_indentation}model_schema do\n",
|
76
|
-
"#{commands}\n",
|
77
|
-
"#{schema_indentation}end\n"]
|
78
|
-
|
79
|
-
lines = model_info[:lines_before] + dump_lines + model_info[:lines_after]
|
80
|
-
File.write(opts[:model], lines.join)
|
81
|
-
end
|
82
|
-
|
83
|
-
# Parses the model file at the given path, returning a hash of the form:
|
84
|
-
#
|
85
|
-
# :table_name => the model table name
|
86
|
-
# :lines_before => an array of lines before the expected model schema dump
|
87
|
-
# :lines_after => an array of lines after the expected model schema dump
|
88
|
-
# :indentation => the indentation (leading whitespace) of the model class
|
89
|
-
#
|
90
|
-
# Returns nil if the file couldn't be parsed.
|
91
|
-
def parse_model_file(path)
|
92
|
-
lines = File.read(path).lines
|
93
|
-
|
94
|
-
lines.each_with_index do |line, index|
|
95
|
-
match = SEQUEL_MODEL_REGEX.match(line)
|
96
|
-
|
97
|
-
if match
|
98
|
-
# extract table name as symbol
|
99
|
-
table_name = match[1]
|
100
|
-
if table_name[0] == ':'
|
101
|
-
table_name = table_name[1..-1].to_sym
|
102
|
-
else
|
103
|
-
abort "Can't find a symbol table name on line: #{line}"
|
104
|
-
end
|
105
|
-
|
106
|
-
# indentation for model_schema block
|
107
|
-
indentation = LEADING_WHITESPACE_REGEX.match(line)[0]
|
108
|
-
|
109
|
-
return {
|
110
|
-
:table_name => table_name.to_sym,
|
111
|
-
:lines_before => lines[0..index],
|
112
|
-
:lines_after => lines[(index + 1)..-1],
|
113
|
-
:indentation => indentation,
|
114
|
-
}
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
nil
|
119
|
-
end
|
120
|
-
|
121
|
-
main(ARGV) if $PROGRAM_NAME == __FILE__
|
5
|
+
ModelSchema::Dumper.run(ARGV)
|
data/lib/model_schema.rb
CHANGED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
SEQUEL_MODEL_REGEX = /class\s+.*?<\s+Sequel::Model\((.*?)\)/
|
4
|
+
LEADING_WHITESPACE_REGEX = /^\s*/
|
5
|
+
|
6
|
+
module ModelSchema
|
7
|
+
module Dumper
|
8
|
+
# Parses options and then dumps the model schema.
|
9
|
+
def self.run(args)
|
10
|
+
opts = {}
|
11
|
+
opts[:tabbing] = 2
|
12
|
+
|
13
|
+
parser = OptionParser.new do |p|
|
14
|
+
p.banner = "Usage: dump_model_schema [options]"
|
15
|
+
|
16
|
+
p.on('-m', '--model MODEL', 'Model file to dump schema in') do |model|
|
17
|
+
opts[:model] = model
|
18
|
+
end
|
19
|
+
|
20
|
+
p.on('-c', '--connection CONNECTION',
|
21
|
+
'Connection string for database') do |connection|
|
22
|
+
opts[:connection] = connection
|
23
|
+
end
|
24
|
+
|
25
|
+
p.on('-t', '--tabbing TABBING', Integer,
|
26
|
+
'Number of spaces for tabbing, or 0 for hard tabs') do |tabbing|
|
27
|
+
opts[:tabbing] = tabbing
|
28
|
+
end
|
29
|
+
|
30
|
+
p.on('-v', '--version', 'Print version') do
|
31
|
+
puts ModelSchema::VERSION
|
32
|
+
exit
|
33
|
+
end
|
34
|
+
|
35
|
+
p.on('-h', '--help', 'Print help') do
|
36
|
+
puts parser
|
37
|
+
exit
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
parser.parse(args)
|
42
|
+
|
43
|
+
# model and connection are required
|
44
|
+
abort 'Must provide a model file with -m or --model.' if !opts[:model]
|
45
|
+
abort 'Must provide a connection string with -c or --connection.' if !opts[:connection]
|
46
|
+
|
47
|
+
dump_model_schema(opts)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Dumps the model schema based on the given options (see option parsing above).
|
51
|
+
def self.dump_model_schema(opts)
|
52
|
+
model_info = parse_model_file(opts[:model])
|
53
|
+
abort "Couldn't find class that extends Sequel::Model" if !model_info
|
54
|
+
|
55
|
+
db = Sequel.connect(opts[:connection])
|
56
|
+
db.extension(:schema_dumper)
|
57
|
+
|
58
|
+
klass = Class.new(Sequel::Model(model_info[:table_name]))
|
59
|
+
klass.db = db
|
60
|
+
|
61
|
+
# dump table generator given by model_schema
|
62
|
+
generator = klass.send(:table_generator)
|
63
|
+
commands = [generator.dump_columns, generator.dump_constraints,
|
64
|
+
generator.dump_indexes].reject{|s| s == ''}.join("\n\n")
|
65
|
+
|
66
|
+
# account for indentation
|
67
|
+
tab = opts[:tabbing] == 0 ? "\t" : ' ' * opts[:tabbing]
|
68
|
+
schema_indentation = model_info[:indentation] + tab
|
69
|
+
command_indentation = schema_indentation + tab
|
70
|
+
|
71
|
+
commands = commands.lines.map {|l| l == "\n" ? l : command_indentation + l}.join
|
72
|
+
commands = commands.gsub('=>', ' => ')
|
73
|
+
|
74
|
+
dump_lines = ["#{schema_indentation}model_schema do\n",
|
75
|
+
"#{commands}\n",
|
76
|
+
"#{schema_indentation}end\n"]
|
77
|
+
|
78
|
+
lines = model_info[:lines_before] + dump_lines + model_info[:lines_after]
|
79
|
+
File.write(opts[:model], lines.join)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Parses the model file at the given path, returning a hash of the form:
|
83
|
+
#
|
84
|
+
# :table_name => the model table name
|
85
|
+
# :lines_before => an array of lines before the expected model schema dump
|
86
|
+
# :lines_after => an array of lines after the expected model schema dump
|
87
|
+
# :indentation => the indentation (leading whitespace) of the model class
|
88
|
+
#
|
89
|
+
# Returns nil if the file couldn't be parsed.
|
90
|
+
def self.parse_model_file(path)
|
91
|
+
lines = File.read(path).lines
|
92
|
+
|
93
|
+
lines.each_with_index do |line, index|
|
94
|
+
match = SEQUEL_MODEL_REGEX.match(line)
|
95
|
+
|
96
|
+
if match
|
97
|
+
# extract table name as symbol
|
98
|
+
table_name = match[1]
|
99
|
+
if table_name[0] == ':'
|
100
|
+
table_name = table_name[1..-1].to_sym
|
101
|
+
else
|
102
|
+
abort "Can't find a symbol table name on line: #{line}"
|
103
|
+
end
|
104
|
+
|
105
|
+
# indentation for model_schema block
|
106
|
+
indentation = LEADING_WHITESPACE_REGEX.match(line)[0]
|
107
|
+
|
108
|
+
return {
|
109
|
+
:table_name => table_name.to_sym,
|
110
|
+
:lines_before => lines[0..index],
|
111
|
+
:lines_after => lines[(index + 1)..-1],
|
112
|
+
:indentation => indentation,
|
113
|
+
}
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
nil
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
data/lib/model_schema/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: model_schema
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Karthik Viswanathan
|
@@ -155,6 +155,7 @@ files:
|
|
155
155
|
- bin/repl
|
156
156
|
- lib/model_schema.rb
|
157
157
|
- lib/model_schema/constants.rb
|
158
|
+
- lib/model_schema/dumper.rb
|
158
159
|
- lib/model_schema/plugin.rb
|
159
160
|
- lib/model_schema/schema_error.rb
|
160
161
|
- lib/model_schema/version.rb
|