oculus 0.9.2 → 0.9.3
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.
- data/CHANGELOG.md +34 -0
- data/README.md +1 -1
- data/Rakefile +3 -3
- data/bin/oculus +2 -1
- data/features/support/env.rb +5 -1
- data/lib/oculus.rb +7 -6
- data/lib/oculus/query.rb +2 -0
- data/lib/oculus/server/public/css/style.css +15 -0
- data/lib/oculus/server/public/js/application.js +1 -1
- data/lib/oculus/server/views/index.erb +6 -2
- data/lib/oculus/server/views/show.erb +8 -2
- data/lib/oculus/storage.rb +14 -2
- data/lib/oculus/storage/file_store.rb +2 -2
- data/lib/oculus/storage/sequel_store.rb +108 -0
- data/lib/oculus/version.rb +1 -1
- data/oculus.gemspec +1 -0
- data/spec/connection/postgres_spec.rb +1 -1
- data/spec/connection_spec.rb +2 -2
- data/spec/{file_store_spec.rb → storage_spec.rb} +85 -48
- metadata +21 -3
data/CHANGELOG.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
## 0.9.3 (June 19, 2012)
|
2
|
+
|
3
|
+
Breaking Changes:
|
4
|
+
|
5
|
+
* `Oculus.cache_path` removed, please use `Oculus.storage_options[:cache_path]`
|
6
|
+
instead.
|
7
|
+
|
8
|
+
Features:
|
9
|
+
|
10
|
+
* Support for database-backed result storage (SequelStore). Usage:
|
11
|
+
|
12
|
+
Oculus.storage_options = {
|
13
|
+
adapter: 'sequel',
|
14
|
+
uri: 'mysql://localhost/your_db',
|
15
|
+
table: 'your_table' # default: oculus
|
16
|
+
}
|
17
|
+
|
18
|
+
*Jonathan Rudenberg*
|
19
|
+
|
20
|
+
* Hover actions for the SQL statement on the query detail page, to send it to
|
21
|
+
the editor or rerun it.
|
22
|
+
|
23
|
+
* Command-R/Ctrl-R executes the query instead of reloading the page in most
|
24
|
+
browsers.
|
25
|
+
|
26
|
+
Bugfixes:
|
27
|
+
|
28
|
+
* Escape special characters in query results.
|
29
|
+
|
30
|
+
*Jonathan Rudenberg*
|
31
|
+
|
32
|
+
## 0.9.2 (June 2, 2012)
|
33
|
+
|
34
|
+
Initial public release
|
data/README.md
CHANGED
@@ -10,7 +10,7 @@ and the results they returned, so your research is always at hand, easy to share
|
|
10
10
|
and easy to repeat or reproduce in the future.
|
11
11
|
|
12
12
|
**Oculus will not prevent you from doing stupid things! I recommend using a
|
13
|
-
readonly
|
13
|
+
readonly SQL account.**
|
14
14
|
|
15
15
|
## Installation
|
16
16
|
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ require 'pg'
|
|
9
9
|
desc 'Run RSpec tests'
|
10
10
|
RSpec::Core::RakeTask.new(:spec) do |task|
|
11
11
|
task.rspec_opts = %w[--color --format documentation]
|
12
|
-
task.pattern = 'spec
|
12
|
+
task.pattern = 'spec/**/*_spec.rb'
|
13
13
|
end
|
14
14
|
|
15
15
|
desc 'Run Cucumber features'
|
@@ -44,12 +44,12 @@ namespace :db do
|
|
44
44
|
|
45
45
|
# Postgres
|
46
46
|
#
|
47
|
-
client = PG::Connection.new(:host => "localhost", :dbname => "postgres")
|
47
|
+
client = PG::Connection.new(:host => "localhost", :user => "postgres", :dbname => "postgres")
|
48
48
|
client.query "DROP DATABASE IF EXISTS oculus_test"
|
49
49
|
client.query "CREATE DATABASE oculus_test"
|
50
50
|
client.close
|
51
51
|
|
52
|
-
client = PG::Connection.new(:host => "localhost", :dbname => "oculus_test")
|
52
|
+
client = PG::Connection.new(:host => "localhost", :user => "postgres", :dbname => "oculus_test")
|
53
53
|
client.query %[
|
54
54
|
CREATE TABLE oculus_users (
|
55
55
|
id INT NOT NULL UNIQUE,
|
data/bin/oculus
CHANGED
@@ -31,6 +31,7 @@ Vegas::Runner.new(Oculus::Server, 'oculus') do |runner, opts, app|
|
|
31
31
|
Oculus.connection_options[:adapter] = adapter
|
32
32
|
end
|
33
33
|
opts.on("-d", "--data DIRECTORY", "Data cache path (default: tmp/data)") do |path|
|
34
|
-
Oculus.
|
34
|
+
Oculus.storage_options[:adapter] = "file"
|
35
|
+
Oculus.storage_options[:cache_path] = path
|
35
36
|
end
|
36
37
|
end
|
data/features/support/env.rb
CHANGED
@@ -7,7 +7,11 @@ require 'capybara/cucumber'
|
|
7
7
|
Capybara.app = Oculus::Server
|
8
8
|
Capybara.default_wait_time = 10
|
9
9
|
|
10
|
-
Oculus.
|
10
|
+
Oculus.storage_options = {
|
11
|
+
:adapter => 'file',
|
12
|
+
:cache_path => 'tmp/test_cache'
|
13
|
+
}
|
14
|
+
|
11
15
|
Oculus.connection_options = {
|
12
16
|
:adapter => 'mysql',
|
13
17
|
:host => 'localhost',
|
data/lib/oculus.rb
CHANGED
@@ -7,17 +7,18 @@ module Oculus
|
|
7
7
|
extend self
|
8
8
|
|
9
9
|
DEFAULT_CONNECTION_OPTIONS = { :adapter => 'mysql', :host => 'localhost' }
|
10
|
+
DEFAULT_STORAGE_OPTIONS = { :adapter => 'file', :host => 'localhost' }
|
10
11
|
|
11
|
-
attr_writer :
|
12
|
+
attr_writer :data_store
|
12
13
|
|
13
|
-
def
|
14
|
-
@
|
14
|
+
def data_store
|
15
|
+
@data_store ||= Oculus::Storage.create(Oculus.storage_options)
|
15
16
|
end
|
16
17
|
|
17
|
-
attr_writer :
|
18
|
+
attr_writer :storage_options
|
18
19
|
|
19
|
-
def
|
20
|
-
@
|
20
|
+
def storage_options
|
21
|
+
@storage_options ||= DEFAULT_STORAGE_OPTIONS
|
21
22
|
end
|
22
23
|
|
23
24
|
attr_writer :connection_options
|
data/lib/oculus/query.rb
CHANGED
@@ -118,6 +118,21 @@ button.starred .unstarred-contents {
|
|
118
118
|
display: none;
|
119
119
|
}
|
120
120
|
|
121
|
+
#query-sql-container {
|
122
|
+
position: relative;
|
123
|
+
}
|
124
|
+
|
125
|
+
#query-sql-actions {
|
126
|
+
display:none;
|
127
|
+
position: absolute;
|
128
|
+
top: 4px;
|
129
|
+
right: 5px;
|
130
|
+
}
|
131
|
+
|
132
|
+
#query-sql-container:hover #query-sql-actions {
|
133
|
+
display: block;
|
134
|
+
}
|
135
|
+
|
121
136
|
#loading .cancel-container {
|
122
137
|
float: right;
|
123
138
|
margin: -1px -26px 0 0;
|
@@ -165,7 +165,7 @@ QueryEditor.prototype.initCodeMirror = function() {
|
|
165
165
|
QueryEditor.prototype.bindEvents = function() {
|
166
166
|
var self = this;
|
167
167
|
$(document).on('keydown', 'form', function(e) {
|
168
|
-
if ((e.keyCode === 13
|
168
|
+
if ((e.keyCode === 13 || e.keyCode === 82) && (e.ctrlKey || e.metaKey)) {
|
169
169
|
e.preventDefault();
|
170
170
|
|
171
171
|
// CodeMirror normally saves itself automatically, but since there is no
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
<form id="query-form" method="POST" action="/queries">
|
4
4
|
<div id="editor-container">
|
5
|
-
<textarea name="query" id="query-field"
|
5
|
+
<textarea name="query" id="query-field"><%= h(params[:q]) %></textarea>
|
6
6
|
</div>
|
7
7
|
<div class="form-actions">
|
8
8
|
<input type="submit" class="btn" name="submit" value="Run" />
|
@@ -86,7 +86,7 @@
|
|
86
86
|
var row = $('<tr></tr>');
|
87
87
|
|
88
88
|
for (var j = 0; j < result.length; j++) {
|
89
|
-
row.append('<td>'
|
89
|
+
row.append($('<td></td>').text(result[j]));
|
90
90
|
}
|
91
91
|
|
92
92
|
container.append(row);
|
@@ -102,4 +102,8 @@
|
|
102
102
|
});
|
103
103
|
|
104
104
|
editor.focus();
|
105
|
+
|
106
|
+
<% if params[:run] %>
|
107
|
+
editor.submit();
|
108
|
+
<% end %>
|
105
109
|
</script>
|
@@ -38,7 +38,13 @@
|
|
38
38
|
<input type="submit" class="btn" name="submit" value="Save" />
|
39
39
|
</form>
|
40
40
|
|
41
|
-
<
|
41
|
+
<div id="query-sql-container">
|
42
|
+
<div id="query-sql-actions">
|
43
|
+
<a class="btn btn-mini" href="/?q=<%= URI.escape(@query.query) %>"><i class="icon-edit"></i> Send to editor</a>
|
44
|
+
<a class="btn btn-mini" href="/?q=<%= URI.escape(@query.query) %>&run=1"><i class="icon-repeat"></i> Rerun</a>
|
45
|
+
</div>
|
46
|
+
<pre class="cm-s-default"><%= @query.query %></pre>
|
47
|
+
</div>
|
42
48
|
|
43
49
|
<div id="loading">
|
44
50
|
<div class="alert">
|
@@ -96,7 +102,7 @@
|
|
96
102
|
var row = $('<tr></tr>');
|
97
103
|
|
98
104
|
for (var j = 0; j < result.length; j++) {
|
99
|
-
row.append('<td>'
|
105
|
+
row.append($('<td></td>').text(result[j]));
|
100
106
|
}
|
101
107
|
|
102
108
|
container.append(row);
|
data/lib/oculus/storage.rb
CHANGED
@@ -1,7 +1,19 @@
|
|
1
|
-
require 'oculus/storage/file_store'
|
2
|
-
|
3
1
|
module Oculus
|
4
2
|
module Storage
|
5
3
|
class QueryNotFound < RuntimeError; end
|
4
|
+
class AdapterNotFound < StandardError; end
|
5
|
+
|
6
|
+
def self.create(options)
|
7
|
+
case options[:adapter]
|
8
|
+
when 'file'
|
9
|
+
require 'oculus/storage/file_store'
|
10
|
+
FileStore
|
11
|
+
when 'sequel'
|
12
|
+
require 'oculus/storage/sequel_store'
|
13
|
+
SequelStore
|
14
|
+
else
|
15
|
+
raise AdapterNotFound, "#{options[:adapter]} is not currently implemented. You should write it!"
|
16
|
+
end.new(options)
|
17
|
+
end
|
6
18
|
end
|
7
19
|
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'sequel'
|
2
|
+
require 'csv'
|
3
|
+
|
4
|
+
module Oculus
|
5
|
+
module Storage
|
6
|
+
class SequelStore
|
7
|
+
attr_reader :table_name
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
raise ArgumentError, "URI is required" unless options[:uri]
|
11
|
+
@uri = options[:uri]
|
12
|
+
@table_name = options[:table] || :oculus
|
13
|
+
create_table
|
14
|
+
end
|
15
|
+
|
16
|
+
def with_db
|
17
|
+
db = Sequel.connect(@uri, :encoding => 'utf8')
|
18
|
+
result = yield db
|
19
|
+
db.disconnect
|
20
|
+
result
|
21
|
+
end
|
22
|
+
|
23
|
+
def with_table
|
24
|
+
with_db { |db| yield db.from(@table_name) }
|
25
|
+
end
|
26
|
+
|
27
|
+
def all_queries
|
28
|
+
with_table do |table|
|
29
|
+
to_queries table.order(:id.desc)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def starred_queries
|
34
|
+
with_table do |table|
|
35
|
+
to_queries table.where(:starred => true).order(:id.desc)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def save_query(query)
|
40
|
+
attrs = serialize(query)
|
41
|
+
with_table do |table|
|
42
|
+
if query.id
|
43
|
+
table.where(:id => query.id).update(attrs)
|
44
|
+
else
|
45
|
+
query.id = table.insert(attrs)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def load_query(id)
|
51
|
+
with_table do |table|
|
52
|
+
if query = table.where(:id => id).first
|
53
|
+
deserialize query
|
54
|
+
else
|
55
|
+
raise QueryNotFound, id
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def delete_query(id)
|
61
|
+
with_table do |table|
|
62
|
+
raise ArgumentError unless id.to_i > 0
|
63
|
+
raise QueryNotFound, id unless table.where(:id => id).delete == 1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_table
|
68
|
+
with_db do |db|
|
69
|
+
db.create_table?(table_name) do
|
70
|
+
primary_key :id
|
71
|
+
Integer :thread_id
|
72
|
+
String :name
|
73
|
+
String :author
|
74
|
+
String :query
|
75
|
+
String :results
|
76
|
+
Time :started_at
|
77
|
+
Time :finished_at
|
78
|
+
TrueClass :starred
|
79
|
+
String :error
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def drop_table
|
85
|
+
with_db { |db| db.drop_table(table_name) }
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def to_queries(rows)
|
91
|
+
rows.map { |r| Query.new deserialize(r) }
|
92
|
+
end
|
93
|
+
|
94
|
+
def deserialize(row)
|
95
|
+
row[:results] = row[:results] ? CSV.new(row[:results]).to_a : []
|
96
|
+
row.delete(:error) unless row[:error]
|
97
|
+
row
|
98
|
+
end
|
99
|
+
|
100
|
+
def serialize(query)
|
101
|
+
attrs = query.attributes
|
102
|
+
attrs[:starred] ||= false
|
103
|
+
attrs[:results] = query.to_csv if query.results
|
104
|
+
attrs
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/lib/oculus/version.rb
CHANGED
data/oculus.gemspec
CHANGED
@@ -2,7 +2,7 @@ require 'oculus'
|
|
2
2
|
require 'oculus/connection/postgres'
|
3
3
|
|
4
4
|
describe Oculus::Connection::Postgres do
|
5
|
-
subject { Oculus::Connection::Postgres.new(:host => 'localhost', :database => 'oculus_test') }
|
5
|
+
subject { Oculus::Connection::Postgres.new(:host => 'localhost', :username => 'postgres', :database => 'oculus_test') }
|
6
6
|
|
7
7
|
it "fetches a result set" do
|
8
8
|
subject.execute("SELECT * FROM oculus_users").should == [['id', 'name'],
|
data/spec/connection_spec.rb
CHANGED
@@ -18,14 +18,14 @@ describe Oculus::Connection do
|
|
18
18
|
|
19
19
|
describe "postgres adapter option" do
|
20
20
|
it "returns a new instance of Postgres adapter" do
|
21
|
-
adapter = Oculus::Connection.connect adapter: 'postgres', database: 'oculus_test'
|
21
|
+
adapter = Oculus::Connection.connect adapter: 'postgres', database: 'oculus_test', :host => 'localhost', :username => 'postgres'
|
22
22
|
adapter.should be_an_instance_of Oculus::Connection::Postgres
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
describe "pg adapter alias" do
|
27
27
|
it "returns a new instance of Postgres adapter" do
|
28
|
-
adapter = Oculus::Connection.connect adapter: 'pg', database: 'oculus_test'
|
28
|
+
adapter = Oculus::Connection.connect adapter: 'pg', database: 'oculus_test', :host => 'localhost', :username => 'postgres'
|
29
29
|
adapter.should be_an_instance_of Oculus::Connection::Postgres
|
30
30
|
end
|
31
31
|
end
|
@@ -1,8 +1,28 @@
|
|
1
1
|
require 'oculus'
|
2
|
+
require 'oculus/storage/file_store'
|
3
|
+
require 'oculus/storage/sequel_store'
|
4
|
+
|
5
|
+
describe Oculus::Storage do
|
6
|
+
describe "#create" do
|
7
|
+
it "should initialize FileStore" do
|
8
|
+
Oculus::Storage::FileStore.should_receive(:new)
|
9
|
+
Oculus::Storage.create(:adapter => 'file')
|
10
|
+
end
|
2
11
|
|
3
|
-
|
4
|
-
|
12
|
+
it "should initialize SequelStore" do
|
13
|
+
Oculus::Storage::SequelStore.should_receive(:new)
|
14
|
+
Oculus::Storage.create(:adapter => 'sequel')
|
15
|
+
end
|
5
16
|
|
17
|
+
it "should forward its options to the storage" do
|
18
|
+
opts = { :adapter => 'file' }
|
19
|
+
Oculus::Storage::FileStore.should_receive(:new).with(opts)
|
20
|
+
Oculus::Storage.create(opts)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
shared_examples "storage" do |subject|
|
6
26
|
let(:query) do
|
7
27
|
Oculus::Query.new(:name => "All users",
|
8
28
|
:query => "SELECT * FROM oculus_users",
|
@@ -27,18 +47,10 @@ describe Oculus::Storage::FileStore do
|
|
27
47
|
:error => "You have an error in your SQL syntax")
|
28
48
|
end
|
29
49
|
|
30
|
-
|
31
|
-
FileUtils.mkdir_p('tmp/test_cache')
|
32
|
-
end
|
33
|
-
|
34
|
-
after do
|
35
|
-
FileUtils.rm_r('tmp/test_cache')
|
36
|
-
end
|
37
|
-
|
38
|
-
it "round-trips a query with no results to disk" do
|
50
|
+
it "round-trips a query with no results" do
|
39
51
|
query = Oculus::Query.new(:name => "Unfinished query", :author => "Me")
|
40
|
-
|
41
|
-
|
52
|
+
storage.save_query(query)
|
53
|
+
storage.load_query(query.id).should == {
|
42
54
|
:id => query.id,
|
43
55
|
:name => query.name,
|
44
56
|
:author => query.author,
|
@@ -51,9 +63,9 @@ describe Oculus::Storage::FileStore do
|
|
51
63
|
}
|
52
64
|
end
|
53
65
|
|
54
|
-
it "round-trips a query with an error
|
55
|
-
|
56
|
-
|
66
|
+
it "round-trips a query with an error" do
|
67
|
+
storage.save_query(broken_query)
|
68
|
+
storage.load_query(broken_query.id).should == {
|
57
69
|
:id => broken_query.id,
|
58
70
|
:name => broken_query.name,
|
59
71
|
:error => broken_query.error,
|
@@ -67,9 +79,9 @@ describe Oculus::Storage::FileStore do
|
|
67
79
|
}
|
68
80
|
end
|
69
81
|
|
70
|
-
it "round-trips a query
|
71
|
-
|
72
|
-
|
82
|
+
it "round-trips a query" do
|
83
|
+
storage.save_query(query)
|
84
|
+
storage.load_query(query.id).should == {
|
73
85
|
:id => query.id,
|
74
86
|
:name => query.name,
|
75
87
|
:author => query.author,
|
@@ -83,75 +95,100 @@ describe Oculus::Storage::FileStore do
|
|
83
95
|
end
|
84
96
|
|
85
97
|
it "doesn't overwrite an existing query id when saving" do
|
86
|
-
|
98
|
+
storage.save_query(query)
|
87
99
|
original_id = query.id
|
88
|
-
|
100
|
+
storage.save_query(query)
|
89
101
|
query.id.should == original_id
|
90
102
|
end
|
91
103
|
|
92
104
|
it "raises QueryNotFound for missing queries" do
|
93
105
|
lambda {
|
94
|
-
|
106
|
+
storage.load_query(39827493)
|
95
107
|
}.should raise_error(Oculus::Storage::QueryNotFound)
|
96
108
|
end
|
97
109
|
|
98
110
|
it "fetches all queries in reverse chronological order" do
|
99
|
-
|
100
|
-
|
111
|
+
storage.save_query(query)
|
112
|
+
storage.save_query(other_query)
|
101
113
|
|
102
|
-
|
114
|
+
storage.all_queries.map(&:results).should == [other_query.results, query.results]
|
103
115
|
end
|
104
116
|
|
105
117
|
it "fetches starred queries" do
|
106
118
|
query.starred = true
|
107
|
-
|
108
|
-
|
119
|
+
storage.save_query(query)
|
120
|
+
storage.save_query(other_query)
|
109
121
|
|
110
|
-
results =
|
122
|
+
results = storage.starred_queries
|
111
123
|
results.map(&:results).should == [query.results]
|
112
124
|
results.first.starred.should be true
|
113
125
|
end
|
114
126
|
|
115
127
|
it "deletes queries" do
|
116
|
-
|
117
|
-
|
118
|
-
|
128
|
+
storage.save_query(query)
|
129
|
+
storage.load_query(query.id)[:name].should == query.name
|
130
|
+
storage.delete_query(query.id)
|
119
131
|
|
120
132
|
lambda {
|
121
|
-
|
133
|
+
storage.load_query(query.id)
|
122
134
|
}.should raise_error(Oculus::Storage::QueryNotFound)
|
123
135
|
end
|
124
136
|
|
125
137
|
it "raises QueryNotFound when deleting a nonexistent query" do
|
126
138
|
lambda {
|
127
|
-
|
139
|
+
storage.delete_query(10983645)
|
128
140
|
}.should raise_error(Oculus::Storage::QueryNotFound)
|
129
141
|
end
|
130
142
|
|
131
143
|
it "sanitizes query IDs" do
|
132
144
|
lambda {
|
133
|
-
|
145
|
+
storage.delete_query('..')
|
134
146
|
}.should raise_error(ArgumentError)
|
135
147
|
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe Oculus::Storage::FileStore do
|
151
|
+
it_behaves_like "storage" do
|
152
|
+
let(:storage) { Oculus::Storage::FileStore.new(:cache_path => 'tmp/test_cache') }
|
136
153
|
|
137
|
-
context "when cache dir does not exist (like for a new install)" do
|
138
154
|
before do
|
155
|
+
FileUtils.mkdir_p('tmp/test_cache')
|
156
|
+
end
|
157
|
+
|
158
|
+
after do
|
139
159
|
FileUtils.rm_r('tmp/test_cache')
|
140
160
|
end
|
141
161
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
162
|
+
context "when cache dir does not exist (like for a new install)" do
|
163
|
+
before do
|
164
|
+
FileUtils.rm_r('tmp/test_cache')
|
165
|
+
end
|
166
|
+
|
167
|
+
it "round-trips a query to disk" do
|
168
|
+
storage.save_query(query)
|
169
|
+
storage.load_query(query.id).should == {
|
170
|
+
:id => query.id,
|
171
|
+
:name => query.name,
|
172
|
+
:author => query.author,
|
173
|
+
:query => query.query,
|
174
|
+
:results => query.results,
|
175
|
+
:thread_id => query.thread_id,
|
176
|
+
:starred => false,
|
177
|
+
:started_at => query.started_at,
|
178
|
+
:finished_at => query.finished_at
|
179
|
+
}
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe Oculus::Storage::SequelStore do
|
186
|
+
it_behaves_like "storage" do
|
187
|
+
let(:storage) { Oculus::Storage::SequelStore.new(:uri => 'postgres://postgres@localhost/oculus_test') }
|
188
|
+
|
189
|
+
before do
|
190
|
+
storage.drop_table
|
191
|
+
storage.create_table
|
155
192
|
end
|
156
193
|
end
|
157
194
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oculus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.3
|
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: 2012-06-
|
12
|
+
date: 2012-06-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sinatra
|
@@ -139,6 +139,22 @@ dependencies:
|
|
139
139
|
- - ! '>='
|
140
140
|
- !ruby/object:Gem::Version
|
141
141
|
version: 0.13.2
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: sequel
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '3'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '3'
|
142
158
|
description: Oculus is a web-based logging SQL client. It keeps a history of your
|
143
159
|
queries and the results they returned, so your research is always at hand, easy
|
144
160
|
to share and easy to repeat or reproduce in the future.
|
@@ -151,6 +167,7 @@ extra_rdoc_files: []
|
|
151
167
|
files:
|
152
168
|
- .gitignore
|
153
169
|
- .travis.yml
|
170
|
+
- CHANGELOG.md
|
154
171
|
- Gemfile
|
155
172
|
- LICENSE
|
156
173
|
- README.md
|
@@ -186,14 +203,15 @@ files:
|
|
186
203
|
- lib/oculus/server/views/starred.erb
|
187
204
|
- lib/oculus/storage.rb
|
188
205
|
- lib/oculus/storage/file_store.rb
|
206
|
+
- lib/oculus/storage/sequel_store.rb
|
189
207
|
- lib/oculus/version.rb
|
190
208
|
- oculus.gemspec
|
191
209
|
- spec/connection/mysql2_spec.rb
|
192
210
|
- spec/connection/postgres_spec.rb
|
193
211
|
- spec/connection_spec.rb
|
194
|
-
- spec/file_store_spec.rb
|
195
212
|
- spec/query_presenter_spec.rb
|
196
213
|
- spec/query_spec.rb
|
214
|
+
- spec/storage_spec.rb
|
197
215
|
homepage: http://oculusapp.com
|
198
216
|
licenses: []
|
199
217
|
post_install_message:
|