wewoo 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b9405068406bfb2b2a289835503acf38b8c41a13
4
+ data.tar.gz: caddd5fad7db02dd7711fff21615bec5ae0ceb29
5
+ SHA512:
6
+ metadata.gz: 60c3603e885d9bab087e80053136bc37896b7a018a664da10e15b8f697f366e39e555f30e2da84e83a61606596504e14b88e65733b136fb67dbdc414c2de3703
7
+ data.tar.gz: b8f56a6f2ef9892eaefe802cd3ad81cdd6dcbc9b603c3c4b4bc5479173817bc5c632706f37244e9dcdb6aa8f42505c1fdbbc67d5f13d05f7b4e0aa22a3d5ade1
@@ -0,0 +1,21 @@
1
+ curls.txt
2
+ todo.txt
3
+ *.gem
4
+ *.rbc
5
+ *.swo
6
+ *.swp
7
+ .bundle
8
+ .config
9
+ .yardoc
10
+ Gemfile.lock
11
+ InstalledFiles
12
+ _yardoc
13
+ coverage
14
+ doc/
15
+ lib/bundler/man
16
+ pkg
17
+ rdoc
18
+ spec/reports
19
+ test/tmp
20
+ test/version_tmp
21
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in titanup.gemspec
4
+ gemspec
5
+
6
+ gem 'main', '~> 5.2.0'
@@ -0,0 +1,11 @@
1
+ guard 'bundler' do
2
+ watch('Gemfile')
3
+ watch(/^.+\.gemspec/)
4
+ end
5
+
6
+ guard 'rspec', cli: "--color --format Fuubar --fail-fast --drb", all_after_pass: false, all_on_start: false do
7
+ watch(%r{^spec/.+_spec\.rb$})
8
+ watch(%r{^spec/support/.+\.rb$}) { "spec"}
9
+ watch(%r{^lib/wewoo/(.+)\.rb$}) { |m| "spec/wewoo/#{m[1]}_spec.rb" }
10
+ watch('spec/spec_helper.rb') { "spec" }
11
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 derailed
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,176 @@
1
+ # WeWoo
2
+
3
+ Wewoo is a small wrapper library that provides for graph database
4
+ management using Ruby. Any graph databases that supports the Rexster graph
5
+ server REST API can be integrated with Wewoo.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```
12
+ gem 'wewoo'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ ```
18
+ $ bundle
19
+ ```
20
+
21
+ Or install it yourself as:
22
+
23
+ ```
24
+ $ gem install wewoo
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ Wewoo comes bundled with a REPL console to make for experimentation with the
30
+ graph database using Ruby a joy.
31
+
32
+ ```
33
+ $ wewoo
34
+ ```
35
+
36
+ ### Connecting to a graph
37
+
38
+ Dependending on your Rexster configuration, you will need to specify the
39
+ host and port to tell Wewoo how to connect. The default url is localhost:8182.
40
+ You may optionaly choose to set the configuration in a shell environment variable
41
+ WEWOO_URL ie WEWOO_URL='http://localhost:8185'
42
+
43
+ ```ruby
44
+ # List out all available graphs
45
+ Wewoo::Graph.available_graphs #=> ["test_graph", "my_awesome_graph"]
46
+
47
+ # Connect to an existing graph on localhost:8182
48
+ g = Wewoo::Graph.new( :my_awesome_graph )
49
+ # or...
50
+ g = Wewoo::Graph.new( :my_awesome_graph, 'localhost', 9000 )
51
+
52
+ # List out all vertices
53
+ g.V # => [v(95084), v(95072), v(95076), v(95088), v(95080)]
54
+
55
+ # List out all edges
56
+ g.E # => [e(1lIN-oJG-4K) [95088-created-95076], e(1lIJ-oJy-4K) [95080-created-95084]]
57
+ ```
58
+
59
+ ### Adding a vertex
60
+
61
+ Most graph database don't allow setting an id on a graph element. Wewoo errs on
62
+ letting the graph implementation assign an internal id. It is usually considered
63
+ good practice to keep vertex properties to a minimum. Wewoo provides a special
64
+ property :gid to integrate the graph element with another data source.
65
+ You can leverage :gid to represent a foreign key to another store. Hence :gid must
66
+ be unique. If not set the gid will refer to the underlying graph
67
+ implementation id.
68
+
69
+ ```ruby
70
+ v = g.add_vertex( name: 'Fred', age: 20, active: true, gid: 'user_900' )
71
+ v.id #=> 1234
72
+ v.gid #=> 'user_900'
73
+ v.props #=> {name: 'Fred', age: 20, active: true}
74
+ v.props.age #=> 20
75
+ ```
76
+
77
+ ### Adding an edge
78
+
79
+ ```ruby
80
+ v1 = g.add_vertex( name: 'Fred' )
81
+ v2 = g.add_vertex( name: 'Blee' )
82
+ e = g.add_edge( v1, v2, :friend, timestamp: Time.now )
83
+ e.id #=> 1234
84
+ e.gid #=> 1234
85
+ e.props #=> {"timestamp"=>"2014-03-01 13:55:26 -0700"}
86
+ ```
87
+
88
+ ### Deleting elements
89
+
90
+ Wewoo provides two way to delete a graph element. If you have a handle on the
91
+ instance, you can call destroy on it directly. If not you can remove an element
92
+ by calling the associated remove method on a graph instance using the graph
93
+ element id.
94
+ NOTE: By virtue of a graph database, when deleting a vertex, all associated
95
+ edges will be deleted.
96
+
97
+ ```ruby
98
+ # Delete edge with id 1234
99
+ g.e( 1234 ).destroy
100
+ # or ...
101
+ g.remove_edge( 1234 )
102
+
103
+ # Delete a vertex with id 5678
104
+ g.v( 5678 ).destroy
105
+ # or...
106
+ g.remove_vertex( 5678 )
107
+
108
+ # Clear out the graph
109
+ g.clear
110
+ ```
111
+
112
+ ### Traversing
113
+
114
+ The power of graph database is in traversal. Traversal in Wewoo is made available
115
+ using the [Gremlin](http://gremlindocs.com/) graph api.
116
+
117
+ ```ruby
118
+ # Find all vertices outbound from vertex 1234
119
+ g.v( 1234 ).out #=> [v(4567)]
120
+
121
+ # Find all vertices inbound to vertex 1234
122
+ g.v( 1234 ).in #=> [v(7890), v(7891)]
123
+
124
+ # Find all vertices directly connected to vertex 1234
125
+ g.v( 1234 ).both #=> [v(7890), v(7891), v(4567)]
126
+
127
+ # Find all edges connected to vertex 1234 with labels fred or created
128
+ g.v(1234).bothE( :fred, :created) #=> [e(1lIJ-oJy-4K) [95080-created-95084]]
129
+
130
+ # Find all vertices with name property blee
131
+ g.find_vertices( :name, 'blee' ) #=> [v(1234)]
132
+
133
+ # Find vertex with gid 1234
134
+ g.find_first_vertex( :gid, 1234 ) #=> [v(567)]
135
+
136
+ # Find vertex with id 456
137
+ g.find_vertex( 456 ) #=> [v(456)]
138
+ # or...
139
+ g.v( 456 ) #=> [v(456)]
140
+
141
+ # Paging support...
142
+ g.find_vertices( 'enabled', true, 1, 2 ) #=> [v(7890), v(7891)]
143
+ ```
144
+
145
+ You can access the full gremlin query api using the Wewoo::Graph#query
146
+ method. Wewoo does its best to construct graph elements objects with the returning
147
+ results.
148
+
149
+ ```ruby
150
+ # Find all vertices who's name is fred
151
+ g.query( "g.V.out.groupCount.cap") #=> {v(113420)=>2, v(113416)=>2, v(113412)=>1}
152
+
153
+ # Find all edge with weight < 0.5
154
+ g.q( "g.E.has( 'weight', T.lt, 0.5f)" ) #=> [e(1xSj-tve-2W) [113412-friend-113416]]
155
+ ```
156
+
157
+ ## Releases
158
+
159
+ * 0.1.0 Initial drop
160
+ * 0.1.1 Disable user defined IDs as most graphs disallow
161
+ * 0.1.2 Bug fixes and spec updates
162
+ * 0.1.3 Spec'ed out Gremlin API
163
+ * 0.1.4 Refactor graph elements
164
+ * 0.1.5 Beef up specs + README
165
+
166
+ ## Contributing
167
+
168
+ 1. Fork it
169
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
170
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
171
+ 4. Push to the branch (`git push origin my-new-feature`)
172
+ 5. Create new Pull Request
173
+
174
+ ## License
175
+
176
+ Wewoo is released under the [MIT](http://opensource.org/licenses/MIT) license.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
3
+
4
+ require 'bundler'
5
+ Bundler.require
6
+ require 'wewoo'
7
+ require 'pry'
8
+
9
+ Main {
10
+ def run
11
+ puts "WeWoo Console"
12
+ Pry.config.prompt_name = "WeWoo"
13
+ Pry.start
14
+ end
15
+ }
@@ -0,0 +1,19 @@
1
+ require "wewoo/version"
2
+
3
+ module Wewoo
4
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
5
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
6
+
7
+ def self.configure(&block)
8
+ Configuration.module_eval( &block )
9
+ end
10
+
11
+ def self.require_all_libs_relative_to( fname, dir = nil )
12
+ dir ||= ::File.basename(fname, '.*')
13
+ search_me = ::File.expand_path(
14
+ ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
15
+ Dir.glob(search_me).sort.each { |rb| require rb }
16
+ end
17
+ end
18
+
19
+ Wewoo.require_all_libs_relative_to File.expand_path( "wewoo", Wewoo::LIBPATH )
@@ -0,0 +1,58 @@
1
+ require 'typhoeus'
2
+ require 'json'
3
+ require 'map'
4
+
5
+ module Wewoo
6
+ module Adapter
7
+ module_function
8
+
9
+ class NoDataError < RuntimeError; end
10
+ class InvalidRequestError < RuntimeError; end
11
+
12
+ def get( url, opts={} )
13
+ handle_response( Typhoeus.get( url, opts ) )
14
+ end
15
+
16
+ def post( url, opts={} )
17
+ handle_response( Typhoeus.post( url, opts ) )
18
+ end
19
+
20
+ def put( url, opts={} )
21
+ handle_response( Typhoeus.put( url, opts ) )
22
+ end
23
+
24
+ def delete( url, opts={} )
25
+ handle_response( Typhoeus.delete( url, opts ) )
26
+ end
27
+
28
+ def log( title, message )
29
+ return unless Configuration.debug
30
+
31
+ msg = "[Wewoo] #{title} -- #{message}"
32
+ if Object.const_defined? :Rails
33
+ Rails.logger.info msg
34
+ else
35
+ puts msg
36
+ end
37
+ end
38
+
39
+ def handle_response( resp )
40
+ log "URL", resp.effective_url
41
+
42
+ unless resp.success?
43
+ error = "-- " + JSON.parse( resp.response_body )['message'] rescue ""
44
+ raise InvalidRequestError, "<#{resp.response_code}> " +
45
+ "Failed request:#{resp.effective_url} #{error}"
46
+ end
47
+
48
+ if resp.body.empty? or resp.body == "null"
49
+ raise NoDataError, "No data found at location #{url}"
50
+ end
51
+
52
+ body = JSON.parse( resp.body )
53
+ log "RESP", body
54
+ results = body['results'] || body
55
+ results.is_a?(Hash) ? Map[results] : results
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,24 @@
1
+ module Wewoo
2
+ class Configuration
3
+ def self.debug(value=false)
4
+ @debug ||= value
5
+ end
6
+
7
+ def self.url(host=nil, port=nil)
8
+ @url = nil if host
9
+ @url ||= begin
10
+ url = compute_url( host, port) || ENV['WEWOO_URL'] || default_url
11
+ url.to_s.gsub( %r(/*$), '' )
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def self.compute_url( host, port )
18
+ return nil unless host and port
19
+ "http://#{host}:#{port}"
20
+ end
21
+
22
+ def self.default_url; compute_url( :localhost, 8182 ); end
23
+ end
24
+ end
@@ -0,0 +1,54 @@
1
+ require 'wewoo/element'
2
+
3
+ module Wewoo
4
+ class Edge < Element
5
+ include Adapter
6
+
7
+ attr_accessor :label, :from_id, :to_id
8
+
9
+ def ==( other )
10
+ self.class == other.class and
11
+ self.id == other.id and
12
+ self.from_id == other.from_id and
13
+ self.to_id == other.to_id and
14
+ self.label == other.label and
15
+ self.props == other.props
16
+ end
17
+ alias :eql? :==
18
+ def hash; id; end
19
+
20
+ def get_vertex( direction )
21
+ id = (direction == :in ? to_id : from_id)
22
+ graph.find_vertex( id )
23
+ end
24
+ def in; @in || get_vertex(:in); end
25
+ def out; @out || get_vertex(:out); end
26
+
27
+ def to_s
28
+ "e(#{self.id}) [#{from_id}-#{label}-#{to_id}]"
29
+ end
30
+ alias :inspect :to_s
31
+
32
+ def destroy
33
+ graph.remove_edge( id )
34
+ end
35
+
36
+ private
37
+
38
+ def self.from_hash( graph, hash )
39
+ new( graph,
40
+ hash.delete( '_id' ),
41
+ hash.delete( '_outV' ),
42
+ hash.delete( '_inV' ),
43
+ hash.delete('_label'), hash )
44
+ end
45
+
46
+ def initialize( graph, id, from_id, to_id, label, properties )
47
+ super( graph, id, properties )
48
+
49
+ @from_id = from_id
50
+ @to_id = to_id
51
+ @label = label
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,28 @@
1
+ module Wewoo
2
+ class Element
3
+ attr_reader :id, :graph
4
+ attr_accessor :properties
5
+
6
+ alias :props :properties
7
+
8
+ def gid
9
+ props.gid
10
+ end
11
+
12
+ private
13
+
14
+ def initialize( graph, id, properties )
15
+ @graph = graph
16
+ @id = id
17
+ @properties = to_props( properties )
18
+ @properties[:gid] = id unless props[:gid]
19
+ end
20
+
21
+ def to_props( properties )
22
+ properties.delete( '_type' )
23
+ Map[Hash[properties.map { |k,v|
24
+ [k, ((v.is_a? Hash and v.has_key? 'type') ? v['value'] : v)]
25
+ }]]
26
+ end
27
+ end
28
+ end