wordnet 1.0.1 → 1.1.0

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.
@@ -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 )