SqlType:
This module contains a type describing data types of SQL database
values.
These types are based on the set of JDBC data types, and are more fine-
grained than those in ValueType.
Also, some of the types include additional information, such as the
precision/scale or maximum character length.
BusinessCalendar:
This module contains the BusinessCalendar type which provides
information about valid period values, display names, etc... for
period types (Year, Quarter, Month, etc...) in the calendar.
There are also functions to build database expressions for extracting
period values (relative to the calendar) from a database date/time
field.
Actual implementations of BusinessCalendars can be found in
GregorianBusinessCalendar and FiscalBusinessCalendar.
GregorianBusinessCalendar:
This module contains an implementation of a BusinessCalendar based on
the Gregorian calendar.
Here, the periods have their usual Gregorian values and names.
FiscalBusinessCalendar:
This module contains an implementation of a BusinessCalendar based on
a simple fiscal calendar which can be shifted some number of months
from the Gregorian calendar.
DataDictionary:
This module contains the DataDictionary type class, which exposes a
simplified view of a database and can be queried more simply than
constructing SQL (directly or using the Sql module types).
The SqlDataDictionary module provides one implementation of a
DataDictionary, however others are possible as well.
SqlDataDictionary:
This module contains an implementation of a DataDictionary based on
the Sql and DataGems modules.
Information about SQL expressions and join is specified when the data
dictionary is constructed, but users of the data dictionary work with
a simplified query model.
DictionaryQuery:
This module contains the model for constructing database queries
against data dictionaries.
Much of this model resembles the Sql module functionality; however
complex concepts like database tables and joins are omitted.
DirectedGraph:
This module contains a DirectedGraph type, which is an ordered
collection of values and the relationships between them.
Drawing:
This experimental module contains functions which give access to
Java2D functionality from CAL.
There are functions to draw text, shapes, images, etc... to a Java
Graphics2D.
Functions also exist to perform any drawing with a transformation
applied (scaling, shifting, etc...).
CollectionUtilities:
This module contains a variety of utility functions for working with
collections (List, Sets, Maps, etc...).
Most of these were pulled out of other modules where they were being
used as private helper functions.
XmlParser:
This module implements an experimental XML parser based on the
functions from the Parser library module.
The XmlParser.parseXmlDocument function accepts a String containing
XML text, parses this, and returns the resulting XmlDocument or throws
an error if the XML is not valid.
Can't wait to see the data dictionary modules - I don't really get
what they do exactly yet but they do sound interesting. Actually it
all sounds interesting and it's good to see so much progress.
Steve
PS: I looked up the missing ones. Implementations are included below
which don't require changing the Java side (except the Decimal one
really needs to call a new ResultSet.getBigDecimal() directly, as
mentioned). Sorry if it's mangled, I don't have access to a web
server just now :
extractDecimal :: Int -> ResultRow -> Decimal;
public extractDecimal !cnum !row =
Prelude.stringToDecimal $ jObjectToString $ DataGems.extractObject
cnum row;
extractMaybeDecimal :: Int -> ResultRow -> Maybe Decimal;
public extractMaybeDecimal !cnum !row =
let maybeObj = eager $ DataGems.extractMaybeObject cnum row;
in case maybeObj of
Just o -> Just $ Prelude.stringToDecimal $ jObjectToString o;
Nothing -> Nothing;
;
extractLong :: Int -> ResultRow -> Long;
public extractLong !cnum !row =
longFromJNumber $ castJObjectToJNumber $ DataGems.extractObject
cnum row;
extractMaybeLong :: Int -> ResultRow -> Maybe Long;
public extractMaybeLong !cnum !row =
let maybeObj = eager $ DataGems.extractMaybeObject cnum row;
in case maybeObj of
Just o -> Just $ longFromJNumber (castJObjectToJNumber o);
Nothing -> Nothing;
;
extractShort :: Int -> ResultRow -> Short;
public extractShort !cnum !row =
shortFromJNumber $ castJObjectToJNumber $ DataGems.extractObject
cnum row;
extractMaybeShort :: Int -> ResultRow -> Maybe Short;
public extractMaybeShort !cnum !row =
let maybeObj = eager $ DataGems.extractMaybeObject cnum row;
in case maybeObj of
Just o -> Just $ shortFromJNumber (castJObjectToJNumber o);
Nothing -> Nothing;
;
extractFloat :: Int -> ResultRow -> Float;
public extractFloat !cnum !row = Prelude.toFloat $
DataGems.extractDouble cnum row;
extractMaybeFloat :: Int -> ResultRow -> Maybe Float;
public extractMaybeFloat !cnum !row =
case DataGems.extractMaybeDouble cnum row of
Just d -> Just (Prelude.toFloat d);
Nothing -> Nothing;;
extractRelativeTime :: Int -> ResultRow -> RelativeTime;
public extractRelativeTime !cnum !row =
jTimeToRelativeTime $ castJObjectToJTime $ DataGems.extractObject
cnum row;
extractMaybeRelativeTime :: Int -> ResultRow -> Maybe RelativeTime;
public extractMaybeRelativeTime !cnum !row =
case DataGems.extractMaybeObject cnum row of
Just o -> Just (jTimeToRelativeTime $ castJObjectToJTime o);
Nothing -> Nothing;
;
// DataGems has the extractRelativeDate function, but not the Maybe
version.
extractMaybeRelativeDate :: Int -> ResultRow -> Maybe RelativeDate;
public extractMaybeRelativeDate !cnum !row =
case DataGems.extractMaybeDate cnum row of
Just jdate -> Just (RelativeTime.jDateToRelativeDate jdate);
Nothing -> Nothing;
;
extractMaybeJObject :: Int -> ResultRow -> Maybe JObject;
public extractMaybeJObject = DataGems.extractMaybeObject;
// Blob and Clob types would be nice...
extractBlob :: Int -> ResultRow -> Blob;
public extractBlob !cnum !row =
Prelude.input $ DataGems.extractObject cnum row;
extractMaybeBlob :: Int -> ResultRow -> Maybe Blob;
public extractMaybeBlob !cnum !row =
let maybeObj = eager $ DataGems.extractMaybeObject cnum row;
in case maybeObj of
Just o -> Just $ Prelude.input o;
Nothing -> Nothing;
;
extractClob :: Int -> ResultRow -> Clob;
public extractClob !cnum !row =
Prelude.input $ DataGems.extractObject cnum row;
extractMaybeClob :: Int -> ResultRow -> Maybe Clob;
public extractMaybeClob !cnum !row =
let maybeObj = eager $ DataGems.extractMaybeObject cnum row;
in case maybeObj of
Just o -> Just $ Prelude.input o;
Nothing -> Nothing;
;
// Helper functions for field extractors
data foreign unsafe import jvm "java.lang.Number"
private JNumber;
foreign unsafe import jvm "cast"
private castJObjectToJNumber :: JObject -> JNumber;
foreign unsafe import jvm "method longValue"
private longFromJNumber :: JNumber -> Long;
foreign unsafe import jvm "method shortValue"
private shortFromJNumber :: JNumber -> Short;
foreign unsafe import jvm "method toString"
private jObjectToString :: JObject -> String;
data foreign unsafe import jvm "java.sql.Time"
private JTime;
foreign unsafe import jvm "cast"
private castJObjectToJTime :: JObject -> JTime;
foreign unsafe import jvm "method getTime"
private jTimeToMillis :: JTime -> Long;
jTimeToRelativeTime :: JTime -> RelativeTime;
jTimeToRelativeTime !jTime =
let millis = jTimeToMillis jTime;
secs = fromLong (millis/1000)%60;
mins = fromLong (millis/60000)%60;
hrs = fromLong (millis/3600000);
in
RelativeTime.makeRelativeTimeValue hrs mins secs;
It definitely make sense to be able to extract values such as Decimals
properly.
I've added the functions to extract Decimal and Long values (as well
as the Maybe and 'with default' versions).
I have also added extractMaybeRelativeDate for consistency.
For Clob and Blob values, you might be ok with the String and Binary
extractor functions.
However, these will attempt to fetch the entire value at once.
It might be worth considering an approach where we access the values
in chunks or as a stream.
I wanted to get the Decimal and Long functions in for the Open Quark
1.6 release (which they will be).
I'll look into some of the other functions you proposed later.
Thanks
Rich
thanks for being so responsive as usual,
Steve