rdf-mapper 0.0.1
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/README.rdoc +188 -0
- data/UNLICENSE +25 -0
- data/VERSION +1 -0
- data/lib/lib/adapters/base.rb +83 -0
- data/lib/lib/adapters/rails.rb +307 -0
- data/lib/lib/adapters/rest.rb +45 -0
- data/lib/lib/adapters/sparql.rb +105 -0
- data/lib/lib/associations/base.rb +95 -0
- data/lib/lib/associations/belongs_to.rb +64 -0
- data/lib/lib/associations/has_and_belongs.rb +17 -0
- data/lib/lib/associations/has_many.rb +147 -0
- data/lib/lib/associations/has_one.rb +17 -0
- data/lib/lib/model/association.rb +59 -0
- data/lib/lib/model/attribute.rb +186 -0
- data/lib/lib/model/base.rb +623 -0
- data/lib/lib/model/output.rb +70 -0
- data/lib/lib/model/property.rb +78 -0
- data/lib/lib/scope/collection.rb +165 -0
- data/lib/lib/scope/condition.rb +132 -0
- data/lib/lib/scope/loader.rb +111 -0
- data/lib/lib/scope/model.rb +129 -0
- data/lib/lib/scope/query.rb +281 -0
- data/lib/lib/util/http.rb +66 -0
- data/lib/lib/util/logger.rb +68 -0
- data/lib/rdf-mapper.rb +15 -0
- metadata +141 -0
@@ -0,0 +1,281 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
module Scope
|
3
|
+
##
|
4
|
+
# [-]
|
5
|
+
##
|
6
|
+
class Query
|
7
|
+
|
8
|
+
include RDFMapper::Logger
|
9
|
+
|
10
|
+
attr_reader :cls
|
11
|
+
attr_reader :conditions
|
12
|
+
attr_reader :sql # Remaining unparsed conditions
|
13
|
+
|
14
|
+
def initialize(cls, options = {})
|
15
|
+
@options = options
|
16
|
+
@conditions = []
|
17
|
+
@options[:include] ||= []
|
18
|
+
@cls = cls
|
19
|
+
@modifier = :and
|
20
|
+
|
21
|
+
case @options[:conditions]
|
22
|
+
when Hash then parse_hash
|
23
|
+
when Array then parse_array
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# [-]
|
30
|
+
##
|
31
|
+
def modifier
|
32
|
+
@modifier.to_s.upcase
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# [-]
|
37
|
+
##
|
38
|
+
def strict?
|
39
|
+
@modifier == :and
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# [-]
|
44
|
+
##
|
45
|
+
def offset
|
46
|
+
@options[:offset] || 0
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# [-]
|
51
|
+
##
|
52
|
+
def limit
|
53
|
+
@options[:limit]
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# [-]
|
58
|
+
##
|
59
|
+
def include
|
60
|
+
@options[:include]
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# [-]
|
65
|
+
##
|
66
|
+
def include!(name)
|
67
|
+
@options[:include] << name
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# @todo. Not implemented
|
72
|
+
##
|
73
|
+
def order
|
74
|
+
nil
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# [-]
|
79
|
+
##
|
80
|
+
def [](name)
|
81
|
+
@conditions.select do |condition|
|
82
|
+
condition.name == name
|
83
|
+
end.map do |condition|
|
84
|
+
condition.value
|
85
|
+
end.first
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# Follows the same logic as `to_a` method and returns a Hash instead
|
90
|
+
# of an Array (:name => { :eq => value, :value => value }).
|
91
|
+
#
|
92
|
+
# @see to_a
|
93
|
+
#
|
94
|
+
# @param [Array<Symbol>] required association attributes that should be preloaded
|
95
|
+
# @return [Hash]
|
96
|
+
##
|
97
|
+
def to_hash(required = [])
|
98
|
+
Hash[to_a(required).map do |name, eq, value|
|
99
|
+
[name, { :eq => eq, :value => value }]
|
100
|
+
end]
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Returns an Array of search conditions. Will preload any associated
|
105
|
+
# models if their properties are undefined (e.g. in case of REST and
|
106
|
+
# SPARQL models are required to have `id` as RDF::URI, and `rails_id`
|
107
|
+
# in case of Rails).
|
108
|
+
#
|
109
|
+
# Note that any foreign-key associations will be renamed. For instance:
|
110
|
+
# :employee_id => #<RDF::URI(http://example.org/people/1354534)>
|
111
|
+
# is transformed into
|
112
|
+
# :employee => #<RDFMapper::Model:217132856>
|
113
|
+
#
|
114
|
+
# @param [Array<Symbol>] required association attributes that should be preloaded
|
115
|
+
# @return [Array<Condition>]
|
116
|
+
##
|
117
|
+
def to_a(required = [])
|
118
|
+
unless required.kind_of? Array
|
119
|
+
required = [required]
|
120
|
+
end
|
121
|
+
@conditions.each do |condition|
|
122
|
+
condition.check(required)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
##
|
127
|
+
# [-]
|
128
|
+
##
|
129
|
+
def to_triples
|
130
|
+
to_statements.map do |statement|
|
131
|
+
[ statement[:subject], statement[:predicate], statement[:object] ]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
##
|
136
|
+
# [-]
|
137
|
+
##
|
138
|
+
def to_statements
|
139
|
+
target = if self[:id].nil?
|
140
|
+
RDF::Query::Variable.new
|
141
|
+
else
|
142
|
+
RDF::URI.new(self[:id].to_s)
|
143
|
+
end
|
144
|
+
[{ :subject => target,
|
145
|
+
:predicate => RDF.type,
|
146
|
+
:object => @cls.type
|
147
|
+
}] + to_a(:id).map do |condition|
|
148
|
+
condition.to_statements(target)
|
149
|
+
end.flatten.compact
|
150
|
+
end
|
151
|
+
|
152
|
+
##
|
153
|
+
# [-]
|
154
|
+
##
|
155
|
+
def flatten(required = [])
|
156
|
+
to_a(required).map do |condition|
|
157
|
+
(condition.class == self.class) ? condition.flatten(required) : condition
|
158
|
+
end.flatten
|
159
|
+
end
|
160
|
+
|
161
|
+
alias_method :check, :to_a
|
162
|
+
|
163
|
+
##
|
164
|
+
# Developer-friendly representation of the instance
|
165
|
+
#
|
166
|
+
# @return [String]
|
167
|
+
##
|
168
|
+
def inspect #nodoc
|
169
|
+
"#<Query%s>" % to_a.map do |condition|
|
170
|
+
condition.inspect
|
171
|
+
end.inspect
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
private
|
176
|
+
|
177
|
+
def add_condition(name, value, eq = '=') #nodoc
|
178
|
+
if value.kind_of? Array and value.empty?
|
179
|
+
raise RuntimeError, 'No value assigned to `%s`' % name
|
180
|
+
end
|
181
|
+
@conditions << RDFMapper::Scope::Condition.new(@cls, name, value, eq)
|
182
|
+
end
|
183
|
+
|
184
|
+
##
|
185
|
+
# [-]
|
186
|
+
##
|
187
|
+
def parse_array #nodoc
|
188
|
+
@ary = @options[:conditions][1,255]
|
189
|
+
while (read_subquery || read_collection || read_value || read_modifier); end
|
190
|
+
end
|
191
|
+
|
192
|
+
##
|
193
|
+
# [-]
|
194
|
+
##
|
195
|
+
def read_collection #nodoc
|
196
|
+
full, name = match(/([^\s]+)[\s]*IN[\s]+\(\?\)[\s]*/)
|
197
|
+
return nil if full.nil?
|
198
|
+
add_condition(name, @ary.shift)
|
199
|
+
end
|
200
|
+
|
201
|
+
##
|
202
|
+
# [-]
|
203
|
+
##
|
204
|
+
def read_modifier #nodoc
|
205
|
+
full, modifier = match(/[\s]*(AND|OR)/)
|
206
|
+
return nil if full.nil?
|
207
|
+
@modifier = (modifier == 'OR') ? :or : :and
|
208
|
+
end
|
209
|
+
|
210
|
+
##
|
211
|
+
# [-]
|
212
|
+
##
|
213
|
+
def read_value #nodoc
|
214
|
+
full, name, eq, value, literal, digit = match(/([^\s]+)[\s]*([=><]+)\s*("([\s\w]*)"|([\d\.]+))/)
|
215
|
+
return nil if full.nil?
|
216
|
+
value = literal.nil? ? digit.to_f : literal.to_s
|
217
|
+
add_condition(name, value, eq)
|
218
|
+
end
|
219
|
+
|
220
|
+
##
|
221
|
+
# [-]
|
222
|
+
##
|
223
|
+
def read_subquery #nodoc
|
224
|
+
read_subquery_start || read_subquery_end
|
225
|
+
end
|
226
|
+
|
227
|
+
##
|
228
|
+
# [-]
|
229
|
+
##
|
230
|
+
def read_subquery_start #nodoc
|
231
|
+
return nil if match(/\(/).nil?
|
232
|
+
sub = Query.new(@cls, :conditions => [@sql] + @ary)
|
233
|
+
@sql = sub.sql[1, sub.sql.length]
|
234
|
+
@conditions << sub
|
235
|
+
end
|
236
|
+
|
237
|
+
##
|
238
|
+
# [-]
|
239
|
+
##
|
240
|
+
def read_subquery_end #nodoc
|
241
|
+
return nil if match(/\)/).nil?
|
242
|
+
@sql = "|" + @sql
|
243
|
+
end
|
244
|
+
|
245
|
+
##
|
246
|
+
# Returns a match array
|
247
|
+
##
|
248
|
+
def match(pattern)
|
249
|
+
if @sql.nil?
|
250
|
+
@sql = @options[:conditions].first
|
251
|
+
end
|
252
|
+
if (@sql =~ pattern) == 0
|
253
|
+
@sql = $'.lstrip
|
254
|
+
Regexp.last_match.to_a
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
##
|
259
|
+
# Parses all user-specified `options[:conditions]`
|
260
|
+
##
|
261
|
+
def parse_hash #nodoc
|
262
|
+
@options[:conditions].map do |att, value|
|
263
|
+
parse_hash_item(att, value)
|
264
|
+
end.flatten
|
265
|
+
end
|
266
|
+
|
267
|
+
##
|
268
|
+
# Parses a single `option`
|
269
|
+
##
|
270
|
+
def parse_hash_item(att, value) #nodoc
|
271
|
+
if value.kind_of? Array
|
272
|
+
return value.map do |item|
|
273
|
+
parse_hash_item(att, item)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
add_condition(att, value)
|
277
|
+
end
|
278
|
+
|
279
|
+
end # Query
|
280
|
+
end # Scope
|
281
|
+
end # RDFMapper
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
##
|
3
|
+
# Basic HTTP interface, built on top of Patron[http://github.com/toland/patron]
|
4
|
+
# library. Used by RDFMapper adapters for communication with external data sources.
|
5
|
+
#
|
6
|
+
# Patron automatically handles cookies, redirects, timeouts. Can be substituted
|
7
|
+
# by any other library as long as HTTP class implements `get` and `post` methods.
|
8
|
+
##
|
9
|
+
class HTTP
|
10
|
+
|
11
|
+
require 'patron'
|
12
|
+
|
13
|
+
class << self
|
14
|
+
|
15
|
+
##
|
16
|
+
# Performs a `GET` request and returns received data
|
17
|
+
#
|
18
|
+
# @param [String, RDF::URI] url
|
19
|
+
# @param [Hash] options for Patron constructor
|
20
|
+
# @return [String]
|
21
|
+
##
|
22
|
+
def get(url, options = {})
|
23
|
+
self.new(options).get(url.to_s)
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Performs a `POST` request and returns received data
|
28
|
+
#
|
29
|
+
# @param [String, RDF::URI] url
|
30
|
+
# @param [String] data
|
31
|
+
# @param [Hash] options for Patron constructor
|
32
|
+
# @return [String]
|
33
|
+
##
|
34
|
+
def post(url, data, options = {})
|
35
|
+
self.new(options).post(url.to_s, data)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# @return [self]
|
42
|
+
##
|
43
|
+
def initialize(options = {})
|
44
|
+
@session = Patron::Session.new
|
45
|
+
@session.handle_cookies
|
46
|
+
@session.timeout = 10
|
47
|
+
@session.headers['User-Agent'] = 'Mozilla / RDFMapper'
|
48
|
+
@options = options
|
49
|
+
end
|
50
|
+
|
51
|
+
def get(url)
|
52
|
+
@session.get(url, headers).body
|
53
|
+
end
|
54
|
+
|
55
|
+
def post(url, data)
|
56
|
+
@session.post(url, data, headers).body
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def headers
|
62
|
+
@options[:headers] || {}
|
63
|
+
end
|
64
|
+
|
65
|
+
end # HTTP
|
66
|
+
end # RDFMapper
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
##
|
3
|
+
# A convenience wrapper around Ruby's standard Logger object.
|
4
|
+
##
|
5
|
+
module Logger
|
6
|
+
module Configuration
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def to(target, level = 4, name = nil)
|
10
|
+
io = case target
|
11
|
+
when :stdout then $stdout
|
12
|
+
when :file then File.open(name, 'a+')
|
13
|
+
else String
|
14
|
+
end
|
15
|
+
@target = ::Logger.new(io)
|
16
|
+
end
|
17
|
+
|
18
|
+
def target
|
19
|
+
@target || to(:stdout)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Logs a fatal error using RDFMapper::Logger
|
27
|
+
#
|
28
|
+
# @return[true]
|
29
|
+
##
|
30
|
+
def fatal(message)
|
31
|
+
log(4, message)
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Logs a warning message using RDFMapper::Logger
|
36
|
+
#
|
37
|
+
# @return[true]
|
38
|
+
##
|
39
|
+
def warn(message)
|
40
|
+
log(2, message)
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Logs a debug message using RDFMapper::Logger
|
45
|
+
#
|
46
|
+
# @return[true]
|
47
|
+
##
|
48
|
+
def debug(message)
|
49
|
+
log(0, message)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
##
|
55
|
+
# Logs a message using RDFMapper::Logger
|
56
|
+
#
|
57
|
+
# @param [Integer] severity from 0 to 5 (see Logger::Severity)
|
58
|
+
# @param [String] message
|
59
|
+
# @return[true]
|
60
|
+
##
|
61
|
+
def log(severity, message)
|
62
|
+
timestamp = Time.now.strftime('%m-%d %H:%M:%S')
|
63
|
+
formatted = "[%s] %s | %s" % [timestamp, self.class.name, message]
|
64
|
+
RDFMapper::Logger::Configuration.target.add(severity, formatted)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
data/lib/rdf-mapper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
|
3
|
+
require 'rdf-xml'
|
4
|
+
require 'rdf-sparql'
|
5
|
+
|
6
|
+
autoload :Model, 'lib/model/base'
|
7
|
+
autoload :Scope, 'lib/scope/model'
|
8
|
+
autoload :Associations, 'lib/associations/base'
|
9
|
+
autoload :Adapters, 'lib/adapters/base'
|
10
|
+
autoload :HTTP, 'lib/util/http'
|
11
|
+
autoload :Logger, 'lib/util/logger'
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
|
metadata
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rdf-mapper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Alex Serebryakov
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-04-27 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 1
|
29
|
+
- 3
|
30
|
+
- 0
|
31
|
+
version: 1.3.0
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rdf
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 1
|
44
|
+
- 1
|
45
|
+
version: 0.1.1
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rdf-xml
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
- 0
|
58
|
+
- 1
|
59
|
+
version: 0.0.1
|
60
|
+
type: :runtime
|
61
|
+
version_requirements: *id003
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: patron
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
- 4
|
72
|
+
- 6
|
73
|
+
version: 0.4.6
|
74
|
+
type: :runtime
|
75
|
+
version_requirements: *id004
|
76
|
+
description: RDFMapper is a lightweight Ruby ORM that works with RDF data in a Rails-like fashion. Is supports XML, N-Triples, JSON formats, SPARQL and ActiveRecord as data sources.
|
77
|
+
email: serebryakov@gmail.com
|
78
|
+
executables: []
|
79
|
+
|
80
|
+
extensions: []
|
81
|
+
|
82
|
+
extra_rdoc_files: []
|
83
|
+
|
84
|
+
files:
|
85
|
+
- README.rdoc
|
86
|
+
- UNLICENSE
|
87
|
+
- VERSION
|
88
|
+
- lib/lib/adapters/base.rb
|
89
|
+
- lib/lib/adapters/rails.rb
|
90
|
+
- lib/lib/adapters/rest.rb
|
91
|
+
- lib/lib/adapters/sparql.rb
|
92
|
+
- lib/lib/associations/base.rb
|
93
|
+
- lib/lib/associations/belongs_to.rb
|
94
|
+
- lib/lib/associations/has_and_belongs.rb
|
95
|
+
- lib/lib/associations/has_many.rb
|
96
|
+
- lib/lib/associations/has_one.rb
|
97
|
+
- lib/lib/model/association.rb
|
98
|
+
- lib/lib/model/attribute.rb
|
99
|
+
- lib/lib/model/base.rb
|
100
|
+
- lib/lib/model/output.rb
|
101
|
+
- lib/lib/model/property.rb
|
102
|
+
- lib/lib/scope/collection.rb
|
103
|
+
- lib/lib/scope/condition.rb
|
104
|
+
- lib/lib/scope/loader.rb
|
105
|
+
- lib/lib/scope/model.rb
|
106
|
+
- lib/lib/scope/query.rb
|
107
|
+
- lib/lib/util/http.rb
|
108
|
+
- lib/lib/util/logger.rb
|
109
|
+
- lib/rdf-mapper.rb
|
110
|
+
has_rdoc: true
|
111
|
+
homepage: http://github.com/42cities/rdf-mapper/
|
112
|
+
licenses: []
|
113
|
+
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options: []
|
116
|
+
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
segments:
|
124
|
+
- 0
|
125
|
+
version: "0"
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
segments:
|
131
|
+
- 0
|
132
|
+
version: "0"
|
133
|
+
requirements: []
|
134
|
+
|
135
|
+
rubyforge_project: rdf-mapper
|
136
|
+
rubygems_version: 1.3.6
|
137
|
+
signing_key:
|
138
|
+
specification_version: 3
|
139
|
+
summary: A Ruby ORM that is designed to play nicely with RDF data.
|
140
|
+
test_files: []
|
141
|
+
|