Overview
Installation
VTL reference
Configuration
Architecture
Java reference
Velosurf FAQ |
XML Configuration
Don't be confused here, 'entity' and 'attribute' are both used as XML concepts and velosurf concepts... The velosurf entity has a corresponding XML entity, the velosurf attribute has a corresponding XML entity, and both have XML attributes.
The DTD can be found here.
Here is the syntax and meaning of all the XML attributes:
XML entity |
XML attribute |
syntax |
default value |
meaning |
database |
user |
string |
(required) |
database account login |
database |
password |
string |
(required) |
database account password |
database |
url |
string |
(required) |
database url |
database |
driver |
java_class_name |
(none) |
database driver class - if not specified, Velosurf will try to deduce it from the database url |
database |
schema |
string |
(none) |
schema used, if any |
database |
default-access |
ro | rw |
ro |
entities default access mode, read-only or read-write |
database |
default-caching |
none | soft | full |
none |
default caching method |
database |
case |
sensitive |
uppercase |
lowercase |
(driver-dependant) |
case-sensivity: sensitive, uppercase or lowercase - see remarks |
database |
reverse |
none | partial | full |
full |
degree of reverse-enginering: in the 'partial' mode, only the tables corresponding to entities listed in the config file are reverse-enginered - it may become the default mode in future versions |
database |
loglevel |
trace | debug | info | warn | error |
trace |
logging level, from the most verbose to the less verbose |
database |
min-connections |
integer |
1 |
the initial number of connections in the connection pool |
database |
max-connections |
integer |
50 |
the maximum number of connections in the connection pool |
entity |
name |
string |
(required) |
entity name; if it is the name of an existing table, the columns of the table will automatically become attributes of this entity |
entity |
table |
string |
entity name |
use this attribute if the table name and the entity name are to be different |
entity |
access |
ro | rw |
ro |
access mode, read-only or read-write |
entity |
class |
java_class_name |
velosurf.context.Instance |
java class used to map an instance of this entity (that must inherit velosurf.context.Instance and have the same constructor, see the javadoc) |
entity |
caching |
none | soft | full |
(none) |
caching method: none, soft (automatic with respect to memory) or full (only cleared on Entity.clearCache() calls) |
entity |
obfuscate |
column [,column...] |
(none) |
columns that will be obfuscated |
entity |
autofetch |
[[query.]name =] http_param_name |
(none) |
whenever http_param_name is found in the HTTP query string, the HttpQueryTool interprets it as a primary key and fetches the corresponding instance, storing it in the context under $name or $query.name (or the name of the entity if unspecified) |
attribute |
name |
string |
(required) |
attribute name, can overload an existing column |
attribute |
result |
scalar |
row[/entity] |
rowset[/entity] |
(none) |
result type: scalar, single row or rowset ; in the last two cases, the resulting entity can be specified, so that access can be re-entrant; in the first case (scalar), the engine will return the value found in the first column of the first row. |
attribute |
foreign-key |
column_name |
(none) |
foreign-key column towards the entity specified as a result (that is required in this case) ; when this XML attribute is used, the SQL query is ignored ; in fact this XML attribute is just a shorthand for the join query |
action |
name |
string |
(required) |
action name |
And some important remarks on this config file:
- root attributes and actions: Along with attributes and actions declared inside an entity (that become properties of this entity),
attributes and actions can be declared directly under <database>: they become root attributes and root actions, direct
properties of $db.
If specified, the root action named startup is executed at startup.
- using current instance values: SQL queries of attributes and actions may (and often have to) reference columns of the current instance, by simply inserting XML tags at the right place.
For instance, assuming 'owner_id' is a field of the 'event' table:<entity name="event">
<attribute name="owner" result="row/user">
select * from user where user_id = <owner_id/>
</attribute>
</entity>
Then, in VTL, if $event contains an event, then $event.owner will return the user that owns the event.
- external parameters: sometimes there is the need for an external parameter to appear in an SQL query. In that case, it can be named as an XML tag inside the query, and later used by setting its value on the surrounding entity (or on $db for root actions/attributes).
For instance, here is the definition of a root attribute that lists all events of a month:<attribute name="month_events" result="rowset/event">
select * from event where month(event_date) = <selected_month/>
</attribute>
In VTL, you can then write:
#set($db.selected_month = 3)
#foreach($event in $db.month_events)
... display the event ...
#end
Note that the name selected_month does not correspond to anything in the database: it is only a label that can be used as a prepared statement parameter.
Note also that external parameters only retain their value within the scope of one VelosurfTool instance (which is the request scope by default).
- XML parsing of queries: Since XML parsers may add spaces here and there inside #PCDATA, and since that may sometimes break the syntax of SQL queries, it is a good idea to specify
xml-space="preserve" as an XML attribute of any XML entity containing a SQL query.
- escaping of XML special characters: be sure to escapes characters < > & and ' with their XML equivalent whenever they appear inside your queries.
- IDs obfuscation: When you obfuscate a key column, be sure to also obfuscate all foreign-keys that reference this column. If you want to specify an explicit value to an obfuscated column (via an update or an insert), you have to obfuscate it first since it will always be deobfuscated - you can do so with the
entity.obfuscate(value) method. Please note that this feature requires some javax.crypto classes that are not included by default in the jdk for versions prior to 1.4 ; in this case, you'll have to download the Java Cryptographic Extension (jce1_2_2.jar and sunjce_provider.jar) from java.sun.com.
- Autofetching: Autofetching only works if you are using the toolbox.xml mechanism and the velosurf.tool.HttpQueryTool tool. Here are the VTL equivalent for the three forms of the declaration (assuming the HttpQueryTool is named $query):
<entity name="user" autofetch="user_id"/> is equivalent to:
#if( $query.user_id ) #set( $user = $db.user.fetch( $query.user_id )) #end
<entity name="user" autofetch="logged_user=user_id"/> is equivalent to:
#if( $query.user_id ) #set( $logged_user = $db.user.fetch( $query.user_id )) #end
<entity name="user" autofetch="query.logged_user=user_id"/> is equivalent to:
#if( $query.user_id ) #set( $query.loggued_user = $db.user.fetch( $query.user_id )) #end
- Case-sensivity: Indicates the policy that Velosurf must follow with SQL keywords (tables and columns). It should mimic the behaviour the database engine has with its metadata tables, and the default is choosen depending on the database vendor (see DriverInfo.java). It is one of:
sensitive : It does not necessarily mean that the database is case-sensitive, only that Velosurf won't issue any conversion.
uppercase : Entities and attributes are case-insensitive; all identifiers will be stored internally and passed to the JDBC driver as uppercase strings (references in templates and names in the configuration file are then case-insensitive).lowercase : Same as above, lowercase.
- Connection pooling: Velosurf uses two connection pools. One with connections having the autocommit flag set to true for all
standard queries, and one with connections having the autocommit flag set to false for transactionnal queries (i.e. composite queries made of
a sequence of several atomic queries, and on wich a rollback must be issued when something goes wrong during the processing). Since such
queries are
usually less frequent and less heavy than standard ones, the latter pool is initialized with only one connection. The
min-connections parameter only applies to the former pool.
|