Subject | Re: [Firebird-Architect] External routines body |
---|---|
Author | Adriano dos Santos Fernandes |
Post date | 2009-05-24T03:03:04Z |
FWIW, code implemented, and here a real demonstration:
create or alter procedure query1 returns (
rdb$relation_id smallint,
rdb$relation_name varchar(31) character set utf8,
rdb$relation_type smallint
) external name
'fbjavademo.FbJdbc.executeQuery(org.firebirdsql.sqlj.ProcedureContext)
return org.firebirdsql.sqlj.ExternalResultSet!
jdbc:firebirdsql:embedded:/tmp/t.fdb|sysdba|masterke'
engine java
as
q'{
select *
from rdb$relations
where rdb$relation_name not starting 'RDB$'
}';
select * from query1;
Although there are better way to handle the connection
string/username/password (i.e., via a config name and a table with that
info), that demonstrate how powerful generic external routines could be.
With that simple one, FB is able to execute (typed) queries at any DBMS
(or other datasource types) with the user just defining a selectable
stored procedure for each query.
--------------------
public class FbJdbc
{
public static ExternalResultSet executeQuery(final ProcedureContext
context) throws Exception
{
return new ExternalResultSet() {
Values outValues = context.getOutputValues();
int count = outValues.getCount();
Connection conn;
PreparedStatement stmt;
ResultSet rs;
{
StringTokenizer tokenizer = new
StringTokenizer(context.getNameInfo(), "|");
conn =
DriverManager.getConnection(tokenizer.nextToken(),
tokenizer.nextToken(), tokenizer.nextToken());
StringBuilder sb = new StringBuilder("select ");
for (int i = 0; i < count; ++i)
{
if (i != 0)
sb.append(", ");
sb.append(outValues.getName(i + 1));
}
sb.append(" from (" + context.getBody() + ")");
stmt = conn.prepareStatement(sb.toString());
rs = stmt.executeQuery();
}
@Override
public boolean fetch() throws Exception
{
if (!rs.next())
{
rs.close();
stmt.close();
conn.close();
return false;
}
for (int i = 0; i < count; ++i)
outValues.setValue(i + 1, rs.getObject(i + 1));
return true;
}
};
}
}
--------------------
Adriano
create or alter procedure query1 returns (
rdb$relation_id smallint,
rdb$relation_name varchar(31) character set utf8,
rdb$relation_type smallint
) external name
'fbjavademo.FbJdbc.executeQuery(org.firebirdsql.sqlj.ProcedureContext)
return org.firebirdsql.sqlj.ExternalResultSet!
jdbc:firebirdsql:embedded:/tmp/t.fdb|sysdba|masterke'
engine java
as
q'{
select *
from rdb$relations
where rdb$relation_name not starting 'RDB$'
}';
select * from query1;
Although there are better way to handle the connection
string/username/password (i.e., via a config name and a table with that
info), that demonstrate how powerful generic external routines could be.
With that simple one, FB is able to execute (typed) queries at any DBMS
(or other datasource types) with the user just defining a selectable
stored procedure for each query.
--------------------
public class FbJdbc
{
public static ExternalResultSet executeQuery(final ProcedureContext
context) throws Exception
{
return new ExternalResultSet() {
Values outValues = context.getOutputValues();
int count = outValues.getCount();
Connection conn;
PreparedStatement stmt;
ResultSet rs;
{
StringTokenizer tokenizer = new
StringTokenizer(context.getNameInfo(), "|");
conn =
DriverManager.getConnection(tokenizer.nextToken(),
tokenizer.nextToken(), tokenizer.nextToken());
StringBuilder sb = new StringBuilder("select ");
for (int i = 0; i < count; ++i)
{
if (i != 0)
sb.append(", ");
sb.append(outValues.getName(i + 1));
}
sb.append(" from (" + context.getBody() + ")");
stmt = conn.prepareStatement(sb.toString());
rs = stmt.executeQuery();
}
@Override
public boolean fetch() throws Exception
{
if (!rs.next())
{
rs.close();
stmt.close();
conn.close();
return false;
}
for (int i = 0; i < count; ++i)
outValues.setValue(i + 1, rs.getObject(i + 1));
return true;
}
};
}
}
--------------------
Adriano