@@ -385,16 +385,19 @@ function TplEntry( node, tpl )
385385function multisplit ( tpl , delims , postop )
386386{
387387 var IDL = delims [ 0 ] , IDR = delims [ 1 ] ,
388- OBL = delims [ 2 ] , OBR = delims [ 3 ] , TPL = delims [ 4 ] ,
388+ OBL = delims [ 2 ] , OBR = delims [ 3 ] ,
389389 lenIDL = IDL . length , lenIDR = IDR . length ,
390- lenOBL = OBL . length , lenOBR = OBR . length , lenTPL = TPL . length ,
390+ lenOBL = OBL . length , lenOBR = OBR . length ,
391391 ESC = '\\' , OPT = '?' , OPTR = '*' , NEG = '!' , DEF = '|' , COMMENT = '#' ,
392- REPL = '{' , REPR = '}' , DOT = '.' , REF = ':' , ALGN = '@' , //NOTALGN = '&',
392+ TPL = ':=' , REPL = '{' , REPR = '}' , DOT = '.' , REF = ':' , ALGN = '@' , //NOTALGN = '&',
393+ COMMENT_CLOSE = COMMENT + OBR ,
393394 default_value = null , negative = 0 , optional = 0 ,
394395 nested , aligned = 0 , localised = 0 , start_i , end_i , template ,
395- argument , p , stack , c , a , b , s , l = tpl . length , i , j , jl , escaped , ch ,
396+ argument , p , stack , c , a , b , s , l = tpl . length , i , j , jl ,
396397 subtpl , arg_tpl , cur_tpl , start_tpl , cur_arg , opt_args ,
397- roottpl , block , cur_block , prev_arg , prev_opt_args ;
398+ roottpl , block , cur_block , prev_arg , prev_opt_args ,
399+ delim1 = [ IDL , lenIDL , IDR , lenIDR ] , delim2 = [ OBL , lenOBL , OBR , lenOBR ] ,
400+ delim_order = [ null , 0 , null , 0 , null , 0 , null , 0 ] , delim ;
398401
399402 postop = true === postop ;
400403 a = new TplEntry ( { type : 0 , val : '' , algn : '' } ) ;
@@ -413,46 +416,86 @@ function multisplit( tpl, delims, postop )
413416 } ;
414417 roottpl = a ; block = null ;
415418 opt_args = null ; subtpl = { } ; cur_tpl = null ; arg_tpl = { } ; start_tpl = null ;
416- stack = null ; s = '' ; escaped = false ;
419+
420+ // hard-coded merge-sort for arbitrary delims parsing based on str len
421+ if ( delim1 [ 1 ] < delim1 [ 3 ] )
422+ {
423+ s = delim1 [ 0 ] ; delim1 [ 2 ] = delim1 [ 0 ] ; delim1 [ 0 ] = s ;
424+ i = delim1 [ 1 ] ; delim1 [ 3 ] = delim1 [ 1 ] ; delim1 [ 1 ] = i ;
425+ }
426+ if ( delim2 [ 1 ] < delim2 [ 3 ] )
427+ {
428+ s = delim2 [ 0 ] ; delim2 [ 2 ] = delim2 [ 0 ] ; delim2 [ 0 ] = s ;
429+ i = delim2 [ 1 ] ; delim2 [ 3 ] = delim2 [ 1 ] ; delim2 [ 1 ] = i ;
430+ }
431+ start_i = 0 ; end_i = 0 ; i = 0 ;
432+ while ( ( 4 > start_i ) && ( 4 > end_i ) )
433+ {
434+ if ( delim1 [ start_i + 1 ] < delim2 [ end_i + 1 ] )
435+ {
436+ delim_order [ i ] = delim2 [ end_i ] ;
437+ delim_order [ i + 1 ] = delim2 [ end_i + 1 ] ;
438+ end_i += 2 ;
439+ }
440+ else
441+ {
442+ delim_order [ i ] = delim1 [ start_i ] ;
443+ delim_order [ i + 1 ] = delim1 [ start_i + 1 ] ;
444+ start_i += 2 ;
445+ }
446+ i += 2 ;
447+ }
448+ while ( 4 > start_i )
449+ {
450+ delim_order [ i ] = delim1 [ start_i ] ;
451+ delim_order [ i + 1 ] = delim1 [ start_i + 1 ] ;
452+ start_i += 2 ; i += 2 ;
453+ }
454+ while ( 4 > end_i )
455+ {
456+ delim_order [ i ] = delim2 [ end_i ] ;
457+ delim_order [ i + 1 ] = delim2 [ end_i + 1 ] ;
458+ end_i += 2 ; i += 2 ;
459+ }
460+
461+ stack = null ; s = '' ;
417462
418463 i = 0 ;
419464 while ( i < l )
420465 {
421- escaped = false ;
422- ch = tpl [ CHAR ] ( i ) ;
423- if ( ESC === ch )
466+ c = tpl [ CHAR ] ( i ) ;
467+ if ( ESC === c )
424468 {
425- escaped = true ;
426- i += 1 ;
469+ s += i + 1 < l ? tpl [ CHAR ] ( i + 1 ) : '' ;
470+ i += 2 ;
471+ continue ;
427472 }
428473
429- if ( IDL === tpl . substr ( i , lenIDL ) )
474+ delim = null ;
475+ if ( delim_order [ 0 ] === tpl . substr ( i , delim_order [ 1 ] ) )
476+ delim = delim_order [ 0 ] ;
477+ else if ( delim_order [ 2 ] === tpl . substr ( i , delim_order [ 3 ] ) )
478+ delim = delim_order [ 2 ] ;
479+ else if ( delim_order [ 4 ] === tpl . substr ( i , delim_order [ 5 ] ) )
480+ delim = delim_order [ 4 ] ;
481+ else if ( delim_order [ 6 ] === tpl . substr ( i , delim_order [ 7 ] ) )
482+ delim = delim_order [ 6 ] ;
483+
484+ if ( IDL === delim )
430485 {
431486 i += lenIDL ;
432487
433- if ( escaped )
434- {
435- s += IDL ;
436- continue ;
437- }
438-
439488 if ( s . length )
440489 {
441490 if ( 0 === a . node . type ) a . node . val += s ;
442491 else a = new TplEntry ( { type : 0 , val : s , algn : '' } , a ) ;
443492 }
444493 s = '' ;
445494 }
446- else if ( IDR === tpl . substr ( i , lenIDR ) )
495+ else if ( IDR === delim )
447496 {
448497 i += lenIDR ;
449498
450- if ( escaped )
451- {
452- s += IDR ;
453- continue ;
454- }
455-
456499 // argument
457500 argument = s ; s = '' ;
458501 if ( - 1 < ( p = argument . indexOf ( DEF ) ) )
@@ -560,11 +603,6 @@ function multisplit( tpl, delims, postop )
560603 aligned = 1 ;
561604 argument = argument . slice ( 1 ) ;
562605 }
563- /*else if ( NOTALGN === c )
564- {
565- aligned = 0;
566- argument = argument.slice(1);
567- }*/
568606 else
569607 {
570608 aligned = 0 ;
@@ -587,10 +625,10 @@ function multisplit( tpl, delims, postop )
587625
588626 if ( cur_tpl && ! HAS ( arg_tpl , cur_tpl ) ) arg_tpl [ cur_tpl ] = { } ;
589627
590- if ( TPL + OBL === tpl . substr ( i , lenTPL + lenOBL ) )
628+ if ( TPL + OBL === tpl . substr ( i , 2 + lenOBL ) )
591629 {
592630 // template definition
593- i += lenTPL ;
631+ i += 2 ;
594632 template = template && template . length ? template : 'grtpl--' + guid ( ) ;
595633 start_tpl = template ;
596634 if ( cur_tpl && argument . length )
@@ -665,16 +703,10 @@ function multisplit( tpl, delims, postop )
665703 end : end_i
666704 } , a ) ;
667705 }
668- else if ( OBL === tpl . substr ( i , lenOBL ) )
706+ else if ( OBL === delim )
669707 {
670708 i += lenOBL ;
671709
672- if ( escaped )
673- {
674- s += OBL ;
675- continue ;
676- }
677-
678710 if ( s . length )
679711 {
680712 if ( 0 === a . node . type ) a . node . val += s ;
@@ -686,7 +718,7 @@ function multisplit( tpl, delims, postop )
686718 if ( COMMENT === tpl [ CHAR ] ( i ) )
687719 {
688720 j = i + 1 ; jl = l ;
689- while ( ( j < jl ) && ( COMMENT + OBR !== tpl . substr ( j , lenOBR + 1 ) ) ) s += tpl [ CHAR ] ( j ++ ) ;
721+ while ( ( j < jl ) && ( COMMENT_CLOSE !== tpl . substr ( j , lenOBR + 1 ) ) ) s += tpl [ CHAR ] ( j ++ ) ;
690722 i = j + lenOBR + 1 ;
691723 if ( 0 === a . node . type ) a . node . algn = compute_alignment ( a . node . val , 0 , a . node . val . length ) ;
692724 a = new TplEntry ( { type : - 100 , val : s } , a ) ;
@@ -715,16 +747,10 @@ function multisplit( tpl, delims, postop )
715747 a = new TplEntry ( { type : 0 , val : '' , algn : '' } ) ;
716748 block = a ;
717749 }
718- else if ( OBR === tpl . substr ( i , lenOBR ) )
750+ else if ( OBR === delim )
719751 {
720752 i += lenOBR ;
721753
722- if ( escaped )
723- {
724- s += OBR ;
725- continue ;
726- }
727-
728754 b = a ;
729755 cur_block = block ;
730756 prev_arg = cur_arg ;
@@ -782,8 +808,8 @@ function multisplit( tpl, delims, postop )
782808 }
783809 else
784810 {
785- ch = tpl [ CHAR ] ( i ++ ) ;
786- if ( "\n" === ch )
811+ c = tpl [ CHAR ] ( i ++ ) ;
812+ if ( "\n" === c )
787813 {
788814 // note line changes to handle alignments
789815 if ( s . length )
@@ -797,7 +823,7 @@ function multisplit( tpl, delims, postop )
797823 }
798824 else
799825 {
800- s += ch ;
826+ s += c ;
801827 }
802828 }
803829 }
@@ -996,10 +1022,10 @@ function GrammarTemplate( tpl, delims, postop )
9961022 self . tpl = null ;
9971023 self . fn = { } ;
9981024 // lazy init
999- self . _args = [ tpl || '' , delims || GrammarTemplate . defaultDelims , postop || false ] ;
1025+ self . _args = [ tpl || '' , delims || GrammarTemplate . defaultDelimiters , postop || false ] ;
10001026} ;
10011027GrammarTemplate . VERSION = '3.0.0' ;
1002- GrammarTemplate . defaultDelims = [ '<' , '>' , '[' , ']' , ':=' /*,'?','*','!','|','{','}'*/ ] ;
1028+ GrammarTemplate . defaultDelimiters = [ '<' , '>' , '[' , ']' ] ;
10031029GrammarTemplate . fnGlobal = { } ;
10041030GrammarTemplate . subGlobal = { } ;
10051031GrammarTemplate . guid = guid ;
@@ -1522,7 +1548,7 @@ Ref[PROTO] = {
15221548} ;
15231549
15241550var dialects = {
1525- "mysql" : {
1551+ "mysqli" : {
15261552 "quotes" : [ [ "'" , "'" , "\\'" , "\\'" ] , [ "`" , "`" ] , [ "" , "" ] ]
15271553
15281554 , "functions" : {
@@ -1558,7 +1584,7 @@ var dialects = {
15581584}
15591585
15601586
1561- , "sqlserver" : {
1587+ , "transactsql" : {
15621588 "quotes" : [ [ "'" , "'" , "''" , "''" ] , [ "[" , "]" ] , [ "" , " ESCAPE '\\'" ] ]
15631589
15641590 , "functions" : {
@@ -1593,13 +1619,17 @@ var dialects = {
15931619 , "clauses" : "[<?transact_clause|>BEGIN <type|> TRANSACTION;\n<statements>;[\n<*statements>;]\n[<?rollback|>ROLLBACK;][<?!rollback>COMMIT;]][<?create_clause|>[<?view|>CREATE[ <?temporary|>TEMPORARY] VIEW[ <?ifnotexists|>IF NOT EXISTS] <create_table> [(\n<?columns>[,\n<*columns>]\n)] AS <query>][<?!view>CREATE[ <?temporary|>TEMPORARY] TABLE[ <?ifnotexists|>IF NOT EXISTS] <create_table> [<?!query>(\n<columns>:=[<col:COL>:=[[[CONSTRAINT <?constraint> ]<?column> <type|>[ <?isnotnull|>NOT NULL][ DEFAULT <?default_value>][ CHECK (<?check>)][ <?!primary><?unique|>UNIQUE][ <?!unique><?primary|>PRIMARY KEY[ <?auto_increment|>AUTOINCREMENT][ COLLATE <?collation>]]]][,\n<*col:COL>]]\n)[ <?without_rowid|>WITHOUT ROWID]][AS <?query>]]][<?alter_clause|>ALTER [<?view|>VIEW][<?!view>TABLE] <alter_table>\n<columns>[ <?options>]][<?drop_clause|>DROP [<?view|>VIEW][<?!view>TABLE][ <?ifexists|>IF EXISTS] <drop_tables>][<?select_clause|>SELECT <select_columns>[,<*select_columns>]\nFROM <from_tables>[,<*from_tables>][\n<?join_clauses>:=[<join:JOIN>:=[[<?type> ]JOIN <table>[ ON <?cond>]][\n<*join:JOIN>]]][\nWHERE <?where_conditions>][\nGROUP BY <?group_conditions>[,<*group_conditions>]][\nHAVING <?having_conditions>][\nORDER BY <?order_conditions>[,<*order_conditions>]][\nLIMIT <?count> OFFSET <offset|0>]][<?insert_clause|>INSERT INTO <insert_tables> (<insert_columns>[,<*insert_columns>])\nVALUES <values_values>[,<*values_values>]][<?update_clause|>UPDATE <update_tables>\nSET <set_values>[,<*set_values>][\nWHERE <?where_conditions>]][<?delete_clause|>[<?!order_conditions><?!count>DELETE FROM <from_tables> [, <*from_tables>][\nWHERE <?where_conditions>]][DELETE FROM <from_tables> [, <*from_tables>] WHERE rowid IN (\nSELECT rowid FROM <from_tables> [, <*from_tables>][\nWHERE <?where_conditions>]\nORDER BY <?order_conditions> [, <*order_conditions>][\nLIMIT <?count> OFFSET <offset|0>]\n)][<?!order_conditions>DELETE FROM <from_tables> [, <*from_tables>] WHERE rowid IN (\nSELECT rowid FROM <from_tables> [, <*from_tables>][\nWHERE <?where_conditions>]\nLIMIT <?count> OFFSET <offset|0>\n)]]"
15941620}
15951621} ;
1596-
1622+ var dialect_aliases = {
1623+ "mysql" : "mysqli"
1624+ , "sqlserver" : "transactsql"
1625+ } ;
15971626function Dialect ( type )
15981627{
15991628 var self = this ;
16001629 if ( ! ( self instanceof Dialect ) ) return new Dialect ( type ) ;
16011630 if ( ! arguments . length ) type = 'mysql' ;
16021631
1632+ if ( type && Dialect . aliases [ type ] ) type = Dialect . aliases [ type ] ;
16031633 if ( ! type || ! Dialect . dialects [ type ] || ! Dialect . dialects [ type ] [ 'clauses' ] )
16041634 {
16051635 throw new TypeError ( 'Dialect: SQL dialect does not exist for "' + type + '"' ) ;
@@ -1625,6 +1655,7 @@ function Dialect( type )
16251655Dialect . VERSION = "0.8.2" ;
16261656//Dialect.TPL_RE = /\$\(([^\)]+)\)/g;
16271657Dialect . dialects = dialects ;
1658+ Dialect . aliases = dialect_aliases ;
16281659Dialect . StringTemplate = StringTemplate ;
16291660Dialect . GrammarTemplate = GrammarTemplate ;
16301661Dialect . Ref = Ref ;
0 commit comments