SqlStatement 1.0.0 → 1.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/doc/ChangeLog ADDED
@@ -0,0 +1,14 @@
1
+ =Change Log
2
+ ==1.0.1
3
+ * +add_fields+ and +add_tables+ now support hashes too, so no more of
4
+ this silly <tt>stmt.fields.merge!</tt> stuff is requred anymore
5
+ * now there's a DBI adaptor that lets DBI accept +SQLStatements+ and
6
+ process them automatically, so no more of this silly
7
+ <tt>dbh.do(stmt.to_s,*stmt.placeheld)</tt> you can just say
8
+ <tt>dbh.do(stmt)</tt> (likewise for +execute+)
9
+ * fix a bug in string_func which broke it completely.
10
+ * Documentation fixes
11
+ * Make <tt>== nil</tt> comparisons turn into <tt>is null</tt> in SQL.
12
+
13
+ ==1.0.0
14
+ Initial Release
data/doc/EXAMPLE ADDED
@@ -0,0 +1,124 @@
1
+ #=Example
2
+ # # We subclass the standard classes so that we can construct
3
+ # # a query with a complex computed field. The newlists method
4
+ # # makes this easy, giving us a constructor and combination
5
+ # # operators for free.
6
+ #
7
+ # class ProbabilityParts < SQLStatement::SelectParts
8
+ # newlists :multiply
9
+ # end
10
+ # class ProbabilityStatement < SQLStatement::SelectCreate
11
+ # newlists :multiply
12
+ #
13
+ # # Add our own special fields here, computed
14
+ # # from the list we added to this class.
15
+ # def allfields
16
+ # retval=super
17
+ # retval.merge! :probability =>
18
+ # SQLFunc(@multiply.collect{|x| x.to_sqlpart}.join('*'))
19
+ # retval
20
+ # end
21
+ # end
22
+ #
23
+ #
24
+ # #In real life, I use a special library for detecting what attributes
25
+ # #are available based on the columns in my tables.
26
+ # #We'll mimic that functionality here.
27
+ # #
28
+ # #The first definition of this module mocks the stuff that's in my more
29
+ # #complicated library
30
+ # module AttributeDetection
31
+ # class Attribute
32
+ # def initialize(domain,name)
33
+ # @domain=domain
34
+ # @name=name
35
+ # end
36
+ # attr_reader :name, :domain
37
+ # end
38
+ # class Hierarchy < Attribute
39
+ # def initialize(leftcolumn)
40
+ # ignored1,m_domain,m_name,ignored2=leftcolumn.split(/_/)
41
+ # super(m_domain,m_name)
42
+ # end
43
+ # end
44
+ # class DomainlessPerGroup < Attribute
45
+ # def initialize (colname)
46
+ # name=@colname=colname
47
+ # domain="!"
48
+ # super(domain,name)
49
+ # end
50
+ # end
51
+ #
52
+ # #I have a few other attribute types, none of which
53
+ # #are used in this code yet.
54
+ #
55
+ # end
56
+ #
57
+ # include SQLHelpers
58
+ #
59
+ # #The second definition of this module is the code that I actually define
60
+ # #in this particular program.
61
+ # module AttributeDetection
62
+ # class Attribute
63
+ # def condname
64
+ # :"cond_#{name}"
65
+ # end
66
+ # def priorname
67
+ # :"prior_#{name}"
68
+ # end
69
+ # #parts that go in to the CREATE TABLE `probabilities` statement
70
+ # #which relate to the attribute we are disambiguating
71
+ # def probability_disambig
72
+ # parts=ProbabilityParts.new
73
+ # parts.add_fields [priorname[probkey]]
74
+ # parts.add_tables [priorname]
75
+ # parts.multiply << priorname[:pt]
76
+ # parts
77
+ # end
78
+ # #parts that go in to the CREATE TABLE `probabilities` statement
79
+ # #which relate to the attributes we are using as features
80
+ # def probability_features(conditionalon)
81
+ # parts=ProbabilityParts.new
82
+ # parts.tables={priorname=>priorname,condname=>condname}
83
+ # parts.add_fields [priorname[probkey]]
84
+ # parts.conditions << sql_func{ condname[probkey]==priorname[probkey]}
85
+ # parts.conditions << sql_func{
86
+ # condname[conditionalon.probkey]==
87
+ # conditionalon.priorname[conditionalon.probkey]
88
+ # }
89
+ # parts.multiply << sql_func{condname[:pt]/priorname[:pt]}
90
+ # parts
91
+ # end
92
+ # end
93
+ # class Hierarchy
94
+ # def probkey
95
+ # "att_#{domain}_#{name}_left".to_sym
96
+ # end
97
+ # end
98
+ # class DomainlessPerGroup
99
+ # def probkey
100
+ # @colname.to_sym
101
+ # end
102
+ # end
103
+ # end
104
+ #
105
+ # include AttributeDetection
106
+ # include SQLHelpers
107
+ #
108
+ # #And this code calls methods to actually build the query.
109
+ #
110
+ # #First we define the names of the attributes
111
+ # att_disambig=Hierarchy.new("att_appraisal_attitude_left")
112
+ # att_features=[Hierarchy.new("att_products_appraisedtype_left"),
113
+ # DomainlessPerGroup.new("priority")]
114
+ #
115
+ #
116
+ # #Then we construct the statement
117
+ # stmt=ProbabilityStatement.new :probabilities,true
118
+ #
119
+ # stmt << att_disambig.probability_disambig
120
+ # att_features.each { |x| stmt<< x.probability_features(att_disambig) }
121
+ #
122
+ # #Finally, we execute it against the database. Assume dbh is a
123
+ # #dbi connection handle.
124
+ # dbh.execute(stmt.to_s,*stmt.placeheld)
@@ -0,0 +1,25 @@
1
+ #Redefine DBI's query methods to accept SQL statement objects from
2
+ #this library. This is automatically loaded if DBI was loaded before
3
+ #+sqlstatement+. If not, <tt>require 'sql/dbi-support'</tt> after DBI
4
+ #is included and you'll be on your way.
5
+ class DBI::DatabaseHandle
6
+ alias_method :kenbloom_sqlstatement_old_do, :"do"
7
+ alias_method :kenbloom_sqlstatement_old_execute, :execute
8
+
9
+ def do(stmt,*args)
10
+ if stmt.respond_to?(:placeheld)
11
+ kenbloom_sqlstatement_old_do(stmt.to_s,*stmt.placeheld)
12
+ else
13
+ kenbloom_sqlstatement_old_do(stmt,*args)
14
+ end
15
+ end
16
+ def execute(stmt,*args)
17
+ if stmt.respond_to?(:placeheld)
18
+ kenbloom_sqlstatement_old_execute(stmt.to_s,*stmt.placeheld)
19
+ else
20
+ kenbloom_sqlstatement_old_execute(stmt,*args)
21
+ end
22
+ end
23
+
24
+ end
25
+
@@ -12,6 +12,10 @@ class Array
12
12
  "count(distinct "+rest_sqlpart+")"
13
13
  elsif first.to_s =~ /[a-zA-Z]/
14
14
  first.to_s+"("+rest_sqlpart+")"
15
+ elsif first == :== and self[2]==nil
16
+ self[1].to_sqlpart+" is null"
17
+ elsif first == :== and self[1]==nil
18
+ self[2].to_sqlpart+" is null"
15
19
  elsif x={:& => " and ", :| => " or ", :== => "="}[first]
16
20
  "("+self[1].to_sqlpart+x+self[2].to_sqlpart+")"
17
21
  else
data/lib/sql/statement.rb CHANGED
@@ -1,70 +1,3 @@
1
- =begin rdoc
2
- = sqlstatement - Generate complex SQL statements programmatically
3
-
4
- The main goal of this library is to be able to construct an SQL statement
5
- from "slices" that concern different aspects of the final query (perhaps
6
- in different places in your code) and then combine them all together into
7
- one statement easily.
8
-
9
- Another important goal of this library is to give some consistent Ruby
10
- syntax to three statements (INSERT, SELECT, and UPDATE) that seem to have
11
- different enough syntax that one has two write different code to generate
12
- each kind of statement.
13
-
14
- I use my SQL database (specifically MySQL) largely as a bulk data
15
- processing engine, by doing INSERT...SELECT or CREATE TABLE...SELECT
16
- statements. This library is intended to make that kind of coding easier. I
17
- expect that Object Relational mappers (such as ActiveRecord) are more
18
- useful for most people, who are performing queries and
19
- inserting/updating/querying for individual records. I have nevertheless
20
- added INSERT...VALUES statements, and will add other statements soon, for
21
- consistency.
22
-
23
- This library is inspired by CLSQL[http://clsql.b9.com/] for Common LISP,
24
- or SchemeQL[http://schematics.sourceforge.net/schemeql.html] for Scheme,
25
- although it is very different from these two libraries. Scheme and
26
- LISP's use of s-expressions make it very easy to construct an entire
27
- sublanguage for the WHERE clause, simply by list parsing. The
28
- Criteria[http://mephle.org/Criteria/] library for Ruby has attempted
29
- this, but in a more limited manner than SchemeQL or CLSQL. My library
30
- aims to cover much of the functionality in these libraries.
31
-
32
- This library doesn't try to abstract out the limitations of your DBMS, and
33
- I think that the SQL it uses should be fairly portable, in large measure
34
- because it hasn't attempted to deal with serious CREATE TABLE statements,
35
- where a lot of syntax concerning types, keys and sequences is much more
36
- variable.
37
-
38
- ==License
39
-
40
- Copyright (c) 2006 Ken Bloom
41
- All rights reserved.
42
-
43
- Redistribution and use in source and binary forms, with or without
44
- modification, are permitted provided that the following conditions
45
- are met:
46
- 1. Redistributions of source code must retain the above copyright
47
- notice, this list of conditions and the following disclaimer.
48
- 2. Redistributions in binary form must reproduce the above copyright
49
- notice, this list of conditions and the following disclaimer in the
50
- documentation and/or other materials provided with the distribution.
51
- 3. Neither Ken Bloom's name, nor the name of any of his contributors may
52
- may be used to endorse or promote products derived from this software
53
- without specific prior written permission.
54
-
55
- THIS SOFTWARE IS PROVIDED BY THE KEN BLOOM AND CONTRIBUTORS ``AS IS'' AND
56
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58
- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
59
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
61
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65
- SUCH DAMAGE.
66
- =end
67
-
68
1
  # Everything in Ruby is a descendant of the Object class. Practically
69
2
  # speaking, this means that any object that hasn't otherwise defined
70
3
  # the +placeheld+ and <tt>to_sqlpart</tt> methods will be treated as a piece
@@ -107,6 +40,15 @@ class Symbol
107
40
  end
108
41
  end
109
42
 
43
+ class NilClass
44
+ def to_sqlpart
45
+ "null"
46
+ end
47
+ def placeheld
48
+ []
49
+ end
50
+ end
51
+
110
52
  module SQLStatement
111
53
 
112
54
  # This class is used to represent complex SQL expressions, so that
@@ -118,7 +60,7 @@ module SQLStatement
118
60
  class Function < String
119
61
 
120
62
  def initialize(val="",placeheld=[])
121
- super
63
+ super val
122
64
  @placeheld=placeheld
123
65
  end
124
66
 
@@ -220,19 +162,24 @@ class SelectParts
220
162
  #See the documentation for SelectStatement which describes these.
221
163
  attr_accessor :conditions, :groupby, :orderby, :fields, :tables
222
164
 
223
- #Adds an array of unaliased fields to this SQL statement. See
224
- #documentation at SelectStatement
165
+ #Adds an array of unaliased fields, or a hash of aliased fields to
166
+ #this SQL statement. See documentation at SelectStatement
225
167
  def add_fields (newfields)
226
- newfields.each do |x|
227
- @fields[x]=x
168
+ if newfields.is_a?(Hash)
169
+ @fields.merge! newfields
170
+ else
171
+ newfields.each { |x| @fields[x]=x }
228
172
  end
173
+ nil
229
174
  end
230
175
 
231
- #Adds an array of unaliased tables to this SQL statement. See
232
- #documentation for SelectStatement
176
+ #Adds an array of unaliased tables or a hash of aliased tables to
177
+ #this SQL statement. See documentation for SelectStatement
233
178
  def add_tables (newtables)
234
- newtables.each do |x|
235
- @tables[x]=x
179
+ if newtables.is_a?(Hash)
180
+ @tables.merge! newtables
181
+ else
182
+ newtables.each { |x| @tables[x]=x }
236
183
  end
237
184
  end
238
185
 
@@ -297,11 +244,15 @@ class Select
297
244
  #aliasing a field name, use the form <tt>fieldname => fieldname</tt>.
298
245
  attr_accessor :fields
299
246
 
300
- #Adds an array of unaliased fields to this SQL statement.
247
+ #Adds an array of unaliased fields, or a hash of aliased fields to
248
+ #this SQL statement.
301
249
  def add_fields (newfields)
302
- newfields.each do |x|
303
- @fields[x]=x
250
+ if newfields.is_a?(Hash)
251
+ @fields.merge! newfields
252
+ else
253
+ newfields.each { |x| @fields[x]=x }
304
254
  end
255
+ nil
305
256
  end
306
257
 
307
258
  #This is the tables to include in the query (i.e. the +FROM+ clause).
@@ -311,10 +262,13 @@ class Select
311
262
  #aliasing a table name, use the form <tt>tablename => tablename</tt>.
312
263
  attr_accessor :tables
313
264
 
314
- #Adds an array of unaliased tables to this SQL statement.
265
+ #Adds an array of unaliased tables or a hash of aliased tables to
266
+ #this SQL statement.
315
267
  def add_tables (newtables)
316
- newtables.each do |x|
317
- @tables[x]=x
268
+ if newtables.is_a?(Hash)
269
+ @tables.merge! newtables
270
+ else
271
+ newtables.each { |x| @tables[x]=x }
318
272
  end
319
273
  end
320
274
 
data/lib/sqlstatement.rb CHANGED
@@ -1,2 +1,81 @@
1
+ =begin rdoc
2
+ = sqlstatement - Generate complex SQL statements programmatically
3
+
4
+ The main goal of this library is to be able to construct an SQL statement
5
+ from "slices" that concern different aspects of the final query (perhaps
6
+ in different places in your code) and then combine them all together into
7
+ one statement easily.
8
+
9
+ Another important goal of this library is to give some consistent Ruby
10
+ syntax to three statements (INSERT, SELECT, and UPDATE) that seem to have
11
+ different enough syntax that one has two write different code to generate
12
+ each kind of statement.
13
+
14
+ I use my SQL database (specifically MySQL) largely as a bulk data
15
+ processing engine, by doing INSERT...SELECT or CREATE TABLE...SELECT
16
+ statements. This library is intended to make that kind of coding easier. I
17
+ expect that Object Relational mappers (such as ActiveRecord) are more
18
+ useful for most people, who are performing queries and
19
+ inserting/updating/querying for individual records. I have nevertheless
20
+ added INSERT...VALUES statements, and will add other statements soon, for
21
+ consistency.
22
+
23
+ This library is inspired by CLSQL[http://clsql.b9.com/] for Common LISP,
24
+ or SchemeQL[http://schematics.sourceforge.net/schemeql.html] for Scheme,
25
+ although it is very different from these two libraries. Scheme and
26
+ LISP's use of s-expressions make it very easy to construct an entire
27
+ sublanguage for the WHERE clause, simply by list parsing. The
28
+ Criteria[http://mephle.org/Criteria/] library for Ruby has attempted
29
+ this, but in a more limited manner than SchemeQL or CLSQL. My library
30
+ aims to cover much of the functionality in these libraries.
31
+
32
+ This library doesn't try to abstract out the limitations of your DBMS, and
33
+ I think that the SQL it uses should be fairly portable, in large measure
34
+ because it hasn't attempted to deal with serious CREATE TABLE statements,
35
+ where a lot of syntax concerning types, keys and sequences is much more
36
+ variable.
37
+
38
+ This library can be downloaded from
39
+ http://rubyforge.org/projects/sqlstatement/
40
+
41
+ ==Author
42
+ Ken Bloom <mailto:kbloom@gmail.com>
43
+
44
+ http://www.iit.edu/~kbloom1/
45
+
46
+ ==License
47
+
48
+ Copyright (c) 2006 Ken Bloom
49
+ All rights reserved.
50
+
51
+ Redistribution and use in source and binary forms, with or without
52
+ modification, are permitted provided that the following conditions
53
+ are met:
54
+ 1. Redistributions of source code must retain the above copyright
55
+ notice, this list of conditions and the following disclaimer.
56
+ 2. Redistributions in binary form must reproduce the above copyright
57
+ notice, this list of conditions and the following disclaimer in the
58
+ documentation and/or other materials provided with the distribution.
59
+ 3. Neither Ken Bloom's name, nor the name of any of his contributors may
60
+ may be used to endorse or promote products derived from this software
61
+ without specific prior written permission.
62
+
63
+ THIS SOFTWARE IS PROVIDED BY THE KEN BLOOM AND CONTRIBUTORS ``AS IS'' AND
64
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
66
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
67
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
69
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
70
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
71
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
72
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
73
+ SUCH DAMAGE.
74
+ =end
75
+
76
+
1
77
  require 'sql/statement'
2
78
  require 'sql/expression'
79
+ if defined?(DBI)
80
+ require 'sql/dbi-support'
81
+ end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: SqlStatement
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.0
7
- date: 2006-10-09 00:00:00 -05:00
6
+ version: 1.0.1
7
+ date: 2006-11-20 00:00:00 -06:00
8
8
  summary: A library for generating arbitrary SQL statements using convenient Ruby objects.
9
9
  require_paths:
10
10
  - lib
@@ -29,18 +29,22 @@ post_install_message:
29
29
  authors:
30
30
  - Ken Bloom
31
31
  files:
32
- - bin/example.rb
33
32
  - lib/sql
34
33
  - lib/sqlstatement.rb
35
34
  - lib/sql/expression.rb
36
35
  - lib/sql/bathon-sxp.rb
37
36
  - lib/sql/statement.rb
37
+ - lib/sql/dbi-support.rb
38
+ - doc/EXAMPLE
39
+ - doc/ChangeLog
38
40
  test_files: []
39
41
 
40
- rdoc_options: []
41
-
42
- extra_rdoc_files: []
43
-
42
+ rdoc_options:
43
+ - --main
44
+ - lib/sqlstatement.rb
45
+ extra_rdoc_files:
46
+ - doc/EXAMPLE
47
+ - doc/ChangeLog
44
48
  executables: []
45
49
 
46
50
  extensions: []
data/bin/example.rb DELETED
@@ -1,129 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require_gem 'SqlStatement'
3
- require 'sql/statement'
4
- require 'sql/expression'
5
-
6
- # We subclass the standard classes so that we can construct
7
- # a query with a complex computed field. The newlists method
8
- # makes this easy, giving us a constructor and combination
9
- # operators for free.
10
-
11
- class ProbabilityParts < SQLStatement::SelectParts
12
- newlists :multiply
13
- end
14
- class ProbabilityStatement < SQLStatement::SelectCreate
15
- newlists :multiply
16
-
17
- # Add our own special fields here, computed
18
- # from the list we added to this class.
19
- def allfields
20
- retval=super
21
- retval.merge! :probability =>
22
- SQLFunc(@multiply.collect{|x| x.to_sqlpart}.join('*'))
23
- retval
24
- end
25
- end
26
-
27
-
28
- #In real life, I use a special library for detecting what attributes
29
- #are available based on the columns in my tables.
30
- #We'll mimic that functionality here.
31
- #
32
- #The first definition of this module mocks the stuff that's in my more
33
- #complicated library
34
- module AttributeDetection
35
- class Attribute
36
- def initialize(domain,name)
37
- @domain=domain
38
- @name=name
39
- end
40
- attr_reader :name, :domain
41
- end
42
- class Hierarchy < Attribute
43
- def initialize(leftcolumn)
44
- ignored1,m_domain,m_name,ignored2=leftcolumn.split(/_/)
45
- super(m_domain,m_name)
46
- end
47
- end
48
- class DomainlessPerGroup < Attribute
49
- def initialize (colname)
50
- name=@colname=colname
51
- domain="!"
52
- super(domain,name)
53
- end
54
- end
55
-
56
- #I have a few other attribute types, none of which
57
- #are used in this code yet.
58
-
59
- end
60
-
61
- include SQLHelpers
62
-
63
- #The second definition of this module is the code that I actually define
64
- #in this particular program.
65
- module AttributeDetection
66
- class Attribute
67
- def condname
68
- :"cond_#{name}"
69
- end
70
- def priorname
71
- :"prior_#{name}"
72
- end
73
- #parts that go in to the CREATE TABLE `probabilities` statement
74
- #which relate to the attribute we are disambiguating
75
- def probability_disambig
76
- parts=ProbabilityParts.new
77
- parts.add_fields [priorname[probkey]]
78
- parts.add_tables [priorname]
79
- parts.multiply << priorname[:pt]
80
- parts
81
- end
82
- #parts that go in to the CREATE TABLE `probabilities` statement
83
- #which relate to the attributes we are using as features
84
- def probability_features(conditionalon)
85
- parts=ProbabilityParts.new
86
- parts.tables={priorname=>priorname,condname=>condname}
87
- parts.add_fields [priorname[probkey]]
88
- parts.conditions << sql_func{ condname[probkey]==priorname[probkey]}
89
- parts.conditions << sql_func{
90
- condname[conditionalon.probkey]==
91
- conditionalon.priorname[conditionalon.probkey]
92
- }
93
- parts.multiply << sql_func{condname[:pt]/priorname[:pt]}
94
- parts
95
- end
96
- end
97
- class Hierarchy
98
- def probkey
99
- "att_#{domain}_#{name}_left".to_sym
100
- end
101
- end
102
- class DomainlessPerGroup
103
- def probkey
104
- @colname.to_sym
105
- end
106
- end
107
- end
108
-
109
- include AttributeDetection
110
- include SQLHelpers
111
-
112
- #And this code calls methods to actually build the query.
113
-
114
- #First we define the names of the attributes
115
- att_disambig=Hierarchy.new("att_appraisal_attitude_left")
116
- att_features=[Hierarchy.new("att_products_appraisedtype_left"),
117
- DomainlessPerGroup.new("priority")]
118
-
119
-
120
- #Then we construct the statement
121
- stmt=ProbabilityStatement.new :probabilities,true
122
-
123
- stmt << att_disambig.probability_disambig
124
- att_features.each { |x| stmt<< x.probability_features(att_disambig) }
125
-
126
- #Finally, we print it (or execute it against the database)
127
- puts stmt.to_s
128
-
129
-