live_sql 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/.gitignore +5 -0
- data/README.md +20 -8
- data/exe/live_sql +8 -0
- data/lib/live_sql/cursorable.rb +34 -0
- data/lib/live_sql/interface.rb +6 -22
- data/lib/live_sql/psql_dbconnection.rb +18 -0
- data/lib/live_sql/sqlite3_dbconnection.rb +11 -0
- data/lib/live_sql/util.rb +6 -0
- data/lib/live_sql/version.rb +1 -1
- data/lib/live_sql.rb +78 -70
- data/live_sql.gemspec +7 -8
- metadata +38 -22
- data/bin/console +0 -17
- data/bin/setup +0 -7
- data/lib/live_sql/default_db/.DS_Store +0 -0
- data/lib/live_sql/default_db/cats.db +0 -0
- data/lib/live_sql/default_db/movie.db +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99f8b166541e4e08506407da8489e03e215fd309
|
4
|
+
data.tar.gz: fe379eafbe5cedc9f9a096397df3586b8041b993
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4959bf437934808eb258a11a9b4368b0e43b7e5c3b497a8e889f5ffe53bf520dd55c854a1e536b827ff897ec8997594b84f31dd5e51edff435023cbb09a7bdc
|
7
|
+
data.tar.gz: 3097213f35b819504d4b77df88e79a9e3537e8b3899cf4fe1173e9675c81161a18039c85da72ceae65873987021f5bc9ed7b111792e3219d7b13c15b74d5db78
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# LiveSql
|
2
2
|
|
3
|
-
Hello friends! live_sql is a little program I wrote to watch how your
|
3
|
+
Hello friends! live_sql is a little program I wrote to watch how your SQL queries change your results as you type. This is a baby gem, so contributions are welcome! Fixing problems, adding new features, or reporting bugs is greatly appreciated!
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -17,14 +17,27 @@ And then execute:
|
|
17
17
|
Or install it yourself as:
|
18
18
|
|
19
19
|
$ gem install live_sql
|
20
|
+
|
20
21
|
## Usage
|
21
22
|
|
22
|
-
|
23
|
+
### Running from the Terminal
|
24
|
+
To use with a postgres db, simply run:
|
25
|
+
|
26
|
+
live_sql your_database_name_here
|
27
|
+
|
28
|
+
To use sqlite3 db, navigate to the folder containing the db and run
|
29
|
+
|
30
|
+
live_sql your_database_name_here.db sqlite3
|
31
|
+
|
23
32
|
|
24
|
-
|
33
|
+
### Using the class
|
25
34
|
|
26
|
-
|
27
|
-
|
35
|
+
The gem exposes the LiveSQL object. To open the interface create a new instance, and call the run method.
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
options = { db: :sqlite3, limit: 40 }
|
39
|
+
LiveSQL.new(your_database_name, options).run
|
40
|
+
```
|
28
41
|
|
29
42
|
## Contributing
|
30
43
|
|
@@ -32,10 +45,9 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/fsladk
|
|
32
45
|
|
33
46
|
## Running list of bugs and potential features:
|
34
47
|
|
35
|
-
-
|
36
|
-
|
37
|
-
- The most obvious extension is to get this thing hooked up to postgres as well as sqlite3.
|
48
|
+
- Allow aggregate functions to be included in select but not actually used in the query until a group by clause is added.
|
38
49
|
|
50
|
+
- Allow cursor navigation by holding down command/option for jumping words etc.
|
39
51
|
|
40
52
|
## License
|
41
53
|
|
data/exe/live_sql
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module Cursorable
|
2
|
+
|
3
|
+
def error
|
4
|
+
end
|
5
|
+
|
6
|
+
def quit
|
7
|
+
system("clear")
|
8
|
+
abort
|
9
|
+
end
|
10
|
+
|
11
|
+
def left
|
12
|
+
@cursor_pos -= 1 unless @cursor_pos == 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def right
|
16
|
+
@cursor_pos += 1 unless @cursor_pos == @string.length - 1
|
17
|
+
end
|
18
|
+
|
19
|
+
def backspace
|
20
|
+
if @string.length > 1
|
21
|
+
@string.slice!(@cursor_pos - 1)
|
22
|
+
@cursor_pos -= 1 unless @cursor_pos == 0
|
23
|
+
end
|
24
|
+
attempt_to_query_db
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete
|
28
|
+
if @string.length > 1
|
29
|
+
@string.slice!(@cursor_pos)
|
30
|
+
end
|
31
|
+
attempt_to_query_db
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
data/lib/live_sql/interface.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
require 'io/console'
|
2
2
|
|
3
|
-
# Reads keypresses from the user including 2 and 3 escape character sequences.
|
4
|
-
|
5
3
|
class Interface
|
6
4
|
attr_accessor :string
|
7
5
|
|
@@ -23,26 +21,15 @@ class Interface
|
|
23
21
|
|
24
22
|
# oringal case statement from:
|
25
23
|
# http://www.alecjacobson.com/weblog/?p=75
|
24
|
+
|
26
25
|
def get_keyboard_input
|
27
26
|
c = read_char
|
28
27
|
|
29
28
|
case c
|
30
|
-
# when " "
|
31
|
-
# "SPACE"
|
32
|
-
# when "\t"
|
33
|
-
# :query
|
34
29
|
when "\r"
|
35
30
|
:error
|
36
|
-
# when "\n"
|
37
|
-
# "LINE FEED"
|
38
31
|
when "\e"
|
39
|
-
:
|
40
|
-
# when "\e[A"
|
41
|
-
# "UP ARROW"
|
42
|
-
# :error
|
43
|
-
# when "\e[B"
|
44
|
-
# "DOWN ARROW"
|
45
|
-
# :error
|
32
|
+
:quit
|
46
33
|
when "\e[C"
|
47
34
|
"RIGHT ARROW"
|
48
35
|
:right
|
@@ -51,13 +38,10 @@ class Interface
|
|
51
38
|
:left
|
52
39
|
when "\177"
|
53
40
|
:backspace
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
# when "\u0003"
|
59
|
-
# "CONTROL-C"
|
60
|
-
# exit 0
|
41
|
+
when "\004"
|
42
|
+
:delete
|
43
|
+
when "\e[3~"
|
44
|
+
:delete
|
61
45
|
when /^.$/
|
62
46
|
c
|
63
47
|
else
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'pg'
|
2
|
+
|
3
|
+
class PostgresDatabaseConnection
|
4
|
+
|
5
|
+
def initialize(db)
|
6
|
+
@connection = PG.connect(dbname: db)
|
7
|
+
@connection.type_map_for_results = PG::BasicTypeMapForResults.new @connection
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute(arg)
|
11
|
+
results = []
|
12
|
+
result = @connection.exec(arg)
|
13
|
+
result.each_row do |row|
|
14
|
+
results << Hash[result.fields.zip(row)]
|
15
|
+
end
|
16
|
+
results
|
17
|
+
end
|
18
|
+
end
|
data/lib/live_sql/version.rb
CHANGED
data/lib/live_sql.rb
CHANGED
@@ -1,115 +1,123 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
require_relative "./live_sql/version.rb"
|
2
|
+
require_relative "./live_sql/interface.rb"
|
3
|
+
require_relative "./live_sql/cursorable.rb"
|
4
|
+
require_relative "./live_sql/util.rb"
|
5
|
+
require_relative "./live_sql/sqlite3_dbconnection.rb"
|
6
|
+
require_relative "./live_sql/psql_dbconnection.rb"
|
5
7
|
require 'table_print'
|
6
8
|
require 'colorize'
|
7
9
|
|
8
|
-
|
9
|
-
class QuestionsDatabase < SQLite3::Database
|
10
|
-
|
11
|
-
def initialize(db)
|
12
|
-
super(db)
|
13
|
-
|
14
|
-
self.results_as_hash = true
|
15
|
-
self.type_translation = true
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
10
|
class LiveSQL
|
20
|
-
|
11
|
+
include Cursorable
|
12
|
+
include Util
|
21
13
|
|
22
|
-
|
23
|
-
|
24
|
-
live_sql.run
|
25
|
-
end
|
14
|
+
attr_accessor :result, :cursor_pos, :errors, :string, :state
|
15
|
+
attr_reader :db, :limit, :interface
|
26
16
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
17
|
+
def initialize(db, opts = {})
|
18
|
+
if opts[:db] == :sqlite3
|
19
|
+
@db = Sqlite3DatabaseConnection.new(db)
|
20
|
+
else
|
21
|
+
@db = PostgresDatabaseConnection.new(db)
|
22
|
+
end
|
31
23
|
|
32
|
-
def initialize(db)
|
33
24
|
@interface = Interface.new
|
34
|
-
@
|
35
|
-
|
25
|
+
@limit = 30
|
36
26
|
@string = " "
|
37
27
|
@result = []
|
38
28
|
|
39
|
-
@
|
29
|
+
@state = :invalid
|
40
30
|
@cursor_pos = 0
|
41
31
|
@errors = []
|
42
32
|
end
|
43
33
|
|
34
|
+
|
44
35
|
def run
|
45
|
-
|
36
|
+
loop do
|
46
37
|
print_display
|
47
|
-
input =
|
38
|
+
input = interface.get_keyboard_input
|
48
39
|
handle_input(input)
|
49
40
|
end
|
50
41
|
end
|
51
42
|
|
43
|
+
# private
|
44
|
+
|
52
45
|
def handle_input(input)
|
53
|
-
if input
|
54
|
-
|
55
|
-
abort
|
56
|
-
elsif input == :error
|
57
|
-
elsif input == :right
|
58
|
-
@cursor_pos += 1 unless @cursor_pos == @string.length - 1
|
59
|
-
elsif input == :left
|
60
|
-
@cursor_pos -= 1 unless @cursor_pos == 0
|
61
|
-
elsif input == :backspace
|
62
|
-
if @string.length > 1
|
63
|
-
@string.slice!(@cursor_pos - 1)
|
64
|
-
@cursor_pos -= 1 unless @cursor_pos == 0
|
65
|
-
end
|
66
|
-
attempt_to_query_db
|
46
|
+
if input.is_a?(Symbol)
|
47
|
+
send(input)
|
67
48
|
else
|
68
|
-
|
69
|
-
|
49
|
+
string.insert(cursor_pos, input)
|
50
|
+
self.cursor_pos += 1
|
70
51
|
attempt_to_query_db
|
71
52
|
end
|
72
53
|
end
|
73
54
|
|
74
55
|
def attempt_to_query_db
|
75
|
-
old_table =
|
76
|
-
|
77
|
-
|
56
|
+
old_table = result
|
57
|
+
filter_aggregate_functions
|
58
|
+
|
59
|
+
self.result = query_db(string)
|
60
|
+
self.state = :valid
|
78
61
|
rescue StandardError => e
|
79
|
-
|
80
|
-
|
81
|
-
|
62
|
+
errors << e.message
|
63
|
+
self.result = old_table
|
64
|
+
self.state = :invalid
|
65
|
+
end
|
66
|
+
|
67
|
+
def filter_aggregate_functions
|
68
|
+
if aggregate_func_names.any? { |func| string.upcase.include?(func) } && !terminated?
|
69
|
+
raise "Aggregate queries must be terminated with a semi-colon"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def terminated?
|
74
|
+
!!(string =~ /\;\s*$/)
|
75
|
+
end
|
76
|
+
|
77
|
+
def query_db(string)
|
78
|
+
return if string =~ /drop/i
|
79
|
+
db.execute(<<-SQL)
|
80
|
+
#{string}
|
81
|
+
LIMIT
|
82
|
+
#{limit}
|
83
|
+
SQL
|
82
84
|
end
|
83
85
|
|
84
86
|
def print_display
|
85
87
|
system("clear")
|
88
|
+
prompt
|
89
|
+
render
|
90
|
+
end
|
91
|
+
|
92
|
+
def prompt
|
86
93
|
puts "Enter a query!".underline.bold
|
87
94
|
puts "Green is for a valid query, red for syntax error."
|
95
|
+
puts "Queries using AVG() or COUNT() must be terminated with a semi-colon."
|
88
96
|
puts "The table always shows the last valid query."
|
89
97
|
puts "Press esc to quit."
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
puts
|
95
|
-
else
|
96
|
-
print @string[0...@cursor_pos].colorize(:green)
|
97
|
-
print @string[@cursor_pos].colorize(background: :cyan)
|
98
|
-
print @string[@cursor_pos + 1..-1].colorize(:green)
|
99
|
-
puts
|
100
|
-
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def render
|
101
|
+
state == :invalid ? print_invalid_query : print_valid_query
|
101
102
|
print_table
|
102
103
|
end
|
103
104
|
|
104
|
-
def
|
105
|
-
|
105
|
+
def print_invalid_query
|
106
|
+
print @string[0...@cursor_pos].colorize(:red)
|
107
|
+
print @string[@cursor_pos].colorize(background: :cyan, color: :red)
|
108
|
+
print @string[@cursor_pos + 1..-1].colorize(:red)
|
109
|
+
puts
|
106
110
|
end
|
107
111
|
|
108
|
-
def
|
109
|
-
@
|
110
|
-
|
111
|
-
|
112
|
-
|
112
|
+
def print_valid_query
|
113
|
+
print @string[0...@cursor_pos].colorize(:green)
|
114
|
+
print @string[@cursor_pos].colorize(background: :cyan)
|
115
|
+
print @string[@cursor_pos + 1..-1].colorize(:green)
|
116
|
+
puts
|
117
|
+
end
|
118
|
+
|
119
|
+
def print_table
|
120
|
+
tp result
|
113
121
|
end
|
114
122
|
|
115
123
|
end
|
data/live_sql.gemspec
CHANGED
@@ -8,23 +8,22 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = LiveSql::VERSION
|
9
9
|
spec.authors = ["Fred Sladkey"]
|
10
10
|
spec.email = ["fsladkey@gmail.com"]
|
11
|
+
spec.executables = ["live_sql"]
|
11
12
|
|
12
|
-
spec.summary = %q{
|
13
|
+
spec.summary = %q{Live updating database querying utility.}
|
14
|
+
spec.description = %q{Interact with psql/sqlite3 database and watch your results change as you type the query.}
|
13
15
|
spec.homepage = "https://github.com/fsladkey/Live-SQL"
|
14
16
|
spec.license = "MIT"
|
15
17
|
|
16
|
-
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
17
|
-
# delete this section to allow pushing this gem to any host.
|
18
|
-
|
19
18
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
19
|
spec.bindir = "exe"
|
21
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
20
|
spec.require_paths = ["lib"]
|
23
21
|
|
24
22
|
spec.add_development_dependency "bundler", "~> 1.10"
|
25
23
|
spec.add_development_dependency "rake", "~> 10.0"
|
26
24
|
|
27
|
-
spec.add_dependency 'sqlite3'
|
28
|
-
spec.add_dependency '
|
29
|
-
spec.add_dependency '
|
25
|
+
spec.add_dependency 'sqlite3', '1.3.11'
|
26
|
+
spec.add_dependency 'pg', '0.18.4'
|
27
|
+
spec.add_dependency 'colorize', '0.7.7'
|
28
|
+
spec.add_dependency 'table_print', '1.5.4'
|
30
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: live_sql
|
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
|
- Fred Sladkey
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -42,48 +42,64 @@ dependencies:
|
|
42
42
|
name: sqlite3
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 1.3.11
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 1.3.11
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pg
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.18.4
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.18.4
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: colorize
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
|
-
- -
|
73
|
+
- - '='
|
60
74
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
75
|
+
version: 0.7.7
|
62
76
|
type: :runtime
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
|
-
- -
|
80
|
+
- - '='
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
82
|
+
version: 0.7.7
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: table_print
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
|
-
- -
|
87
|
+
- - '='
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
89
|
+
version: 1.5.4
|
76
90
|
type: :runtime
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
|
-
- -
|
94
|
+
- - '='
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
83
|
-
description:
|
96
|
+
version: 1.5.4
|
97
|
+
description: Interact with psql/sqlite3 database and watch your results change as
|
98
|
+
you type the query.
|
84
99
|
email:
|
85
100
|
- fsladkey@gmail.com
|
86
|
-
executables:
|
101
|
+
executables:
|
102
|
+
- live_sql
|
87
103
|
extensions: []
|
88
104
|
extra_rdoc_files: []
|
89
105
|
files:
|
@@ -93,13 +109,13 @@ files:
|
|
93
109
|
- LICENSE.txt
|
94
110
|
- README.md
|
95
111
|
- Rakefile
|
96
|
-
-
|
97
|
-
- bin/setup
|
112
|
+
- exe/live_sql
|
98
113
|
- lib/live_sql.rb
|
99
|
-
- lib/live_sql/
|
100
|
-
- lib/live_sql/default_db/cats.db
|
101
|
-
- lib/live_sql/default_db/movie.db
|
114
|
+
- lib/live_sql/cursorable.rb
|
102
115
|
- lib/live_sql/interface.rb
|
116
|
+
- lib/live_sql/psql_dbconnection.rb
|
117
|
+
- lib/live_sql/sqlite3_dbconnection.rb
|
118
|
+
- lib/live_sql/util.rb
|
103
119
|
- lib/live_sql/version.rb
|
104
120
|
- live_sql.gemspec
|
105
121
|
homepage: https://github.com/fsladkey/Live-SQL
|
@@ -125,5 +141,5 @@ rubyforge_project:
|
|
125
141
|
rubygems_version: 2.2.2
|
126
142
|
signing_key:
|
127
143
|
specification_version: 4
|
128
|
-
summary:
|
144
|
+
summary: Live updating database querying utility.
|
129
145
|
test_files: []
|
data/bin/console
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require "bundler/setup"
|
4
|
-
require "live_sql"
|
5
|
-
|
6
|
-
db = ARGV[0]
|
7
|
-
db ||= './lib/live_sql/default_db/movie.db'
|
8
|
-
|
9
|
-
live_sql = LiveSQL.new(db)
|
10
|
-
live_sql.run
|
11
|
-
|
12
|
-
|
13
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
14
|
-
# with your gem easier. You can also use a different console, if you like.
|
15
|
-
|
16
|
-
require "pry"
|
17
|
-
Pry.start
|
data/bin/setup
DELETED
Binary file
|
Binary file
|
Binary file
|