live_sql 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 54b7fcbd0ff4dcad2f1cceaa5364da65597caa06
4
- data.tar.gz: f96754e32f6f59e747322dc02507aa01b29c0145
3
+ metadata.gz: 99f8b166541e4e08506407da8489e03e215fd309
4
+ data.tar.gz: fe379eafbe5cedc9f9a096397df3586b8041b993
5
5
  SHA512:
6
- metadata.gz: df1290c2e5878ca6202b1d23d388c08d193360b857c80795fa98caf0bca7bc2d7b84c372a5de5c92a5e88b7dfb092680e896b351b04e70313e030b44541ca547
7
- data.tar.gz: 06e8008ed6dbc71ccfd2743a457968d8222108bcdfe853a18631c6b18e42e216ff9de5a96f36dc1ee44d052fd1d337cea6f01905a0cf3d4b24ae26e48b84ee66
6
+ metadata.gz: b4959bf437934808eb258a11a9b4368b0e43b7e5c3b497a8e889f5ffe53bf520dd55c854a1e536b827ff897ec8997594b84f31dd5e51edff435023cbb09a7bdc
7
+ data.tar.gz: 3097213f35b819504d4b77df88e79a9e3537e8b3899cf4fe1173e9675c81161a18039c85da72ceae65873987021f5bc9ed7b111792e3219d7b13c15b74d5db78
data/.gitignore CHANGED
@@ -7,3 +7,8 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+
11
+
12
+ .DS_Store
13
+ .byebug_history
14
+ live_sql-*
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 sqlite queries change your results as you type. This is a baby gem. It's has a few known bugs, probably way more unknown bugs, not to mention it could use some sexy new features. If you want to contribute either by pointing out bugs, fixing problems. or adding new features, your help would be greatly appreciated!
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
- To use the test database, just download this repo and run bin/console. You can check out how it works with a simple actor, casting, and movie table.
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
- To use on any sqlite3 db, navigate to the folder containing the db, run pry (or irb) and
33
+ ### Using the class
25
34
 
26
- require 'live_sql'
27
- LiveSQL.run_with('your-db-name-here.db')
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
- - Oh god, I already forgot the most recent bug. It'll come back to me....
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,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "live_sql"
5
+
6
+ db_name = ARGV[0]
7
+ options = { db: ARGV[1] && ARGV[1].to_sym }
8
+ LiveSQL.new(db_name, options).run
@@ -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
@@ -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
- :abort
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
- # when "\004"
55
- # "DELETE"
56
- # when "\e[3~"
57
- # "ALTERNATE DELETE"
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
@@ -0,0 +1,11 @@
1
+ require 'sqlite3'
2
+
3
+ class Sqlite3DatabaseConnection < SQLite3::Database
4
+
5
+ def initialize(db)
6
+ super(db)
7
+
8
+ self.results_as_hash = true
9
+ self.type_translation = true
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ module Util
2
+
3
+ def aggregate_func_names
4
+ %w(AVG COUNT FIRST LAST MAX MIN SUM)
5
+ end
6
+ end
@@ -1,3 +1,3 @@
1
1
  module LiveSql
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/live_sql.rb CHANGED
@@ -1,115 +1,123 @@
1
- require "live_sql/version"
2
- require "live_sql/interface"
3
- require 'singleton'
4
- require 'sqlite3'
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
- attr_accessor :result
11
+ include Cursorable
12
+ include Util
21
13
 
22
- def self.run_default
23
- live_sql = LiveSQL.new('./live_sql/default_db/movie.db')
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 self.run_with(db_name)
28
- live_sql = LiveSQL.new(db_name)
29
- live_sql.run
30
- end
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
- @db = QuestionsDatabase.new(db)
35
-
25
+ @limit = 30
36
26
  @string = " "
37
27
  @result = []
38
28
 
39
- @move = :invalid
29
+ @state = :invalid
40
30
  @cursor_pos = 0
41
31
  @errors = []
42
32
  end
43
33
 
34
+
44
35
  def run
45
- while true
36
+ loop do
46
37
  print_display
47
- input = @interface.get_keyboard_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 == :abort
54
- system("clear")
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
- @string.insert(@cursor_pos, input)
69
- @cursor_pos += 1
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 = @result
76
- @result = query_db(@string)
77
- @mode = :valid
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
- @errors << e.message
80
- @result = old_table
81
- @mode = :invalid
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
- if @mode == :invalid
91
- print @string[0...@cursor_pos].colorize(:red)
92
- print @string[@cursor_pos].colorize(background: :cyan, color: :red)
93
- print @string[@cursor_pos + 1..-1].colorize(:red)
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 print_table
105
- tp @result
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 query_db(string)
109
- @db.execute(<<-SQL)
110
- #{string}
111
- LIMIT 30
112
- SQL
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{Interact with sqlite3 db and watch your query as you type.}
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 'colorize'
29
- spec.add_dependency 'table_print'
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.0
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: 2015-10-17 00:00:00.000000000 Z
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: '0'
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: '0'
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: '0'
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: '0'
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: '0'
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: '0'
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
- - bin/console
97
- - bin/setup
112
+ - exe/live_sql
98
113
  - lib/live_sql.rb
99
- - lib/live_sql/default_db/.DS_Store
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: Interact with sqlite3 db and watch your query as you type.
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
@@ -1,7 +0,0 @@
1
- #!/bin/bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
-
5
- bundle install
6
-
7
- # Do any other automated setup that you need to do here
Binary file
Binary file
Binary file