wordnet 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,17 +4,21 @@
4
4
  require 'loggability'
5
5
  require 'sequel'
6
6
 
7
- # Use a mock database until the real one is provided by the user
8
- Sequel::Model.db = Sequel.mock if Sequel::DATABASES.empty?
9
-
10
7
  require 'wordnet' unless defined?( WordNet )
11
8
 
9
+
12
10
  module WordNet
13
11
 
12
+ Model = Class.new( Sequel::Model )
13
+ Model.def_Model( WordNet )
14
+
15
+ Model.require_valid_table = false
16
+
17
+
14
18
  # The base WordNet database-backed domain class. It's a subclass of Sequel::Model, so
15
- # you'll first need to be familiar with Sequel (http://sequel.rubyforge.org/) and
19
+ # you'll first need to be familiar with Sequel (http://sequel.jeremyevans.net/) and
16
20
  # especially its Sequel::Model ORM.
17
- class Model < Sequel::Model
21
+ class Model
18
22
  extend Loggability
19
23
 
20
24
  # Loggability API -- log to the WordNet module's logger
@@ -22,58 +26,46 @@ module WordNet
22
26
 
23
27
  # Sequel plugins
24
28
  plugin :validation_helpers
25
- plugin :schema
26
29
  plugin :subclasses
27
30
 
28
31
 
29
- ### Execute a block after removing all loggers from the current database handle, then
30
- ### restore them before returning.
31
- def self::without_sql_logging( logged_db=nil )
32
- logged_db ||= self.db
33
-
34
- loggers_to_restore = logged_db.loggers.dup
35
- logged_db.loggers.clear
36
- yield
37
- ensure
38
- logged_db.loggers.replace( loggers_to_restore )
32
+ # Allow registration of subclasses to load once the db is connected
33
+ class << self
34
+ attr_reader :registered_models
39
35
  end
36
+ @registered_models = []
40
37
 
41
38
 
42
39
  ### Reset the database connection that all model objects will use.
43
40
  ### @param [Sequel::Database] newdb the new database object.
44
41
  def self::db=( newdb )
45
- self.without_sql_logging( newdb ) do
42
+ Loggability.with_level( :fatal ) do
46
43
  super
47
44
  end
48
45
 
49
- self.descendents.each do |subclass|
50
- self.log.debug "Resetting database connection for: %p to: %p" % [ subclass, newdb ]
51
- subclass.db = newdb
52
- end
46
+ self.load_registered_models if self == WordNet::Model
53
47
  end
54
48
 
55
- end # class Model
56
-
57
49
 
58
- ### Overridden version of Sequel.Model() that creates subclasses of WordNet::Model instead
59
- ### of Sequel::Model.
60
- ### @see Sequel.Model()
61
- def self::Model( source )
62
- unless Sequel::Model::ANONYMOUS_MODEL_CLASSES.key?( source )
63
- anonclass = nil
64
- WordNet::Model.without_sql_logging do
65
- if source.is_a?( Sequel::Database )
66
- anonclass = Class.new( WordNet::Model )
67
- anonclass.db = source
68
- else
69
- anonclass = Class.new( WordNet::Model ).set_dataset( source )
70
- end
50
+ ### Register a model subclass path to load when the database is connected. If
51
+ ### there's already a database connection, just `require` it immediately.
52
+ def self::register_model( name )
53
+ if @db
54
+ require( name )
55
+ else
56
+ self.registered_models << name
71
57
  end
58
+ end
59
+
72
60
 
73
- Sequel::Model::ANONYMOUS_MODEL_CLASSES[ source ] = anonclass
61
+ ### Load any models which have been registered.
62
+ def self::load_registered_models
63
+ self.registered_models.each do |path|
64
+ require( path )
65
+ end
74
66
  end
75
67
 
76
- return Sequel::Model::ANONYMOUS_MODEL_CLASSES[ source ]
77
- end
68
+ end # class Model
69
+
78
70
 
79
71
  end # module WordNet
@@ -36,9 +36,9 @@ class WordNet::Morph < WordNet::Model( :morphs )
36
36
  # "fk_morphmaps_morphid" FOREIGN KEY (morphid) REFERENCES morphs(morphid)
37
37
  # "fk_morphmaps_wordid" FOREIGN KEY (wordid) REFERENCES words(wordid)
38
38
  many_to_many :words,
39
- :join_table => :morphmaps,
40
- :right_key => :wordid,
41
- :left_key => :morphid
39
+ join_table: :morphmaps,
40
+ right_key: :wordid,
41
+ left_key: :morphid
42
42
 
43
43
 
44
44
  ### Return the stringified word; alias for #lemma.
@@ -13,15 +13,15 @@ class WordNet::SemanticLink < WordNet::Model( :semlinks )
13
13
  set_primary_key [:synset1id, :synset2id, :linkid]
14
14
 
15
15
  many_to_one :origin,
16
- :class => :"WordNet::Synset",
17
- :key => :synset1id,
18
- :primary_key => :synsetid
16
+ class: 'WordNet::Synset',
17
+ key: :synset1id,
18
+ primary_key: :synsetid
19
19
 
20
20
  one_to_one :target,
21
- :class => :"WordNet::Synset",
22
- :key => :synsetid,
23
- :primary_key => :synset2id,
24
- :eager => :words
21
+ class: 'WordNet::Synset',
22
+ key: :synsetid,
23
+ primary_key: :synset2id,
24
+ eager: :words
25
25
 
26
26
 
27
27
  ######
@@ -12,19 +12,19 @@ class WordNet::Sense < WordNet::Model( :senses )
12
12
 
13
13
  ##
14
14
  # The Synset this is a Sense for
15
- many_to_one :synset, :key => :synsetid
15
+ many_to_one :synset, key: :synsetid
16
16
 
17
17
  ##
18
18
  # The Word this is a Sense for
19
- many_to_one :word, :key => :wordid
19
+ many_to_one :word, key: :wordid
20
20
 
21
21
  ##
22
22
  # The lexical links between this sense and its related Synsets.
23
23
  # Sense -> [ LexicalLinks ] -> [ Synsets ]
24
24
  one_to_many :lexlinks,
25
- :class => :"WordNet::LexicalLink",
26
- :key => [ :synset1id, :word1id ],
27
- :primary_key => [ :synsetid, :wordid ]
25
+ class: 'WordNet::LexicalLink',
26
+ key: [ :synset1id, :word1id ],
27
+ primary_key: [ :synsetid, :wordid ]
28
28
 
29
29
 
30
30
  ### Generate a method that will return Synsets related by the given lexical pointer
@@ -37,8 +37,8 @@ class WordNet::Sense < WordNet::Model( :senses )
37
37
  method_body = Proc.new do
38
38
  linkinfo = WordNet::Synset.linktypes[ typekey ] or
39
39
  raise ScriptError, "no such link type %p" % [ typekey ]
40
- ssids = self.lexlinks_dataset.filter( :linkid => linkinfo[:id] ).select( :synset2id )
41
- self.class.filter( :synsetid => ssids )
40
+ ssids = self.lexlinks_dataset.filter( linkid: linkinfo[:id] ).select( :synset2id )
41
+ self.class.filter( synsetid: ssids )
42
42
  end
43
43
 
44
44
  define_method( type, &method_body )
@@ -8,11 +8,11 @@ require 'wordnet/constants'
8
8
 
9
9
  # Experimental support for the WordNet mapping for the {Suggested Upper Merged
10
10
  # Ontology}[http://www.ontologyportal.org/] (SUMO).
11
- # This is still a work in progress, and isn't supported by all of the WordNet-SQL
12
- # databases.
11
+ # It's still a work in progress.
13
12
  class WordNet::SumoTerm < WordNet::Model( :sumoterms )
14
13
  include WordNet::Constants
15
14
 
15
+
16
16
  # Table "public.sumoterms"
17
17
  # Column | Type | Modifiers
18
18
  # -----------------------+------------------------+--------------------
@@ -69,9 +69,9 @@ class WordNet::SumoTerm < WordNet::Model( :sumoterms )
69
69
  ##
70
70
  # WordNet::Synsets that are related to this term
71
71
  many_to_many :synsets,
72
- :join_table => :sumomaps,
73
- :left_key => :sumoid,
74
- :right_key => :synsetid
72
+ join_table: :sumomaps,
73
+ left_key: :sumoid,
74
+ right_key: :synsetid
75
75
 
76
76
  end # class WordNet::SumoTerm
77
77
 
@@ -14,7 +14,7 @@ require 'wordnet/model'
14
14
  #
15
15
  # We can either fetch the synset from a connected Lexicon:
16
16
  #
17
- # lexicon = WordNet::Lexicon.new( 'postgres://localhost/wordnet30' )
17
+ # lexicon = WordNet::Lexicon.new( 'postgres://localhost/wordnet31' )
18
18
  # ss = lexicon[ :first, 'time' ]
19
19
  # # => #<WordNet::Synset:0x7ffbf2643bb0 {115265518} 'commencement, first,
20
20
  # # get-go, offset, outset, start, starting time, beginning, kickoff,
@@ -101,9 +101,9 @@ require 'wordnet/model'
101
101
  # API if you need to do something not provided by a high-level method.
102
102
  #
103
103
  # In order to make use of this API, you'll need to be familiar with
104
- # {Sequel}[http://sequel.rubyforge.org/], especially
105
- # {Datasets}[http://sequel.rubyforge.org/rdoc/files/doc/dataset_basics_rdoc.html] and
106
- # {Model Associations}[http://sequel.rubyforge.org/rdoc/files/doc/association_basics_rdoc.html].
104
+ # {Sequel}[http://sequel.jeremyevans.net/], especially
105
+ # {Datasets}[http://sequel.jeremyevans.net/rdoc/files/doc/dataset_basics_rdoc.html] and
106
+ # {Model Associations}[http://sequel.jeremyevans.net/rdoc/files/doc/association_basics_rdoc.html].
107
107
  # Most of Ruby-WordNet's functionality is implemented in terms of one or both
108
108
  # of these.
109
109
  #
@@ -179,42 +179,42 @@ class WordNet::Synset < WordNet::Model( :synsets )
179
179
  ##
180
180
  # The WordNet::Words associated with the receiver
181
181
  many_to_many :words,
182
- :join_table => :senses,
183
- :left_key => :synsetid,
184
- :right_key => :wordid
182
+ join_table: :senses,
183
+ left_key: :synsetid,
184
+ right_key: :wordid
185
185
 
186
186
 
187
187
  ##
188
188
  # The WordNet::Senses associated with the receiver
189
189
  one_to_many :senses,
190
- :key => :synsetid,
191
- :primary_key => :synsetid
190
+ key: :synsetid,
191
+ primary_key: :synsetid
192
192
 
193
193
 
194
194
  ##
195
195
  # The WordNet::SemanticLinks indicating a relationship with other
196
196
  # WordNet::Synsets
197
197
  one_to_many :semlinks,
198
- :class => :"WordNet::SemanticLink",
199
- :key => :synset1id,
200
- :primary_key => :synsetid,
201
- :eager => :target
198
+ class: 'WordNet::SemanticLink',
199
+ key: :synset1id,
200
+ primary_key: :synsetid,
201
+ eager: :target
202
202
 
203
203
 
204
204
  ##
205
205
  # The WordNet::SemanticLinks pointing *to* this Synset
206
206
  many_to_one :semlinks_to,
207
- :class => :"WordNet::SemanticLink",
208
- :key => :synsetid,
209
- :primary_key => :synset2id
207
+ class: 'WordNet::SemanticLink',
208
+ key: :synsetid,
209
+ primary_key: :synset2id
210
210
 
211
211
 
212
212
  ##
213
213
  # Terms from the Suggested Upper Merged Ontology
214
214
  many_to_many :sumo_terms,
215
- :join_table => :sumomaps,
216
- :left_key => :synsetid,
217
- :right_key => :sumoid
215
+ join_table: :sumomaps,
216
+ left_key: :synsetid,
217
+ right_key: :sumoid
218
218
 
219
219
 
220
220
  #################################################################
@@ -252,30 +252,43 @@ class WordNet::Synset < WordNet::Model( :synsets )
252
252
  # # organ of a bird>]
253
253
  #
254
254
 
255
- ##
256
- # :singleton-method: nouns
257
- # Dataset method: filtered by part of speech: nouns.
258
- def_dataset_method( :nouns ) { filter(pos: 'n') }
255
+ dataset_module do
259
256
 
260
- ##
261
- # :singleton-method: verbs
262
- # Dataset method: filtered by part of speech: verbs.
263
- def_dataset_method( :verbs ) { filter(pos: 'v') }
257
+ ### :singleton-method: nouns
258
+ ### Limit results to nouns.
259
+ def nouns
260
+ return self.where( pos: 'n' )
261
+ end
264
262
 
265
- ##
266
- # :singleton-method: adjectives
267
- # Dataset method: filtered by part of speech: adjectives.
268
- def_dataset_method( :adjectives ) { filter(pos: 'a') }
269
263
 
270
- ##
271
- # :singleton-method: adverbs
272
- # Dataset method: filtered by part of speech: adverbs.
273
- def_dataset_method( :adverbs ) { filter(pos: 'r') }
264
+ ### :singleton-method: verbs
265
+ ### Limit results to verbs.
266
+ def verbs
267
+ return self.where( pos: 'v' )
268
+ end
274
269
 
275
- ##
276
- # :singleton-method: adjective_satellites
277
- # Dataset method: filtered by part of speech: adjective satellites.
278
- def_dataset_method( :adjective_satellites ) { filter(pos: 's') }
270
+
271
+ ### :singleton-method: adjectives
272
+ ### Limit results to adjectives.
273
+ def adjectives
274
+ return self.where( pos: 'a' )
275
+ end
276
+
277
+
278
+ ### :singleton-method: adverbs
279
+ ### Limit results to adverbs.
280
+ def adverbs
281
+ return self.where( pos: 'r' )
282
+ end
283
+
284
+
285
+ ### :singleton-method: adjective_satellites
286
+ ### Limit results to adjective satellites.
287
+ def adjective_satellites
288
+ return self.where( pos: 's' )
289
+ end
290
+
291
+ end
279
292
 
280
293
 
281
294
  # :section:
@@ -318,10 +331,10 @@ class WordNet::Synset < WordNet::Model( :synsets )
318
331
  def self::linktype_table
319
332
  @linktype_table ||= self.db[:linktypes].inject({}) do |hash,row|
320
333
  hash[ row[:linkid] ] = {
321
- :id => row[:linkid],
322
- :typename => row[:link],
323
- :type => row[:link].gsub( /\s+/, '_' ).to_sym,
324
- :recurses => row[:recurses] && row[:recurses] != 0,
334
+ id: row[:linkid],
335
+ typename: row[:link],
336
+ type: row[:link].gsub( /\s+/, '_' ).to_sym,
337
+ recurses: row[:recurses] && row[:recurses] != 0,
325
338
  }
326
339
  hash
327
340
  end
@@ -388,9 +401,9 @@ class WordNet::Synset < WordNet::Model( :synsets )
388
401
  typekey = SEMANTIC_TYPEKEYS[ type ]
389
402
  linkinfo = self.class.linktypes[ typekey ] or
390
403
  raise ArgumentError, "no such link type %p" % [ typekey ]
391
- ssids = self.semlinks_dataset.filter( :linkid => linkinfo[:id] ).select( :synset2id )
404
+ ssids = self.semlinks_dataset.filter( linkid: linkinfo[:id] ).select( :synset2id )
392
405
 
393
- return self.class.filter( :synsetid => ssids )
406
+ return self.class.filter( synsetid: ssids )
394
407
  end
395
408
 
396
409
 
@@ -66,31 +66,36 @@ class WordNet::Word < WordNet::Model( :words )
66
66
  ##
67
67
  # The WordNet::Sense objects that relate the word with its Synsets
68
68
  one_to_many :senses,
69
- :key => :wordid,
70
- :primary_key => :wordid
69
+ key: :wordid,
70
+ primary_key: :wordid
71
71
 
72
72
  ##
73
73
  # The WordNet::Synsets related to the word via its senses
74
74
  many_to_many :synsets,
75
- :join_table => :senses,
76
- :left_key => :wordid,
77
- :right_key => :synsetid
75
+ join_table: :senses,
76
+ left_key: :wordid,
77
+ right_key: :synsetid
78
78
 
79
79
  ##
80
80
  # The WordNet::Morphs related to the word
81
81
  many_to_many :morphs,
82
- :join_table => :morphmaps,
83
- :left_key => :wordid,
84
- :right_key => :morphid
82
+ join_table: :morphmaps,
83
+ left_key: :wordid,
84
+ right_key: :morphid
85
85
 
86
86
 
87
87
  #
88
88
  # Dataset methods
89
89
  #
90
90
 
91
- ##
92
- # Return a dataset for words matching the given +lemma+.
93
- def_dataset_method( :by_lemma ) {|lemma| filter( lemma: lemma ) }
91
+ dataset_module do
92
+
93
+ ### Limit the dataset to words matching the given +lemma+.
94
+ def by_lemma( lemma )
95
+ return where( lemma: lemma )
96
+ end
97
+
98
+ end
94
99
 
95
100
 
96
101
  #
@@ -5,9 +5,12 @@
5
5
  # SimpleCov test coverage reporting; enable this using the :coverage rake task
6
6
  require 'simplecov' if ENV['COVERAGE']
7
7
 
8
+ $LOAD_PATH.unshift( 'wordnet-defaultdb/lib' )
9
+
8
10
  require 'rspec'
9
11
  require 'loggability/spechelpers'
10
12
  require 'wordnet'
13
+ require 'wordnet/defaultdb'
11
14
 
12
15
 
13
16
  ### RSpec helper functions.
@@ -23,17 +26,18 @@ RSpec.configure do |config|
23
26
  config.mock_with( :rspec ) do |mock|
24
27
  mock.syntax = :expect
25
28
  end
29
+ config.example_status_persistence_file_path = "spec/.state"
26
30
 
27
- if Gem::Specification.find_all_by_name( 'pg' ).empty?
31
+ if Gem::Specification.find_all_by_name( 'pg' ).any?
32
+ $dburi = 'postgres:/wordnet31'
33
+ else
28
34
  config.filter_run_excluding( :requires_pg )
35
+ unless (( $dburi = WordNet::Lexicon.default_db_uri ))
36
+ config.filter_run_excluding( :requires_database )
37
+ end
29
38
  end
30
39
 
31
- begin
32
- uri = WordNet::Lexicon.default_db_uri
33
- WordNet.log.info "Database tests will use: #{uri}"
34
- rescue WordNet::LexiconError
35
- config.filter_run_excluding( :requires_database )
36
- end
40
+ $stderr.puts "Using database: %p" % [ $dburi ]
37
41
 
38
42
  config.include( WordNet::SpecHelpers )
39
43
  config.include( Loggability::SpecHelpers )