globegit-postgresql-plruby 0.5.4

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.
Files changed (122) hide show
  1. data/Changes +121 -0
  2. data/README.markdown +155 -0
  3. data/Rakefile +48 -0
  4. data/docs/plruby.rb +1931 -0
  5. data/ex_trans.sql +33 -0
  6. data/extconf.rb +267 -0
  7. data/plruby.html +1454 -0
  8. data/plruby.rd +1571 -0
  9. data/postgresql-plruby.gemspec +56 -0
  10. data/src/conversions.h +5 -0
  11. data/src/conversions/basic/conversions.h +25 -0
  12. data/src/conversions/basic/extconf.rb +8 -0
  13. data/src/conversions/basic/plruby_basic.c +357 -0
  14. data/src/conversions/bitstring/bitstring.sql +75 -0
  15. data/src/conversions/bitstring/conversions.h +15 -0
  16. data/src/conversions/bitstring/extconf.rb +8 -0
  17. data/src/conversions/bitstring/plruby_bitstring.c +579 -0
  18. data/src/conversions/convcommon.h +129 -0
  19. data/src/conversions/datetime/conversions.h +13 -0
  20. data/src/conversions/datetime/extconf.rb +8 -0
  21. data/src/conversions/datetime/plruby_datetime.c +269 -0
  22. data/src/conversions/geometry/conversions.h +37 -0
  23. data/src/conversions/geometry/extconf.rb +8 -0
  24. data/src/conversions/geometry/geometry.sql +196 -0
  25. data/src/conversions/geometry/plruby_geometry.c +2494 -0
  26. data/src/conversions/network/conversions.h +21 -0
  27. data/src/conversions/network/extconf.rb +8 -0
  28. data/src/conversions/network/network.sql +63 -0
  29. data/src/conversions/network/plruby_network.c +537 -0
  30. data/src/package.h +20 -0
  31. data/src/plpl.c +1708 -0
  32. data/src/plplan.c +893 -0
  33. data/src/plruby.c +1676 -0
  34. data/src/plruby.h +324 -0
  35. data/src/pltrans.c +388 -0
  36. data/test/conv_bitstring/b.rb +45 -0
  37. data/test/conv_bitstring/runtest +26 -0
  38. data/test/conv_bitstring/test.expected.73 +148 -0
  39. data/test/conv_bitstring/test.expected.74 +148 -0
  40. data/test/conv_bitstring/test.expected.80 +148 -0
  41. data/test/conv_bitstring/test.expected.81 +148 -0
  42. data/test/conv_bitstring/test.expected.82 +148 -0
  43. data/test/conv_bitstring/test.expected.83 +148 -0
  44. data/test/conv_bitstring/test.expected.84 +148 -0
  45. data/test/conv_bitstring/test.out +148 -0
  46. data/test/conv_bitstring/test_mklang.sql +8 -0
  47. data/test/conv_bitstring/test_queries.sql +63 -0
  48. data/test/conv_bitstring/test_queries.sql.in +63 -0
  49. data/test/conv_geometry/b.rb +45 -0
  50. data/test/conv_geometry/runtest +26 -0
  51. data/test/conv_geometry/test.expected.73 +265 -0
  52. data/test/conv_geometry/test.expected.74 +265 -0
  53. data/test/conv_geometry/test.expected.80 +265 -0
  54. data/test/conv_geometry/test.expected.81 +265 -0
  55. data/test/conv_geometry/test.expected.82 +265 -0
  56. data/test/conv_geometry/test.expected.83 +265 -0
  57. data/test/conv_geometry/test.expected.84 +265 -0
  58. data/test/conv_geometry/test.out +265 -0
  59. data/test/conv_geometry/test_mklang.sql +8 -0
  60. data/test/conv_geometry/test_queries.sql +194 -0
  61. data/test/conv_geometry/test_queries.sql.in +194 -0
  62. data/test/conv_network/b.rb +45 -0
  63. data/test/conv_network/runtest +26 -0
  64. data/test/conv_network/test.expected.73 +213 -0
  65. data/test/conv_network/test.expected.74 +237 -0
  66. data/test/conv_network/test.expected.80 +237 -0
  67. data/test/conv_network/test.expected.81 +237 -0
  68. data/test/conv_network/test.expected.82 +237 -0
  69. data/test/conv_network/test.expected.83 +237 -0
  70. data/test/conv_network/test.expected.84 +237 -0
  71. data/test/conv_network/test.out +237 -0
  72. data/test/conv_network/test_mklang.sql +8 -0
  73. data/test/conv_network/test_queries.sql +60 -0
  74. data/test/conv_network/test_queries.sql.in +60 -0
  75. data/test/plp/b.rb +34 -0
  76. data/test/plp/runtest +29 -0
  77. data/test/plp/test.expected.73 +472 -0
  78. data/test/plp/test.expected.74 +472 -0
  79. data/test/plp/test.expected.75 +472 -0
  80. data/test/plp/test.expected.80 +472 -0
  81. data/test/plp/test.expected.81 +472 -0
  82. data/test/plp/test.expected.82 +472 -0
  83. data/test/plp/test.expected.83 +472 -0
  84. data/test/plp/test.expected.84 +472 -0
  85. data/test/plp/test.out +472 -0
  86. data/test/plp/test_mklang.sql +8 -0
  87. data/test/plp/test_queries.sql +273 -0
  88. data/test/plp/test_setup.sql +931 -0
  89. data/test/plp/test_setup.sql.in +931 -0
  90. data/test/plt/b.rb +34 -0
  91. data/test/plt/runtest +29 -0
  92. data/test/plt/test.expected.73 +178 -0
  93. data/test/plt/test.expected.74 +178 -0
  94. data/test/plt/test.expected.75 +178 -0
  95. data/test/plt/test.expected.80 +178 -0
  96. data/test/plt/test.expected.81 +178 -0
  97. data/test/plt/test.expected.82 +178 -0
  98. data/test/plt/test.expected.83 +164 -0
  99. data/test/plt/test.expected.84 +168 -0
  100. data/test/plt/test.out +168 -0
  101. data/test/plt/test_mklang.sql +8 -0
  102. data/test/plt/test_queries.sql +72 -0
  103. data/test/plt/test_setup.sql +252 -0
  104. data/test/plt/test_setup.sql.in +252 -0
  105. data/test/range/b.rb +45 -0
  106. data/test/range/runtest +26 -0
  107. data/test/range/test.expected.73 +396 -0
  108. data/test/range/test.expected.73.in +396 -0
  109. data/test/range/test.expected.74 +396 -0
  110. data/test/range/test.expected.74.in +396 -0
  111. data/test/range/test.expected.75 +396 -0
  112. data/test/range/test.expected.75.in +396 -0
  113. data/test/range/test.expected.80 +396 -0
  114. data/test/range/test.expected.81 +397 -0
  115. data/test/range/test.expected.82 +397 -0
  116. data/test/range/test.expected.83 +397 -0
  117. data/test/range/test.expected.84 +399 -0
  118. data/test/range/test.out +399 -0
  119. data/test/range/test_mklang.sql +8 -0
  120. data/test/range/test_queries.sql +249 -0
  121. data/test/range/test_queries.sql.in +249 -0
  122. metadata +207 -0
data/Changes ADDED
@@ -0,0 +1,121 @@
1
+ -- 0.1.0 - 0.2.5
2
+
3
+ adaptation for new version of PostgreSQL
4
+
5
+ -- 0.2.6
6
+
7
+ #exec can have an optional output of type "array", "hash"
8
+ (see the example in plruby.html)
9
+
10
+ -- 0.2.7
11
+
12
+ PLrubyplan#each
13
+
14
+ --- 0.2.8
15
+
16
+ adapted for 7.3b3
17
+
18
+ --- 0.2.9
19
+
20
+ adapted for 1.8.0
21
+ corrected stupid bug with GC
22
+
23
+ --- 0.3.0
24
+
25
+ *experimental* timeout (--with-timeout)
26
+ fixed SPI_execp()
27
+
28
+ --- 0.3.1
29
+
30
+ corrected for_numvals() (Thanks Brad Hilton <bhilton@vpop.net>)
31
+
32
+ --- 0.3.2
33
+
34
+ functions returning set (PostgreSQL >= 7.3)
35
+
36
+ --- 0.3.3
37
+
38
+ corrected timeout
39
+ corrected bug with GC
40
+ new classes PL::Plan, PL::Cursor
41
+
42
+ --- 0.3.4
43
+
44
+ adapted for 7.4
45
+ Warning : array as input and output (7.4)
46
+ anyarray/anyelement in input/output for 7.4
47
+
48
+ --- 0.3.6
49
+
50
+ corrected "EACH STATEMENT"
51
+ added ExprMultiResult
52
+
53
+ --- 0.3.7
54
+
55
+ corrected full qualified type names for SPI_prepare
56
+ #each return nil for PL::Plan
57
+ protected PL::PLan::new against parse error
58
+ protected thread value when there is a timeout
59
+
60
+ --- 0.3.8
61
+
62
+ stupid bug portalActive (only 7.4)
63
+
64
+ --- 0.3.9
65
+
66
+ corrected rb_hash_delete for 1.6 (Thanks Dennis Vshivkov <walrus@amur.ru>)
67
+ decode arrays in tuples (Thanks Dennis Vshivkov <walrus@amur.ru>)
68
+ corrected pl_yield (Thanks Dennis Vshivkov <walrus@amur.ru>)
69
+ convert arguments (--enable-conversion at compile time : experimental)
70
+ conversion plfunction ==> method (only with --enable-conversion)
71
+ add network, geometry (experimental)
72
+ corrected function returning table
73
+
74
+ --- 0.4.0
75
+
76
+ --enable-shared
77
+ array for trigger
78
+
79
+ --- 0.4.1
80
+
81
+ add bitstring
82
+
83
+ --- 0.4.2
84
+
85
+ by default convert arguments ( --disable-conversion to remove it)
86
+
87
+ --- 0.4.3
88
+
89
+ IMPORTANT : work only with postgres >= 7.3
90
+ transaction and named arguments for 8.0
91
+
92
+ --- 0.4.4
93
+
94
+ * patch written by Dennis Vshivkov <walrus@amur.ru>
95
+ - Time-conversion-fix
96
+ - typtypmod-fix
97
+ - Integer-conversion-fix
98
+ - extconf.rb-PG_TRY-test-fix
99
+ - redundant-ReleaseSysCache-fix
100
+ - BYTEA-conv
101
+ - MONEY-conv-fix
102
+ - Float-conv-back-fix
103
+
104
+ --- 0.4.5
105
+
106
+ * corrected ReleaseSysCache() (Thanks to Peter Eisentraut <peter_e@gmx.net>)
107
+ * conversion function String#to_datum (Thanks to Dennis Vshivkov <walrus@amur.ru>)
108
+
109
+ --- 0.4.5 - 0.5.3 (2008-03-03)
110
+
111
+ * adapted for 8.1, 8.2, and 8.3
112
+
113
+ The original author Guy Decoux passed away in the beginning of the
114
+ month of July 2008 at the age of 53. The development is inherited by
115
+ Akinori MUSHA.
116
+
117
+ --- 0.5.4 (2010-01-02)
118
+
119
+ * adapted for 8.4
120
+ * bug-fix
121
+ * extconf.rb changed to make use of pg_config(1)
@@ -0,0 +1,155 @@
1
+ PL/ruby
2
+ =======
3
+
4
+ PL/Ruby is a loadable procedural language for the PostgreSQL database
5
+ system that enables the Ruby language to create functions and trigger
6
+ procedures.
7
+
8
+
9
+ Prerequisite
10
+ ------------
11
+
12
+ > * ruby 1.8.7 or later
13
+ > * postgresql >= 7.3
14
+
15
+ All PostgreSQL development headers need to be installed. If you installed
16
+ using a package manager of some sort, be sure to install the "dev" package.
17
+
18
+ If you built from source you can run the following command:
19
+
20
+ make install-all-headers
21
+
22
+ Installation
23
+ ------------
24
+
25
+ If you're installing the gem:
26
+
27
+ gem install postgresql-plruby
28
+
29
+ If you want to allow the ability to require external libraries:
30
+
31
+ gem install postgresql-plruby -- --with-safe-level=0
32
+
33
+ If you're doing things the old fashioned way:
34
+
35
+ ruby extconf.rb
36
+ make
37
+ make install
38
+
39
+ You may need to specify some of the following extconf.rb options:
40
+
41
+ --with-pg-config=<location of the pg_config command of PostgreSQL>
42
+
43
+ Specifies the location of pg_config.
44
+ e.g. --with-pg-config=/usr/local/bin/pg_config
45
+
46
+ --with-greenplum
47
+
48
+ Builds plruby for Greenplum instead of PostgreSQL.
49
+
50
+ --disable-conversion
51
+
52
+ By default plruby tries to convert a postgres type to a ruby class.
53
+ This option gives the possibility to disable all conversions.
54
+
55
+ --with-suffix=<suffix to add>
56
+
57
+ Specifies a suffix to add to the extension module file.
58
+ e.g. `ruby extconf.rb --with-suffix=_geo` will create
59
+ `plruby_geo.so`.
60
+
61
+ --with-safe-level
62
+
63
+ Lowers the safe level which the plruby functions are run under.
64
+ (default: 12; meaning the maximum)
65
+
66
+ --with-timeout=<seconds>
67
+
68
+ Sets the timeout for each function call. (default: none)
69
+
70
+ --with-main-safe-level
71
+
72
+ Lowers the safe level which the main thread waiting for timeouts is
73
+ run under. (default: 3) This option is read only when --with-timeout
74
+ is given.
75
+
76
+
77
+ Test (and examples)
78
+ -------------------
79
+
80
+ WARNING: if plruby was compiled without --disable-conversion you
81
+ must **FIRST** run `make install` before `make test`.
82
+
83
+ make test
84
+
85
+ This will run the following two commands:
86
+
87
+ ( cd test/plt; ./runtest )
88
+ ( cd test/plp; ./runtest )
89
+
90
+ The database `plruby_test` is created and then destroyed. Don't use
91
+ it if you have such a database.
92
+
93
+ Now you are ready to create the PL/Ruby language in PostgreSQL.
94
+
95
+ Since the `pg_language` system catalog is private to each database,
96
+ the new language can be created only for individual databases, or in
97
+ the template1 database. In the latter case, it is automatically
98
+ available in all newly created databases.
99
+
100
+ The commands to create the new language are:
101
+
102
+ create function plruby_call_handler () returns language_handler
103
+ as 'path-to-plruby-shared-lib'
104
+ language 'C';
105
+
106
+ create trusted language 'plruby'
107
+ handler plruby_call_handler
108
+ lancompiler 'PL/Ruby';
109
+
110
+
111
+ The `trusted` keyword on `create language` tells PostgreSQL,
112
+ that all users (not only those with superuser privilege) are
113
+ permitted to create functions with `LANGUAGE 'plruby'`. This is
114
+ absolutely safe, because there is nothing a normal user can do
115
+ with PL/Ruby, to get around access restrictions he/she has.
116
+
117
+ Sample Functions
118
+ ----------------
119
+ CREATE FUNCTION ruby_max(int4, int4) RETURNS int4 AS '
120
+ if args[0] > args[1]
121
+ return args[0]
122
+ else
123
+ return args[1]
124
+ end
125
+ ' LANGUAGE 'plruby';
126
+
127
+ select ruby_max(1,2);
128
+
129
+ CREATE FUNCTION ruby_max2(x int4, y int4) RETURNS int4 AS '
130
+ return x > y ? x : y
131
+ ' LANGUAGE 'plruby';
132
+
133
+ select ruby_max2(7,8);
134
+
135
+ Documentation
136
+ -------------
137
+
138
+ see `plruby.rd` and `plruby.html`
139
+
140
+ Development
141
+ -----------
142
+
143
+ New releases and sources can be obtained from <http://github.com/knu/postgresql-plruby>
144
+
145
+ Copying
146
+ -------
147
+
148
+ This extension module is copyrighted free software by Guy Decoux.
149
+
150
+ You can redistribute it and/or modify it under the same term as Ruby.
151
+
152
+ * * *
153
+
154
+ Guy Decoux <ts@moulon.inra.fr> (original author, deceased in July 2008)
155
+ Akinori MUSHA <knu@idaemons.org> (current maintainer)
@@ -0,0 +1,48 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/clean'
4
+ require 'rbconfig'
5
+ include Config
6
+
7
+ # TODO: Reorganize code to use Rake compiler.
8
+
9
+ CLEAN.include(
10
+ '**/*.gem', # Gem files
11
+ '**/*.rbc', # Rubinius
12
+ '**/*.o', # C object file
13
+ '**/*.log', # Ruby extension build log
14
+ '**/Makefile', # C Makefile
15
+ '**/conftest.dSYM', # OS X build directory
16
+ "**/*.#{CONFIG['DLEXT']}" # C shared object
17
+ )
18
+
19
+ desc 'Build the postgresql-plruby source code'
20
+ task :build => [:clean] do
21
+ ruby "extconf.rb"
22
+ sh "make"
23
+ end
24
+
25
+ namespace :gem do
26
+ desc 'Create the gem'
27
+ task :create => [:clean] do
28
+ spec = eval(IO.read('postgresql-plruby.gemspec'))
29
+ Gem::Builder.new(spec).build
30
+ end
31
+
32
+ desc 'Install the gem'
33
+ task :install => [:create] do
34
+ file = Dir["*.gem"].first
35
+ sh "gem install #{file}"
36
+ end
37
+ end
38
+
39
+ # TODO: Reorganize tests to make them work.
40
+ Rake::TestTask.new do |t|
41
+ task :test => [:build]
42
+ t.libs << 'ext'
43
+ t.test_files = FileList['test/**/*.rb']
44
+ t.warning = true
45
+ t.verbose = true
46
+ end
47
+
48
+ task :default => :test
@@ -0,0 +1,1931 @@
1
+ # = Warning
2
+ #
3
+ # <em>For documentation purpose, the modules PLRuby, PLRuby::Description
4
+ # are defined but don't exist in reality</em>
5
+ #
6
+ # = PLRuby
7
+ #
8
+ # PLRuby is a loadable procedural language for the PostgreSQL database
9
+ # system that enables the Ruby language to create functions and
10
+ # trigger procedures.
11
+ #
12
+ # Functions and triggers are singleton methods of the module PLtemp.
13
+ #
14
+ # = WARNING
15
+ #
16
+ # <b>if PLRuby was NOT compiled with <em>--enable-conversion</em>
17
+ # all arguments (to the function or the triggers) are passed as string
18
+ # values, except for NULL values represented by <em>nil</em>.</b>
19
+ #
20
+ # <b>In this case, you must explicitely call a conversion function (like to_i)
21
+ # if you want to use an argument as an integer</b>
22
+ #
23
+ # = See
24
+ #
25
+ # * PLRuby::Description::Function
26
+ #
27
+ # To create a function
28
+ #
29
+ # * PLRuby::Description::Function::SFRM
30
+ #
31
+ # To create a function returning SET (SFRM Materialize)
32
+ #
33
+ # * PLRuby::Description::Function::ExprMultiResult
34
+ #
35
+ # To create a function returning SET (ExprMultiResult)
36
+ #
37
+ # * PLRuby::Description::Trigger
38
+ #
39
+ # To define a trigger
40
+ #
41
+ # * PLRuby::Description::Singleton_method
42
+ #
43
+ # To define singleton methods
44
+ #
45
+ # * PLRuby::Description::Conversion
46
+ #
47
+ # What conversions are done when this option is not disabled
48
+ # (<em>--disable-conversion</em>)
49
+ #
50
+ # = Class hierarchy
51
+ #
52
+ # * PLRuby::PL
53
+ #
54
+ # * PLRuby::PL::Plan
55
+ #
56
+ # * PLRuby::PL::Cursor
57
+ #
58
+ # * PLRuby::PL::Transaction
59
+ #
60
+ # * PLRuby::BitString
61
+ #
62
+ # * PLRuby::Tinterval
63
+ #
64
+ # * PLRuby::NetAddr
65
+ #
66
+ # * PLRuby::MacAddr
67
+ #
68
+ # * PLRuby::Box
69
+ #
70
+ # * PLRuby::Circle
71
+ #
72
+ # * PLRuby::Path
73
+ #
74
+ # * PLRuby::Point
75
+ #
76
+ # * PLRuby::Polygon
77
+ #
78
+ # * PLRuby::Segment
79
+ #
80
+ # Global variable
81
+ #
82
+ # $Plans:: can be used to store prepared plans. (hash, tainted)
83
+ #
84
+ #
85
+ module PLRuby
86
+ #
87
+ # Create a new transaction and yield an object <em>PL::Transaction</em>
88
+ #
89
+ # Only available with PostgreSQL >= 8.0
90
+ def transaction()
91
+ yield txn
92
+ end
93
+
94
+ # Ruby interface to PostgreSQL elog()
95
+ #
96
+ # Possible value for <tt>level</tt> are <tt>NOTICE</tt>,
97
+ # <tt>DEBUG</tt> and <tt>NOIND</tt>
98
+ #
99
+ # Use <tt>raise()</tt> if you want to simulate <tt>elog(ERROR, "...")</tt>
100
+ def warn(level = NOTICE, message)
101
+ end
102
+ end
103
+ #
104
+ # Pseudo module to describe the syntax to define function and triggers
105
+ #
106
+ # There is documentation for
107
+ # * PLRuby::Description::Function
108
+ #
109
+ # To create a function
110
+ #
111
+ # * PLRuby::Description::Function::SFRM
112
+ #
113
+ # To create a function returning SET (SFRM Materialize)
114
+ #
115
+ # * PLRuby::Description::Function::ExprMultiResult
116
+ #
117
+ # To create a function returning SET (ExprMultiResult)
118
+ #
119
+ # * PLRuby::Description::Trigger
120
+ #
121
+ # To define a trigger
122
+ #
123
+ # * PLRuby::Description::Singleton_method
124
+ #
125
+ # To define singleton methods
126
+ #
127
+ # * PLRuby::Description::Conversion
128
+ #
129
+ # What conversions are done when this option is not disabled
130
+ # (<em>--disable-conversion</em>)
131
+ module PLRuby::Description
132
+ end
133
+ #
134
+ # To create a function in the PLRuby language use the syntax
135
+ #
136
+ # CREATE FUNCTION funcname(arguments_type) RETURNS type AS '
137
+ #
138
+ # # PLRuby function body
139
+ #
140
+ # ' LANGUAGE 'plruby';
141
+ #
142
+ # when calling the function in a query, the arguments are given
143
+ # in the array <em>args</em>. To create a little max
144
+ # function returning the higher of two int4 values write :
145
+ #
146
+ # CREATE FUNCTION ruby_max(int4, int4) RETURNS int4 AS '
147
+ # if args[0] > args[1]
148
+ # return args[0]
149
+ # else
150
+ # return args[1]
151
+ # end
152
+ # ' LANGUAGE 'plruby';
153
+ #
154
+ #
155
+ # Tuple arguments are given as hash. Here is an example that defines
156
+ # the overpaid_2 function (as found in the older Postgres documentation)
157
+ # in PLRuby.
158
+ #
159
+ # CREATE FUNCTION overpaid_2 (EMP) RETURNS bool AS '
160
+ # args[0]["salary"] > 200000 ||
161
+ # (args[0]["salary"] > 100000 && args[0]["age"] < 30)
162
+ # ' LANGUAGE 'plruby';
163
+ #
164
+ #
165
+ # === Warning : with PostgreSQL >= 7.4 "array" are given as a ruby Array
166
+ #
167
+ # For example to define a function (int4[], int4) and return int4[],
168
+ # in version < 7.4 you write
169
+ #
170
+ # CREATE FUNCTION ruby_int4_accum(_int4, int4) RETURNS _int4 AS '
171
+ # if /\\{(\\d+),(\\d+)\\}/ =~ args[0]
172
+ # a, b = $1, $2
173
+ # newsum = a + args[1]
174
+ # newcnt = b + 1
175
+ # else
176
+ # raise "unexpected value #{args[0]}"
177
+ # end
178
+ # "{#{newsum},#{newcnt}}"
179
+ # ' LANGUAGE 'plruby';
180
+ #
181
+ # This must now (>= 7.4) be written
182
+ #
183
+ # CREATE FUNCTION ruby_int4_accum(_int4, int4) RETURNS _int4 AS '
184
+ # a = args[0]
185
+ # [a[0] + args[1], a[1] + 1]
186
+ # ' LANGUAGE 'plruby';
187
+ #
188
+ # === Release PostgreSQL 8.0
189
+ #
190
+ # With this version, plruby can have named arguments and the previous functions
191
+ # can be written
192
+ #
193
+ # CREATE FUNCTION ruby_max(a int4, b int4) RETURNS int4 AS '
194
+ # if a > b
195
+ # a
196
+ # else
197
+ # b
198
+ # end
199
+ # ' LANGUAGE 'plruby';
200
+ #
201
+ #
202
+ # CREATE FUNCTION overpaid_2 (emp EMP) RETURNS bool AS '
203
+ # emp["salary"] > 200000 ||
204
+ # (emp["salary"] > 100000 && emp["age"] < 30)
205
+ # ' LANGUAGE 'plruby';
206
+ #
207
+ # With this version, you can also use transaction. For example
208
+ #
209
+ # plruby_test=# create table tu (a int, b int);
210
+ # CREATE TABLE
211
+ # plruby_test=# create or replace function tt(abort bool) returns bool as '
212
+ # plruby_test'# transaction do |txn|
213
+ # plruby_test'# PL.exec("insert into tu values (1, 2)")
214
+ # plruby_test'# transaction do |txn1|
215
+ # plruby_test'# PL.exec("insert into tu values (3, 4)")
216
+ # plruby_test'# txn1.abort
217
+ # plruby_test'# end
218
+ # plruby_test'# PL.exec("insert into tu values (5, 6)")
219
+ # plruby_test'# txn.abort if abort
220
+ # plruby_test'# end
221
+ # plruby_test'# abort
222
+ # plruby_test'# ' language 'plruby';
223
+ # CREATE FUNCTION
224
+ # plruby_test=#
225
+ # plruby_test=# select tt(true);
226
+ # tt
227
+ # ----
228
+ # t
229
+ # (1 row)
230
+ #
231
+ # plruby_test=# select * from tu;
232
+ # a | b
233
+ # ---+---
234
+ # (0 rows)
235
+ #
236
+ # plruby_test=# select tt(false);
237
+ # tt
238
+ # ----
239
+ # f
240
+ # (1 row)
241
+ #
242
+ # plruby_test=# select * from tu;
243
+ # a | b
244
+ # ---+---
245
+ # 1 | 2
246
+ # 5 | 6
247
+ # (2 rows)
248
+ #
249
+ # plruby_test=#
250
+ #
251
+ #
252
+ module PLRuby::Description::Function
253
+ end
254
+ #
255
+ # == Function returning SET (SFRM Materialize)
256
+ #
257
+ # The return type must be declared as SETOF
258
+ #
259
+ # The function must call <em>yield</em> to return rows or return a String
260
+ # which must be a valid SELECT statement
261
+ #
262
+ # For example to concatenate 2 rows create the function
263
+ #
264
+ # plruby_test=# CREATE FUNCTION tu(varchar) RETURNS setof record
265
+ # plruby_test-# AS '
266
+ # plruby_test'# size = PL.column_name(args[0]).size
267
+ # plruby_test'# res = nil
268
+ # plruby_test'# PL::Plan.new("select * from #{args[0]}",
269
+ # plruby_test'# "block" => 50).each do |row|
270
+ # plruby_test'# if res.nil?
271
+ # plruby_test'# res = row.values
272
+ # plruby_test'# else
273
+ # plruby_test'# res.concat row.values
274
+ # plruby_test'# yield res
275
+ # plruby_test'# res = nil
276
+ # plruby_test'# end
277
+ # plruby_test'# end
278
+ # plruby_test'# if res
279
+ # plruby_test'# res.concat Array.new(size)
280
+ # plruby_test'# yield res
281
+ # plruby_test'# end
282
+ # plruby_test'# ' language 'plruby';
283
+ # CREATE FUNCTION
284
+ # plruby_test=#
285
+ # plruby_test=# select * from tt;
286
+ # a | b
287
+ # ---+----
288
+ # 1 | 2
289
+ # 3 | 4
290
+ # 5 | 6
291
+ # 7 | 8
292
+ # 9 | 10
293
+ # (5 rows)
294
+ #
295
+ # plruby_test=# select * from tu('tt') as tbl(a int, b int, c int, d int);
296
+ # a | b | c | d
297
+ # ---+----+---+---
298
+ # 1 | 2 | 3 | 4
299
+ # 5 | 6 | 7 | 8
300
+ # 9 | 10 | |
301
+ # (3 rows)
302
+ #
303
+ # plruby_test=#
304
+ #
305
+ class PLRuby::Description::Function::SFRM
306
+ end
307
+ # == Function returning SET (ExprMultiResult)
308
+ #
309
+ # The return type must be declared as SETOF
310
+ #
311
+ # The function is called until it returns nil
312
+ #
313
+ # The method PL#context and PL#context= give the possibility to store
314
+ # information between the call
315
+ #
316
+ # For example
317
+ #
318
+ # plruby_test=# create or replace function vv(int) returns setof int as '
319
+ # plruby_test'# i = PL.context || 0
320
+ # plruby_test'# if i >= args[0]
321
+ # plruby_test'# nil
322
+ # plruby_test'# else
323
+ # plruby_test'# PL.context = i + 1
324
+ # plruby_test'# end
325
+ # plruby_test'# ' language plruby;
326
+ # CREATE FUNCTION
327
+ # plruby_test=#
328
+ # plruby_test=# select * from uu;
329
+ # b
330
+ # ---
331
+ # 2
332
+ # (1 row)
333
+ #
334
+ # plruby_test=#
335
+ # plruby_test=# select *,vv(3) from uu;
336
+ # b | vv
337
+ # ---+----
338
+ # 2 | 1
339
+ # 2 | 2
340
+ # 2 | 3
341
+ # (3 rows)
342
+ #
343
+ # plruby_test=#
344
+ #
345
+ class PLRuby::Description::Function::ExprMultiResult
346
+ end
347
+ #
348
+ # Trigger procedures are defined in Postgres as functions without
349
+ # arguments and a return type of trigger. In PLRuby the procedure is
350
+ # called with 4 arguments :
351
+ #
352
+ # * new (hash, tainted)
353
+ #
354
+ # an hash containing the values of the new table row on INSERT/UPDATE
355
+ # actions, or empty on DELETE.
356
+ # * old (hash, tainted)
357
+ #
358
+ # an hash containing the values of the old table row on UPDATE/DELETE
359
+ # actions, or empty on INSERT
360
+ # * args (array, tainted, frozen)
361
+ #
362
+ # An array of the arguments to the procedure as given in the CREATE
363
+ # TRIGGER statement
364
+ # * tg (hash, tainted, frozen)
365
+ #
366
+ # The following keys are defined
367
+ #
368
+ # - name
369
+ #
370
+ # The name of the trigger from the CREATE TRIGGER statement.
371
+ #
372
+ # - relname
373
+ #
374
+ # The name of the relation who has fired the trigger
375
+ #
376
+ # - relid
377
+ #
378
+ # The object ID of the table that caused the trigger procedure to be invoked.
379
+ #
380
+ # - relatts
381
+ #
382
+ # An array containing the name of the tables field.
383
+ #
384
+ # - when
385
+ #
386
+ # The constant <em>PL::BEFORE</em>, <em>PL::AFTER</em> or
387
+ # <em>PL::UNKNOWN</em> depending on the event of the trigger call.
388
+ #
389
+ # - level
390
+ #
391
+ # The constant <em>PL::ROW</em> or <em>PL::STATEMENT</em>
392
+ # depending on the event of the trigger call.
393
+ #
394
+ # - op
395
+ #
396
+ # The constant <em>PL::INSERT</em>, <em>PL::UPDATE</em> or
397
+ # <em>PL::DELETE</em> depending on the event of the trigger call.
398
+ #
399
+ #
400
+ # The return value from a trigger procedure is one of the constant
401
+ # <em>PL::OK</em> or <em>PL::SKIP</em>, or an hash. If the
402
+ # return value is <em>PL::OK</em>, the normal operation
403
+ # (INSERT/UPDATE/DELETE) that fired this trigger will take
404
+ # place. Obviously, <em>PL::SKIP</em> tells the trigger manager to
405
+ # silently suppress the operation. The hash tells
406
+ # PLRuby to return a modified row to the trigger manager that will be
407
+ # inserted instead of the one given in <em>new</em> (INSERT/UPDATE
408
+ # only). Needless to say that all this is only meaningful when the
409
+ # trigger is BEFORE and FOR EACH ROW.
410
+ #
411
+ # Here's a little example trigger procedure that forces an integer
412
+ # value in a table to keep track of the # of updates that are performed
413
+ # on the row. For new row's inserted, the value is initialized to 0 and
414
+ # then incremented on every update operation :
415
+ #
416
+ # CREATE FUNCTION trigfunc_modcount() RETURNS TRIGGER AS '
417
+ # case tg["op"]
418
+ # when PL::INSERT
419
+ # new[args[0]] = 0
420
+ # when PL::UPDATE
421
+ # new[args[0]] = old[args[0]] + 1
422
+ # else
423
+ # return PL::OK
424
+ # end
425
+ # new
426
+ # ' LANGUAGE 'plruby';
427
+ #
428
+ # CREATE TABLE mytab (num int4, modcnt int4, descr text);
429
+ #
430
+ # CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab
431
+ # FOR EACH ROW EXECUTE PROCEDURE trigfunc_modcount('modcnt');
432
+ #
433
+ #
434
+ #
435
+ # A more complex example (extract from test_setup.sql in the distribution)
436
+ # which use the global variable <em>$Plans</em> to store a prepared
437
+ # plan
438
+ #
439
+ # create function trig_pkey2_after() returns trigger as '
440
+ # if ! $Plans.key?("plan_dta2_upd")
441
+ # $Plans["plan_dta2_upd"] =
442
+ # PL::Plan.new("update T_dta2
443
+ # set ref1 = $3, ref2 = $4
444
+ # where ref1 = $1 and ref2 = $2",
445
+ # ["int4", "varchar", "int4", "varchar" ]).save
446
+ # $Plans["plan_dta2_del"] =
447
+ # PL::Plan.new("delete from T_dta2
448
+ # where ref1 = $1 and ref2 = $2",
449
+ # ["int4", "varchar"]).save
450
+ # end
451
+ #
452
+ # old_ref_follow = false
453
+ # old_ref_delete = false
454
+ #
455
+ # case tg["op"]
456
+ # when PL::UPDATE
457
+ # new["key2"] = new["key2"].upcase
458
+ # old_ref_follow = (new["key1"] != old["key1"]) ||
459
+ # (new["key2"] != old["key2"])
460
+ # when PL::DELETE
461
+ # old_ref_delete = true
462
+ # end
463
+ #
464
+ # if old_ref_follow
465
+ # n = $Plans["plan_dta2_upd"].exec([old["key1"], old["key2"], new["key1"],
466
+ # new["key2"]])
467
+ # warn "updated #{n} entries in T_dta2 for new key in T_pkey2" if n != 0
468
+ # end
469
+ #
470
+ # if old_ref_delete
471
+ # n = $Plans["plan_dta2_del"].exec([old["key1"], old["key2"]])
472
+ # warn "deleted #{n} entries from T_dta2" if n != 0
473
+ # end
474
+ #
475
+ # PL::OK
476
+ # ' language 'plruby';
477
+ #
478
+ # create trigger pkey2_after after update or delete on T_pkey2
479
+ # for each row execute procedure
480
+ # trig_pkey2_after();
481
+ #
482
+ #
483
+ class PLRuby::Description::Trigger
484
+ end
485
+ # == plruby_singleton_methods
486
+ #
487
+ # Sometime it can be usefull to define methods (in pure Ruby) which can be
488
+ # called from a PLRuby function or a PLRuby trigger.
489
+ #
490
+ # In this case, you have 2 possibilities
491
+ #
492
+ # * the "stupid" way :-) :-) :-)
493
+ #
494
+ # just close the current definition of the function (or trigger) with a
495
+ # <em>end</em> and define your singleton method without the final <em>end</em>
496
+ #
497
+ # Here a small and useless example
498
+ #
499
+ # plruby_test=# CREATE FUNCTION tutu() RETURNS int4 AS '
500
+ # plruby_test'# toto(1, 3) + toto(4, 4)
501
+ # plruby_test'# end
502
+ # plruby_test'#
503
+ # plruby_test'# def PLtemp.toto(a, b)
504
+ # plruby_test'# a + b
505
+ # plruby_test'# ' LANGUAGE 'plruby';
506
+ # CREATE
507
+ # plruby_test=# select tutu();
508
+ # tutu
509
+ # ----
510
+ # 12
511
+ # (1 row)
512
+ #
513
+ # plruby_test=#
514
+ #
515
+ #
516
+ # * create a table plruby_singleton_methods with the columns (name, args, body)
517
+ #
518
+ # At load time, PLRuby look if it exist a table plruby_singleton_methods
519
+ # and if found try, for each row, to define singleton methods with the
520
+ # template :
521
+ #
522
+ # def PLtemp.#{name}(#{args})
523
+ # #{body}
524
+ # end
525
+ #
526
+ # The previous example can be written (you have a more complete example in
527
+ # test/plp/test_setup.sql)
528
+ #
529
+ #
530
+ # plruby_test=# SELECT * FROM plruby_singleton_methods;
531
+ # name|args|body
532
+ # ----+----+-----
533
+ # toto|a, b|a + b
534
+ # (1 row)
535
+ #
536
+ # plruby_test=# CREATE FUNCTION tutu() RETURNS int4 AS '
537
+ # plruby_test'# toto(1, 3) + toto(4, 4)
538
+ # plruby_test'# ' LANGUAGE 'plruby';
539
+ # CREATE
540
+ # plruby_test=# select tutu();
541
+ # tutu
542
+ # ----
543
+ # 12
544
+ # (1 row)
545
+ #
546
+ # plruby_test=#
547
+ #
548
+ # * Another example, if PLRuby was compiled with --enable-conversion and it
549
+ # exist a column with the name '***' then it can create a singleton method
550
+ # from a PLRuby function
551
+ #
552
+ #
553
+ # plruby_test=# select * from plruby_singleton_methods;
554
+ # name | args | body
555
+ # ------+------+------
556
+ # *** | |
557
+ # (1 row)
558
+ #
559
+ # plruby_test=# create function add_value(int, int) returns int as '
560
+ # plruby_test'# args[0] + args[1]
561
+ # plruby_test'# ' language 'plruby';
562
+ # CREATE FUNCTION
563
+ # plruby_test=#
564
+ # plruby_test=# select add_value(10, 2);
565
+ # add_value
566
+ # -----------
567
+ # 12
568
+ # (1 row)
569
+ #
570
+ # plruby_test=#
571
+ # plruby_test=# create function add_one(int) returns int as '
572
+ # plruby_test'# add_value(args[0], 1)
573
+ # plruby_test'# ' language 'plruby';
574
+ # CREATE FUNCTION
575
+ # plruby_test=#
576
+ # plruby_test=# select add_one(11);
577
+ # add_one
578
+ # ---------
579
+ # 12
580
+ # (1 row)
581
+ #
582
+ # plruby_test=#
583
+ #
584
+ #
585
+ #
586
+ class PLRuby::Description::Singleton_method
587
+ end
588
+ #If the conversions was not disabled (--disable-conversion), the following
589
+ #conversions are made
590
+ #
591
+ # PostgreSQL Ruby
592
+ # ---------- ----
593
+ # OID Fixnum
594
+ # INT2OID Fixnum
595
+ # INT4OID Fixnum
596
+ # INT8OID Fixnum (or Bignum)
597
+ # FLOAT4OID Float
598
+ # FLOAT8OID Float
599
+ # CASHOID Float
600
+ # NUMERICOID Float
601
+ # BOOLOID true, false
602
+ # ABSTIMEOID Time
603
+ # RELTIMEOID Time
604
+ # TIMEOID Time
605
+ # TIMETZOID Time
606
+ # TIMESTAMPOID Time
607
+ # TIMESTAMPTZOID Time
608
+ # DATEOID Time
609
+ # INTERVALOID Time
610
+ # TINTERVALOID Tinterval (new Ruby class)
611
+ # BITOID BitString (new Ruby class)
612
+ # VARBITOID BitString (new Ruby class)
613
+ # INETOID NetAddr (new Ruby class)
614
+ # CIDROID NetAddr (new Ruby class)
615
+ # MACADDROID MacAddr (new Ruby class)
616
+ # POINTOID Point (new Ruby class)
617
+ # LSEGOID Segment (new Ruby class)
618
+ # BOXOID Box (new Ruby class)
619
+ # PATHOID Path (new Ruby class)
620
+ # POLYGONOID Polygon (new Ruby class)
621
+ # CIRCLEOID Circle (new Ruby class)
622
+ #
623
+ #all others OID are converted to a String object
624
+ #
625
+ class PLRuby::Description::Conversion
626
+ end
627
+ #
628
+ # general module
629
+ #
630
+ module PLRuby::PL
631
+ class << self
632
+ #
633
+ #Return the type of the arguments given to the function
634
+ #
635
+ def args_type
636
+ end
637
+ #
638
+ #Return the name of the columns for the table
639
+ #
640
+ def column_name(table)
641
+ end
642
+ #
643
+ #return the type of the columns for the table
644
+ #
645
+ def column_type(table)
646
+ end
647
+ #
648
+ #Return the context (or nil) associated with a SETOF function
649
+ #(ExprMultiResult)
650
+ #
651
+ def context
652
+ end
653
+ #
654
+ #Set the context for a SETOF function (ExprMultiResult)
655
+ #
656
+ def context=
657
+ end
658
+ #
659
+ #
660
+ #Duplicates all occurences of single quote and backslash
661
+ #characters. It should be used when variables are used in the query
662
+ #string given to spi_exec or spi_prepare (not for the value list on
663
+ #execp).
664
+ #
665
+ def quote(string)
666
+ end
667
+ #
668
+ #Return the name of the columns for a function returning a SETOF
669
+ #
670
+ def result_name
671
+ end
672
+ #
673
+ #Return the type of the columns for a function returning a SETOF
674
+ #or the type of the return value
675
+ #
676
+ def result_type
677
+ end
678
+ #
679
+ #Return the number of columns for a function returning a SETOF
680
+ #
681
+ def result_size
682
+ end
683
+ #
684
+ #Return the table description given to a function returning a SETOF
685
+ #
686
+ def result_description
687
+ end
688
+ #
689
+ #
690
+ #Call parser/planner/optimizer/executor for query. The optional
691
+ #<em>count</em> value tells spi_exec the maximum number of rows to be
692
+ #processed by the query.
693
+ #
694
+ #* SELECT
695
+ #If the query is a SELECT statement, an array is return (if count is
696
+ #not specified or with a value > 1). Each element of this array is an
697
+ #hash where the key is the column name.
698
+ #
699
+ #If type is specified it can take the value
700
+ #
701
+ #* "array" return for each column an array with the element
702
+ #["name", "value", "type", "len", "typeid"]
703
+ #* "hash" return for each column an hash with the keys
704
+ #{"name", "value", "type", "len", "typeid"}
705
+ #* "value" return all values
706
+ #
707
+ #For example this procedure display all rows in the table pg_table.
708
+ #
709
+ # CREATE FUNCTION pg_table_dis() RETURNS int4 AS '
710
+ # res = PL.exec("select * from pg_class")
711
+ # res.each do |x|
712
+ # warn "======================"
713
+ # x.each do |y, z|
714
+ # warn "name = #{y} -- value = #{z}"
715
+ # end
716
+ # warn "======================"
717
+ # end
718
+ # return res.size
719
+ # ' LANGUAGE 'plruby';
720
+ #
721
+ #A block can be specified, in this case a call to yield() will be
722
+ #made.
723
+ #
724
+ #If count is specified with the value 1, only the first row (or
725
+ #FALSE if it fail) is returned as a hash. Here a little example :
726
+ #
727
+ #
728
+ # CREATE FUNCTION pg_table_dis() RETURNS int4 AS '
729
+ # PL.exec("select * from pg_class", 1) { |y, z|
730
+ # warn "name = #{y} -- value = #{z}"
731
+ # }
732
+ # return 1
733
+ # ' LANGUAGE 'plruby';
734
+ #
735
+ #Another example with count = 1
736
+ #
737
+ # create table T_pkey1 (
738
+ # skey1 int4,
739
+ # skey2 varchar(20),
740
+ # stxt varchar(40)
741
+ # );
742
+ #
743
+ # create function toto() returns bool as '
744
+ # warn("=======")
745
+ # PL.exec("select * from T_pkey1", 1, "hash") do |a|
746
+ # warn(a.inspect)
747
+ # end
748
+ # warn("=======")
749
+ # PL.exec("select * from T_pkey1", 1, "array") do |a|
750
+ # warn(a.inspect)
751
+ # end
752
+ # warn("=======")
753
+ # PL.exec("select * from T_pkey1", 1) do |a|
754
+ # warn(a.inspect)
755
+ # end
756
+ # warn("=======")
757
+ # return true
758
+ # ' language 'plruby';
759
+ #
760
+ # plruby_test=# select toto();
761
+ # NOTICE: =======
762
+ # NOTICE: {"name"=>"skey1", "typeid"=>23, "type"=>"int4", "value"=>"12", "len"=>4}
763
+ # NOTICE: {"name"=>"skey2", "typeid"=>1043, "type"=>"varchar", "value"=>"a", "len"=>20}
764
+ # NOTICE: {"name"=>"stxt", "typeid"=>1043, "type"=>"varchar", "value"=>"b", "len"=>40}
765
+ # NOTICE: =======
766
+ # NOTICE: ["skey1", "12", "int4", 4, 23]
767
+ # NOTICE: ["skey2", "a", "varchar", 20, 1043]
768
+ # NOTICE: ["stxt", "b", "varchar", 40, 1043]
769
+ # NOTICE: =======
770
+ # NOTICE: ["skey1", "12"]
771
+ # NOTICE: ["skey2", "a"]
772
+ # NOTICE: ["stxt", "b"]
773
+ # NOTICE: =======
774
+ # toto
775
+ # ------
776
+ # t
777
+ # (1 row)
778
+ #
779
+ # plruby_test=#
780
+ #
781
+ #
782
+ #* SELECT INTO, INSERT, UPDATE, DELETE
783
+ #return the number of rows insered, updated, deleted, ...
784
+ #
785
+ #
786
+ #* UTILITY
787
+ #return TRUE
788
+ #
789
+ def exec(string [, count [, type]])
790
+ end
791
+ #same than <em> exec</em>
792
+ def spi_exec(string [, count [, type]])
793
+ end
794
+
795
+ #
796
+ #
797
+ #Deprecated : See <em>PL::Plan::new</em> and <em>PL::Plan#save</em>
798
+ #
799
+ #Prepares AND SAVES a query plan for later execution. It is a bit
800
+ #different from the C level SPI_prepare in that the plan is
801
+ #automatically copied to the toplevel memory context.
802
+ #
803
+ #If the query references arguments, the type names must be given as a
804
+ #Ruby array of strings. The return value from prepare is a
805
+ #<em>PL::Plan</em> object to be used in subsequent calls to
806
+ #<em>PL::Plan#exec</em>.
807
+ #
808
+ #If the hash given has the keys <em>count</em>, <em>output</em> these values
809
+ #will be given to the subsequent calls to <em>each</em>
810
+ def prepare(string[, types])
811
+ end
812
+ #same than <em> prepare</em>
813
+ def spi_prepare(string[, types])
814
+ end
815
+ end
816
+ #
817
+ # class for prepared plan
818
+ #
819
+ class PL::Plan
820
+ #
821
+ #
822
+ #Prepares a query plan for later execution.
823
+ #
824
+ #If the query references arguments, the type names must be given as a
825
+ #Ruby array of strings.
826
+ #
827
+ #If the hash given has the keys <em>output</em>, <em>count</em> these values
828
+ #will be given to the subsequent calls to <em>each</em>
829
+ #
830
+ #If <em>"save"</em> as a true value, the plan will be saved
831
+ #
832
+ #
833
+ def initialize(string, "types" => types, "count" => count, "output" => type, "save" => false)
834
+ end
835
+ #
836
+ #
837
+ #Execute a prepared plan from <em>PL::Plan::new</em> with variable
838
+ #substitution. The optional <em>count</em> value tells
839
+ #<em>PL::Plan#exec</em> the maximum number of rows to be processed by the
840
+ #query.
841
+ #
842
+ #If there was a typelist given to <em>PL::Plan::new</em>, an array
843
+ #of <em>values</em> of exactly the same length must be given to
844
+ #<em>PL::Plan#exec</em> as first argument. If the type list on
845
+ #<em>PL::Plan::new</em> was empty, this argument must be omitted.
846
+ #
847
+ #If the query is a SELECT statement, the same as described for
848
+ #<em>PL#exec</em> happens for the loop-body and the variables for
849
+ #the fields selected.
850
+ #
851
+ #If type is specified it can take the values
852
+ #* "array" return an array with the element ["name", "value", "type", "len", "typeid"]
853
+ #* "hash" return an hash with the keys {"name", "value", "type", "len", "typeid"}
854
+ #* "value" return an array with all values
855
+ #
856
+ #Here's an example for a PLRuby function using a prepared plan :
857
+ #
858
+ # CREATE FUNCTION t1_count(int4, int4) RETURNS int4 AS '
859
+ # if ! $Plans.key?("plan")
860
+ # # prepare the saved plan on the first call
861
+ # $Plans["plan"] = PL::Plan.new("SELECT count(*) AS cnt FROM t1
862
+ # WHERE num >= $1 AND num <= $2",
863
+ # ["int4", "int4"]).save
864
+ # end
865
+ # n = $Plans["plan"].exec([args[0], args[1]], 1)
866
+ # n["cnt"]
867
+ # ' LANGUAGE 'plruby';
868
+ #
869
+ def exec(values, [count [, type]])
870
+ end
871
+ #same than <em> exec</em>
872
+ def execp(values, [count [, type]])
873
+ end
874
+ #same than <em> exec</em>
875
+ def execp("values" => values, "count" => count, "output" => type)
876
+ end
877
+ #
878
+ #
879
+ #Create a new object PL::Cursor
880
+ #
881
+ #If output is specified it can take the values
882
+ #* "array" return an array with the element ["name", "value", "type", "len", "typeid"]
883
+ #* "hash" return an hash with the keys {"name", "value", "type", "len", "typeid"}
884
+ #* "value" return an array with all values
885
+ #
886
+ #If there was a typelist given to <em>PL::Plan::new</em>, an array
887
+ #of <em>values</em> of exactly the same length must be given to
888
+ #<em>PL::Plan#cursor</em>
889
+ #
890
+ def cursor(name = nil, "values" => values, "output" => type)
891
+ end
892
+ #
893
+ #
894
+ #Same then #exec but a call to SPI_cursor_open(), SPI_cursor_fetch() is made.
895
+ #
896
+ #Can be used only with a block and a SELECT statement
897
+ #
898
+ # create function toto() returns bool as '
899
+ # plan = PL::Plan.new("select * from T_pkey1")
900
+ # warn "=====> ALL"
901
+ # plan.each do |x|
902
+ # warn(x.inspect)
903
+ # end
904
+ # warn "=====> FIRST 2"
905
+ # plan.each("count" => 2) do |x|
906
+ # warn(x.inspect)
907
+ # end
908
+ # return true
909
+ # ' language 'plruby';
910
+ #
911
+ # plruby_test=# select * from T_pkey1;
912
+ # skey1 | skey2 | stxt
913
+ # -------+-------+------
914
+ # 12 | a | b
915
+ # 24 | c | d
916
+ # 36 | e | f
917
+ # (3 rows)
918
+ #
919
+ # plruby_test=#
920
+ # plruby_test=# select toto();
921
+ # NOTICE: =====> ALL
922
+ # NOTICE: {"skey1"=>"12", "skey2"=>"a", "stxt"=>"b"}
923
+ # NOTICE: {"skey1"=>"24", "skey2"=>"c", "stxt"=>"d"}
924
+ # NOTICE: {"skey1"=>"36", "skey2"=>"e", "stxt"=>"f"}
925
+ # NOTICE: =====> FIRST 2
926
+ # NOTICE: {"skey1"=>"12", "skey2"=>"a", "stxt"=>"b"}
927
+ # NOTICE: {"skey1"=>"24", "skey2"=>"c", "stxt"=>"d"}
928
+ # toto
929
+ # ------
930
+ # t
931
+ # (1 row)
932
+ #
933
+ # plruby_test=#
934
+ #
935
+ def each(values, [count [, type ]]) { ... }
936
+ end
937
+ #same than <em> each</em>
938
+ def fetch(values, [count [, type ]]) { ... }
939
+ end
940
+ #same than <em> each</em>
941
+ def fetch("values" => values, "count" => count, "output" => type) { ... }
942
+ end
943
+ #
944
+ #
945
+ #Release a query plan
946
+ #
947
+ def release
948
+ end
949
+ #
950
+ #
951
+ #Save a query plan for later execution. The plan is copied to the
952
+ #toplevel memory context.
953
+ #
954
+ def save
955
+ end
956
+ end
957
+ end
958
+
959
+ #
960
+ # A cursor is created with the method PL::Plan#cursor
961
+ #
962
+ class PLRuby::PL::Cursor
963
+ #Closes a cursor
964
+ #
965
+ def close
966
+ end
967
+ #
968
+ #
969
+ #Iterate over all rows (forward)
970
+ #
971
+ def each
972
+ yield row
973
+ end
974
+ #
975
+ #
976
+ #Fetches some rows from a cursor
977
+ #
978
+ #if count > 0 fetch forward else backward
979
+ #
980
+ def fetch(count = 1)
981
+ end
982
+ #same than <em> fetch</em>
983
+ def row(count = 1)
984
+ end
985
+ #
986
+ #
987
+ #Move a cursor : if count > 0 move forward else backward
988
+ #
989
+ def move(count)
990
+ end
991
+ #
992
+ #
993
+ #Iterate over all rows (backward)
994
+ #
995
+ def reverse_each
996
+ yield row
997
+ end
998
+ end
999
+
1000
+ #
1001
+ # A transaction is created with the global function #transaction
1002
+ #
1003
+ # Only available with PostgreSQL >= 8.0
1004
+ #
1005
+ class PLRuby::PL::Transaction
1006
+
1007
+ # abort the transaction
1008
+ def abort
1009
+ end
1010
+
1011
+ # commit the transaction
1012
+ def commit
1013
+ end
1014
+ end
1015
+ #
1016
+ # The class PLRuby::BitString implement the PostgreSQL type <em>bit</em>
1017
+ # and <em>bit varying</em>
1018
+ #
1019
+ class PLRuby::BitString
1020
+ include Comparable
1021
+ include Enumerable
1022
+
1023
+ class << self
1024
+
1025
+ # Convert a <em>String</em> to a <em>BitString</em>
1026
+ def from_string(string, length = strlen(string))
1027
+ end
1028
+ end
1029
+
1030
+ # comparison function for 2 <em>BitString</em> objects
1031
+ #
1032
+ # All bits are considered and additional zero bits may make one string
1033
+ # smaller/larger than the other, even if their zero-padded values would
1034
+ # be the same.
1035
+ def <=>(other)
1036
+ end
1037
+
1038
+ # Concatenate <em>self</em> and <em>other</em>
1039
+ def +(other)
1040
+ end
1041
+
1042
+ # AND operator
1043
+ def &(other)
1044
+ end
1045
+
1046
+ # OR operator
1047
+ def |(other)
1048
+ end
1049
+
1050
+ # XOR operator
1051
+ def ^(other)
1052
+ end
1053
+
1054
+ # NOT operator
1055
+ def ~()
1056
+ end
1057
+
1058
+ # LEFT SHIFT operator
1059
+ def <<(lshft)
1060
+ end
1061
+
1062
+ # RIGHT SHIFT operator
1063
+ def >>(rshft)
1064
+ end
1065
+
1066
+ # Element reference with the same syntax that for a <em>String</em> object
1067
+ #
1068
+ # Return a <em>BitString</em> or a <em>Fixnum</em> 0, 1
1069
+ #
1070
+ # bitstring[fixnum]
1071
+ # bitstring[fixnum, fixnum]
1072
+ # bitstring[range]
1073
+ # bitstring[regexp]
1074
+ # bitstring[regexp, fixnum]
1075
+ # bitstring[string]
1076
+ # bitstring[other_bitstring]
1077
+ def [](*args)
1078
+ end
1079
+
1080
+ # Element assignment with the same syntax that for a <em>String</em> object
1081
+ #
1082
+ # bitstring[fixnum] = fixnum
1083
+ # bitstring[fixnum] = string_or_bitstring
1084
+ # bitstring[fixnum, fixnum] = string_or_bitstring
1085
+ # bitstring[range] = string_or_bitstring
1086
+ # bitstring[regexp] = string_or_bitstring
1087
+ # bitstring[regexp, fixnum] = string_or_bitstring
1088
+ # bitstring[other_str] = string_or_bitstring
1089
+ def []=(*args)
1090
+ end
1091
+
1092
+ # append <em>other</em> to <em>self</em>
1093
+ def concat(other)
1094
+ end
1095
+
1096
+ # iterate other each bit
1097
+ def each
1098
+ end
1099
+
1100
+ # return <em>true</em> if <em>other</em> is included in <em>self</em>
1101
+ def include?(other)
1102
+ end
1103
+
1104
+ # return the position of <em>other</em> in <em>self</em>
1105
+ #
1106
+ # return <em>nil</em> if <em>other</em> is not included in <em>self</em>
1107
+ def index(other)
1108
+ end
1109
+
1110
+ # create a new <em>BitString</em> object with <em>nbits</em> bits
1111
+ #
1112
+ # <em>init</em> can be a <em>Fixnum</em> or a <em>String</em>
1113
+ #
1114
+ # For a <em>String</em> the first character can be 'x', 'X' for and
1115
+ # hexadecimal representation, or 'b', 'B' for a binary representation.
1116
+ # The default is a binary representation
1117
+ def initialize(init, nbits = -1)
1118
+ end
1119
+
1120
+ # return the length of <em>self</em> in bits
1121
+ def length
1122
+ end
1123
+
1124
+ # return the length of <em>self</em> in octets
1125
+ def octet_length
1126
+ end
1127
+
1128
+ # append <em>other</em> to <em>self</em>
1129
+ def push(other)
1130
+ end
1131
+
1132
+ # convert <em>self</em> to a <em>Fixnum</em>
1133
+ def to_i
1134
+ end
1135
+
1136
+ # convert <em>self</em> to a <em>String</em>
1137
+ def to_s
1138
+ end
1139
+
1140
+ end
1141
+
1142
+ #
1143
+ # The class PLRuby::NetAddr implement the PostgreSQL type <em>inet</em>
1144
+ # and <em>cidr</em>
1145
+ #
1146
+ class PLRuby::NetAddr
1147
+ include Comparable
1148
+
1149
+ class << self
1150
+
1151
+ # Convert a <em>String</em> to a <em>NetAddr</em>
1152
+ def from_string(string, cidr = false)
1153
+ end
1154
+ end
1155
+
1156
+ # comparison function for 2 <em>NetAddr</em> objects
1157
+ #
1158
+ # comparison is first on the common bits of the network part, then on
1159
+ # the length of the network part, and then on the whole unmasked address.
1160
+ def <=>(other)
1161
+ end
1162
+
1163
+ # return the abbreviated display format as a <em>String</em> object
1164
+ def abbrev
1165
+ end
1166
+
1167
+ # return the broadcast address from the network
1168
+ def broadcast
1169
+ end
1170
+
1171
+ # return true if <em>other</em> is included in <em>self</em>
1172
+ def contain?(other)
1173
+ end
1174
+
1175
+ # return true if <em>other</em> is included in <em>self</em>, or equal
1176
+ def contain_or_equal?(other)
1177
+ end
1178
+
1179
+ # return true if <em>self</em> is included in <em>other</em>
1180
+ def contained?(other)
1181
+ end
1182
+
1183
+ # return true if <em>self</em> is included in <em>other</em>, or equal
1184
+ def contained_or_equal?(other)
1185
+ end
1186
+
1187
+ # return the String "AF_INET" or "AF_INET6"
1188
+ def family
1189
+ end
1190
+
1191
+ # return the first address in the network
1192
+ def first
1193
+ end
1194
+
1195
+ # extract the IP address and return it as a <em>String</em>
1196
+ def host
1197
+ end
1198
+
1199
+ # return the host mask for network
1200
+ def hostmask
1201
+ end
1202
+
1203
+ # create a <em>NetAddr</em> from a <em>String</em>
1204
+ def initialize(string, cidr = false)
1205
+ end
1206
+
1207
+ # return the last address in the network
1208
+ def last
1209
+ end
1210
+
1211
+ # return the length of the netmask
1212
+ def masklen
1213
+ end
1214
+
1215
+ # return the netmask for the network
1216
+ def netmask
1217
+ end
1218
+
1219
+ # return the network part of the address
1220
+ def network
1221
+ end
1222
+
1223
+ # return a new <em>NetAddr</em> with netmask length <em>len</em>
1224
+ def set_masklen(len)
1225
+ end
1226
+
1227
+ # return the string representation of the address
1228
+ def to_s
1229
+ end
1230
+
1231
+ end
1232
+
1233
+ #
1234
+ # The class PLRuby::MacAddr implement the PostgreSQL type <em>macaddr</em>
1235
+ #
1236
+ class PLRuby::MacAddr
1237
+ include Comparable
1238
+
1239
+ class << self
1240
+
1241
+ # Convert a <em>String</em> to a <em>MacAddr</em>
1242
+ def from_string(string, cidr = false)
1243
+ end
1244
+ end
1245
+
1246
+ # comparison function for 2 <em>MacAddr</em> objects
1247
+ def <=>(other)
1248
+ end
1249
+
1250
+ # create a <em>MacAddr</em> from a <em>String</em>
1251
+ def initialize(string)
1252
+ end
1253
+
1254
+ # return the string representation of the MAC address
1255
+ def to_s
1256
+ end
1257
+
1258
+ # return a new object with the last 3 bytes set to zero
1259
+ def truncate
1260
+ end
1261
+
1262
+ end
1263
+
1264
+ #
1265
+ # The class PLRuby::Tinterval implement the PostgreSQL type <em>tinterval</em>
1266
+ #
1267
+ class PLRuby::Tinterval
1268
+ class << self
1269
+
1270
+ # Convert a <em>String</em> (PostgreSQL representation)
1271
+ # to a <em>Tinterval</em>
1272
+ def from_string(string)
1273
+ end
1274
+ end
1275
+
1276
+ # return a <em>Time</em> which is the high value of the interval
1277
+ def high
1278
+ end
1279
+
1280
+ # set the high value for the interval
1281
+ def high=(time)
1282
+ end
1283
+
1284
+ # create a <em>Tinterval</em> with the 2 <em>Time</em> objects
1285
+ # <em>low</em> and <em>high</em>
1286
+ def initialize(low, high)
1287
+ end
1288
+
1289
+ # return a <em>Time</em> which is the low value of the interval
1290
+ def low
1291
+ end
1292
+
1293
+ # set the low value for the interval
1294
+ def low=(time)
1295
+ end
1296
+
1297
+ # return the string representation of the object
1298
+ def to_s
1299
+ end
1300
+
1301
+ end
1302
+
1303
+ #
1304
+ # The class PLRuby::Box implement the PostgreSQL type <em>box</em>
1305
+ #
1306
+ class PLRuby::Box
1307
+ include Comparable
1308
+
1309
+ class << self
1310
+
1311
+ # Convert a <em>String</em> (PostgreSQL representation)
1312
+ # to a <em>Box</em> object
1313
+ def from_string(string)
1314
+ end
1315
+ end
1316
+
1317
+ # translate (right, up) <em>self</em>
1318
+ def +(point)
1319
+ end
1320
+
1321
+ # translate (left, down) <em>self</em>
1322
+ def -(point)
1323
+ end
1324
+
1325
+ # scale and rotate <em>self</em>
1326
+ def *(point)
1327
+ end
1328
+
1329
+ # scale and rotate <em>self</em>
1330
+ def /(point)
1331
+ end
1332
+
1333
+ # return true if the 2 boxes <em>self</em> and <em>other</em> are identical
1334
+ def ===(other)
1335
+ end
1336
+
1337
+ # comparison operator for 2 Box based on the area of the 2 objects, i.e.
1338
+ # self.area <=> box.area
1339
+ def <=>(other)
1340
+ end
1341
+
1342
+ # return true if <em>self</em> is above <em>other</em>
1343
+ def above?(other)
1344
+ end
1345
+
1346
+ # return the area of the Box
1347
+ def area
1348
+ end
1349
+
1350
+ # return true if <em>self</em> is below <em>other</em>
1351
+ def below?(other)
1352
+ end
1353
+
1354
+ # return the center point of the Box
1355
+ def center
1356
+ end
1357
+
1358
+ # closest point to <em>other</em>
1359
+ #
1360
+ # <em>other</em> can be a Point, or Segment
1361
+ def closest(other)
1362
+ end
1363
+
1364
+ # return true if <em>self</em> contain <em>other</em>
1365
+ def contain?(other)
1366
+ end
1367
+
1368
+ # return true if <em>self</em> is contained by <em>other</em>
1369
+ def contained?(other)
1370
+ end
1371
+
1372
+ # return a line Segment which happens to be the
1373
+ # positive-slope diagonal of Box
1374
+ def diagonal
1375
+ end
1376
+
1377
+ # return the height of the Box (vertical magnitude)
1378
+ def height
1379
+ end
1380
+
1381
+ # return true if <em>self</em> is contained by <em>other</em>
1382
+ def in?(other)
1383
+ end
1384
+
1385
+ # create a new Box object
1386
+ #
1387
+ # <em>args</em> can be 2 Point objects (low, high) or 4 Float objects
1388
+ # (low.x, low.y, high.x, high.y)
1389
+ def initialize(*args)
1390
+ end
1391
+
1392
+ # returns the overlapping portion of two boxes,
1393
+ # or <em>nil</em> if they do not intersect.
1394
+ def intersection(other)
1395
+ end
1396
+
1397
+ # returns true if the Segment <em>segment</em>
1398
+ # intersect with the Box
1399
+ #
1400
+ # Segment completely inside box counts as intersection.
1401
+ # If you want only segments crossing box boundaries,
1402
+ # try converting Box to Path first.
1403
+ #
1404
+ def intersect?(segment)
1405
+ end
1406
+
1407
+ # return true if <em>self</em> is strictly left of <em>other</em>
1408
+ def left?(other)
1409
+ end
1410
+
1411
+ # return true if <em>self</em> overlap <em>other</em>
1412
+ def overlap?(other)
1413
+ end
1414
+
1415
+ # return true if the right edge of <em>self</em> is to the left of
1416
+ # the right edge of <em>other</em>
1417
+ def overleft?(other)
1418
+ end
1419
+
1420
+ # return true if the left edge of <em>self</em> is to the right of
1421
+ # the left edge of <em>other</em>
1422
+ def overright?(other)
1423
+ end
1424
+
1425
+ # return true if <em>self</em> is strictly right of <em>other</em>
1426
+ def right?(other)
1427
+ end
1428
+
1429
+ # return true if the 2 boxes <em>self</em> and <em>other</em> are identical
1430
+ def same?(other)
1431
+ end
1432
+
1433
+ # convert a Box to a Circle
1434
+ def to_circle
1435
+ end
1436
+
1437
+ # return the center Point of the Box
1438
+ def to_point
1439
+ end
1440
+
1441
+ # convert a Box to a Polygon
1442
+ def to_polygon
1443
+ end
1444
+
1445
+ # return a line Segment which happens to be the
1446
+ # positive-slope diagonal of Box
1447
+ def to_segment
1448
+ end
1449
+
1450
+ # return the width of the Box (horizontal magnitude)
1451
+ def width
1452
+ end
1453
+ end
1454
+
1455
+ #
1456
+ # The class PLRuby::Path implement the PostgreSQL type <em>path</em>
1457
+ #
1458
+ class PLRuby::Path
1459
+ include Comparable
1460
+
1461
+ class << self
1462
+
1463
+ # Convert a <em>String</em> (PostgreSQL representation)
1464
+ # to a <em>Path</em>
1465
+ def from_string(string)
1466
+ end
1467
+ end
1468
+
1469
+ # concatenate the two paths (only if they are both open)
1470
+ def <<(path)
1471
+ end
1472
+
1473
+ # translate (right, up) <em>self</em>
1474
+ def +(point)
1475
+ end
1476
+
1477
+ # translate (left, down) <em>self</em>
1478
+ def -(point)
1479
+ end
1480
+
1481
+ # scale and rotate <em>self</em>
1482
+ def *(point)
1483
+ end
1484
+
1485
+ # scale and rotate <em>self</em>
1486
+ def /(point)
1487
+ end
1488
+
1489
+ # comparison function based on the path cardinality, i.e.
1490
+ # self.npoints <=> other.npoints
1491
+ def <=>(other)
1492
+ end
1493
+
1494
+ # make a closed path
1495
+ def close
1496
+ end
1497
+
1498
+ # return true if <em>self</em> is a closed path
1499
+ def closed?
1500
+ end
1501
+
1502
+ # concatenate the two paths (only if they are both open)
1503
+ def concat(path)
1504
+ end
1505
+
1506
+ # create a new Path object from the Array of Point <em>points</em>
1507
+ def initialize(points, closed = false)
1508
+ end
1509
+
1510
+ # return the length of <em>self</em>
1511
+ def length
1512
+ end
1513
+
1514
+ # return the path cardinality
1515
+ def npoints
1516
+ end
1517
+
1518
+ # make an open path
1519
+ def open
1520
+ end
1521
+
1522
+ # convert <em>self</em> to a Polygon object
1523
+ def to_polygon
1524
+ end
1525
+ end
1526
+ #
1527
+ # The class PLRuby::Point implement the PostgreSQL type <em>point</em>
1528
+ #
1529
+ class PLRuby::Point
1530
+ include Comparable
1531
+
1532
+ class << self
1533
+
1534
+ # Convert a <em>String</em> (PostgreSQL representation)
1535
+ # to a <em>Point</em>
1536
+ def from_string(string)
1537
+ end
1538
+ end
1539
+
1540
+ # translate (right, up) <em>self</em>
1541
+ def +(point)
1542
+ end
1543
+
1544
+ # translate (left, down) <em>self</em>
1545
+ def -(point)
1546
+ end
1547
+
1548
+ # scale and rotate <em>self</em>
1549
+ def *(point)
1550
+ end
1551
+
1552
+ # scale and rotate <em>self</em>
1553
+ def /(point)
1554
+ end
1555
+
1556
+ # return the coordinate
1557
+ #
1558
+ # <em>indice</em> can have the value 0 or 1
1559
+ def [](indice)
1560
+ end
1561
+
1562
+ # set the coordinate
1563
+ #
1564
+ # <em>indice</em> can have the value 0 or 1
1565
+ def []=(indice, value)
1566
+ end
1567
+
1568
+ # return true if <em>self</em> and <em>other</em> are the same,
1569
+ # i.e. self.x == other.x && self.y == other.y
1570
+ def ==(other)
1571
+ end
1572
+
1573
+ # return true if <em>self</em> is above <em>other</em>,
1574
+ # i.e. self.y > other.y
1575
+ def above?(other)
1576
+ end
1577
+
1578
+ # return true if <em>self</em> is below <em>other</em>,
1579
+ # i.e. self.y < other.y
1580
+ def below?(other)
1581
+ end
1582
+
1583
+ # return true if <em>self</em> is contained in <em>other</em>
1584
+ #
1585
+ # <em>other</em> can be Point, Polygon or a Circle object
1586
+ def contained?(other)
1587
+ end
1588
+
1589
+ # return true if <em>self</em> and <em>other</em> are horizontal,
1590
+ # i.e. self.y == other.y
1591
+ def horizontal?(other)
1592
+ end
1593
+
1594
+ # return true if <em>self</em> is contained in <em>other</em>
1595
+ #
1596
+ # <em>other</em> can be Point, Polygon or a Circle object
1597
+ def in?(other)
1598
+ end
1599
+
1600
+ # create a Point with the 2 Float object (x, y)
1601
+ def initialize(x, y)
1602
+ end
1603
+
1604
+ # return true if <em>self</em> is at the left of <em>other</em>,
1605
+ # i.e. self.x < other.x
1606
+ def left?(other)
1607
+ end
1608
+
1609
+ # return true if <em>self</em> is on <em>other</em>
1610
+ #
1611
+ # <em>other</em> can be Point, Segment, Box or Path object
1612
+ def on?(other)
1613
+ end
1614
+
1615
+ # return true if <em>self</em> is at the right of <em>other</em>,
1616
+ # i.e. self.x > other.x
1617
+ def right?(other)
1618
+ end
1619
+
1620
+ # return true if <em>self</em> and <em>other</em> are vertical,
1621
+ # i.e. self.x == other.x
1622
+ def vertical?(other)
1623
+ end
1624
+
1625
+ # return <em>x</em> for <em>self</em>
1626
+ def x
1627
+ end
1628
+
1629
+ # set the <em>x</em> value for <em>self</em>
1630
+ def x=(value)
1631
+ end
1632
+
1633
+ # return <em>y</em> for <em>self</em>
1634
+ def y
1635
+ end
1636
+
1637
+ # set the <em>y</em> value for <em>self</em>
1638
+ def y=(value)
1639
+ end
1640
+
1641
+ end
1642
+
1643
+ #
1644
+ # The class PLRuby::Segment implement the PostgreSQL type <em>lseg</em>
1645
+ #
1646
+ class PLRuby::Segment
1647
+ include Comparable
1648
+
1649
+ class << self
1650
+
1651
+ # Convert a <em>String</em> (PostgreSQL representation)
1652
+ # to a <em>Segment</em>
1653
+ def from_string(string)
1654
+ end
1655
+ end
1656
+
1657
+ # comparison function for the 2 segments, returns
1658
+ #
1659
+ # 0 if self[0] == other[0] && self[1] == other[1]
1660
+ #
1661
+ # 1 if distance(self[0], self[1]) > distance(other[0], other[1])
1662
+ #
1663
+ # -1 if distance(self[0], self[1]) < distance(other[0], other[1])
1664
+ def <=>(other)
1665
+ end
1666
+
1667
+ # return the center of the segment
1668
+ def center
1669
+ end
1670
+
1671
+ # closest point to other
1672
+ #
1673
+ # <em>other</em> can be a Point, Segment or Box
1674
+ #
1675
+ # With a point, take the closest endpoint
1676
+ # if the point is left, right, above, or below the segment, otherwise
1677
+ # find the intersection point of the segment and its perpendicular through
1678
+ # the point.
1679
+ def closest(other)
1680
+ end
1681
+
1682
+ # returns true if <em>self</em> is a horizontal Segment
1683
+ def horizontal?
1684
+ end
1685
+
1686
+ # create a Segment from the 2 Point p0, p1
1687
+ def initialize(point0, point1)
1688
+ end
1689
+
1690
+ # returns true if <em>self</em> and <em>other</em> intersect
1691
+ def intersect?(other)
1692
+ end
1693
+
1694
+ # returns the Point where the 2 Segment <em>self</em> and <em>other</em>
1695
+ # intersect or nil
1696
+ def intersection(other)
1697
+ end
1698
+
1699
+ # return the length of <em>self</em>, i.e. the distnace between the 2 points
1700
+ def length
1701
+ end
1702
+
1703
+ # return true if <em>self</em> is on <em>other</em>
1704
+ #
1705
+ # <em>other</em> can be a Segment, or a Box object
1706
+ def on?(other)
1707
+ end
1708
+
1709
+ # returns true if the 2 Segment <em>self</em> and <em>other</em>
1710
+ # are parallel
1711
+ def parallel?(other)
1712
+ end
1713
+
1714
+ # returns true if <em>self</em> is perpendicular to <em>other</em>
1715
+ def perpendicular?(other)
1716
+ end
1717
+
1718
+ # conversion function to a Point, return the center of the segment
1719
+ def to_point
1720
+ end
1721
+
1722
+ # returns true if <em>self</em> is a vertical Segment
1723
+ def vertical?
1724
+ end
1725
+ end
1726
+ #
1727
+ # The class PLRuby::Polygon implement the PostgreSQL type <em>polygon</em>
1728
+ #
1729
+ class PLRuby::Polygon
1730
+ class << self
1731
+
1732
+ # Convert a <em>String</em> (PostgreSQL representation)
1733
+ # to a <em>Polygon</em>
1734
+ def from_string(string)
1735
+ end
1736
+ end
1737
+
1738
+ # return true if <em>self</em> is the same as <em>other</em>, i.e. all
1739
+ # the points are the same
1740
+ def ==(other)
1741
+ end
1742
+
1743
+ # return the center of <em>self</em>, i.e. create a circle and return its
1744
+ # center
1745
+ def center
1746
+ end
1747
+
1748
+ # return true if <em>self</em> contains <em>other</em>
1749
+ #
1750
+ # <em>other</em> can be a Point or a Polygon
1751
+ def contain?(other)
1752
+ end
1753
+
1754
+ # return true if <em>self</em> is contained in <em>other</em> by determining
1755
+ # if <em>self</em> bounding box is contained by <em>other</em>'s bounding box.
1756
+ def contained?(other)
1757
+ end
1758
+
1759
+ # return true if <em>self</em> is contained in <em>other</em> by determining
1760
+ # if <em>self</em> bounding box is contained by <em>other</em>'s bounding box.
1761
+ def in?(other)
1762
+ end
1763
+
1764
+ # create a new Polygon object from the Array of Point <em>points</em>
1765
+ def initialize(points, closed = false)
1766
+ end
1767
+
1768
+ # return true if <em>self</em> is strictly left of <em>other</em>, i.e.
1769
+ # the right most point of <em>self</em> is left of the left
1770
+ # most point of <em>other</em>
1771
+ def left?(other)
1772
+ end
1773
+
1774
+ # return true if <em>self</em> is overlapping or left of <em>other</em>,
1775
+ # i.e. the left most point of <em>self</em> is left of the right
1776
+ # most point of <em>other</em>
1777
+ def overleft?(other)
1778
+ end
1779
+
1780
+ # return true if <em>self</em> is overlapping or right of <em>other</em>,
1781
+ # i.e. the right most point of <em>self</em> is right of the left
1782
+ # most point of <em>other</em>
1783
+ def overright?(other)
1784
+ end
1785
+
1786
+ # return true if <em>self</em> and <em>other</em> overlap by determining if
1787
+ # their bounding boxes overlap.
1788
+ def overlap?(other)
1789
+ end
1790
+
1791
+ # return the number of points in <em>self</em>
1792
+ def npoints
1793
+ end
1794
+
1795
+ # return true if <em>self</em> is strictly right of <em>other</em>, i.e.
1796
+ # the left most point of <em>self</em> is right of the left
1797
+ # most point of <em>other</em>
1798
+ def right?(other)
1799
+ end
1800
+
1801
+ # return true if <em>self</em> is the same as <em>other</em>, i.e. all
1802
+ # the points are the same
1803
+ def same?(other)
1804
+ end
1805
+
1806
+ # convert <em>self</em> to a Box
1807
+ def to_box
1808
+ end
1809
+
1810
+ # convert <em>self</em> to a Circle
1811
+ def to_circle
1812
+ end
1813
+
1814
+ # convert <em>self</em> to a Path
1815
+ def to_path
1816
+ end
1817
+
1818
+ # convert <em>self</em> to a Point by returning its center
1819
+ def to_point
1820
+ end
1821
+ end
1822
+
1823
+ #
1824
+ # The class PLRuby::Circle implement the PostgreSQL type <em>circle</em>
1825
+ #
1826
+ class PLRuby::Circle
1827
+ include Comparable
1828
+
1829
+ class << self
1830
+
1831
+ # Convert a <em>String</em> (PostgreSQL representation)
1832
+ # to a <em>Circle</em>
1833
+ def from_string(string)
1834
+ end
1835
+ end
1836
+
1837
+ # translate (right, up) <em>self</em>
1838
+ def +(point)
1839
+ end
1840
+
1841
+ # translate (left, down) <em>self</em>
1842
+ def -(point)
1843
+ end
1844
+
1845
+ # scale and rotate <em>self</em>
1846
+ def *(point)
1847
+ end
1848
+
1849
+ # scale and rotate <em>self</em>
1850
+ def /(point)
1851
+ end
1852
+
1853
+ # comparison function based on area,
1854
+ # i.e. self.area <=> other.area
1855
+ def <=>(other)
1856
+ end
1857
+
1858
+ # return the area
1859
+ def area
1860
+ end
1861
+
1862
+ # return true if <em>self</em> is entirely above <em>other</em>
1863
+ def above?(other)
1864
+ end
1865
+
1866
+ # return true if <em>self</em> is entirely below <em>other</em>
1867
+ def below?(other)
1868
+ end
1869
+
1870
+ # return true if <em>self</em> contain <em>other</em>
1871
+ def contain?(other)
1872
+ end
1873
+
1874
+ # return true if <em>self</em> is contained in <em>other</em>
1875
+ def contained?(other)
1876
+ end
1877
+
1878
+ # return the diameter
1879
+ def diameter
1880
+ end
1881
+
1882
+ # create a Circle object with <em>center</em> and <em>radius</em>
1883
+ #
1884
+ # <em>center</em> can be a Point or an Array [x, y]
1885
+ def initialize(center, radius)
1886
+ end
1887
+
1888
+ # return true if <em>self</em> overlap <em>other</em>
1889
+ def overlap?(other)
1890
+ end
1891
+
1892
+ # return true if the right edge of <em>self</em> is to the left of
1893
+ # the right edge of <em>other</em>
1894
+ def overleft?(other)
1895
+ end
1896
+
1897
+ # return true if <em>self</em> is strictly left of <em>other</em>
1898
+ def left?(other)
1899
+ end
1900
+
1901
+ # return true if the left edge of <em>self</em> is to the right of
1902
+ # the left edge of <em>other</em>
1903
+ def overright?(other)
1904
+ end
1905
+
1906
+ # return the radius
1907
+ def radius
1908
+ end
1909
+
1910
+ # return true if <em>self</em> is strictly right of <em>other</em>
1911
+ def right?(other)
1912
+ end
1913
+
1914
+ # return true if <em>self</em> is the same than <em>other</em>, i.e.
1915
+ # self.center == other.center && self.radius == other.radius
1916
+ def same?(other)
1917
+ end
1918
+
1919
+ # convert <em>self</em> to a Box
1920
+ def to_box
1921
+ end
1922
+
1923
+ # convert <em>self</em> to a Point by returning its center
1924
+ def to_point
1925
+ end
1926
+
1927
+ # convert <em>self</em> to a Polygon with <em>npts</em> Points
1928
+ def to_polygon(npts)
1929
+ end
1930
+
1931
+ end