), elements using an ID, and classes if you use a '.' to prefix the class name.
Usage to remove our postData tag that indicates that LD+Json is being used: removeStr(value, "postData")
Usage to remove the 'foo' class from a string: removeStrBetween(str, '.foo');
*/
var removeStrBetween = function(str, selector) {
// Create a new container to operate on
var wrapped = $(" " + str + " ");
// Remove the content between the tags.
wrapped.find(selector).remove();
// Return it
return wrapped.html();
}
// Function to truncate and add an elipsis if the text exceeds a certain value
function truncateWithEllipses(text, max) {
return text.substr(0,max-1)+(text.length>max?'...':'');
}
function stripHtml(html){
html.replace(/<[^>]*>?/gm, '');
return html;
}
// Determine if a string has a space
function hasWhiteSpace(s) {
const whitespaceChars = [' ', '\t', '\n'];
return whitespaceChars.some(char => s.includes(char));
}
// ColdFusion like string functions
// ReplaceNoCase, scope is either 'all' or 'one'.
// Gregory Alexander
function replaceNoCase(string,subString,replacement, scope){
if (scope == 'all'){
// i is a RegEx ignore case flag, g is global flag
var regEx = new RegExp(subString, "ig");
} else {
// i is an RegEx ignore case flag
var regEx = new RegExp(subString, "i");
}
// i is an ignore case flag, g is global flag
var regEx = new RegExp(subString, "ig");
var result = string.replace(regEx, replacement);
return result;
}
// ColdFusion like list functions
function listLen(list, delimiter){
// Gregory Alexander
if(delimiter == null) { delimiter = ','; }
var thisLen = list.split(delimiter);
return thisLen.length;
}
function listGetAt(list, position, delimiter, zeroIndex) {
// Gregory Alexander
if(delimiter == null) { delimiter = ','; }
if(zeroIndex == null) { zeroIndex = true; }
list = list.split(delimiter);
if(list.length > position) {
if(zeroIndex){
// Better handling for JavaScript arrays
return list[position];
} else {
// Handles like the CF version without a zero-index
return list[position-1];
}
} else {
return 0;
}
}
function listFind(list, value, delimiter) {
// Adapted from a variety of sources by Gregory Alexander
var result = 0;
if(delimiter == null) delimiter = ',';
list = list.split(delimiter);
for ( var i = 0; i < list.length; i++ ) {
if ( value == list[i] ) {
result = i + 1;
return result;
}
}
return result;
}
// Compares two lists of comma seperated strings. Used to determine if the selected capabilities match the default capabilities for a given role. Function based on the listCompare method found in cflib.
function listCompare(string1, string2){
// Adapted from a variety of sources by Gregory Alexander
var s = string1.split(",");
for(var k = 0 ;k < s.length; k++){
if(string2.indexOf("," + s[k] + ",") ){
return true;
}
}
return false;
}
// Adds a value to a comma separated list. Will not add the value if the list already contains the value.
function listAppend(list, value) {
// Adapted from a variety of sources by Gregory Alexander
var re = new RegExp('(^|\\b)' + value + '(\\b|$)');
if (!re.test(list)) {
return list + (list.length? ',' : '') + value;
}
return list;
}
// Removes a value to a comma separated list. Based on the ListDeleteValue function by Ben Nadel CF fuction https://gist.github.com/bennadel/9753040
var listDeleteValue = function(list, value){
// Adapted from a variety of sources by Gregory Alexander
var values = list.split(",");
for(var i = 0 ; i < values.length ; i++) {
if (values[i] == value) {
values.splice(i, 1);
return values.join(",");
}
}
return list;
}
// URL functions
//
// parseUri 1.2.2
// (c) Steven Levithan
// MIT License
/*
Splits any well-formed URI into the following parts (all are optional):
----------------------
- source (since the exec method returns the entire match as key 0, we might as well use it)
- protocol (i.e., scheme)
- authority (includes both the domain and port)
- domain (i.e., host; can be an IP address)
- port
- path (includes both the directory path and filename)
- directoryPath (supports directories with periods, and without a trailing backslash)
- fileName
- query (does not include the leading question mark)
- anchor (i.e., fragment) */
function parseUri (str) {
var o = parseUri.options,
m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
uri = {},
i = 14;
while (i--) uri[o.key[i]] = m[i] || "";
uri[o.q.name] = {};
uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
if ($1) uri[o.q.name][$1] = $2;
});
return uri;
};
parseUri.options = {
strictMode: false,
key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
q: {
name: "queryKey",
parser: /(?:^|&)([^&=]*)=?([^&]*)/g
},
parser: {
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
}
};
// Dump function. Use like you would with cfdump.
// function to dump out a a javascript object.
function mydump(arr,level) {
var dumped_text = "";
if(!level) level = 0;
var level_padding = "";
for(var j=0;j \"" + value + "\"\n";
}
}
} else {
dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
}
console.log(dumped_text);
}
Introducing ColdFusion ORM
by Gregory Alexander
ColdFusion ORM Supported Databases with a Custom Dialect
The following databases should be supported as long as you provide the custom dialect using the fully qualified class name.
RDBMS |
ORM Dialect |
Oracle (any version) |
org.hibernate.dialect.OracleDialect |
Oracle 11g |
org.hibernate.dialect.Oracle10gDialect |
Microsoft SQL Server 2000 |
org.hibernate.dialect.SQLServerDialect |
Microsoft SQL Server 2005 |
org.hibernate.dialect.SQLServer2005Dialect |
Microsoft SQL Server 2008 |
org.hibernate.dialect.SQLServer2008Dialect |
SAP DB |
org.hibernate.dialect.SAPDBDialect |
Informix |
org.hibernate.dialect.InformixDialect |
Hypersonic SQL |
org.hibernate.dialect.HSQLDialect |
H2 Database |
org.hibernate.dialect.H2Dialect |
Ingres |
org.hibernate.dialect.IngresDialect |
Progress |
org.hibernate.dialect.ProgressDialect |
Mckoi SQL |
org.hibernate.dialect.MckoiDialect |
Interbase |
org.hibernate.dialect.InterbaseDialect |
Pointbase |
org.hibernate.dialect.PointbaseDialect |
FrontBase |
org.hibernate.dialect.FrontbaseDialect |
Firebird |
org.hibernate.dialect.FirebirdDialect |
However, ColdFusion ORM is not without its challenges
While having CF-ORM support all database platforms is terrific; using CF-ORM may lock you into using a particular ColdFusion version. CF-ORM functionality changes depending upon the version of ColdFusion. CF-ORM on ColdFusion 9 is quite a bit different than CF-ORM on ColdFusion 2016. So, while you may be supporting a wide variety of database platforms, you may be stuck on a particular ColdFusion version. There are also differences between CF-ORM between ColdFusion, and its open-source sister, Lucee.
Also, CF-ORM has a slew of other challenges. Error reporting is confusing. Since CF-ORM is built upon Hibernate, it does not have the error messages that we typically expect out of a ColdFusion product. Error messages are not always available and are often confusing. The documentation is sparse, and at times misleading. Take for example the cfproperty documentation on the Adobe site. Most of the properties are not documented at all. Two-thirds of the description columns are blank.
Additionally, if you dig around and find documentation for a certain feature, it may not work at all! For example, I wanted to eliminate the database constraint for some of the database columns using the constrained="false" argument. Adobe's own cfproperty documentation mentioned the constrained property, but gave no description. Finally, I was able to find some documentation on the constrained property on another site, however, no matter what I did, I could not get the argument to work. I also went to the ORM channel on cfslack to ask for help, and no one knew how to get it to work.
Finally, another issue is that just like ColdFusion UI, CF-ORM is tied to Adobe ColdFusion and you're limited in what changes you can make. You'll have to wait until a new ColdFusion version to come out before you can upgrade to a new version of Hibernate.
ColdFusion ORM alternatives
While I have not used them yet myself, I have heard good things about Quick and cbOrm. Quick is written in ColdFusion and it handles errors much better than CF-ORM. cbOrm is an extension of CF-ORM, and Ortus has added a lot of functionality and flexibility to the underlying Hibernate engine that CF-ORM uses. I won't cover either Quick or cbOrm here, but they are both worth recommending if you want to avoid CF-ORM, especially if you're already using the ColdBox framework.
Since my project requires that I support as many database platforms possible, and I don't want to include another library, such as ColdBox, I am using CF-ORM and will show you some of the solutions that I used to overcome common CF-ORM pitfalls.
In the next article, we'll jump in and look at the code....
Tags
ColdFusion ORM
|
Gregory Alexander
|
Hi, my name is Gregory! I have several degrees in computer graphics and multimedia authoring, and I have been developing enterprise web applications for the last 25 years. I love web technologies and the outdoors and am passionate about giving back to the community.
|
This entry was posted on December 28, 2019 at 8:30 PM and has received 3715 views.
|