PL/Ruby is a loadable procedural language for the PostgreSQL database system that enables the Ruby language to create functions and trigger procedures.
Functions and triggers are defined as singleton methods of the module PLtemp.
if PL/Ruby was compiled with --disable-conversion, all arguments (to the function or the triggers) are passed as string values, except for NULL values represented by Qnil. In this case you must explicitely call a conversion function (like to_i) if you want to use an argument as an integer
To create a function in the PL/Ruby language use the syntax
CREATE FUNCTION funcname(arguments_type) RETURNS type AS ' # PL/Ruby function body ' LANGUAGE 'plruby';
when calling the function in a query, the arguments are given in the array args. To create a little max function returning the higher of two int4 values write :
CREATE FUNCTION ruby_max(int4, int4) RETURNS int4 AS ' if args[0] > args[1] return args[0] else return args[1] end ' LANGUAGE 'plruby';
Tuple arguments are given as hash. Here is an example that defines the overpaid_2 function (as found in the older Postgres documentation) in PL/Ruby.
CREATE FUNCTION overpaid_2 (EMP) RETURNS bool AS ' args[0]["salary"] > 200000 || (args[0]["salary"] > 100000 && args[0]["age"] < 30) ' LANGUAGE 'plruby';
For example to define a function (int4[], int4) and return int4[], in version < 7.4 you write
CREATE FUNCTION ruby_int4_accum(_int4, int4) RETURNS _int4 AS ' if /\\{(\\d+),(\\d+)\\}/ =~ args[0] a, b = $1, $2 newsum = a + args[1] newcnt = b + 1 else raise "unexpected value #{args[0]}" end "{#{newsum},#{newcnt}}" ' LANGUAGE 'plruby';
This must now (>= 7.4) be written
CREATE FUNCTION ruby_int4_accum(_int4, int4) RETURNS _int4 AS ' a = args[0] [a[0] + args[1], a[1] + 1] ' LANGUAGE 'plruby';
With this version, plruby can have named arguments and the previous functions can be written
CREATE FUNCTION ruby_max(a int4, b int4) RETURNS int4 AS ' if a > b a else b end ' LANGUAGE 'plruby'; CREATE FUNCTION overpaid_2 (emp EMP) RETURNS bool AS ' emp["salary"] > 200000 || (emp["salary"] > 100000 && emp["age"] < 30) ' LANGUAGE 'plruby';
With this version, you can also use transaction. For example
plruby_test=# create table tu (a int, b int); CREATE TABLE plruby_test=# create or replace function tt(abort bool) returns bool as ' plruby_test'# transaction do |txn| plruby_test'# PL.exec("insert into tu values (1, 2)") plruby_test'# transaction do |txn1| plruby_test'# PL.exec("insert into tu values (3, 4)") plruby_test'# txn1.abort plruby_test'# end plruby_test'# PL.exec("insert into tu values (5, 6)") plruby_test'# txn.abort if abort plruby_test'# end plruby_test'# abort plruby_test'# ' language 'plruby'; CREATE FUNCTION plruby_test=# plruby_test=# select tt(true); tt ---- t (1 row) plruby_test=# select * from tu; a | b ---+--- (0 rows) plruby_test=# select tt(false); tt ---- f (1 row) plruby_test=# select * from tu; a | b ---+--- 1 | 2 5 | 6 (2 rows) plruby_test=#
The return type must be declared as SETOF
The function must call yield to return rows or return a String which must be a valid SELECT statement
For example to concatenate 2 rows create the function
plruby_test=# CREATE FUNCTION tu(varchar) RETURNS setof record plruby_test-# AS ' plruby_test'# size = PL.column_name(args[0]).size plruby_test'# res = nil plruby_test'# PL::Plan.new("select * from #{args[0]}", plruby_test'# "block" => 50).each do |row| plruby_test'# if res.nil? plruby_test'# res = row.values plruby_test'# else plruby_test'# res.concat row.values plruby_test'# yield res plruby_test'# res = nil plruby_test'# end plruby_test'# end plruby_test'# if res plruby_test'# res.concat Array.new(size) plruby_test'# yield res plruby_test'# end plruby_test'# ' language 'plruby'; CREATE FUNCTION plruby_test=# plruby_test=# select * from tt; a | b ---+---- 1 | 2 3 | 4 5 | 6 7 | 8 9 | 10 (5 rows) plruby_test=# select * from tu('tt') as tbl(a int, b int, c int, d int); a | b | c | d ---+----+---+--- 1 | 2 | 3 | 4 5 | 6 | 7 | 8 9 | 10 | | (3 rows) plruby_test=#
The return type must be declared as SETOF
The function is called until it returns nil
The method PL#context and PL#context= give the possibility to store information between the call
For example
plruby_test=# create or replace function vv(int) returns setof int as ' plruby_test'# i = PL.context || 0 plruby_test'# if i >= args[0] plruby_test'# nil plruby_test'# else plruby_test'# PL.context = i + 1 plruby_test'# end plruby_test'# ' language plruby; CREATE FUNCTION plruby_test=# plruby_test=# select * from uu; b --- 2 (1 row) plruby_test=# plruby_test=# select *,vv(3) from uu; b | vv ---+---- 2 | 1 2 | 2 2 | 3 (3 rows) plruby_test=#
Trigger procedures are defined in Postgres as functions without arguments and a return type of trigger. In PL/Ruby the procedure is called with 4 arguments :
The return value from a trigger procedure is one of the constant PL::OK or PL::SKIP, or an hash. If the return value is PL::OK, the normal operation (INSERT/UPDATE/DELETE) that fired this trigger will take place. Obviously, PL::SKIP tells the trigger manager to silently suppress the operation. The hash tells PL/Ruby to return a modified row to the trigger manager that will be inserted instead of the one given in new (INSERT/UPDATE only). Needless to say that all this is only meaningful when the trigger is BEFORE and FOR EACH ROW.
Here's a little example trigger procedure that forces an integer value in a table to keep track of the # of updates that are performed on the row. For new row's inserted, the value is initialized to 0 and then incremented on every update operation :
CREATE FUNCTION trigfunc_modcount() RETURNS TRIGGER AS ' case tg["op"] when PL::INSERT new[args[0]] = 0 when PL::UPDATE new[args[0]] = old[args[0]] + 1 else return PL::OK end new ' LANGUAGE 'plruby'; CREATE TABLE mytab (num int4, modcnt int4, descr text); CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab FOR EACH ROW EXECUTE PROCEDURE trigfunc_modcount('modcnt');
A more complex example (extract from test_setup.sql in the distribution) which use the global variable $Plans to store a prepared plan
create function trig_pkey2_after() returns trigger as ' if ! $Plans.key?("plan_dta2_upd") $Plans["plan_dta2_upd"] = PL::Plan.new("update T_dta2 set ref1 = $3, ref2 = $4 where ref1 = $1 and ref2 = $2", ["int4", "varchar", "int4", "varchar" ]).save $Plans["plan_dta2_del"] = PL::Plan.new("delete from T_dta2 where ref1 = $1 and ref2 = $2", ["int4", "varchar"]).save end old_ref_follow = false old_ref_delete = false case tg["op"] when PL::UPDATE new["key2"] = new["key2"].upcase old_ref_follow = (new["key1"] != old["key1"]) || (new["key2"] != old["key2"]) when PL::DELETE old_ref_delete = true end if old_ref_follow n = $Plans["plan_dta2_upd"].exec([old["key1"], old["key2"], new["key1"], new["key2"]]) warn "updated #{n} entries in T_dta2 for new key in T_pkey2" if n != 0 end if old_ref_delete n = $Plans["plan_dta2_del"].exec([old["key1"], old["key2"]]) warn "deleted #{n} entries from T_dta2" if n != 0 end PL::OK ' language 'plruby'; create trigger pkey2_after after update or delete on T_pkey2 for each row execute procedure trig_pkey2_after();
Sometime it can be usefull to define methods (in pure Ruby) which can be called from a PL/Ruby function or a PL/Ruby trigger.
In this case, you have 2 possibilities
:-) :-) :-)
just close the current definition of the function (or trigger) with a
end
and define your singleton method without the final end
Here a small and useless example
plruby_test=# CREATE FUNCTION tutu() RETURNS int4 AS ' plruby_test'# toto(1, 3) + toto(4, 4) plruby_test'# end plruby_test'# plruby_test'# def PLtemp.toto(a, b) plruby_test'# a + b plruby_test'# ' LANGUAGE 'plruby'; CREATE plruby_test=# select tutu(); tutu ---- 12 (1 row) plruby_test=#
At load time, PL/Ruby look if it exist a table plruby_singleton_methods and if found try, for each row, to define singleton methods with the template :
def PLtemp.#{name} (#{args}) #{body} end
The previous example can be written (you have a more complete example in test/plp/test_setup.sql)
plruby_test=# SELECT * FROM plruby_singleton_methods; name|args|body ----+----+----- toto|a, b|a + b (1 row) plruby_test=# CREATE FUNCTION tutu() RETURNS int4 AS ' plruby_test'# toto(1, 3) + toto(4, 4) plruby_test'# ' LANGUAGE 'plruby'; CREATE plruby_test=# select tutu(); tutu ---- 12 (1 row) plruby_test=#
Another example, if PLRuby was compiled with --enable-conversion and it exist a column with the name '***' then it can create a singleton method from a PLRuby function
plruby_test=# select * from plruby_singleton_methods; name | args | body ------+------+------ *** | | (1 row) plruby_test=# create function add_value(int, int) returns int as ' plruby_test'# args[0] + args[1] plruby_test'# ' language 'plruby'; CREATE FUNCTION plruby_test=# plruby_test=# select add_value(10, 2); add_value ----------- 12 (1 row) plruby_test=# plruby_test=# create function add_one(int) returns int as ' plruby_test'# add_value(args[0], 1) plruby_test'# ' language 'plruby'; CREATE FUNCTION plruby_test=# plruby_test=# select add_one(11); add_one --------- 12 (1 row) plruby_test=#
If the conversions was not disabled (--disable-conversion), the following conversions are made
PostgreSQL Ruby ---------- ---- OID Fixnum INT2OID Fixnum INT4OID Fixnum INT8OID Fixnum (or Bignum) FLOAT4OID Float FLOAT8OID Float CASHOID Float NUMERICOID Float BOOLOID true, false ABSTIMEOID Time RELTIMEOID Time TIMEOID Time TIMETZOID Time TIMESTAMPOID Time TIMESTAMPTZOID Time DATEOID Time INTERVALOID Time TINTERVALOID Tinterval (new Ruby class) BITOID BitString (new Ruby class) VARBITOID BitString (new Ruby class) INETOID NetAddr (new Ruby class) CIDROID NetAddr (new Ruby class) MACADDROID MacAddr (new Ruby class) POINTOID Point (new Ruby class) LSEGOID Segment (new Ruby class) BOXOID Box (new Ruby class) PATHOID Path (new Ruby class) POLYGONOID Polygon (new Ruby class) CIRCLEOID Circle (new Ruby class)
all others OID are converted to a String object
transaction {|txn| }
warn [level], message
Ruby interface to PostgreSQL elog()
Possible value for level are NOTICE, DEBUG and NOIND
Use raise() if you want to simulate elog(ERROR, "...")
$Plans (hash, tainted)
general module
args_type
column_name(table)
column_type(table)
context
context=
quote(string)
result_name
result_type
result_size
result_description
exec(string [, count [, type]])
spi_exec(string [, count [, type]])
If the query is a SELECT statement, an array is return (if count is not specified or with a value > 1). Each element of this array is an hash where the key is the column name.
If type is specified it can take the value
For example this procedure display all rows in the table pg_table.
CREATE FUNCTION pg_table_dis() RETURNS int4 AS ' res = PLruby.exec("select * from pg_class") res.each do |x| warn "======================" x.each do |y, z| warn "name = #{y} -- value = #{z}" end warn "======================" end return res.size ' LANGUAGE 'plruby';
A block can be specified, in this case a call to yield() will be made.
If count is specified with the value 1, only the first row (or FALSE if it fail) is returned as a hash. Here a little example :
CREATE FUNCTION pg_table_dis() RETURNS int4 AS ' PL.exec("select * from pg_class", 1) { |y, z| warn "name = #{y} -- value = #{z}" } return 1 ' LANGUAGE 'plruby';
Another example with count = 1
create table T_pkey1 ( skey1 int4, skey2 varchar(20), stxt varchar(40) ); create function toto() returns bool as ' warn("=======") PL.exec("select * from T_pkey1", 1, "hash") do |a| warn(a.inspect) end warn("=======") PL.exec("select * from T_pkey1", 1, "array") do |a| warn(a.inspect) end warn("=======") PL.exec("select * from T_pkey1", 1) do |a| warn(a.inspect) end warn("=======") return true ' language 'plruby'; plruby_test=# select toto(); NOTICE: ======= NOTICE: {"name"=>"skey1", "typeid"=>23, "type"=>"int4", "value"=>"12", "len"=>4} NOTICE: {"name"=>"skey2", "typeid"=>1043, "type"=>"varchar", "value"=>"a", "len"=>20} NOTICE: {"name"=>"stxt", "typeid"=>1043, "type"=>"varchar", "value"=>"b", "len"=>40} NOTICE: ======= NOTICE: ["skey1", "12", "int4", 4, 23] NOTICE: ["skey2", "a", "varchar", 20, 1043] NOTICE: ["stxt", "b", "varchar", 40, 1043] NOTICE: ======= NOTICE: ["skey1", "12"] NOTICE: ["skey2", "a"] NOTICE: ["stxt", "b"] NOTICE: ======= toto ------ t (1 row) plruby_test=#
prepare(string[, types])
spi_prepare(string[, types])
prepare(string, "types" => types, "count" => count, "output" => type, "tmp" => true)
Deprecated : See PL::Plan::new and PL::Plan#save
Prepares AND SAVES a query plan for later execution. It is a bit different from the C level SPI_prepare in that the plan is automatically copied to the toplevel memory context.
If the query references arguments, the type names must be given as a Ruby array of strings. The return value from prepare is a PL::Plan object to be used in subsequent calls to PL::Plan#exec.
If the hash given has the keys count, output these values will be given to the subsequent calls to each
class for prepared plan
initialize(string, "types" => types, "count" => count, "output" => type, "save" => false)
Prepares a query plan for later execution.
If the query references arguments, the type names must be given as a Ruby array of strings.
If the hash given has the keys output, count these values will be given to the subsequent calls to each
If "save" as a true value, the plan will be saved
exec(values, [count [, type]])
execp(values, [count [, type]])
exec("values" => values, "count" => count, "output" => type)
execp("values" => values, "count" => count, "output" => type)
Execute a prepared plan from PL::PLan::new with variable substitution. The optional count value tells PL::Plan#exec the maximum number of rows to be processed by the query.
If there was a typelist given to PL::Plan::new, an array of values of exactly the same length must be given to PL::Plan#exec as first argument. If the type list on PL::Plan::new was empty, this argument must be omitted.
If the query is a SELECT statement, the same as described for PL#exec happens for the loop-body and the variables for the fields selected.
If type is specified it can take the values
Here's an example for a PL/Ruby function using a prepared plan :
CREATE FUNCTION t1_count(int4, int4) RETURNS int4 AS ' if ! $Plans.key?("plan") # prepare the saved plan on the first call $Plans["plan"] = PL::Plan.new("SELECT count(*) AS cnt FROM t1 WHERE num >= $1 AND num <= $2", ["int4", "int4"]).save end n = $Plans["plan"].exec([args[0], args[1]], 1) n["cnt"] ' LANGUAGE 'plruby';
cursor(name = nil, "values" => values, "output" => type)
Create a new object PL::Cursor
If output is specified it can take the values
If there was a typelist given to PL::Plan::new, an array of values of exactly the same length must be given to PL::Plan#cursor
each(values, [count [, type ]]) { ... }
fetch(values, [count [, type ]]) { ... }
each("values" => values, "count" => count, "output" => type) { ... }
fetch("values" => values, "count" => count, "output" => type) { ... }
Same then #exec but a call to SPI_cursor_open(), SPI_cursor_fetch() is made.
Can be used only with a block and a SELECT statement
create function toto() returns bool as ' plan = PL::Plan.new("select * from T_pkey1") warn "=====> ALL" plan.each do |x| warn(x.inspect) end warn "=====> FIRST 2" plan.each("count" => 2) do |x| warn(x.inspect) end return true ' language 'plruby'; plruby_test=# select * from T_pkey1; skey1 | skey2 | stxt -------+-------+------ 12 | a | b 24 | c | d 36 | e | f (3 rows) plruby_test=# plruby_test=# select toto(); NOTICE: =====> ALL NOTICE: {"skey1"=>"12", "skey2"=>"a", "stxt"=>"b"} NOTICE: {"skey1"=>"24", "skey2"=>"c", "stxt"=>"d"} NOTICE: {"skey1"=>"36", "skey2"=>"e", "stxt"=>"f"} NOTICE: =====> FIRST 2 NOTICE: {"skey1"=>"12", "skey2"=>"a", "stxt"=>"b"} NOTICE: {"skey1"=>"24", "skey2"=>"c", "stxt"=>"d"} toto ------ t (1 row) plruby_test=#
release
save
A cursor is created with the method PL::Plan#cursor
close
each {|row| ... }
fetch(count = 1)
row(count = 1)
Fetches some rows from a cursor
if count > 0 fetch forward else backward
move(count)
reverse_each {|row| ... }
rewind
a transaction is created with the global function transaction(). Only available with PostgreSQL >= 8.0
abort
commit
The class BitString implement the PostgreSQL type bit and bit varying
The modules Comparable and Enumerable are included
from_string(string, length = strlen(string))
<=>(other)
comparison function for 2 BitString objects
All bits are considered and additional zero bits may make one string smaller/larger than the other, even if their zero-padded values would be the same.
+(other)
&(other)
|(other)
^(other)
~
<<(lshft)
>>(rshft)
[*args]
Element reference with the same syntax that for a String object
Return a BitString or a Fixnum 0, 1
bitstring[fixnum] bitstring[fixnum, fixnum] bitstring[range] bitstring[regexp] bitstring[regexp, fixnum] bitstring[string] bitstring[other_bitstring]
[*args] = val
Element assignment with the same syntax that for a String object
bitstring[fixnum] = fixnum bitstring[fixnum] = string_or_bitstring bitstring[fixnum, fixnum] = string_or_bitstring bitstring[range] = string_or_bitstring bitstring[regexp] = string_or_bitstring bitstring[regexp, fixnum] = string_or_bitstring bitstring[other_str] = string_or_bitstring
concat(other)
each
include?(other)
index(other)
return the position of other in self
return nil if other is not included in self
initialize(init, nbits = -1)
create a new BitString object with nbits bits
init can be a Fixnum or a String
For a String the first character can be 'x', 'X' for and hexadecimal representation, or 'b', 'B' for a binary representation. The default is a binary representation
length
octet_length
push(other)
to_i
to_s
The class NetAddr implement the PostgreSQL type inet and cidr
The module Comparable is included
from_string(string, cidr = false)
<=>(other)
comparison function for 2 NetAddr objects
comparison is first on the common bits of the network part, then on the length of the network part, and then on the whole unmasked address.
abbrev
broadcast
contain?(other)
contain_or_equal?(other)
contained?(other)
contained_or_equal?(other)
family
first
host
hostmask
initialize(string, cidr = false)
last
masklen
netmask
network
set_masklen(len)
to_s
The MacAddr implement the PostgreSQL type macaddr
The module Comparable is included
from_string(string, cidr = false)
<=>(other)
initialize(string)
to_s
truncate
The Tinterval implement the PostgreSQL type tinterval
from_string(string)
high
high=(time)
initialize(low, high)
low
low=(time)
to_s
The Box implement the PostgreSQL type box
The module Comparable is included
from_string(string)
+(point)
-(point)
*(point)
/(point)
===(other)
<=>(other)
above?(other)
area
below?(other)
center
closest(other)
closest point to other
other can be a Point, or Segment
contain?(other)
contained?(other)
diagonal
height
in?(other)
initialize(*args)
create a new Box object
args can be 2 Point objects (low, high) or 4 Float objects (low.x, low.y, high.x, high.y)
intersection(other)
intersect?(segment)
returns true if the Segment segment intersect with the Box
Segment completely inside box counts as intersection. If you want only segments crossing box boundaries, try converting Box to Path first.
left?(other)
overlap?(other)
overleft?(other)
overright?(other)
right?(other)
same?(other)
to_circle
to_point
to_polygon
to_segment
width
The Path implement the PostgreSQL type path
The module Comparable is included
from_string(string)
<<(path)
+(point)
-(point)
*(point)
/(point)
<=>(other)
close
closed?
concat(path)
initialize(points, closed = false)
length
npoints
open
to_polygon
The Point implement the PostgreSQL type point
The module Comparable is included
from_string(string)
+(point)
-(point)
*(point)
/(point)
[indice]
return the coordinate
indice can have the value 0 or 1
[indice] = value
set the coordinate
indice can have the value 0 or 1
==(other)
above?(other)
below?(other)
contained?(other)
return true if self is contained in other
other can be Point, Polygon or a Circle object
horizontal?(other)
in?(other)
return true if self is contained in other
other can be Point, Polygon or a Circle object
initialize(x, y)
left?(other)
on?(other)
return true if self is on other
other can be Point, Segment, Box or Path object
right?(other)
vertical?(other)
x
x=(value)
y
y=(value)
The Segment implement the PostgreSQL type lseg
The module Comparable is included
from_string(string)
<=>(other)
comparison function for the 2 segments, returns
0 if self[0] == other[0] && self[1] == other[1] 1 if distance(self[0], self[1]) > distance(other[0], other[1]) -1 if distance(self[0], self[1]) < distance(other[0], other[1])
center
closest(other)
closest point to other
other can be a Point, Segment or Box
With a point, take the closest endpoint if the point is left, right, above, or below the segment, otherwise find the intersection point of the segment and its perpendicular through the point.
horizontal?
initialize(point0, point1)
intersect?(other)
intersection(other)
length
on?(other)
return true if self is on other
other can be a Segment, or a Box object
parallel?(other)
perpendicular?(other)
to_point
vertical?
The Polygon implement the PostgreSQL type polygon
from_string(string)
==(other)
center
contain?(other)
return true if self contains other
other can be a Point or a Polygon
contained?(other)
in?(other)
initialize(points, closed = false)
left?(other)
overleft?(other)
overright?(other)
overlap?(other)
npoints
right?(other)
same?(other)
to_box
to_circle
to_path
to_point
The Circle implement the PostgreSQL type circle
The module Comparable is included
from_string(string)
+(point)
-(point)
*(point)
/(point)
<=>(other)
area
above?(other)
below?(other)
contain?(other)
contained?(other)
diameter
initialize(center, radius)
create a Circle object with center and radius
center can be a Point or an Array [x, y]
overlap?(other)
overleft?(other)
left?(other)
overright?(other)
radius
right?(other)
same?(other)
to_box
to_point
to_polygon(npts)


`RunOrg.Form.List(limit, offset)` reads `limit` groups from the
database, starting at `offset`. The order is unspecified but
consistent.
Only groups for which the viewer has **view** access will be included
in the list.
Returns a [promise](/concepts/promise.htm) that will resolve to a
list of loaded [`RunOrg.Form`](/forms/form.htm) instances, with two
major differences:
- Members `custom` and `audience` are not returned.
- Member `fields` is replaced by the number of fields.
RunOrg.Form.List(10, 0).then(function(list) {
for (var i = 0; i < list.length; ++i)
console.log("Form %s has %d fields", list[i].id, list[i].fields)
})
Explain how to handle errors.
Returns all the forms in the database, in an unspecified but consistent
order, with [pagination](/concepts/pagination.htm).
Only forms for which the viewer has **fill** access will be included
in the list.
The response contains a single field:
| list |
The array contains [`forms`](/forms/form.htm), with two
major differences:
- Members `custom` and `audience` are not returned.
- Member `fields` is replaced by the number of fields.
GET /db/0SNQc00211H/forms?limit=3&offset=16
200 OK
Content-Type: application/json
{ "list" : [
{ "id" : "0SNQe00311H",
"owner" : "person",
"label" : "Why did you join our group ?",
"fields" : 2,
"access" : ["fill"] },
{ "id" : "0SNQg00511H",
"label" : null,
"owner" : "person",
"fields" : 1,
"pic" : ["admin","fill"] }
# Errors
## Returns `401 Unauthorized`
- if the provided token and viewer do not match.
## Returns `404 Not Found`
- if the database does not exist
# Access restrictions
Anyone can retrieve results from this API, though only forms that
the viewer has **fill** access to will be returned.


I am a Los Angeles based Web Developer with a background in Civil Engineering. My time working as a design engineer for a civil engineering and consulting firm allowed me to exercise my strengths in both logic and problem-solving. I have had to exercise this skill from the stages of preliminary design all the way to the final design phases. My prior work experience has also taught me how to manage my time and work on multiple projects in high-pressure environments in order to meet strict deadlines.
I have always been passionate about challenging myself to develop innovative and creative solutions to real-world problems. I am a highly motivated individual who is driven by developing quality products and ensuring that I provide the best services for my clients.
I am extremely passionate about developing performant, consumer-facing experiences using modern web technologies.
Download ResumeIf you would like to contact me, please do not hesitate to do so! For any questions or more information, feel free to email me.


2004
December, 2004
The Curious Incident of the Dog in the Night-Time
Mark Haddon
November, 2004
The Dogs of Babel: A Novel
Carolyn Parkhurst
October, 2004
The Lovely Bones
Alice Sebold
September, 2004
Daisy Miller (Penguin Classics)
Henry James
August, 2004
The Wife: A Novel
Meg Wolitzer
June, 2004
Life of Pi
Yann Martel
May, 2004
Reading Lolita in Tehran: A Memoir in Books
Azar Nafisi
April, 2004
The Wholeness of a Broken Heart: A Novel
Katie Singer
March, 2004
July, July
Tim O'Brien
February, 2004
Child of My Heart
Alice McDermott
January, 2004
The Book of Illusions: A Novel


fun getTree(rootId: Int): TreeNode<Person>
Returns the tree of the root Person and its children recursively.
rootId
- the person ID of the root of the tree
Return
the root node of the tree which contains its children, its children's children, etc.
See Also


The Spring Framework provides abstractions for asynchronous execution and scheduling of tasks
with the TaskExecutor
and TaskScheduler
interfaces, respectively. Spring also features implementations of those interfaces that support
thread pools or delegation to CommonJ within an application server environment. Ultimately
the use of these implementations behind the common interfaces abstracts away the differences
between Java SE 5, Java SE 6 and Java EE environments.
Spring also features integration classes for supporting scheduling with the
Timer
, part of the JDK since 1.3, and the Quartz Scheduler
(http://www.opensymphony.com/quartz/). Both of those schedulers
are set up using a FactoryBean
with optional references
to Timer
or Trigger
instances, respectively.
Furthermore, a convenience class for both the Quartz Scheduler and the Timer
is
available that allows you to invoke a method of an existing target object
(analogous to the normal MethodInvokingFactoryBean
operation).
Spring 2.0 introduces a new abstraction for dealing with executors. Executors are the Java 5 name for the concept of thread pools. The "executor" naming is due to the fact that there is no guarantee that the underlying implementation is actually a pool; an executor may be single-threaded or even synchronous. Spring's abstraction hides implementation details between Java SE 1.4, Java SE 5 and Java EE environments.
Spring's TaskExecutor
interface is
identical to the java.util.concurrent.Executor
interface. In fact, its primary reason for existence is to abstract away
the need for Java 5 when using thread pools. The interface has a single
method execute(Runnable task)
that accepts a task
for execution based on the semantics and configuration of the thread pool.
The TaskExecutor
was originally
created to give other Spring components an abstraction for thread pooling where
needed. Components such as the ApplicationEventMulticaster
,
JMS's AbstractMessageListenerContainer
,
and Quartz integration all use the TaskExecutor
abstraction to pool threads. However, if your beans need thread pooling behavior,
it is possible to use this abstraction for your own needs.
There are a number of pre-built implementations of
TaskExecutor
included with the
Spring distribution. In all likelihood, you shouldn't ever
need to implement your own.
SimpleAsyncTaskExecutor
This implementation does not reuse any threads, rather it starts up a new thread for each invocation. However, it does support a concurrency limit which will block any invocations that are over the limit until a slot has been freed up. If you're looking for true pooling, keep scrolling further down the page.
This implementation doesn't execute invocations asynchronously. Instead, each invocation takes place in the calling thread. It is primarily used in situations where multithreading isn't necessary such as simple test cases.
This implementation is a wrapper for a Java 5
java.util.concurrent.Executor
.
There is an alternative,
ThreadPoolTaskExecutor
,
that exposes the Executor
configuration parameters as bean properties. It
is rare to need to use the ConcurrentTaskExecutor
but if the
ThreadPoolTaskExecutor
isn't robust enough for your needs, the
ConcurrentTaskExecutor
is an alternative.
This implementation is actually a subclass of
Quartz's SimpleThreadPool
which listens to Spring's lifecycle callbacks.
This is typically used when you have a
thread pool that may need to be shared by both
Quartz and non-Quartz components.
This implementation can only be used in a Java 5
environment but is also the most commonly used
one in that environment. It exposes bean properties for
configuring a
java.util.concurrent.ThreadPoolExecutor
and wraps it in a TaskExecutor
.
If you need something advanced such as a
ScheduledThreadPoolExecutor
,
it is recommended that you use a
ConcurrentTaskExecutor
instead.
TimerTaskExecutor
This implementation uses a single
TimerTask
as its backing implementation. It's different
from the
SyncTaskExecutor
in that the method invocations are executed in a
separate thread, although they are synchronous
in that thread.
WorkManagerTaskExecutor
This implementation uses the CommonJ WorkManager
as its backing implementation and is the central
convenience class for setting up a CommonJ
WorkManager reference in a Spring context.
Similar to the
SimpleThreadPoolTaskExecutor
,
this class implements the WorkManager
interface and therefore can be used directly as
a WorkManager as well.
Spring's TaskExecutor
implementations
are used as simple JavaBeans. In the example below, we define
a bean that uses the ThreadPoolTaskExecutor
to asynchronously print out a set of messages.
import org.springframework.core.task.TaskExecutor; public class TaskExecutorExample { private class MessagePrinterTask implements Runnable { private String message; public MessagePrinterTask(String message) { this.message = message; } public void run() { System.out.println(message); } } private TaskExecutor taskExecutor; public TaskExecutorExample(TaskExecutor taskExecutor) { this.taskExecutor = taskExecutor; } public void printMessages() { for(int i = 0; i < 25; i++) { taskExecutor.execute(new MessagePrinterTask("Message" + i)); } } }
As you can see, rather than retrieving a thread from the
pool and executing yourself, you add your Runnable
to the queue and the TaskExecutor
uses its internal rules to decide when the task gets executed.
To configure the rules that the TaskExecutor
will use, simple bean properties have been exposed.
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="5" /> <property name="maxPoolSize" value="10" /> <property name="queueCapacity" value="25" /> </bean> <bean id="taskExecutorExample" class="TaskExecutorExample"> <constructor-arg ref="taskExecutor" /> </bean>
In addition to the TaskExecutor
abstraction, Spring 3.0 introduces a TaskScheduler
with a variety of methods for scheduling tasks to run at some point in the future.
public interface TaskScheduler { ScheduledFuture schedule(Runnable task, Trigger trigger); ScheduledFuture schedule(Runnable task, Date startTime); ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period); ScheduledFuture scheduleAtFixedRate(Runnable task, long period); ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay); ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay); }
The simplest method is the one named 'schedule' that takes a
Runnable
and Date
only. That will cause the task to run once after the specified time. All of
the other methods are capable of scheduling tasks to run repeatedly. The
fixed-rate and fixed-delay methods are for simple, periodic execution, but
the method that accepts a Trigger is much more flexible.
The Trigger
interface is
essentially inspired by JSR-236, which, as of Spring 3.0, has not yet
been officially implemented. The basic idea of the
Trigger
is that execution times may be
determined based on past execution outcomes or even arbitrary
conditions. If these determinations do take into account the outcome of
the preceding execution, that information is available within a
TriggerContext
. The
Trigger
interface itself is quite
simple:
public interface Trigger { Date nextExecutionTime(TriggerContext triggerContext); }
As you can see, the TriggerContext
is the most important part. It encapsulates all of the relevant data,
and is open for extension in the future if necessary. The
TriggerContext
is an interface (a
SimpleTriggerContext
implementation is used by
default). Here you can see what methods are available for
Trigger
implementations.
public interface TriggerContext { Date lastScheduledExecutionTime(); Date lastActualExecutionTime(); Date lastCompletionTime(); }
Spring provides two implementations of the
Trigger
interface. The most interesting
one is the CronTrigger
. It enables the
scheduling of tasks based on cron expressions. For example the
following task is being scheduled to run 15 minutes past each hour but
only during the 9-to-5 "business hours" on weekdays.
scheduler.schedule(task, new CronTrigger("* 15 9-17 * * MON-FRI"));
The other out-of-the-box implementation is a
PeriodicTrigger
that accepts a fixed period, an
optional initial delay value, and a boolean to indicate whether the
period should be interpreted as a fixed-rate or a fixed-delay. Since
the TaskScheduler
interface already
defines methods for scheduling tasks at a fixed-rate or with a
fixed-delay, those methods should be used directly whenever possible.
The value of the PeriodicTrigger
implementation
is that it can be used within components that rely on the
Trigger
abstraction. For example, it may
be convenient to allow periodic triggers, cron-based triggers, and even
custom trigger implementations to be used interchangeably. Such a
component could take advantage of dependency injection so that such
Triggers
could be configured externally.
As with Spring's TaskExecutor
abstraction, the primary benefit of the
TaskScheduler
is that code relying on
scheduling behavior need not be coupled to a particular scheduler
implementation. The flexibility this provides is particularly relevant
when running within Application Server environments where threads
should not be created directly by the application itself. For such
cases, Spring provides a
TimerManagerTaskScheduler
that delegates to a
CommonJ TimerManager instance, typically configured with a JNDI-lookup.
A simpler alternative, the
ThreadPoolTaskScheduler
, can be used whenever
external thread management is not a requirement. Internally, it
delegates to a ScheduledExecutorService
instance. ThreadPoolTaskScheduler
actually
implements Spring's TaskExecutor
interface as well, so that a single instance can be used for
asynchronous execution as soon as possible as well
as scheduled, and potentially recurring, executions.
Beginning with Spring 3.0, there is an XML namespace for configuring
TaskExecutor
and
TaskScheduler
instances. It also provides a
convenient way to configure tasks to be scheduled with a trigger.
The following element will create a
ThreadPoolTaskScheduler
instance with the
specified thread pool size.
<task:scheduler id="scheduler" pool-size="10"/>
The value provided for the 'id' attribute will be used as the prefix for thread names within the pool. The 'scheduler' element is relatively straightforward. If you do not provide a 'pool-size' attribute, the default thread pool will only have a single thread. There are no other configuration options for the scheduler.
The following will create a
ThreadPoolTaskExecutor
instance:
<task:executor id="executor" pool-size="10"/>
As with the scheduler above, the value provided for the 'id'
attribute will be used as the prefix for thread names within the pool.
As far as the pool size is concerned, the 'executor' element supports
more configuration options than the 'scheduler' element. For one thing,
the thread pool for a ThreadPoolTaskExecutor
is
itself more configurable. Rather than just a single size, an executor's
thread pool may have different values for the core
and the max size. If a single value is provided
then the executor will have a fixed-size thread pool (the core and max
sizes are the same). However, the 'executor' element's 'pool-size' attribute
also accepts a range in the form of "min-max".
<task:executor id="executorWithPoolSizeRange" pool-size="5-25" queue-capacity="100"/>
As you can see from that configuration, a 'queue-capacity' value has also been provided. The configuration of the thread pool should also be considered in light of the executor's queue capacity. For the full description of the relationship between pool size and queue capacity, consult the documentation for ThreadPoolExecutor. The main idea is that when a task is submitted, the executor will first try to use a free thread if the number of active threads is currently less than the core size. If the core size has been reached, then the task will be added to the queue as long as its capacity has not yet been reached. Only then, if the queue's capacity has been reached, will the executor create a new thread beyond the core size. If the max size has also been reached, then the executor will reject the task.
By default, the queue is unbounded, but this
is rarely the desired configuration, because it can lead to
OutOfMemoryErrors
if enough tasks are added to
that queue while all pool threads are busy. Furthermore, if the queue
is unbounded, then the max size has no effect at all. Since the
executor will always try the queue before creating a new thread beyond
the core size, a queue must have a finite capacity for the thread pool
to grow beyond the core size (this is why a fixed size
pool is the only sensible case when using an unbounded queue).
In a moment, we will review the effects of the keep-alive setting
which adds yet another factor to consider when providing a pool size
configuration. First, let's consider the case, as mentioned above, when
a task is rejected. By default, when a task is rejected, a thread pool
executor will throw a TaskRejectedException
.
However, the rejection policy is actually configurable. The exception
is thrown when using the default rejection policy which is the
AbortPolicy
implementation. For applications
where some tasks can be skipped under heavy load, either the
DiscardPolicy
or
DiscardOldestPolicy
may be configured instead.
Another option that works well for applications that need to throttle
the submitted tasks under heavy load is the
CallerRunsPolicy
. Instead of throwing an
exception or discarding tasks, that policy will simply force the thread
that is calling the submit method to run the task itself. The idea is
that such a caller will be busy while running that task and not able to
submit other tasks immediately. Therefore it provides a simple way to
throttle the incoming load while maintaining the limits of the thread
pool and queue. Typically this allows the executor to "catch up" on the
tasks it is handling and thereby frees up some capacity on the queue,
in the pool, or both. Any of these options can be chosen from an
enumeration of values available for the 'rejection-policy' attribute on
the 'executor' element.
<task:executor id="executorWithCallerRunsPolicy" pool-size="5-25" queue-capacity="100" rejection-policy="CALLER_RUNS"/>
The most powerful feature of Spring's task namespace is the support for configuring tasks to be scheduled within a Spring Application Context. This follows an approach similar to other "method-invokers" in Spring, such as that provided by the JMS namespace for configuring Message-driven POJOs. Basically a "ref" attribute can point to any Spring-managed object, and the "method" attribute provides the name of a method to be invoked on that object. Here is a simple example.
<task:scheduled-tasks scheduler="myScheduler"> <task:scheduled ref="someObject" method="someMethod" fixed-delay="5000"/> </task:scheduled-tasks> <task:scheduler id="myScheduler" pool-size="10"/>
As you can see, the scheduler is referenced by the outer element, and each individual task includes the configuration of its trigger metadata. In the preceding example, that metadata defines a periodic trigger with a fixed delay. It could also be configured with a "fixed-rate", or for more control, a "cron" attribute could be provided instead. Here's an example featuring these other options.
<task:scheduled-tasks scheduler="myScheduler"> <task:scheduled ref="someObject" method="someMethod" fixed-rate="5000"/> <task:scheduled ref="anotherObject" method="anotherMethod" cron="*/5 * * * * MON-FRI"/> </task:scheduled-tasks> <task:scheduler id="myScheduler" pool-size="10"/>
Spring 3.0 also adds annotation support for both task scheduling and asynchronous method execution.
The @Scheduled annotation can be added to a method along with trigger metadata. For example, the following method would be invoked every 5 seconds with a fixed delay, meaning that the period will be measured from the completion time of each preceding invocation.
@Scheduled(fixedDelay=5000) public void doSomething() { // something that should execute periodically }
If a fixed rate execution is desired, simply change the property name specified within the annotation. The following would be executed every 5 seconds measured between the successive start times of each invocation.
@Scheduled(fixedRate=5000) public void doSomething() { // something that should execute periodically }
If simple periodic scheduling is not expressive enough, then a cron expression may be provided. For example, the following will only execute on weekdays.
@Scheduled(cron="*/5 * * * * MON-FRI") public void doSomething() { // something that should execute on weekdays only }
Notice that the methods to be scheduled must have void returns and must not expect any arguments. If the method needs to interact with other objects from the Application Context, then those would typically have been provided through dependency injection.
The @Async annotation can be provided on a method so that invocation of that method will occur asynchronously. In other words, the caller will return immediately upon invocation and the actual execution of the method will occur in a task that has been submitted to a Spring TaskExecutor. In the simplest case, the annotation may be applied to a void-returning method.
@Async void doSomething() { // this will be executed asynchronously }
Unlike the methods annotated with the @Scheduled annotation, these methods can expect arguments, because they will be invoked in the "normal" way by callers at runtime rather than from a scheduled task being managed by the container. For example, the following is a legitimate application of the @Async annotation.
@Async void doSomething(String s) { // this will be executed asynchronously }
Even methods that return a value can be invoked asynchronously. However, such methods are required to have a Future typed return value. This still provides the benefit of asynchronous execution so that the caller can perform other tasks prior to calling 'get()' on that Future.
@Async Future<String> returnSomething(int i) { // this will be executed asynchronously }
To enable both @Scheduled and @Async annotations, simply include the 'annotation-driven' element from the task namespace in your configuration.
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/> <task:executor id="myExecutor" pool-size="5"/> <task:scheduler id="myScheduler" pool-size="10"/>}
Notice that an executor reference is provided for handling those tasks that correspond to methods with the @Async annotation, and the scheduler reference is provided for managing those methods annotated with @Scheduled.
Quartz uses Trigger
, Job
and
JobDetail
objects to realize scheduling of all kinds of jobs.
For the basic concepts behind Quartz, have a look at
http://www.opensymphony.com/quartz. For convenience purposes,
Spring offers a couple of classes that simplify the usage of Quartz within
Spring-based applications.
JobDetail
objects contain all information needed to
run a job. The Spring Framework provides a JobDetailBean
that makes the JobDetail
more of an actual JavaBean
with sensible defaults. Let's have a look at an example:
<bean name="exampleJob" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass" value="example.ExampleJob" /> <property name="jobDataAsMap"> <map> <entry key="timeout" value="5" /> </map> </property> </bean>
The job detail bean has all information it needs to run the job (ExampleJob
).
The timeout is specified in the job data map. The job data map is
available through the JobExecutionContext
(passed to you at execution time), but the JobDetailBean
also maps the properties from the job data map to properties of the actual job.
So in this case, if the ExampleJob
contains a property
named timeout
, the JobDetailBean
will
automatically apply it:
package example; public class ExampleJob extends QuartzJobBean { private int timeout; /** * Setter called after the ExampleJob is instantiated * with the value from the JobDetailBean (5) */ public void setTimeout(int timeout) { this.timeout = timeout; } protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException { // do the actual work } }
All additional settings from the job detail bean are of course available to you as well.
Note: Using the name
and group
properties,
you can modify the name and the group of the job, respectively. By default, the name of
the job matches the bean name of the job detail bean (in the example above, this is
exampleJob
).
Often you just need to invoke a method on a specific object. Using the
MethodInvokingJobDetailFactoryBean
you can do exactly this:
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="exampleBusinessObject" /> <property name="targetMethod" value="doIt" /> </bean>
The above example will result in the doIt
method being called on the
exampleBusinessObject
method (see below):
public class ExampleBusinessObject { // properties and collaborators public void doIt() { // do the actual work } }
<bean id="exampleBusinessObject" class="examples.ExampleBusinessObject"/>
Using the MethodInvokingJobDetailFactoryBean
, you don't need to
create one-line jobs that just invoke a method, and you only need to create the actual
business object and wire up the detail object.
By default, Quartz Jobs are stateless, resulting in the possibility of jobs interfering
with each other. If you specify two triggers for the same JobDetail
,
it might be possible that before the first job has finished, the second one will start.
If JobDetail
classes implement the
Stateful
interface, this won't happen. The second job
will not start before the first one has finished. To make jobs resulting from the
MethodInvokingJobDetailFactoryBean
non-concurrent, set the
concurrent
flag to false
.
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="exampleBusinessObject" /> <property name="targetMethod" value="doIt" /> <property name="concurrent" value="false" /> </bean>
| Note | |
|---|---|
By default, jobs will run in a concurrent fashion. |
We've created job details and jobs. We've also reviewed the convenience bean
that allows to you invoke a method on a specific object. Of course, we still need
to schedule the jobs themselves. This is done using triggers and a
SchedulerFactoryBean
. Several triggers are available
within Quartz. Spring offers two subclassed triggers with convenient defaults:
CronTriggerBean
and SimpleTriggerBean
.
Triggers need to be scheduled. Spring offers a SchedulerFactoryBean
that exposes triggers to be set as properties. SchedulerFactoryBean
schedules the actual jobs with those triggers.
Find below a couple of examples:
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <!-- see the example of method invoking job above --> <property name="jobDetail" ref="jobDetail" /> <!-- 10 seconds --> <property name="startDelay" value="10000" /> <!-- repeat every 50 seconds --> <property name="repeatInterval" value="50000" /> </bean> <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="exampleJob" /> <!-- run every morning at 6 AM --> <property name="cronExpression" value="0 0 6 * * ?" /> </bean>
Now we've set up two triggers, one running every 50 seconds with a starting delay of
10 seconds and one every morning at 6 AM. To finalize everything, we need to set up the
SchedulerFactoryBean
:
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTrigger" /> <ref bean="simpleTrigger" /> </list> </property> </bean>
More properties are available for the SchedulerFactoryBean
for you
to set, such as the calendars used by the job details, properties to customize Quartz with,
etc. Have a look at the
SchedulerFactoryBean Javadoc
for more information.
The other way to schedule jobs in Spring is to use JDK
Timer
objects. You can create custom timers or
use the timer that invokes methods. Wiring timers is done using the
TimerFactoryBean
.
Using the TimerTask
you can create customer
timer tasks, similar to Quartz jobs:
public class CheckEmailAddresses extends TimerTask { private List emailAddresses; public void setEmailAddresses(List emailAddresses) { this.emailAddresses = emailAddresses; } public void run() { // iterate over all email addresses and archive them } }
Wiring it up is simple:
<bean id="checkEmail" class="examples.CheckEmailAddress"> <property name="emailAddresses"> <list><EMAIL_ADDRESS><EMAIL_ADDRESS><EMAIL_ADDRESS></list> </property> </bean> <bean id="scheduledTask" class="org.springframework.scheduling.timer.ScheduledTimerTask"> <!-- wait 10 seconds before starting repeated execution --> <property name="delay" value="10000" /> <!-- run every 50 seconds --> <property name="period" value="50000" /> <property name="timerTask" ref="checkEmail" /> </bean>
Note that letting the task only run once can be done by changing the
period
property to 0 (or a negative value).
Similar to the Quartz support, the Timer
support also features
a component that allows you to periodically invoke a method:
<bean id="doIt" class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean"> <property name="targetObject" ref="exampleBusinessObject" /> <property name="targetMethod" value="doIt" /> </bean>
The above example will result in the doIt
method being called on the
exampleBusinessObject
(see below):
public class BusinessObject { // properties and collaborators public void doIt() { // do the actual work } }
Changing the timerTask
reference of the
ScheduledTimerTask
example to the bean doIt
will result in the doIt
method being executed on a fixed schedule.
The TimerFactoryBean
is similar to the Quartz
SchedulerFactoryBean
in that it serves the same
purpose: setting up the actual scheduling. The TimerFactoryBean
sets up an actual Timer
and schedules the tasks it has
references to. You can specify whether or not daemon threads should be used.
<bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean"> <property name="scheduledTimerTasks"> <list> <!-- see the example above --> <ref bean="scheduledTask" /> </list> </property> </bean>


Michigan mom facing charges and possible jail time over late library books
by WXYZ StaffCHARLOTTE, Mich. — A Michigan mom is facing criminal charges and possible jail time because of late library books.
The books were checked out two years ago from the Charlotte Community Library near Lansing.
Melinda Sanders Jones said she found out about the warrant for her arrest when her bosses performed a background check for her promotion.
"I really don't think going to jail over those two books is OK, and I definitely didn't want to steal their property," she said.
Sanders is charged with failure to return a rental property, which carries a maximum penalty of 93 days in jail and a $500 fine. She's due back in court on Thursday.
This story was originally published by WXYZ in Detroit.


Sunday, Feb 9, 12:58
Hi, Kate
Kate
Hi, I am good!
Blue Ninja
Hi there, I am also fine, thanks! And how are you?
Hey, look, cutest kitten ever!
Kate
Nice!
Kate
Like it very much!
Blue Ninja
Awesome!


This is a component that takes some number of other components as children and renders them into a
, wrapping each in a

Hint: See the React.Children helpers


MONKEYBONE A film review by Steve Rhodes Copyright 2001 Steve Rhodes RATING (0 TO ****): **
MONKEYBONE is the second film this week -- the other was 3000 MILES TO GRACELAND -- that doesn't live up to the promise of its trailers. MONKEYBONE is by far the better of the two, which isn't exactly high praise.
The movie's twisted, silly and sometimes sick humor comes from the minds of director Henry Selick (THE NIGHTMARE BEFORE CHRISTMAS), screenwriter Sam Hamm (BATMAN) and comics writer Kaja Blackley (DARK TOWN). The stunning visuals look like a cross with THE NIGHTMARE BEFORE CHRISTMAS, the bar scene from STAR WARS and a nightmare vision of an amusement park. Although the images devilishly delight the audience, the script is as dead as the afterlife, called Downtown, in which most of the movie takes place. Whoopi Goldberg has a high old time as Death, the queen of the underworld.
Brendan Fraser, the star of MONKEYBONE, has two modes: hilarious, as he was in my personal favorite of his, BLAST FROM THE PAST, and awful, as in DUDLEY DO-RIGHT. To be fair, he is a wonderfully gifted comedic actor and his failures come mainly from an inability to say no to terrible scripts.
This time Fraser plays Stu Miley, as in S. Miley (get it?), a cartoonist who created "Monkeybone, America's most disturbed comic strip." He met his girlfriend, Dr. Julie McElroy (Bridget Fonda), at The Sleep Institute, where he went to get help with his severe and bizarre nightmares.
After being hit on the head in a car accident, he goes into a deep coma, sending him to Downtown, from which he may never return. At least not unless Death gives him a gold-plated exit pass. Accompanying him on his journey is his sidekick, the sassy Monkeybone, who has a fixation on women's breasts and on his own lack of private parts, which he blames on his creator, Stu. Rose McGowan does a sweet turn as Kitty, Stu's helper in the demented Downtown.
Chris Kattan, as a dead gymnast, gets the most laughs. An organ donor, he has doctors hot on his trail, trying to get his organs. He uses them like water balloons to toss at people. If it sounds gross, it is.
Finally, a piece of friendly advice for Fraser. Please treat the projects that you are offered as you would a serious illness. Once you receive the script, ask for a second opinion.
MONKEYBONE runs 1:27. It is rated PG-13 for crude humor and some nudity and would be acceptable for kids around 12 and up.
My son Jeffrey and his friends, all about 12, had different opinions of the film. Jeffrey (**) said that he didn't laugh once but that he thought the plot was imaginative. Maxim (***) commented on how much he liked the characters and the Fantasyland part. Sam (*** 1/2) said that he found the movie very funny. Nickolas (*** 1/2) mentioned how interesting he found the whole setup. All of them liked the organ donor part.
Web: http://www.InternetReviews.com Email<EMAIL_ADDRESS>Want free reviews and weekly movie and video recommendations via Email? Just send me a letter with the word "subscribe" in the subject line.
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


We are available when you need us. Let’s build web and mobile applications from scratch or help you with scaling/fixing your existing product.


Preparation time
30 mins to 1 hour
Cooking time
30 mins to 1 hour
Serves
Serves 4
Scallops and shrimps served in a scallop shell topped with buttery pastry and a delicious butter sauce. You can make this easier by buying good-quality fish stock instead of making your own.
To make the fish stock, place the bones, onion, fennel, parsley stalks, garlic and bay leaf into a large saucepan. Add the vermouth, white wine and enough water to cover the bones. Bring to the boil and simmer for 20 minutes, skim any scum that rises to the top while cooking. Do not cook for any longer as the stock will be cloudy. Strain and set aside.
For the scallops, place the vegetables in a pan and add enough fish stock to cover. Bring to the boil and cook for a couple of minutes, drain and set aside.
To make the mousse, in a food processor combine the plaice, scallops and 250ml/9fl oz fish stock and blend until smooth. Whip the cream in a separate bowl then add the blended fish to the cream. Season with salt and freshly ground black pepper and stir until combined. Set aside in the fridge until needed.
For the scallops, start to assemble the scallop shells. Place some of the spinach leaves in each shell and add some of the blanched vegetables on top. Place the scallops on top of the vegetables to one side and a spoonful of mousse to the other. Top with the reserved coral and sprinkle the brown shrimps all over. Pour two tablespoons of stock over the top and finish with a sprig of chervil.
 Whisk the egg and milk together in a bowl. Brush the egg mix around the shell edges and underneath (reserving any remaining egg wash for later). Place the pastry on top and seal underneath. Place in the fridge to rest for 30 minutes.
Preheat the oven to 200C/400F/Gas 6.
Meanwhile make the beurre blanc. In a pan, bring the shallots, white wine vinegar, white wine and a tablespoon of water to the boil. Reduce the heat until the mixture is simmering, then continue to simmer until the sauce has reduced to two tablespoons of liquid. Strain and return the liquid to the pan.
Reduce the heat to low, then gradually whisk in the butter, 25g/1oz at a time, waiting until the butter has melted and incorporated into the mixture before adding more. Once all of the butter has been added to the reduction, remove the mixture from the heat and strain it through a fine sieve into a clean saucepan. Season to taste with salt and freshly ground black pepper, then stir in the tarragon and keep warm.
For the scallops, just before baking the shells in the oven brush with the top of the pastry with egg wash. Place in the oven and cook for 8-10 minutes, or until the pastry is golden-brown.
Serve the scallops in their shells with the beurre blanc in a jug.


rocc: ROC based classification
Functions for a classification method based on receiver
operating characteristics (ROC). Briefly, features are selected
according to their ranked AUC value in the training set. The
selected features are merged by the mean value to form a
metagene. The samples are ranked by their metagene value and
the metagene threshold that has the highest accuracy in
splitting the training samples is determined. A new sample is
classified by its metagene value relative to the threshold. In
the first place, the package is aimed at two class problems in
gene expression data, but might also apply to other problems.
| Version: |
1.2 |
| Depends: |
ROCR |
| Published: |
2010-10-04 |
| Author: |
Martin Lauss |
| Maintainer: |
Martin Lauss <martin.lauss at med.lu.se> |
| License: |
GPL-2 | GPL-3 [expanded from: GPL (≥ 2)] |
| NeedsCompilation: |
no |
| CRAN checks: |
rocc results |
Downloads:
Reverse dependencies:
Linking:
Please use the canonical form
https://CRAN.R-project.org/package=rocc
to link to this page.


Welcome to England!
This city is the heart of Europe.
With your traditional Universities. and with an incredible history
of knowledge and many centuries of discoveries. England is without
a doubt one of the best and mysterious cities in the world. Discover
all its magic, which even involves your kingdom with its princes and princesses.
Discover the passion for football and the beautiful stadiums
that exist in cities.
Fall in love with the land of the Beatles, be another
fan of this beautiful place!
Imagem Aérea da Inglaterra
Imagem Aérea da Inglaterra
Imagem Aérea da Inglaterra


--- layout: post permalink: burpeegardening.html Tags: Array NameOfCoupon: Burpee Gardening Cash Back Summary: See our Burpee Gardening Coupon Code, Burpee Gardening Rebate, Burpee Gardening Promo Code, Burpee Gardening Discount, Burpee Gardening Coupon Cash Back Rebate here. MetaKeywords: Burpee Gardening Coupon Code, Burpee Gardening Rebate, Burpee Gardening Promo Code, Burpee Gardening Cash Back Rebate, Burpee Gardening Discount, Burpee Gardening Coupon Image: LinkURL: http://click.linksynergy.com/fs-bin/click?id=6ZrgceZgf7E&offerid=197781.10000218&type=3 affiliate_url_link: http://www.icouponblog.com/jane.php?id=2435 thesis_readmore: See the Burpee Gardening Coupon thesis_thumb: http://www.icouponblog.com/tn.php?merchantURL=burpee.com Title: Save 8% - Burpee Gardening Coupon Code for burpee.com. Burpee Gardening Rebate & Discount thesis_description: Our Burpee Gardening Discount Coupon Code for burpee.com. We have the best Burpee Gardening Rebate anywhere. thesis_keywords: Burpee Gardening, Burpee Gardening Coupon Code, Burpee Gardening Discount, Burpee Gardening Rebate product_name: Burpee Gardening hop_url: http://www.icouponblog.com/hop.php?id=2435 ---
If you don’t have a green thumb but want to have a beautiful garden full of beautiful, colorful, sweet smelling flowers, bulbs, herbs and fresh, great tasting tomatoes, fruits and vegetables, Burpee Gardening will assist you in getting there. For the great soothing and stress relieving experience of watching something that you have planted, grow into a beautiful flower or vegetable garden, trust Gardening. Burpee Gardening seed company is an old, trusted company that has the best reputation for its products. Check it out online at www.burpee.com. Use our discount coupons to save money.
Burpee Gardening seed company has seeds, perennials, heirloom seeds and plants, organic products and lots of gardening supplies. You will find gardening easy and fun with Burpee Gardening. Grow your own luscious tomatoes, blue berries, black berries, strawberries, cantaloupes, honeydews and other mouthwatering and healthy fruits and lots of fresh, scrumptious vegetables. By growing your own, you will have a better control over the products. They will be chemical and pesticide free. Burpee Gardening will assist you, educate you and provide the tools and means of getting the best garden full of flowers, fruits and vegetables. You will love America’s favorite, Burpee Gardening seed company, tried and trusted for years.
Burpee Gardening seeds and other products will help you grow your own fresh and healthy fruits, vegetables and also beautiful flowers that will take away all your stress and put a smile of happiness on your face. Burpee seeds and plants are available for all growing zones and for all seasons and Burpee guarantee each and every product. Visit burpee.com for the best products and tips on gardening.


Ultimately I would like to work projects that are meaningful to me and are in line with my values and ethics. I am particularly passionate about health and well-being, environmentalism, and equality. I would like to find work where my varied work experiences and skills are valued and where I feel a sense of belonging. I am also wanting a career that can fit around my lifestyle and where I can work part-time due to health issues.
Managing the workload with chronic health issues and the symptoms that may affect my participation. Being able to ask for help when I need it because I'm not able to keep on top of things.
I would like to work on my:
I am looking forward to being in a learning environment and drawing on the knowledge and experience of my peers and facilitators. I felt quite isolated during Foundations as I was overseas for most of the time and was not able to ask for help face-to-face. Being around others who are in the same position and having the same experiences as me will make it easier for me to ask for help.
The order in which I will seek help in a timely way:
I will also need to focus on my health and well-being in order to learn and work effectively with others. This means making sure that I sleep well, maintain a healthy diet, exercise, and get plenty of rest so that I can manage the workload and my health. I am particularly aware that this Bootcamp will be very intense and I therefore need to make enough time in the week to look after myself and do the things that keep me well.
A lot of the reasons I am changing careers is because of the stage that I am in life – my partner and I are wanting to start a family next year so I'm wanting to find work that can fit around children, where I can work part-time and remotely from home. I have a background working as an Occupational Therapist so I'm very interested in web accessibility and health-based applications. How can we use technology to increase our well-being and improve our lives? Ultimately, I would like to be working on projects that do this.
I would like to work on my:
Strengths – I persevere and I'm very hard-working and reliable, which makes me a good team-player.
Limitations – perfectionism (spending too much time trying to make things right), imposter syndrome (feeling like I don't belong), not backing myself and skills enough, always feeling that I don't know enough.
To maintain my health and wellbeing in order to learn and work effectively with others, I will do my best to sleep well, exercise, and maintaining a healthy diet. I will work on my perfectionist tendencies and try to remember that it's about learning, rather than getting everything perfect and 'right'. I will be dependable and reliable when working in a team by sticking to time frames, practicing good communication, respecting others, and giving and receiving critical feedback in a positive way. I will do my best to stand up for myself and other learners and make those responsible for helping us learn accountable for ensuring that we're developing the right skills to become developers.
The order:
It will be important for me to set time limits as well as practice seeking help from others, which I find very difficult to do. This way I'll be using my time more effectively and won't be working in isolation and stressing myself out.
I will be overseas from the 13th May – 12th July. I knew this trip was coming up so I specifically chose to do Foundations over 15 weeks. It will be difficult for me to enjoy myself when I know I also have study on my mind, but I have to remember to enjoy the present and live in the moment and remember that the experiences I'm having I don't get to have every day. I will have to juggle travel, catching up with people, going to events, and study. As well, I will have to find appropriate places to study as I will be working in different environments every few days that may not be conducive. Once I am overseas it will be easier to assess how to best study – whether it's doing a couple of hours a day every day or blocking out whole days that are dedicated to study.


Man charged over Ford stabbing is named
Rory Wallace faces three charges after incident on Friday evening
by Carl EveA 23-year-old man from Stoke will appear at Plymouth Magistrates' Court on Monday where he faces three charges relating to an alleged stabbing incident on Friday evening.
Rory Wallace, formerly of Victoria Place, Stoke, but now of no fixed abode, was arrested on Friday evening following an incident in a block of flats in Alexandra Road, Ford .
His alleged victim, said to be in his 20s, remains in Derriford Hospital where he was last described as conscious and stable. He is understood to have suffered multiple wounds to his neck and back, although his injuries were described by police as "not life threatening".
Police later confirmed that Wallace and the injured man were known to each other.
Wallace, aged 23, was charged lated Saturday night with three offences - wounding with intent to cause grievous bodily harm, assault by beating of an emergency worker and criminal damage.
Detectives have confirmed that a weapon has been seized and has been sent for forensic examination.
Wallace has been remanded into custody and will appear on Monday morning before magistrates.


This sample uses SOAP web services with MTOM enabled attachments. You can read more about the Citrus SOAP features in reference guide
Objectives
The Citrus tests in this project send and receive SOAP attachments via MTOM enabled. Both client and server are provided by Citrus so each test receives its own requests as a demo showcase.
The sample shows how to use MTOM enabled SOAP messages as a client and server. First we define the schema and a global namespace for the SOAP messages.
@Bean
public SimpleXsdSchema todoListSchema() {
return new SimpleXsdSchema(new ClassPathResource("schema/ImageService.xsd"));
}
@Bean
public XsdSchemaRepository schemaRepository() {
XsdSchemaRepository schemaRepository = new XsdSchemaRepository();
schemaRepository.getSchemas().add(todoListSchema());
return schemaRepository;
}
@Bean
public NamespaceContextBuilder namespaceContextBuilder() {
NamespaceContextBuilder namespaceContextBuilder = new NamespaceContextBuilder();
namespaceContextBuilder.setNamespaceMappings(Collections.singletonMap("image", "http://www.citrusframework.org/imageService"));
return namespaceContextBuilder;
}
The schema repository holds all known schemas in this project. Citrus will automatically check the syntax rules for incoming messages then. Next we need a SOAP web service client and server component:
@Bean
public SoapMessageFactory messageFactory() {
return new SaajSoapMessageFactory();
}
@Bean
public WebServiceClient imageClient() {
return CitrusEndpoints.soap()
.client()
.defaultUri("http://localhost:8080/services/image")
.build();
}
@Bean
public WebServiceServer imageServer() {
return CitrusEndpoints.soap()
.server()
.port(8080)
.autoStart(true)
.build();
}
As you can see client and server are using the same port 8080
. This means that requests are send to the web service endpoint in Citrus. In addition to that we define a SOAP message factory that is
responsible for creating the SOAP envelope.
Now we can use the web service client and server in the Citrus test.
MTOM enabled
First of all we want to send and receive a SOAP message with MTOM enabled attachment. The request defines the cid:IMAGE
reference in the payload and enabled MTOM usage on the client request.
soap()
.client(imageClient)
.send()
.fork(true)
.soapAction("addImage")
.payload("<image:addImage xmlns:image=\"http://www.citrusframework.org/imageService\">" +
"<image:id>logo</image:id>" +
"<image:image>cid:IMAGE</image:image>" +
"</image:addImage>")
.attachment("IMAGE", "application/octet-stream", new ClassPathResource("image/logo.png"))
.mtomEnabled(true);
soap()
.server(imageServer)
.receive()
.soapAction("addImage")
.schemaValidation(false)
.payload("<image:addImage xmlns:image=\"http://www.citrusframework.org/imageService\">" +
"<image:id>logo</image:id>" +
"<image:image>" +
"<xop:Include xmlns:xop=\"http://www.w3.org/2004/08/xop/include\" href=\"cid:IMAGE\"/>" +
"</image:image>" +
"</image:addImage>")
.attachmentValidator(new BinarySoapAttachmentValidator())
.attachment("IMAGE", "application/octet-stream", new ClassPathResource("image/logo.png"));
The server is able to receive the MTOM enabled message. The image data is streamed as a SOAP attachment using MTOM. This means that the image element in the payload
uses a xop:Inlclude
placeholder element with reference to the cid:IMAGE
attachment. The receiving action in Citrus is able to validate the attachment with BinarySoapAttachmentValidator
as we have a
PNG image content that should be compared as binary stream.
Please note that the schema validation on the receive action is disabled. This is because the xop:Include
placeholder element would break the schema validation with following error:
XML schema validation failed: cvc-type.3.1.2: Element 'image:image' is a simple type, so it must have no element information item [children]
So we have to skip the schema validation when receiving MTOM enabled SOAP messages. In case schema validation is a critical need for you you should be using MTOM inline messages.
MTOM inline
MTOM also supports inline attachment handling with mtom-inline
feature enabled. This means that the image data is automatically added in the payload as base64 encoded data stream.
We can enable MTOM inline on the Citrus SOAP attachment object as follows:
SoapAttachment attachment = new SoapAttachment();
attachment.setContentType("application/octet-stream");
attachment.setContentResourcePath("image/logo.png");
attachment.setMtomInline(true);
attachment.setContentId("IMAGE");
soap()
.client(imageClient)
.send()
.fork(true)
.soapAction("addImage")
.payload("<image:addImage xmlns:image=\"http://www.citrusframework.org/imageService\">" +
"<image:id>logo</image:id>" +
"<image:image>cid:IMAGE</image:image>" +
"</image:addImage>")
.attachment(attachment)
.mtomEnabled(true);
soap()
.server(imageServer)
.receive()
.soapAction("addImage")
.payload("<image:addImage xmlns:image=\"http://www.citrusframework.org/imageService\">" +
"<image:id>logo</image:id>" +
"<image:image>citrus:readFile(image/logo.base64)</image:image>" +
"</image:addImage>");
Now with MTOM inline the request is not using xop:Inlcude
but a base64 encoded data stream in the payload. We can validate this stream with a combination of
citrus:encodeBase64()
and citrus:readFile()
functions.
Run
You can run the sample on your localhost in order to see Citrus in action. Read the instructions how to run the sample.


[gecode-users] Error in GecodeJ
Mikael Zayenz Lagerkvist
zayenz at gmail.com
Sat Dec 8 10:11:15 CET 2007
On 8 dec 2007, at 07.18, Debdeep Banerjee wrote:
> Hi,
> I am getting the following error message after some time the DFS
> search starts.
> --------------------------------------------------------------------------------------------------------------------
> terminate called after throwing an instance of 'Gecode::SpaceFailed'
> what(): Space::clone: Attempt to invoke operation on failed space
> Aborted (core dumped)
> ----------------------------------------------------------------------------------------------------------------------
> I have written a custom propagator. For small size problems my
> program solves correctly, but when ever i have tried a bigger size
> problem or a bit complicated problem where number of backtracks are
> significantly large, I am getting the above error.
>
> I have attached my propagator code.
>
Without looking at your code, there are some general reasons why this
error may happen: http://www.gecode.org/gecode-users/2007-April/001481.html
Cheers,
Mikael
More information about the gecode-users
mailing list


Enter your email to sign in. Don’t worry, we won’t create an account without asking you.
We promise not to spam or sell your email. Check out our Privacy Policy for more details.
Are you sure that email address is right? If you’re super positive, go ahead and click the button again.


| Version: |
1.7-2 |
| Depends: |
R (≥ 2.14.0), awsMethods (≥ 1.0-1), nlme |
| Imports: |
parallel, metafor, methods |
| Suggests: |
tcltk, tkrplot, fastICA, adimpro, oro.nifti |
| Published: |
2016-09-15 |
| Author: |
Karsten Tabelow [aut, cre],
Joerg Polzehl [aut],
Brandon Whitcher [ctb],
Dames Sibylle [ctb] |
| Maintainer: |
Karsten Tabelow <tabelow at wias-berlin.de> |
| License: |
GPL-2 | GPL-3 [expanded from: GPL (≥ 2)] |
| Copyright: |
This package is Copyright (C) 2006-2016 Weierstrass
Institute for Applied Analysis and Stochastics. |
| URL: |
http://www.wias-berlin.de/software/imaging/ |
| NeedsCompilation: |
yes |
| Citation: |
fmri citation info |
| Materials: |
ChangeLog |
| In views: |
ChemPhys, MedicalImaging |
| CRAN checks: |
fmri results |


| PostgreSQL 9.0.10 Documentation | ||||
|---|---|---|---|---|
| Prev | Up | Appendix E. Release Notes | Next |
Release date: 1998-03-01
There are many new features and improvements in this release. Here is a brief, incomplete summary:
Many new SQL features, including full SQL92 subselect capability (everything is here but target-list subselects).
Support for client-side environment variables to specify time zone and date style.
Socket interface for client/server connection. This is the default now so you might need to start postmaster with the -i flag.
Better password authorization mechanisms. Default table privileges have changed.
Old-style time travel has been removed. Performance has been improved.
Note: Bruce Momjian wrote the following notes to introduce the new release.
There are some general 6.3 issues that I want to mention. These are only the big items that cannot be described in one sentence. A review of the detailed changes list is still needed.
First, we now have subselects. Now that we have them, I would like to mention that without subselects, SQL is a very limited language. Subselects are a major feature, and you should review your code for places where subselects provide a better solution for your queries. I think you will find that there are more uses for subselects than you might think. Vadim has put us on the big SQL map with subselects, and fully functional ones too. The only thing you cannot do with subselects is to use them in the target list.
Second, 6.3 uses Unix domain sockets rather than TCP/IP by default. To enable connections from other machines, you have to use the new postmaster -i option, and of course edit pg_hba.conf. Also, for this reason, the format of pg_hba.conf has changed.
Third, char() fields will now allow faster access than varchar() or text. Specifically, the text and varchar() have a penalty for access to any columns after the first column of this type. char() used to also have this access penalty, but it no longer does. This might suggest that you redesign some of your tables, especially if you have short character columns that you have defined as varchar() or text. This and other changes make 6.3 even faster than earlier releases.
We now have passwords definable independent of any Unix file. There are new SQL USER commands. See the Administrator's Guide for more information. There is a new table, pg_shadow, which is used to store user information and user passwords, and it by default only SELECT-able by the postgres super-user. pg_user is now a view of pg_shadow, and is SELECT-able by PUBLIC. You should keep using pg_user in your application without changes.
User-created tables now no longer have SELECT privilege to PUBLIC by default. This was done because the ANSI standard requires it. You can of course GRANT any privileges you want after the table is created. System tables continue to be SELECT-able by PUBLIC.
We also have real deadlock detection code. No more sixty-second timeouts. And the new locking code implements a FIFO better, so there should be less resource starvation during heavy use.
Many complaints have been made about inadequate documentation in previous releases. Thomas has put much effort into many new manuals for this release. Check out the doc/ directory.
For performance reasons, time travel is gone, but can be implemented using triggers (see pgsql/contrib/spi/README). Please check out the new \d command for types, operators, etc. Also, views have their own privileges now, not based on the underlying tables, so privileges on them have to be set separately. Check /pgsql/interfaces for some new ways to talk to PostgreSQL.
This is the first release that really required an explanation for existing users. In many ways, this was necessary because the new release removes many limitations, and the work-arounds people were using are no longer needed.
A dump/restore using pg_dump or pg_dumpall is required for those wishing to migrate data from any previous release of PostgreSQL.
Bug Fixes --------- Fix binary cursors broken by MOVE implementation(Vadim) Fix for tcl library crash(Jan) Fix for array handling, from Gerhard Hintermayer Fix acl error, and remove duplicate pqtrace(Bruce) Fix psql \e for empty file(Bruce) Fix for textcat on varchar() fields(Bruce) Fix for DBT Sendproc (Zeugswetter Andres) Fix vacuum analyze syntax problem(Bruce) Fix for international identifiers(Tatsuo) Fix aggregates on inherited tables(Bruce) Fix substr() for out-of-bounds data Fix for select 1=1 or 2=2, select 1=1 and 2=2, and select sum(2+2)(Bruce) Fix notty output to show status result. -q option still turns it off(Bruce) Fix for count(*), aggs with views and multiple tables and sum(3)(Bruce) Fix cluster(Bruce) Fix for PQtrace start/stop several times(Bruce) Fix a variety of locking problems like newer lock waiters getting lock before older waiters, and having readlock people not share locks if a writer is waiting for a lock, and waiting writers not getting priority over waiting readers(Bruce) Fix crashes in psql when executing queries from external files(James) Fix problem with multiple order by columns, with the first one having NULL values(Jeroen) Use correct hash table support functions for float8 and int4(Thomas) Re-enable JOIN= option in CREATE OPERATOR statement (Thomas) Change precedence for boolean operators to match expected behavior(Thomas) Generate elog(ERROR) on over-large integer(Bruce) Allow multiple-argument functions in constraint clauses(Thomas) Check boolean input literals for 'true','false','yes','no','1','0' and throw elog(ERROR) if unrecognized(Thomas) Major large objects fix Fix for GROUP BY showing duplicates(Vadim) Fix for index scans in MergeJoin(Vadim) Enhancements ------------ Subselects with EXISTS, IN, ALL, ANY key words (Vadim, Bruce, Thomas) New User Manual(Thomas, others) Speedup by inlining some frequently-called functions Real deadlock detection, no more timeouts(Bruce) Add SQL92 "constants" CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER(Thomas) Modify constraint syntax to be SQL92-compliant(Thomas) Implement SQL92 PRIMARY KEY and UNIQUE clauses using indexes(Thomas) Recognize SQL92 syntax for FOREIGN KEY. Throw elog notice(Thomas) Allow NOT NULL UNIQUE constraint clause (each allowed separately before)(Thomas) Allow PostgreSQL-style casting ("::") of non-constants(Thomas) Add support for SQL3 TRUE and FALSE boolean constants(Thomas) Support SQL92 syntax for IS TRUE/IS FALSE/IS NOT TRUE/IS NOT FALSE(Thomas) Allow shorter strings for boolean literals (e.g. "t", "tr", "tru")(Thomas) Allow SQL92 delimited identifiers(Thomas) Implement SQL92 binary and hexadecimal string decoding (b'10' and x'1F')(Thomas) Support SQL92 syntax for type coercion of literal strings (e.g. "DATETIME 'now'")(Thomas) Add conversions for int2, int4, and OID types to and from text(Thomas) Use shared lock when building indexes(Vadim) Free memory allocated for an user query inside transaction block after this query is done, was turned off in <= 6.2.1(Vadim) New SQL statement CREATE PROCEDURAL LANGUAGE(Jan) New PostgreSQL Procedural Language (PL) backend interface(Jan) Rename pg_dump -H option to -h(Bruce) Add Java support for passwords, European dates(Peter) Use indexes for LIKE and ~, !~ operations(Bruce) Add hash functions for datetime and timespan(Thomas) Time Travel removed(Vadim, Bruce) Add paging for \d and \z, and fix \i(Bruce) Add Unix domain socket support to backend and to frontend library(Goran) Implement CREATE DATABASE/WITH LOCATION and initlocation utility(Thomas) Allow more SQL92 and/or PostgreSQL reserved words as column identifiers(Thomas) Augment support for SQL92 SET TIME ZONE...(Thomas) SET/SHOW/RESET TIME ZONE uses TZ backend environment variable(Thomas) Implement SET keyword = DEFAULT and SET TIME ZONE DEFAULT(Thomas) Enable SET TIME ZONE using TZ environment variable(Thomas) Add PGDATESTYLE environment variable to frontend and backend initialization(Thomas) Add PGTZ, PGCOSTHEAP, PGCOSTINDEX, PGRPLANS, PGGEQO frontend library initialization environment variables(Thomas) Regression tests time zone automatically set with "setenv PGTZ PST8PDT"(Thomas) Add pg_description table for info on tables, columns, operators, types, and aggregates(Bruce) Increase 16 char limit on system table/index names to 32 characters(Bruce) Rename system indexes(Bruce) Add 'GERMAN' option to SET DATESTYLE(Thomas) Define an "ISO-style" timespan output format with "hh:mm:ss" fields(Thomas) Allow fractional values for delta times (e.g. '2.5 days')(Thomas) Validate numeric input more carefully for delta times(Thomas) Implement day of year as possible input to date_part()(Thomas) Define timespan_finite() and text_timespan() functions(Thomas) Remove archive stuff(Bruce) Allow for a pg_password authentication database that is separate from the system password file(Todd) Dump ACLs, GRANT, REVOKE privileges(Matt) Define text, varchar, and bpchar string length functions(Thomas) Fix Query handling for inheritance, and cost computations(Bruce) Implement CREATE TABLE/AS SELECT (alternative to SELECT/INTO)(Thomas) Allow NOT, IS NULL, IS NOT NULL in constraints(Thomas) Implement UNIONs for SELECT(Bruce) Add UNION, GROUP, DISTINCT to INSERT(Bruce) varchar() stores only necessary bytes on disk(Bruce) Fix for BLOBs(Peter) Mega-Patch for JDBC...see README_6.3 for list of changes(Peter) Remove unused "option" from PQconnectdb() New LOCK command and lock manual page describing deadlocks(Bruce) Add new psql \da, \dd, \df, \do, \dS, and \dT commands(Bruce) Enhance psql \z to show sequences(Bruce) Show NOT NULL and DEFAULT in psql \d table(Bruce) New psql .psqlrc file start-up(Andrew) Modify sample start-up script in contrib/linux to show syslog(Thomas) New types for IP and MAC addresses in contrib/ip_and_mac(TomH) Unix system time conversions with date/time types in contrib/unixdate(Thomas) Update of contrib stuff(Massimo) Add Unix socket support to DBD::Pg(Goran) New python interface (PyGreSQL 2.0)(D'Arcy) New frontend/backend protocol has a version number, network byte order(Phil) Security features in pg_hba.conf enhanced and documented, many cleanups(Phil) CHAR() now faster access than VARCHAR() or TEXT ecpg embedded SQL preprocessor Reduce system column overhead(Vadmin) Remove pg_time table(Vadim) Add pg_type attribute to identify types that need length (bpchar, varchar) Add report of offending line when COPY command fails Allow VIEW privileges to be set separately from the underlying tables. For security, use GRANT/REVOKE on views as appropriate(Jan) Tables now have no default GRANT SELECT TO PUBLIC. You must explicitly grant such privileges. Clean up tutorial examples(Darren) Source Tree Changes ------------------- Add new html development tools, and flow chart in /tools/backend Fix for SCO compiles Stratus computer port Robert Gillies Added support for shlib for BSD44_derived & i386_solaris Make configure more automated(Brook) Add script to check regression test results Break parser functions into smaller files, group together(Bruce) Rename heap_create to heap_create_and_catalog, rename heap_creatr to heap_create()(Bruce) Sparc/Linux patch for locking(TomS) Remove PORTNAME and reorganize port-specific stuff(Marc) Add optimizer README file(Bruce) Remove some recursion in optimizer and clean up some code there(Bruce) Fix for NetBSD locking(Henry) Fix for libptcl make(Tatsuo) AIX patch(Darren) Change IS TRUE, IS FALSE, ... to expressions using "=" rather than function calls to istrue() or isfalse() to allow optimization(Thomas) Various fixes NetBSD/Sparc related(TomH) Alpha linux locking(Travis,Ryan) Change elog(WARN) to elog(ERROR)(Bruce) FAQ for FreeBSD(Marc) Bring in the PostODBC source tree as part of our standard distribution(Marc) A minor patch for HP/UX 10 vs 9(Stan) New pg_attribute.atttypmod for type-specific info like varchar length(Bruce) UnixWare patches(Billy) New i386 'lock' for spinlock asm(Billy) Support for multiplexed backends is removed Start an OpenBSD port Start an AUX port Start a Cygnus port Add string functions to regression suite(Thomas) Expand a few function names formerly truncated to 16 characters(Thomas) Remove un-needed malloc() calls and replace with palloc()(Bruce)


GCC by itself only compiles the C or C++ code into assembler. Typically
GCC invokes all the passes required for you. These passes are cpp, cc1,
gas, ld. cpp
is the C preprocessor. This will merge in the
include files, expand all macros definitions, and process all the
#ifdef
sections. To see the output of ccp, invoke gcc with the
-E
option, and the preprocessed file will be printed on the
stdout. cc1 is the actual compiler pass that produces the assembler for
the processed file. GCC is actually only a driver program for all the
compiler passes. It will format command line options for the other passes.
The usual command line GCC uses for the final link phase will have LD
link in the startup code and additional libraries by default.
GNU AS started it's life to only function as a compiler pass, but
these days it can also be used as a source level assembler. When used as
a source level assembler, it has a companion assembler preprocessor
called gasp
. This has a syntax similar to most other assembler
macros packages. GAS emits a relocatable object file from the assembler
source. The object file contains the executable part of the application,
and debug symbols.
LD is responsible for resolving the addresses and symbols to something
that will be fully self-contained. Some RTOS's use relocatable object
file formats like a.out
, but more commonly the final image will
only use absolute addresses for symbols. This enables code to be burned
into PROMS as well. Although LD can produce an executable image, there
is usually a hidden object file called crt0.o
that is required as
startup code. With this startup code and a memory map, the executable
image will actually run on the target environment. Startup Files.
The startup code usually defines a special symbol like _start
that is the default base address for the application, and the first
symbol in the executable image. If you plan to use any routines from the
standard C library, you'll also need to implement the functions that
this library is dependent on. Porting Newlib.


Asking questions doesn't seem like it should be a hard thing to do. Turns out, it can be. Just like any form of communication, you need to be able to convey specific meaning to your audience. When you're asking a question, you have to convey exactly what it is looking for to anyone who might have that information. The tricky thing is, if you don't know the answer in the first place, sometimes it can be difficult figuring out how to ask for it.
Let's say you're coding, and you keep getting this weird error. Everything should be working fine, (as far as you can tell,) but it keeps coming up. So, you ask this:
"Hey, guys, I keep getting an error, but I'm doing everything right. Why am I getting an error?"
You're not going to get very helpful responses because, to be honest, your question wasn't very helpful to begin with. When asking a question regarding a situation like this, it is very important to be specific! It would be most helpful to actually provide the exact error message you're getting. Maybe you could even include your code, or what your code is trying to do. Failure to provide any of these is just going to force someone to ask you for these and waste time.
I'm not saying I wouldn't take the extra time to ask for this information and try to help, but there a lot of busy people out there that I'm sure may feel differently. Also, when you include specifics in your question, you can pique the interest of anyone who has had experience with the area of your question, or anyone who has had trouble with it in the past. Without the specifics, they wouldn't know that you were a kindred spirit and could possibly pass your question up.
Sometimes, if you're asking a question about errors in code, it can turn into a long-winded question. When this happens, it is very important to be clear about what you're asking. The following is not helpful:
I'm having a problem. Here is my code:
def blarg
puts "This is my code."
end
Help, please!
These frustrate me to no end. So super not helpful. If you don't actually ask a question, the best anyone can respond is, "Hey. You have code that prints our your sentence, so.... What's wrong?" Again, wasting time. So always be sure to specifiy exactly what you are trying to do, and what your code is doing that you think it shouldn't be doing. If possible, sum it up in an actual question at the end of your post/discussion/blurb/whathaveyou.
So that's all I have on asking good questions. I don't ask questions often, but when I do, I make sure to provide plenty of relevant information and I make sure that it is clear what I am asking.