alf-shell 0.13.1 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +6 -0
- data/Gemfile +1 -3
- data/Gemfile.lock +3 -3
- data/doc/commands/show.md +1 -8
- data/doc/operators/relational/frame.md +26 -0
- data/doc/operators/relational/hierarchize.md +14 -0
- data/doc/operators/relational/page.md +31 -0
- data/lib/alf/shell.rb +4 -0
- data/lib/alf/shell/alfrc.rb +40 -0
- data/lib/alf/shell/command/exec.rb +1 -1
- data/lib/alf/shell/command/main.rb +58 -38
- data/lib/alf/shell/command/show.rb +0 -26
- data/lib/alf/shell/doc_manager.rb +5 -4
- data/lib/alf/shell/from_argv.rb +6 -0
- data/lib/alf/shell/support.rb +5 -4
- data/lib/alf/shell/version.rb +2 -2
- data/spec/fixtures/example.alfrc +13 -0
- data/spec/integration/alf/alf_db.cmd +1 -1
- data/spec/integration/alf/alf_help.stdout +6 -2
- data/spec/integration/frame/frame_0.cmd +1 -0
- data/spec/integration/frame/frame_0.stdout +6 -0
- data/spec/integration/help/help_1.stdout +1 -14
- data/spec/integration/page/page_0.cmd +1 -0
- data/spec/integration/page/page_0.stdout +6 -0
- data/spec/integration/show/show_base_sort_1.cmd +1 -1
- data/spec/integration/show/show_base_sort_2.cmd +1 -1
- data/spec/integration/show/show_ff.cmd +1 -1
- data/spec/integration/show/show_rash.cmd +1 -1
- data/spec/integration/show/show_rash_pretty.cmd +1 -1
- data/spec/integration/show/show_yaml.cmd +1 -1
- data/spec/integration/test_shell.rb +6 -3
- data/spec/unit/alfrc/test_alfrc.rb +59 -0
- data/spec/unit/doc_manager/test_call.rb +9 -11
- data/spec/unit/main/test_I_option.rb +36 -0
- data/spec/unit/main/test_r_option.rb +36 -0
- data/spec/unit/main/test_renderer_option.rb +28 -0
- metadata +18 -7
- data/spec/integration/show/show_conflictual.cmd +0 -1
- data/spec/integration/show/show_conflictual.stdout +0 -5
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
alf-core (0.
|
4
|
+
alf-core (0.14.0)
|
5
5
|
domain (~> 1.0)
|
6
6
|
myrrha (~> 3.0)
|
7
7
|
path (~> 1.3)
|
@@ -11,7 +11,7 @@ GEM
|
|
11
11
|
highline (1.6.19)
|
12
12
|
myrrha (3.0.0)
|
13
13
|
domain (~> 1.0)
|
14
|
-
path (1.3.
|
14
|
+
path (1.3.3)
|
15
15
|
quickl (0.4.3)
|
16
16
|
rake (10.1.0)
|
17
17
|
rspec (2.14.1)
|
@@ -28,7 +28,7 @@ PLATFORMS
|
|
28
28
|
ruby
|
29
29
|
|
30
30
|
DEPENDENCIES
|
31
|
-
alf-core (~> 0.
|
31
|
+
alf-core (~> 0.14.0)
|
32
32
|
highline (~> 1.6)
|
33
33
|
quickl (~> 0.4.3)
|
34
34
|
rake (~> 10.1)
|
data/doc/commands/show.md
CHANGED
@@ -1,19 +1,12 @@
|
|
1
1
|
|
2
|
-
Output input tuples through
|
2
|
+
Output input tuples through the default renderer in a specific order.
|
3
3
|
|
4
4
|
SYNOPSIS
|
5
5
|
|
6
6
|
alf #(command_name) NAME -- [ORDERING]
|
7
7
|
|
8
|
-
OPTIONS
|
9
|
-
|
10
|
-
#(summarized_options)
|
11
|
-
|
12
8
|
DESCRIPTION
|
13
9
|
|
14
10
|
When a name is specified as commandline arg, request the database to
|
15
11
|
provide the corresponding relation variable and prints its value.
|
16
12
|
Otherwise, take what comes on standard input.
|
17
|
-
|
18
|
-
Note that this command is not an operator and should not be piped
|
19
|
-
anymore.
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
Relational framing (aka offset/limit, yet sounder)
|
3
|
+
|
4
|
+
SYNOPSIS
|
5
|
+
|
6
|
+
#(signature)
|
7
|
+
|
8
|
+
DESCRIPTION
|
9
|
+
|
10
|
+
This command provides the classical offset/limit over the input relation.
|
11
|
+
|
12
|
+
This operator skips tuples whose ranking according to `ordering` is between
|
13
|
+
`0` and `offset` exclusive (in other words, it skips `offset` tuples). In
|
14
|
+
addition, it returns maximum `limit` tuples.
|
15
|
+
|
16
|
+
To be sound, this operator requires the ordering to include a candidate key
|
17
|
+
for the input relation. Alf will automatically extend the ordering you provide
|
18
|
+
to guarantee this, provided key inference is possible.
|
19
|
+
|
20
|
+
EXAMPLE
|
21
|
+
|
22
|
+
# Take the first two suppliers ordered by name (then by id)
|
23
|
+
!(alf frame suppliers -- name -- 0 -- 2)
|
24
|
+
|
25
|
+
# Take the next two suppliers
|
26
|
+
!(alf frame suppliers -- name -- 2 -- 2)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
Relational pagination (like frame, but easier)
|
3
|
+
|
4
|
+
SYNOPSIS
|
5
|
+
|
6
|
+
#(signature)
|
7
|
+
|
8
|
+
DESCRIPTION
|
9
|
+
|
10
|
+
This command provides pagination over the input relation.
|
11
|
+
|
12
|
+
When page_index is positive (resp. striclty negative), this operator returns
|
13
|
+
`page_size` tuples whose ranking according to `ordering` (resp. reverse
|
14
|
+
ordering) is between `page_size * (page_index - 1)` and `page_size * page_index`
|
15
|
+
(excluded).
|
16
|
+
|
17
|
+
To be sound, this operator requires the ordering to include a candidate key
|
18
|
+
for the input relation. Alf will automatically extend the ordering you provide
|
19
|
+
to guarantee this, provided key inference is possible.
|
20
|
+
|
21
|
+
EXAMPLE
|
22
|
+
|
23
|
+
# Take the first two suppliers ordered by name (then by id)
|
24
|
+
!(alf page --page-size=2 suppliers -- name -- 1)
|
25
|
+
|
26
|
+
# Take the next two suppliers
|
27
|
+
!(alf page --page-size=2 suppliers -- name -- 2)
|
28
|
+
|
29
|
+
# Take the last two suppliers
|
30
|
+
!(alf page --page-size=2 suppliers -- name -- -1)
|
31
|
+
|
data/lib/alf/shell.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require_relative 'shell/version'
|
2
2
|
require_relative 'shell/loader'
|
3
3
|
require_relative 'shell/ext/signature'
|
4
|
+
require_relative 'shell/alfrc'
|
4
5
|
require_relative 'shell/doc_manager'
|
5
6
|
module Alf
|
6
7
|
module Shell
|
@@ -8,6 +9,9 @@ module Alf
|
|
8
9
|
# This is the main documentation extractor
|
9
10
|
DOC_EXTRACTOR = DocManager.new
|
10
11
|
|
12
|
+
# This is the default configuration to be forked from
|
13
|
+
DEFAULT_CONFIG = Alfrc.new
|
14
|
+
|
11
15
|
# Delegator command factory
|
12
16
|
def self.Delegator()
|
13
17
|
Quickl::Delegator(){|builder|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Alf
|
2
|
+
module Shell
|
3
|
+
class Alfrc < Support::Config
|
4
|
+
|
5
|
+
# Path to be put in $LOAD_PATH before executing alf
|
6
|
+
option :load_paths, Array, []
|
7
|
+
|
8
|
+
# Libraries to require before executing alf
|
9
|
+
option :requires, Array, []
|
10
|
+
|
11
|
+
# Default renderer to use for outputting relations
|
12
|
+
option :default_renderer, Class, ->{ $stdout.tty? ? Renderer::Text : Renderer::Rash }
|
13
|
+
|
14
|
+
# Float format to use
|
15
|
+
option :float_format, String, "%.3f"
|
16
|
+
|
17
|
+
# Pretty print in console mode?
|
18
|
+
option :pretty, Boolean, ->{ $stdout.tty? }
|
19
|
+
|
20
|
+
# The adapter to use by default
|
21
|
+
option :adapter, Object, ->{ Path.pwd }
|
22
|
+
|
23
|
+
# The database to use by default
|
24
|
+
option :database, Database, ->{ Database.new(adapter) }
|
25
|
+
|
26
|
+
# The viewpoint to use by default
|
27
|
+
option :viewpoint, Module, ->{ Viewpoint::NATIVE }
|
28
|
+
|
29
|
+
# If `path` is provided, evaluates the content of the file on this
|
30
|
+
# instance. Also, if a block is passed, yields it with self. Return
|
31
|
+
# self in any case.
|
32
|
+
def alfrc(path = nil)
|
33
|
+
::Kernel.eval(Path(path).read, binding, path.to_s) if path
|
34
|
+
yield(self) if block_given?
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
end # class Alfrc
|
39
|
+
end # module Shell
|
40
|
+
end # module Alf
|
@@ -42,45 +42,37 @@ module Alf
|
|
42
42
|
|
43
43
|
end # class << self
|
44
44
|
|
45
|
-
# Connection instance to use to get base relations
|
46
|
-
attr_accessor :database
|
47
|
-
|
48
45
|
# The reader to use when stdin is used as operand
|
49
46
|
attr_accessor :stdin_operand
|
50
47
|
|
51
|
-
# Output renderer
|
52
|
-
attr_accessor :renderer_class
|
53
|
-
|
54
|
-
# Rendering options
|
55
|
-
attr_reader :rendering_options
|
56
|
-
|
57
48
|
# Creates a command instance
|
58
|
-
def initialize(
|
59
|
-
@
|
60
|
-
@rendering_options = {}
|
49
|
+
def initialize(config = load_config)
|
50
|
+
@config = config
|
61
51
|
end
|
52
|
+
attr_reader :config
|
62
53
|
|
63
54
|
# Install options
|
64
55
|
options do |opt|
|
56
|
+
@rendering_options = {}
|
57
|
+
|
65
58
|
@execute = false
|
66
59
|
opt.on("-e", "--execute", "Execute one line of script (Lispy API)") do
|
67
60
|
@execute = true
|
68
61
|
end
|
69
62
|
|
70
|
-
@renderer_class = nil
|
71
63
|
Renderer.each do |name,descr,clazz|
|
72
64
|
opt.on("--#{name}", "Render output #{descr}"){
|
73
|
-
|
65
|
+
config.default_renderer = clazz
|
74
66
|
}
|
75
67
|
end
|
76
68
|
|
77
69
|
opt.on('--examples', "Use the example database for database") do
|
78
|
-
|
70
|
+
config.adapter = Alf.examples_adapter
|
79
71
|
end
|
80
72
|
|
81
73
|
opt.on('--db=DB',
|
82
74
|
"Set the database to use") do |value|
|
83
|
-
|
75
|
+
config.adapter = value
|
84
76
|
end
|
85
77
|
|
86
78
|
@input_reader = :rash
|
@@ -93,20 +85,27 @@ module Alf
|
|
93
85
|
|
94
86
|
opt.on("-Idirectory",
|
95
87
|
"Specify $LOAD_PATH directory (may be used more than once)") do |val|
|
96
|
-
|
88
|
+
config.load_paths << val
|
97
89
|
end
|
98
90
|
|
99
91
|
opt.on('-rlibrary',
|
100
|
-
"Require the library, before executing alf") do |
|
101
|
-
|
92
|
+
"Require the library, before executing alf") do |val|
|
93
|
+
config.requires << val
|
94
|
+
end
|
95
|
+
|
96
|
+
opt.on("--ff=FORMAT",
|
97
|
+
"Specify the floating point format") do |val|
|
98
|
+
config.float_format = val
|
102
99
|
end
|
103
100
|
|
104
101
|
opt.on("--[no-]pretty",
|
105
102
|
"Enable/disable pretty print best effort") do |val|
|
106
|
-
|
103
|
+
config.pretty = val
|
107
104
|
end
|
108
105
|
|
109
106
|
opt.on_tail('-h', "--help", "Show help") do
|
107
|
+
install_load_path
|
108
|
+
install_requires
|
110
109
|
raise Quickl::Help
|
111
110
|
end
|
112
111
|
|
@@ -120,42 +119,68 @@ module Alf
|
|
120
119
|
@stdin_operand || Reader.send(@input_reader, $stdin)
|
121
120
|
end
|
122
121
|
|
122
|
+
def connection
|
123
|
+
@connection ||= config.database.connection(viewpoint: config.viewpoint)
|
124
|
+
end
|
125
|
+
|
123
126
|
def execute(argv)
|
127
|
+
install_load_path
|
128
|
+
install_requires
|
129
|
+
|
124
130
|
# special case where a .alf file is provided
|
125
|
-
if argv.empty? or (argv.size == 1 && Path(argv.first).
|
131
|
+
if argv.empty? or (argv.size == 1 && Path(argv.first).file?)
|
126
132
|
argv.unshift("exec")
|
127
133
|
end
|
128
134
|
|
129
135
|
# compile the operator, render and returns it
|
130
136
|
compile(argv){ super }.tap do |op|
|
131
|
-
render(op
|
137
|
+
render(connection.compile(op)) if op && requester
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def install_load_path
|
144
|
+
config.load_paths.each do |path|
|
145
|
+
$: << path
|
132
146
|
end
|
133
147
|
end
|
134
148
|
|
135
|
-
def
|
136
|
-
|
137
|
-
|
138
|
-
@rendering_options[:trim_at] = hl.output_cols
|
139
|
-
@rendering_options[:page_at] = hl.output_rows
|
149
|
+
def install_requires
|
150
|
+
config.requires.each do |who|
|
151
|
+
require(who)
|
140
152
|
end
|
141
|
-
val
|
142
153
|
end
|
143
154
|
|
144
|
-
|
155
|
+
def load_config
|
156
|
+
config = Alf::Shell::DEFAULT_CONFIG.dup
|
157
|
+
if alfrc_file = Path.pwd.backfind('.alfrc')
|
158
|
+
config.alfrc(alfrc_file)
|
159
|
+
end
|
160
|
+
config
|
161
|
+
end
|
145
162
|
|
146
163
|
def compile(argv)
|
147
164
|
if @execute
|
148
|
-
|
165
|
+
connection.query(argv.first)
|
149
166
|
else
|
150
167
|
op = yield
|
151
|
-
op = op.bind(
|
168
|
+
op = op.bind(connection) if op
|
152
169
|
op
|
153
170
|
end
|
154
171
|
end
|
155
172
|
|
173
|
+
def rendering_options
|
174
|
+
options = { float_format: config.float_format }
|
175
|
+
if config.pretty? and (hl = highline)
|
176
|
+
options[:pretty] = config.pretty?
|
177
|
+
options[:trim_at] = hl.output_cols - 1
|
178
|
+
end
|
179
|
+
options
|
180
|
+
end
|
181
|
+
|
156
182
|
def render(operator, out = $stdout)
|
157
|
-
|
158
|
-
renderer = renderer_class.new(operator, rendering_options)
|
183
|
+
renderer = config.default_renderer.new(operator, rendering_options)
|
159
184
|
renderer.execute(out)
|
160
185
|
end
|
161
186
|
|
@@ -163,11 +188,6 @@ module Alf
|
|
163
188
|
require 'highline'
|
164
189
|
HighLine.new($stdin, $stdout)
|
165
190
|
rescue LoadError => ex
|
166
|
-
nil
|
167
|
-
end
|
168
|
-
|
169
|
-
def default_renderer_class
|
170
|
-
$stdout.tty? ? Renderer::Text : Renderer::Rash
|
171
191
|
end
|
172
192
|
|
173
193
|
end # class Main
|
@@ -2,37 +2,11 @@ module Alf
|
|
2
2
|
module Shell
|
3
3
|
class Show < Shell::Command()
|
4
4
|
|
5
|
-
options do |opt|
|
6
|
-
@renderer_class = nil
|
7
|
-
Renderer.each do |name,descr,clazz|
|
8
|
-
opt.on("--#{name}", "Render output #{descr}"){
|
9
|
-
@renderer_class = clazz
|
10
|
-
}
|
11
|
-
end
|
12
|
-
|
13
|
-
@pretty = nil
|
14
|
-
opt.on("--[no-]pretty",
|
15
|
-
"Enable/disable pretty print best effort") do |val|
|
16
|
-
@pretty = val
|
17
|
-
end
|
18
|
-
|
19
|
-
@ff = nil
|
20
|
-
opt.on("--ff=FORMAT",
|
21
|
-
"Specify the floating point format") do |val|
|
22
|
-
@ff = val
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
5
|
def run(argv, requester)
|
27
6
|
# set requester and parse options
|
28
7
|
@requester = requester
|
29
8
|
argv = parse_options(argv, :split)
|
30
9
|
|
31
|
-
# Set options on the requester
|
32
|
-
requester.pretty = @pretty unless @pretty.nil?
|
33
|
-
requester.rendering_options[:float_format] = @ff unless @ff.nil?
|
34
|
-
requester.renderer_class = (@renderer_class || requester.renderer_class)
|
35
|
-
|
36
10
|
compile(argv)
|
37
11
|
end
|
38
12
|
|
@@ -9,8 +9,8 @@ module Alf
|
|
9
9
|
# Called by Quickl when it's time to generate documentation of `cmd`.
|
10
10
|
#
|
11
11
|
def call(cmd, options = {})
|
12
|
-
if
|
13
|
-
text =
|
12
|
+
if (file = find_file(cmd)).file?
|
13
|
+
text = file.read
|
14
14
|
|
15
15
|
# Replace occurences of #{signature} to #{signature.to_xxx}
|
16
16
|
# according to options
|
@@ -54,7 +54,8 @@ module Alf
|
|
54
54
|
argv = Quickl.split_commandline_args(argv, '|')
|
55
55
|
argv.inject(nil) do |cmd,arr|
|
56
56
|
arr.shift if arr.first == "alf"
|
57
|
-
main = Alf::Shell::Main.new(Alf
|
57
|
+
main = Alf::Shell::Main.new(Alf::Shell::DEFAULT_CONFIG)
|
58
|
+
main.config.adapter = Alf.examples_adapter
|
58
59
|
main.stdin_operand = cmd unless cmd.nil?
|
59
60
|
main.run(arr, requester)
|
60
61
|
end
|
@@ -75,7 +76,7 @@ module Alf
|
|
75
76
|
else
|
76
77
|
raise "Unexpected command #{cmd}"
|
77
78
|
end
|
78
|
-
|
79
|
+
DOC_FOLDER/where/"#{cmd.command_name}.md"
|
79
80
|
end
|
80
81
|
|
81
82
|
end # class DocManager
|
data/lib/alf/shell/from_argv.rb
CHANGED
@@ -15,6 +15,12 @@ module Alf
|
|
15
15
|
Size.new(Integer(argv.first || 0))
|
16
16
|
}
|
17
17
|
|
18
|
+
# ARGV -> Integer
|
19
|
+
c.coercion(Array, Integer){|argv,_|
|
20
|
+
throw :next_rule if argv.size > 1
|
21
|
+
Integer(argv.first || 0)
|
22
|
+
}
|
23
|
+
|
18
24
|
# ARGV -> AttrName
|
19
25
|
c.coercion(Array, AttrName){|argv,_|
|
20
26
|
throw :next_rule if argv.size > 1
|
data/lib/alf/shell/support.rb
CHANGED
@@ -2,21 +2,22 @@ module Alf
|
|
2
2
|
module Shell
|
3
3
|
module Support
|
4
4
|
|
5
|
-
def
|
6
|
-
requester && requester.
|
5
|
+
def connection
|
6
|
+
requester && requester.connection
|
7
7
|
end
|
8
8
|
|
9
9
|
def compiler
|
10
|
-
@compiler ||= (
|
10
|
+
@compiler ||= (connection && connection.compiler) || Engine::Compiler.new(nil)
|
11
11
|
end
|
12
12
|
|
13
13
|
def operands(argv, size = nil)
|
14
14
|
operands = [ stdin_operand ] + Array(argv)
|
15
15
|
operands = operands[(operands.size - size)..-1] if size
|
16
16
|
operands = operands.map{|arg|
|
17
|
-
arg =
|
17
|
+
arg = connection.relvar(arg) if arg.is_a?(String)
|
18
18
|
Algebra::Operand.coerce(arg)
|
19
19
|
}
|
20
|
+
operands
|
20
21
|
end
|
21
22
|
|
22
23
|
def stdin_operand
|
data/lib/alf/shell/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
alf --db=$(_("alf",__FILE__)) show
|
1
|
+
alf --text --db=$(_("alf",__FILE__)) show rel
|
@@ -19,9 +19,10 @@ OPTIONS
|
|
19
19
|
--csv Render output in CSV
|
20
20
|
--examples Use the example database for database
|
21
21
|
--db=DB Set the database to use
|
22
|
-
--input-reader=READER Specify the kind of reader when reading on $stdin (rash,csv,json)
|
22
|
+
--input-reader=READER Specify the kind of reader when reading on $stdin (rash,csv,json,ruby)
|
23
23
|
-Idirectory Specify $LOAD_PATH directory (may be used more than once)
|
24
24
|
-rlibrary Require the library, before executing alf
|
25
|
+
--ff=FORMAT Specify the floating point format
|
25
26
|
--[no-]pretty Enable/disable pretty print best effort
|
26
27
|
-h, --help Show help
|
27
28
|
-v, --version Show version
|
@@ -29,12 +30,14 @@ OPTIONS
|
|
29
30
|
RELATIONAL OPERATORS
|
30
31
|
|
31
32
|
extend Relational extension (additional, computed attributes)
|
33
|
+
frame Relational framing (aka offset/limit, yet sounder)
|
32
34
|
group Relational grouping (relation-valued attributes)
|
33
35
|
intersect Relational intersection (aka a logical and)
|
34
36
|
join Relational join (and cartesian product)
|
35
37
|
matching Relational matching (join + project back on left)
|
36
38
|
minus Relational minus (aka difference)
|
37
39
|
not-matching Relational not matching (inverse of matching)
|
40
|
+
page Relational pagination (like frame, but easier)
|
38
41
|
project Relational projection (clip + compact)
|
39
42
|
rank Relational ranking (explicit tuple positions)
|
40
43
|
rename Relational renaming (rename some attributes)
|
@@ -47,6 +50,7 @@ RELATIONAL OPERATORS
|
|
47
50
|
|
48
51
|
EXPERIMENTAL RELATIONAL OPERATORS
|
49
52
|
|
53
|
+
hierarchize Relational hierarchy (recursive relation-trees)
|
50
54
|
infer-heading Relational heading inference (print the relation type)
|
51
55
|
quota Generalized quota-queries (position, sum progression, etc.)
|
52
56
|
|
@@ -65,7 +69,7 @@ OTHER NON-RELATIONAL COMMANDS
|
|
65
69
|
|
66
70
|
exec Executes an .alf file on current database
|
67
71
|
help Show help about a specific command
|
68
|
-
show Output input tuples through
|
72
|
+
show Output input tuples through the default renderer in a specific order.
|
69
73
|
|
70
74
|
See 'alf help COMMAND' for details about a specific command.
|
71
75
|
|
@@ -0,0 +1 @@
|
|
1
|
+
alf --text frame suppliers -- name -- 1 -- 2
|
@@ -1,25 +1,12 @@
|
|
1
1
|
|
2
|
-
Output input tuples through
|
2
|
+
Output input tuples through the default renderer in a specific order.
|
3
3
|
|
4
4
|
SYNOPSIS
|
5
5
|
|
6
6
|
alf show NAME -- [ORDERING]
|
7
7
|
|
8
|
-
OPTIONS
|
9
|
-
|
10
|
-
--rash Render output as ruby hashes
|
11
|
-
--text Render output as a text table
|
12
|
-
--yaml Render output in YAML
|
13
|
-
--json Render output in JSON
|
14
|
-
--csv Render output in CSV
|
15
|
-
--[no-]pretty Enable/disable pretty print best effort
|
16
|
-
--ff=FORMAT Specify the floating point format
|
17
|
-
|
18
8
|
DESCRIPTION
|
19
9
|
|
20
10
|
When a name is specified as commandline arg, request the database to
|
21
11
|
provide the corresponding relation variable and prints its value.
|
22
12
|
Otherwise, take what comes on standard input.
|
23
|
-
|
24
|
-
Note that this command is not an operator and should not be piped
|
25
|
-
anymore.
|
@@ -0,0 +1 @@
|
|
1
|
+
alf --text page --page-size=2 suppliers -- name -- 1
|
@@ -1 +1 @@
|
|
1
|
-
alf
|
1
|
+
alf --text show suppliers -- city asc sid asc
|
@@ -1 +1 @@
|
|
1
|
-
alf
|
1
|
+
alf --text show suppliers -- city asc status desc sid asc
|
@@ -1 +1 @@
|
|
1
|
-
alf
|
1
|
+
alf --text --ff=%.6f show parts
|
@@ -1 +1 @@
|
|
1
|
-
alf show suppliers
|
1
|
+
alf --rash show suppliers
|
@@ -1 +1 @@
|
|
1
|
-
alf
|
1
|
+
alf --rash --pretty show suppliers
|
@@ -1 +1 @@
|
|
1
|
-
alf show suppliers --
|
1
|
+
alf --yaml show suppliers -- sid asc
|
@@ -10,8 +10,13 @@ end
|
|
10
10
|
|
11
11
|
describe "Alf's alf command / " do
|
12
12
|
|
13
|
-
|
13
|
+
before do
|
14
|
+
Path.dir.chdir
|
15
|
+
end
|
16
|
+
|
17
|
+
Path.dir.glob('**/*.cmd').each_with_index do |input,index|
|
14
18
|
cmd = wlang(input.readlines.first, binding)
|
19
|
+
|
15
20
|
specify{ cmd.should =~ /^alf / }
|
16
21
|
|
17
22
|
describe "#{input.basename}: #{cmd}" do
|
@@ -36,9 +41,7 @@ describe "Alf's alf command / " do
|
|
36
41
|
|
37
42
|
specify{
|
38
43
|
begin
|
39
|
-
dir = Path.relative('__database__')
|
40
44
|
main = Alf::Shell::Main.new
|
41
|
-
main.database = Alf.connect(dir)
|
42
45
|
main.run(argv, __FILE__)
|
43
46
|
rescue => ex
|
44
47
|
begin
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Shell
|
4
|
+
describe Alfrc, 'alfrc' do
|
5
|
+
|
6
|
+
let(:alfrc){ Alfrc.new{|c| c.load_paths = ["foo"] } }
|
7
|
+
|
8
|
+
context 'with a block' do
|
9
|
+
subject{ alfrc.alfrc{|c| @seen = c } }
|
10
|
+
|
11
|
+
it 'should return the instance itself' do
|
12
|
+
subject.should be(alfrc)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should yield the block' do
|
16
|
+
subject
|
17
|
+
@seen.should be(alfrc)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with a path' do
|
22
|
+
subject{ alfrc.alfrc(path) }
|
23
|
+
|
24
|
+
let(:path){ Path.backfind("spec/fixtures/example.alfrc") }
|
25
|
+
|
26
|
+
it 'should return the instance itself' do
|
27
|
+
subject.should be(alfrc)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should resolve the load paths correctly' do
|
31
|
+
subject.load_paths.should eq([ "foo", path.parent/'lib' ])
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should set requires correctly' do
|
35
|
+
subject.requires.should eq([ 'alf-sequel' ])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with a path and a block' do
|
40
|
+
subject{ alfrc.alfrc(path){|c| c.requires = ['bar'] } }
|
41
|
+
|
42
|
+
let(:path){ Path.backfind("spec/fixtures/example.alfrc") }
|
43
|
+
|
44
|
+
it 'should return the instance itself' do
|
45
|
+
subject.should be(alfrc)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should resolve the load paths correctly' do
|
49
|
+
subject.load_paths.should eq([ "foo", path.parent/'lib' ])
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should yield the block after the path' do
|
53
|
+
subject.requires.should eq([ 'bar' ])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -12,7 +12,7 @@ module Alf
|
|
12
12
|
describe "on a static file" do
|
13
13
|
before{
|
14
14
|
def dm.find_file(cmd);
|
15
|
-
|
15
|
+
Path.dir/'static.md'
|
16
16
|
end
|
17
17
|
}
|
18
18
|
it { should eq("Hello\n") }
|
@@ -21,21 +21,19 @@ module Alf
|
|
21
21
|
describe "on a dynamic file" do
|
22
22
|
before{
|
23
23
|
def dm.find_file(cmd);
|
24
|
-
|
24
|
+
Path.dir/'dynamic.md'
|
25
25
|
end
|
26
26
|
}
|
27
27
|
it { should eq("show\n") }
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
it { should eq(File.read(File.expand_path('../example_1.txt', __FILE__))) }
|
38
|
-
end
|
30
|
+
describe "on an example file" do
|
31
|
+
before{
|
32
|
+
def dm.find_file(cmd);
|
33
|
+
Path.dir/'example.md'
|
34
|
+
end
|
35
|
+
}
|
36
|
+
it { should eq((Path.dir/"example_1.txt").read) }
|
39
37
|
end
|
40
38
|
|
41
39
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Shell
|
4
|
+
describe Main, "-I" do
|
5
|
+
|
6
|
+
before do
|
7
|
+
Path.dir.chdir
|
8
|
+
subject
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:cmd){ Main.new }
|
12
|
+
|
13
|
+
subject{
|
14
|
+
cmd.parse_options(argv)
|
15
|
+
cmd
|
16
|
+
}
|
17
|
+
|
18
|
+
context 'when no explicitly set' do
|
19
|
+
let(:argv){ [] }
|
20
|
+
|
21
|
+
it 'should have defaults only' do
|
22
|
+
cmd.config.load_paths.should eq(["a_load_path"])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when specified multiple times' do
|
27
|
+
let(:argv){ ["-Ilib", "-Ispec"] }
|
28
|
+
|
29
|
+
it 'should have defaults only' do
|
30
|
+
cmd.config.load_paths.should eq(["a_load_path", "lib", "spec"])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Shell
|
4
|
+
describe Main, "-r" do
|
5
|
+
|
6
|
+
before do
|
7
|
+
Path.dir.chdir
|
8
|
+
subject
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:cmd){ Main.new }
|
12
|
+
|
13
|
+
subject{
|
14
|
+
cmd.parse_options(argv)
|
15
|
+
cmd
|
16
|
+
}
|
17
|
+
|
18
|
+
context 'when no explicitly set' do
|
19
|
+
let(:argv){ [] }
|
20
|
+
|
21
|
+
it 'should have defaults only' do
|
22
|
+
cmd.config.requires.should eq(["a_require"])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when specified multiple times' do
|
27
|
+
let(:argv){ ["-ralf-sequel", "-rpry"] }
|
28
|
+
|
29
|
+
it 'should have defaults only' do
|
30
|
+
cmd.config.requires.should eq(["a_require", "alf-sequel", "pry"])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Alf
|
3
|
+
module Shell
|
4
|
+
describe Main, "--text, --json and the like" do
|
5
|
+
|
6
|
+
before do
|
7
|
+
Path.dir.chdir
|
8
|
+
subject
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:cmd){ Main.new }
|
12
|
+
|
13
|
+
subject{
|
14
|
+
cmd.parse_options(argv)
|
15
|
+
cmd
|
16
|
+
}
|
17
|
+
|
18
|
+
context 'when set to --json' do
|
19
|
+
let(:argv){ ["--json"] }
|
20
|
+
|
21
|
+
it 'should set the default renderer' do
|
22
|
+
cmd.config.default_renderer.should be(Alf::Renderer::JSON)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alf-shell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-10-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
requirements:
|
67
67
|
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 0.
|
69
|
+
version: 0.14.0
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -74,7 +74,7 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 0.
|
77
|
+
version: 0.14.0
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
79
|
name: quickl
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,13 +116,16 @@ files:
|
|
116
116
|
- doc/operators/non_relational/sort.md
|
117
117
|
- doc/operators/non_relational/type-safe.md
|
118
118
|
- doc/operators/relational/extend.md
|
119
|
+
- doc/operators/relational/frame.md
|
119
120
|
- doc/operators/relational/group.md
|
121
|
+
- doc/operators/relational/hierarchize.md
|
120
122
|
- doc/operators/relational/infer-heading.md
|
121
123
|
- doc/operators/relational/intersect.md
|
122
124
|
- doc/operators/relational/join.md
|
123
125
|
- doc/operators/relational/matching.md
|
124
126
|
- doc/operators/relational/minus.md
|
125
127
|
- doc/operators/relational/not-matching.md
|
128
|
+
- doc/operators/relational/page.md
|
126
129
|
- doc/operators/relational/project.md
|
127
130
|
- doc/operators/relational/quota.md
|
128
131
|
- doc/operators/relational/rank.md
|
@@ -133,6 +136,7 @@ files:
|
|
133
136
|
- doc/operators/relational/union.md
|
134
137
|
- doc/operators/relational/unwrap.md
|
135
138
|
- doc/operators/relational/wrap.md
|
139
|
+
- lib/alf/shell/alfrc.rb
|
136
140
|
- lib/alf/shell/command/exec.rb
|
137
141
|
- lib/alf/shell/command/help.rb
|
138
142
|
- lib/alf/shell/command/main.rb
|
@@ -151,6 +155,7 @@ files:
|
|
151
155
|
- Manifest.txt
|
152
156
|
- Rakefile
|
153
157
|
- README.md
|
158
|
+
- spec/fixtures/example.alfrc
|
154
159
|
- spec/integration/__database__/group.alf
|
155
160
|
- spec/integration/__database__/parts.rash
|
156
161
|
- spec/integration/__database__/suppliers.rash
|
@@ -192,6 +197,8 @@ files:
|
|
192
197
|
- spec/integration/defaults/defaults_2.stdout
|
193
198
|
- spec/integration/extend/extend_0.cmd
|
194
199
|
- spec/integration/extend/extend_0.stdout
|
200
|
+
- spec/integration/frame/frame_0.cmd
|
201
|
+
- spec/integration/frame/frame_0.stdout
|
195
202
|
- spec/integration/generator/generator_1.cmd
|
196
203
|
- spec/integration/generator/generator_1.stdout
|
197
204
|
- spec/integration/generator/generator_2.cmd
|
@@ -214,6 +221,8 @@ files:
|
|
214
221
|
- spec/integration/minus/minus_0.stdout
|
215
222
|
- spec/integration/not-matching/not-matching_0.cmd
|
216
223
|
- spec/integration/not-matching/not-matching_0.stdout
|
224
|
+
- spec/integration/page/page_0.cmd
|
225
|
+
- spec/integration/page/page_0.stdout
|
217
226
|
- spec/integration/project/project_0.cmd
|
218
227
|
- spec/integration/project/project_0.stdout
|
219
228
|
- spec/integration/project/project_1.cmd
|
@@ -242,8 +251,6 @@ files:
|
|
242
251
|
- spec/integration/show/show_base_sort_1.stdout
|
243
252
|
- spec/integration/show/show_base_sort_2.cmd
|
244
253
|
- spec/integration/show/show_base_sort_2.stdout
|
245
|
-
- spec/integration/show/show_conflictual.cmd
|
246
|
-
- spec/integration/show/show_conflictual.stdout
|
247
254
|
- spec/integration/show/show_ff.cmd
|
248
255
|
- spec/integration/show/show_ff.stdout
|
249
256
|
- spec/integration/show/show_rash.cmd
|
@@ -271,6 +278,7 @@ files:
|
|
271
278
|
- spec/integration/wrap/wrap_0.stdout
|
272
279
|
- spec/spec_helper.rb
|
273
280
|
- spec/test_shell.rb
|
281
|
+
- spec/unit/alfrc/test_alfrc.rb
|
274
282
|
- spec/unit/doc_manager/dynamic.md
|
275
283
|
- spec/unit/doc_manager/example.md
|
276
284
|
- spec/unit/doc_manager/example_1.txt
|
@@ -290,6 +298,9 @@ files:
|
|
290
298
|
- spec/unit/from_argv/test_to_tuple_computation.rb
|
291
299
|
- spec/unit/from_argv/test_to_tuple_expression.rb
|
292
300
|
- spec/unit/main/test_class_methods.rb
|
301
|
+
- spec/unit/main/test_I_option.rb
|
302
|
+
- spec/unit/main/test_r_option.rb
|
303
|
+
- spec/unit/main/test_renderer_option.rb
|
293
304
|
- spec/unit/operator/test_autonum.rb
|
294
305
|
- spec/unit/operator/test_clip.rb
|
295
306
|
- spec/unit/operator/test_coerce.rb
|
@@ -331,7 +342,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
331
342
|
version: '0'
|
332
343
|
segments:
|
333
344
|
- 0
|
334
|
-
hash:
|
345
|
+
hash: 1654527447503089080
|
335
346
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
336
347
|
none: false
|
337
348
|
requirements:
|
@@ -1 +0,0 @@
|
|
1
|
-
alf --yaml show suppliers --rash
|
@@ -1,5 +0,0 @@
|
|
1
|
-
{:sid => "S1", :name => "Smith", :status => 20, :city => "London"}
|
2
|
-
{:sid => "S2", :name => "Jones", :status => 10, :city => "Paris"}
|
3
|
-
{:sid => "S3", :name => "Blake", :status => 30, :city => "Paris"}
|
4
|
-
{:sid => "S4", :name => "Clark", :status => 20, :city => "London"}
|
5
|
-
{:sid => "S5", :name => "Adams", :status => 30, :city => "Athens"}
|