Open agershun opened 9 years ago
I found some guidelines for different databases:
What version to choose? IMHO SQLite is preferable...
The SQLite looks good - and suits our needs - but if we ever make a module setup where you can select your flavour AlaSQL could have an internal error number that it converts to the flavor chosen...
:+1: Great idea! Agree, we can start with SQLite and make mapping to other SQLs error systems.
For example for UNIQUE constraint:
// Definition
var errcodes = {};
// Error function
function erorr(errid) {
if(errcodes[errid]) errid = errcodes[errid];
throw new Error(errid)
}
// Somewhere in SQLite module
// This will work only after 'REQUIRE SQLITE' command
errcode['CONSTRAINT_UNIQUE'] = 'UNIQUE constraint failed'
//Usage
error('CONSTRAINT_UNIQUE');
Looked into the SQLite one. its quite simple, but we might end up in too many 21's
SQLITE_MISUSE 21 /* Library used incorrectly */
MsSQL and Oracle have way too many special cases to start with them. The postgress looks good: http://www.postgresql.org/docs/8.2/static/errcodes-appendix.html
I had a feeling it was a bit crazy to try to map all the (very good) error descriptions in the source to the generic ones in the other frameworks.
I feel the objective is to minimise the code, so saw no reason not to keep a system that makes sense to the alasql setup.
I have made it so when developing with alasql.js the full errors are in the source, while only the error code is in the .min.js file.
Example:
In this alasql.js you can get an error as
You can remove files only in Node.js and Apache Cordova
now the .min.js version only contains the string
e01501
as error description.
Error codes implemented so far: https://github.com/agershun/alasql/wiki/Error-codes
@mathiasrw hmm ... People need error codes not for minimizing the library size, but for automatic processing in case of problems. E.g. AlaSQL returns the error "Cannot open the file", so the main program can generate this file itself, because it understand that this is the particular erro. An it try to recognize the problem by the code, not by text description.
So, I think we need:
1) create a special error(code, description, args)
function with two parameters:
code
- error codedescription
- human readable error descriptionargs
- error parameters including database, table, indexes names, etc.2) This function can be rewritten by user in a standard manner, like:
alasql.error = function(code,description,args) {.
if(code === 123 && args.databaseid == "MyBase") {
// fix something with database MyBase
return; // error was trapped and processed
}
alasql.defaulterror(code, description, args);
}
3) By default it generates new Error() message:
alasql.defaulterror = function() {
new Error(code+' '+description);
}
In more complex case, we can create a special error descriptions table:
alasql.errorcodes = {
123: 'Database $databaseid can not be dropped',
};
alasql.defaulterror = function(code, args) {
new Error(code+' '+template(errorcodes.description,args));
}
And rase if with:
error(123,{databaseid:'MyBase'});
So, it is not good to have different behavior between alasql.js
and alasql.min.js
.
The smallest code for temlate() function (from here):
(function(){
var cache = {};
this.template = function(str,data) {
var fn = cache[str] = cache[str] || new Function("obj",
"var p=[],print=function(){p.push.apply(p,arguments);};" +
"with(obj){p.push('" +
str
.replace(/[\r\t\n]/g, " ")
.split("{{").join("\t")
.replace(/((^|}})[^\t]*)'/g, "$1\r")
.replace(/\t(.*?)}}/g, "',$1,'")
.split("\t").join("');")
.split("}}").join("p.push('")
.split("\r").join("\\'")
+ "');}return p.join('');");
return fn(data);
}
})();
ok ok ok... good point...
Sorry and thank you for code reverting! Together we will do it better :)
Let's define interfaces:
alasql.errorhandler = function(code, args) {...} // by default refers to alasql.defaulterrorhandler()
alasql.defaulterrorhandler = function(code, args) {
throws new Error(code+':'+template(alasql.errorcodes,args));
};
alasql.errorcodes = {
<code-int> : <template-string>
}
alasql.stdfn.template = function(pattern, obj) {
// replace all {{name}} or $name to object properties
};
BTW:Bonus - we can use this template function in SQL queries :)
What do you think about this approach?
Looks good but must say the function(code,description,args)
version makes more sense to me. is the idea to put the discription in the args?
The idea here is to have separate table for all error template messages. The args
object is used only for parameters of error.
Off-topic: what syntax for TEMPLATE(str,obj) function is better?
option 1 - {{prop}}
option 2 - <%prop%>
or use options:
alasql.options.templright = '<$';
alasql.options.templleft = '$>';
We will use the same function for such queries like:
var tmpl = '{{a}} rows included in {{b}}';
var data = [{a:10,b:'one.txt'}, {a:20,b:'two.txt'}];
alasql('SELECT TEMPL(?,_) FROM ?', [tmpl, data]);
Personally I really prefer the {{...}}
syntax.
I have a feeling that setting it as an option creates a complexity with no real benefit.
How come you have a _
as second parameter?
{{ }}
by default._
is similar to *
, but in case of SELECT * FROM ?
AlaSQL copies all columns into the new records, but with SELECT _ FROM ?
(or simply SELECT FROM ?
) AlaSQL uses the same object.This is the example:
var data = [{a:1}];
var res = alasql('SELECT _ AS q, _->a AS w FROM ?',[data]);
// [{q:{a:1}, w:1}]
:+1:
To make error catching easy it is reasonable to number errors, like:
So, people can distinguish errors by their numbers rather than text description: