oculus 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|