expose_db 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2012 Doug Mayer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to
5
+ deal in the Software without restriction, including without limitation the
6
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ ExposeDB
2
+ ========
3
+
4
+ ExposeDB provides raw, read-only access to your data over an HTTP JSON API.
5
+ It uses the excellent [Sinatra][sinatra] and [Sequel][sequel] libraries
6
+ for all of the real work.
7
+
8
+ WARNING: ExposeDB doesn't offer any secure options, and as such is expected
9
+ to be used only in a high-trust network!
10
+
11
+
12
+ Usage
13
+ -----
14
+ ExposeDB is in a very alpha stage of development, but seems to be doing a
15
+ rudimentary job querying for data. Output options are currently limited to
16
+ *all* fields in a table and is only exposed via JSON.
17
+
18
+ expose-db SEQUEL_DATABASE_URI
19
+
20
+ For example:
21
+
22
+ expose-db postgres://user:password@dbhost/my_db
23
+
24
+ Existing endpoints:
25
+ * `/` - Simple query interface
26
+ * `/my_table` - Get all the records in `my_table` as JSON
27
+ * `/my_table?q=ENCODED_QUERY&values[]=2&values[]=bob` - replace ?'s in ENCODED_QUERY with [2, 'bob']
28
+
29
+
30
+ TODO
31
+ ----
32
+ * Tests
33
+ * Improve configuration options
34
+ * HTTP Auth and security
35
+ * Alternate output formats
36
+ * Better documentation
37
+
38
+
39
+ Contributing
40
+ ------------
41
+ * Fork this repository
42
+ * Make your changes and submit a pull request
43
+
44
+
45
+ License
46
+ -------
47
+ Copyright (c) 2012 Doug Mayer. Distributed under the MIT License.
48
+ See `MIT-LICENSE` for further details.
49
+
50
+ [sequel]: http://sequel.rubyforge.org/
51
+ [sinatra]: http://sinatra.restafari.org/
data/bin/expose-db ADDED
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path('../../lib', __FILE__)
4
+
5
+ require 'rubygems'
6
+ require 'optparse'
7
+ require 'expose_db'
8
+
9
+ database_uri = nil
10
+ load_libs = []
11
+ server_port = 4567
12
+
13
+ opts = OptionParser.new do |opts|
14
+ opts.banner = "ExposeDB: Expose your database as an API."
15
+ opts.define_head "Usage: expose-db [options] DATABASE_URI"
16
+ opts.separator ""
17
+ opts.separator "Examples:"
18
+ opts.separator " expose-db postgres://user:password@localhost/my_db"
19
+ opts.separator ""
20
+ opts.separator "For more information see README.md"
21
+ opts.separator ""
22
+ opts.separator "Options:"
23
+
24
+ opts.on "-p", "--port PORT", "Specify the server port number (default: 4567)" do |arg|
25
+ server_port = arg.to_i
26
+ end
27
+
28
+ opts.on "-r", "--require LIB", "require a driver library (ie: pg, sqlite3, etc)" do |arg|
29
+ load_libs << arg
30
+ end
31
+
32
+ opts.on "-v", "--version", "Output version and quit" do
33
+ puts "ExposeDB version #{ExposeDB.version}"
34
+ exit 0
35
+ end
36
+ end
37
+ opts.parse!
38
+
39
+ database_uri = ARGV.shift
40
+
41
+ if database_uri.nil?
42
+ puts "ERROR: Please specify a database URI"
43
+ exit 1
44
+ end
45
+
46
+ load_libs.each { |lib| require lib }
47
+
48
+ db = Sequel.connect(database_uri)
49
+ ExposeDB::App.run!(db, port: server_port)
50
+
51
+ # vim: set ft=ruby:
@@ -0,0 +1,67 @@
1
+ module ExposeDB
2
+ class App < Sinatra::Base
3
+ enable :logging
4
+
5
+ class << self
6
+ attr_reader :db
7
+
8
+ def run!(sequel_db, *args)
9
+ @db = sequel_db
10
+ super(*args)
11
+ end
12
+ end
13
+
14
+ not_found do
15
+ "Unable to find that table or record."
16
+ end
17
+
18
+ error do
19
+ "ERROR: An unhandled error occurred. Check the logs."
20
+ end
21
+
22
+ helpers do
23
+ def db
24
+ self.class.db
25
+ end
26
+
27
+ def ensure_table_exists!
28
+ raise Sinatra::NotFound unless db.table_exists?(table_name)
29
+ end
30
+
31
+ def table_name
32
+ @table_name ||= params[:table].to_sym
33
+ end
34
+
35
+ def json(obj)
36
+ MultiJson.dump obj
37
+ end
38
+ end
39
+
40
+ get '/' do
41
+ erb :index
42
+ end
43
+
44
+ get '/:table' do
45
+ ensure_table_exists!
46
+
47
+ query = params[:q]
48
+ values = params[:values] || []
49
+ dataset = db[table_name]
50
+
51
+ if query && query.length > 0
52
+ dataset = dataset.filter(query, *values)
53
+ end
54
+
55
+ json dataset.to_a
56
+ end
57
+
58
+ get '/:table/:id' do
59
+ ensure_table_exists!
60
+
61
+ id = params[:id]
62
+ dataset = db[table_name]
63
+
64
+ json dataset[id: id]
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,11 @@
1
+ module ExposeDB
2
+ MAJOR = 0
3
+ MINOR = 1
4
+ TINY = 0
5
+
6
+ VERSION = [MAJOR, MINOR, TINY].join('.')
7
+
8
+ def self.version
9
+ VERSION
10
+ end
11
+ end
@@ -0,0 +1,55 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>ExposeDB Console</title>
5
+ <style>
6
+ th {
7
+ vertical-align: top;
8
+ }
9
+ input[type=text] {
10
+ width: 250px;
11
+ }
12
+ </style>
13
+ </head>
14
+ <body>
15
+ <form id="console-form" method="get" action="/">
16
+ <table>
17
+ <tbody>
18
+ <tr>
19
+ <th>Table Name:</th>
20
+ <td><input type="text" id="table-name" value="accounts"/></td>
21
+ </tr>
22
+ <tr>
23
+ <th>Query:</th>
24
+ <td><textarea type="text" name="q" cols="80" rows="5">name = ?</textarea></td>
25
+ </tr>
26
+ <tr>
27
+ <th>Values:</th>
28
+ <td>
29
+ <% 1.upto(6) do |n| %>
30
+ <input type="text" name="values[]" value="<%= n == 1 ? 'Rowe LLC' : '' %>"/>
31
+ <br/>
32
+ <% end %>
33
+ </td>
34
+ </tr>
35
+ <tr>
36
+ <th></th>
37
+ <td><input type="submit"/></td>
38
+ </tr>
39
+ </tbody>
40
+ </table>
41
+ </form>
42
+
43
+ <script>
44
+ (function() {
45
+ var form = document.getElementById('console-form'),
46
+ tableInput = document.getElementById('table-name');
47
+
48
+ form.onsubmit = function() {
49
+ form.action = "/" + tableInput.value;
50
+ return true;
51
+ };
52
+ })();
53
+ </script>
54
+ </body>
55
+ </html>
data/lib/expose_db.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'multi_json'
2
+ require 'sequel'
3
+ require 'sinatra/base'
4
+
5
+ require 'expose_db/version'
6
+ require 'expose_db/app'
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: expose_db
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Doug Mayer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sinatra
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: sequel
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: multi_json
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Expose your database over an API.
63
+ email: doxavore@gmail.com
64
+ executables:
65
+ - expose-db
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - MIT-LICENSE
70
+ - README.md
71
+ - bin/expose-db
72
+ - lib/expose_db.rb
73
+ - lib/expose_db/version.rb
74
+ - lib/expose_db/app.rb
75
+ - lib/expose_db/views/index.erb
76
+ homepage:
77
+ licenses: []
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: 1.9.1
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project: expose_db
96
+ rubygems_version: 1.8.23
97
+ signing_key:
98
+ specification_version: 3
99
+ summary: Expose your database over an API.
100
+ test_files: []