diff --git a/data/System/DBIStoreContrib.txt b/data/System/DBIStoreContrib.txt index a407033..877b029 100644 --- a/data/System/DBIStoreContrib.txt +++ b/data/System/DBIStoreContrib.txt @@ -135,6 +135,11 @@ thing to do is to use the ODBC driver with DBIStoreContrib and create a data source for SQL Server in the ODBC Administrator which uses Windows authentication. Then set an empty username and password for !DBIStoreContrib. +SQL Server does not come equipped with regular expression matching, which is +required for Foswiki, so you wil need to install a regular expression library. +The default personality module included in this module requires the user function =dbo.fn_RegExIsMatch= to stub the =.NET= !RegEx class. Instructions for building and installing this user function can be found at +http://www.codeproject.com/Articles/19502/A-T-SQL-Regular-Expression-Library-for-SQL-Server + ---+++ SQLite Notes SQLite requires the =pcre= module to be installed to support regular expression searches. The path to this module is set up in =configure=. diff --git a/lib/Foswiki/Contrib/DBIStoreContrib/DBIStore.pm b/lib/Foswiki/Contrib/DBIStoreContrib/DBIStore.pm index 4030aff..23cb40f 100644 --- a/lib/Foswiki/Contrib/DBIStoreContrib/DBIStore.pm +++ b/lib/Foswiki/Contrib/DBIStoreContrib/DBIStore.pm @@ -117,8 +117,8 @@ sub _connect { # Custom code to put DB's into ANSI mode and clean up error reporting personality()->startup(); - $CQ = personality()->string_quote(); - $TEXT = personality()->text_type(); + $CQ = personality()->{string_quote}; + $TEXT = personality()->{text_type}; # Check if the DB is initialised with a quick sniff of the tables # to see if all the ones we expect are there @@ -199,7 +199,7 @@ SQL print STDERR "Creating table for $t\n" if MONITOR; $this->_createTableForMETA($t); } - $this->{handle}->do('COMMIT') if personality()->requires_COMMIT(); + $this->{handle}->do('COMMIT') if personality()->{requires_COMMIT}; } # Load all existing webs and topics into the cache DB (expensive) @@ -211,7 +211,7 @@ sub _preload { my $web = $wit->next(); $this->_preloadWeb( $web, $session ); } - $this->{handle}->do('COMMIT') if personality()->requires_COMMIT(); + $this->{handle}->do('COMMIT') if personality()->{requires_COMMIT}; } # Preload a single web - PRIVATE diff --git a/lib/Foswiki/Contrib/DBIStoreContrib/HoistSQL.pm b/lib/Foswiki/Contrib/DBIStoreContrib/HoistSQL.pm index d202076..a3b5660 100644 --- a/lib/Foswiki/Contrib/DBIStoreContrib/HoistSQL.pm +++ b/lib/Foswiki/Contrib/DBIStoreContrib/HoistSQL.pm @@ -48,10 +48,17 @@ use constant { VALUE => 12, TABLE => 13, + + # An integer type used where DB doesn't support a BOOLEAN type + PSEUDO_BOOL => 14, }; our $table_name_RE = qr/^\w+$/; -our $cq; + +# Pseudo-constants, from the Personality +our $CQ; # character string quote +our $TRUE; +our $TRUE_TYPE; BEGIN { @@ -230,6 +237,10 @@ sub _boolean_bop { $lhs = _cast( $lhs, $lhs_type, STRING ); $rhs = _cast( $rhs, $rhs_type, STRING ); } + else { + $lhs = _cast( $lhs, $lhs_type, BOOLEAN ); + $rhs = _cast( $rhs, $rhs_type, BOOLEAN ); + } return ( "($lhs)$opn($rhs)", BOOLEAN ); } @@ -248,7 +259,7 @@ my %bop_map = ( # Special case if ( $lhs eq 'NULL' ) { if ( $rhs eq 'NULL' ) { - return ( _personality()->true(), BOOLEAN ); + return ( $TRUE, $TRUE_TYPE ); } return ( "($rhs) IS NULL", BOOLEAN ); } @@ -305,7 +316,11 @@ Will die with a message if there is a diagnosable problem. sub hoist { my ($query) = @_; - $cq ||= _personality()->string_quote; + unless ( defined $TRUE ) { + $CQ = _personality()->{string_quote}; + $TRUE = _personality()->{true_value}; + $TRUE_TYPE = _personality()->{true_type}; + } print STDERR "HOISTING " . recreate($query) . "\n" if MONITOR; @@ -326,7 +341,7 @@ sub hoist { $h{sql} = "($h{sql})!= 0"; } elsif ( $h{type} == STRING ) { - $h{sql} = "($h{sql})!=$cq$cq"; + $h{sql} = "($h{sql})!=$CQ$CQ"; } return $h{sql}; } @@ -375,7 +390,7 @@ sub _hoist { # Conbvert to an escaped SQL string my $s = $node->{params}[0]; $s =~ s/\\/\\\\/g; - $result{sql} = "$cq$s$cq"; + $result{sql} = "$CQ$s$CQ"; $result{type} = STRING; } elsif ( $node->{op} == NAME ) { @@ -439,11 +454,14 @@ sub _hoist { elsif ( $where{type} == STRING ) { # A simple non-table expression - $where{sql} = "($where{sql})!=$cq$cq"; + $where{sql} = "($where{sql})!=$CQ$CQ"; } elsif ( $where{type} == NUMBER ) { $where{sql} = "($where{sql})!=0"; } + elsif ( $where{type} == BOOLEAN ) { + $where{sql} = "($where{sql})!=0"; + } $result{sql} = _SELECT( select => '*', @@ -514,7 +532,7 @@ sub _hoist { my $tname_sel = $tnames; $tname_sel = "$tnames.$lhs{sel}" if $lhs{sel}; $lhs_where = "($topic_alias.name=$tname_sel OR " - . "($topic_alias.web||$cq.$cq||$topic_alias.name)=$tname_sel)"; + . "($topic_alias.web||$CQ.$CQ||$topic_alias.name)=$tname_sel)"; } elsif ( $lhs{is_table_name} ) { @@ -526,7 +544,7 @@ sub _hoist { # Not a selector or simple table name, must be a simple # expression yielding a selector $lhs_where = "($lhs{sql}) IN " - . "($topic_alias.name,$topic_alias.web||$cq.$cq||$topic_alias.name)"; + . "($topic_alias.name,$topic_alias.web||$CQ.$CQ||$topic_alias.name)"; } # Expand the RHS *without* a constraint on the topic table @@ -632,11 +650,11 @@ sub _hoist { $result{sql} = _SELECT( select => 'DISTINCT ' - . _AS( _personality()->true() => $result{sel} ) . ",tid", + . _AS( $TRUE => $result{sel} ) . ",tid", FROM => _AS( $union_sql, $union_alias ), monitor => __LINE__ ); - $result{type} = BOOLEAN; + $result{type} = $TRUE_TYPE; $result{ignore_tid} = 0; } else { @@ -662,8 +680,9 @@ sub _hoist { ); my $where; if ( $optype == BOOLEAN ) { - $where = $expr; - $expr = _personality()->true(); + $where = $expr; + $expr = $TRUE; + $optype = $TRUE_TYPE; } my $ret_tid = "$lhs_alias.tid"; @@ -704,8 +723,9 @@ sub _hoist { my $where; if ( $optype == BOOLEAN ) { - $where = $expr; - $expr = _personality()->true(); + $where = $expr; + $expr = $TRUE; + $optype = $TRUE_TYPE; } my $ret_tid = "$lhs_alias.tid"; @@ -721,7 +741,7 @@ sub _hoist { select => _AS( $expr => $result{sel} ) . ",$ret_tid", FROM => $tid_table . _AS( $lhs{sql} => $lhs_alias ), WHERE => $where, - monitor => __LINE__ + monitor => __LINE__ . " $op" ); $result{type} = $optype; @@ -743,8 +763,9 @@ sub _hoist { my $where = '_IGNORE_'; if ( $optype == BOOLEAN ) { - $where = $expr; - $expr = _personality()->true(); + $where = $expr; + $expr = $TRUE; + $optype = $TRUE_TYPE; } my $ret_tid = "$rhs_alias.tid"; @@ -786,8 +807,9 @@ sub _hoist { my $where = '_IGNORE_'; if ( $optype == BOOLEAN ) { - $where = $expr; - $expr = _personality()->true(); + $where = $expr; + $expr = $TRUE; + $optype = $TRUE_TYPE; } my $ret_tid = 'tid'; my $tid_table = ''; @@ -834,8 +856,11 @@ sub _cast { if ( $type == NUMBER ) { $arg = "$arg!=0"; } + elsif ( $type == PSEUDO_BOOL ) { + return "$arg=" . $TRUE; + } else { - $arg = "$arg!=$cq$cq"; + $arg = "$arg!=$CQ$CQ"; } } elsif ( $tgt_type == NUMBER ) { @@ -1016,10 +1041,10 @@ sub _format_SQL { my @ss = (); # Replace escaped quotes - $sql =~ s/(\\$cq)/push(@ss,$1); "![$#ss]!"/ges; + $sql =~ s/(\\$CQ)/push(@ss,$1); "![$#ss]!"/ges; # Replace quoted strings - $sql =~ s/($cq([^$cq])*$cq)/push(@ss,$1); "![$#ss]!"/ges; + $sql =~ s/($CQ([^$CQ])*$CQ)/push(@ss,$1); "![$#ss]!"/ges; # Replace bracketed subexpressions my $n = 0; diff --git a/lib/Foswiki/Contrib/DBIStoreContrib/Personality.pm b/lib/Foswiki/Contrib/DBIStoreContrib/Personality.pm index 4deefd2..c2ca284 100644 --- a/lib/Foswiki/Contrib/DBIStoreContrib/Personality.pm +++ b/lib/Foswiki/Contrib/DBIStoreContrib/Personality.pm @@ -12,16 +12,45 @@ use Assert; # have a database personality module, which provides these custom # operations in a consistent way. +=begin TML + +{string_quote} is the quote character to use for character +strings - default is ' + +{true_value} and {true_type} For DB's that +don't support a true BOOLEAN type, the true_type can be PSEUDO_BOOL, +in which case boolean operations on the data will always be preceded +by =1. + +{text_type} the name of the TEXT type, used to store variable-length +strings. + +{requires_COMMIT} is 1 if the DB requires a COMMIT at the end of the +initial transaction. +The default is TRUE which works for SQLite, MySQL and Postgresql. + +=cut + sub new { my ( $class, $dbistore ) = @_; - my $this = bless( { store => $dbistore }, $class ); + my $this = bless( + { + store => $dbistore, + requires_COMMIT => 1, + string_quote => "'", + text_type => 'TEXT', + true_value => '1=1', + true_type => Foswiki::Contrib::DBIStoreContrib::HoistSQL::BOOLEAN, + }, + $class + ); # SQL reserved words. The following words are reserved in all of - # PostgresSQL, ANSI SQL, MySQL and SQLite so provide a good + # PostgresSQL, MySQL, SQLite and T-SQL so provide a good # working basis. Personality modules should extend this list. $this->reserve( qw( - ALL ALTER AND AS ASC BETWEEN BY CASCADE CASE CHECK COLLATE COLUMN + ADD ALL ALTER AND AS ASC BETWEEN BY CASCADE CASE CHECK COLLATE COLUMN CONSTRAINT CREATE CROSS CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP DEFAULT DELETE DESC DISTINCT DROP ELSE EXISTS FOR FOREIGN FROM GROUP HAVING IN INDEX INNER INSERT INTO IS JOIN KEY LEFT LIKE NOT NULL ON OR @@ -76,29 +105,6 @@ SQL =begin TML ----++ require_COMMIT() -> $boolean -True if there is an automatic transaction opened that requires a commit. -The default is TRUE which works for SQLite, MySQL and Postgresql. - -=cut - -sub requires_COMMIT { - return 1; -} - -=begin TML - ----++ text_type() -> string -Get the name of the TEXT type, used to store variable-length strings. - -=cut - -sub text_type { - return 'TEXT'; -} - -=begin TML - ---++ regexp($lhs, $rhs) -> $sql Construct an SQL expression to execute the given regular expression match. @@ -226,29 +232,21 @@ Cast a datum to a character string type for comparison sub cast_to_text { my ( $this, $d ) = @_; - return "CAST(($d) AS " . $this->text_type() . ')'; + return "CAST(($d) AS $this->{text_type})"; } =begin TML ----++ string_quote() -> $quote_char -Quote character for character strings - default is ' +---++ make_comment() -> $comment_string +Make a comment string =cut -sub string_quote { - return "'"; -} - sub make_comment { my $this = shift; return '/*' . join( ' ', @_ ) . '*/'; } -sub true { - return '1=1'; -} - 1; __DATA__ @@ -256,7 +254,7 @@ Author: Crawford Currie http://c-dot.co.uk Module of Foswiki - The Free and Open Source Wiki, http://foswiki.org/, http://Foswiki.org/ -Copyright (C) 2013 Foswiki Contributors. All Rights Reserved. +Copyright (C) 2013-2014 Foswiki Contributors. All Rights Reserved. Foswiki Contributors are listed in the AUTHORS file in the root of this distribution. NOTE: Please extend that file, not this notice. diff --git a/lib/Foswiki/Contrib/DBIStoreContrib/Personality/ODBC.pm b/lib/Foswiki/Contrib/DBIStoreContrib/Personality/ODBC.pm index d261c2a..bb45b34 100644 --- a/lib/Foswiki/Contrib/DBIStoreContrib/Personality/ODBC.pm +++ b/lib/Foswiki/Contrib/DBIStoreContrib/Personality/ODBC.pm @@ -13,45 +13,30 @@ sub new { my ( $class, $dbistore ) = @_; my $this = $class->SUPER::new($dbistore); $this->reserve( - qw( - ABSOLUTE ACTION ADA ADD ALL ALLOCATE ALTER AND ANY ARE AS ASC - ASSERTION AT AUTHORIZATION AVG BACKUP BEGIN BETWEEN BIT BIT_LENGTH - BOTH BREAK BROWSE BULK BY CASCADE CASCADED CASE CAST CATALOG CHAR - CHARACTER CHARACTER_LENGTH CHAR_LENGTH CHECK CHECKPOINT CLOSE - CLUSTERED COALESCE COLLATE COLLATION COLUMN COMMIT COMPUTE CONNECT - CONNECTION CONSTRAINT CONSTRAINTS CONTAINS CONTAINSTABLE CONTINUE - CONVERT CORRESPONDING COUNT CREATE CROSS CURRENT CURRENT_DATE - CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR DATABASE DATE DAY - DBCC DEALLOCATE DEC DECIMAL DECLARE DEFAULT DEFERRABLE DEFERRED DELETE - DENY DESC DESCRIBE DESCRIPTOR DIAGNOSTICS DISCONNECT DISK DISTINCT - DISTRIBUTED DOMAIN DOUBLE DROP DUMP ELSE END END-EXEC ERRLVL ESCAPE - EXCEPT EXCEPTION EXEC EXECUTE EXISTS EXIT EXTERNAL EXTRACT FALSE FETCH - FILE FILLFACTOR FIRST FLOAT FOR FOREIGN FORTRAN FOUND FREETEXT - FREETEXTTABLE FROM FULL FUNCTION GET GLOBAL GO GOTO GRANT GROUP HAVING - HOLDLOCK HOUR IDENTITY IDENTITYCOL IDENTITY_INSERT IF IMMEDIATE IN - INCLUDE INDEX INDICATOR INITIALLY INNER INPUT INSENSITIVE INSERT INT - INTEGER INTERSECT INTERVAL INTO IS ISOLATION JOIN KEY KILL LANGUAGE - LAST LEADING LEFT LEVEL LIKE LINENO LOAD LOCAL LOWER MATCH MAX MERGE - MIN MINUTE MODULE MONTH NAMES NATIONAL NATURAL NCHAR NEXT NO NOCHECK - NONCLUSTERED NONE NOT NULL NULLIF NUMERIC OCTET_LENGTH OF OFF OFFSETS - ON ONLY OPEN OPENDATASOURCE OPENQUERY OPENROWSET OPENXML OPTION OR - ORDER OUTER OUTPUT OVER OVERLAPS PAD PARTIAL PASCAL PERCENT PIVOT PLAN - POSITION PRECISION PREPARE PRESERVE PRIMARY PRINT PRIOR PRIVILEGES - PROC PROCEDURE PUBLIC RAISERROR READ READTEXT REAL RECONFIGURE - REFERENCES RELATIVE REPLICATION RESTORE RESTRICT RETURN REVERT REVOKE - RIGHT ROLLBACK ROWCOUNT ROWGUIDCOL ROWS RULE SAVE SCHEMA SCROLL SECOND - SECTION SECURITYAUDIT SELECT SEMANTICKEYPHRASETABLE - SEMANTICSIMILARITYDETAILSTABLE SEMANTICSIMILARITYTABLE SESSION - SESSION_USER SET SETUSER SHUTDOWN SIZE SMALLINT SOME SPACE SQL SQLCA - SQLCODE SQLERROR SQLSTATE SQLWARNING STATISTICS SUBSTRING SUM - SYSTEM_USER TABLE TABLESAMPLE TEMPORARY TEXTSIZE THEN TIME TIMESTAMP - TIMEZONE_HOUR TIMEZONE_MINUTE TO TOP TRAILING TRAN TRANSACTION - TRANSLATE TRANSLATION TRIGGER TRIM TRUE TRUNCATE TRY_CONVERT TSEQUAL - UNION UNIQUE UNKNOWN UNPIVOT UPDATE UPDATETEXT UPPER USAGE USE USER - USING VALUE VALUES VARCHAR VARYING VIEW WAITFOR WHEN WHENEVER WHERE - WHILE WITH WITHIN GROUP WORK WRITE WRITETEXT YEAR ZONE - ) + qw/ + ANY AUTHORIZATION BACKUP BEGIN BREAK BROWSE BULK CHECKPOINT CLOSE + CLUSTERED COALESCE COMMIT COMPUTE CONTAINS CONTAINSTABLE CONTINUE + CONVERT CURRENT CURRENT_USER CURSOR DATABASE DBCC DEALLOCATE DECLARE + DENY DISK DISTRIBUTED DOUBLE DUMP END ERRLVL ESCAPE EXCEPT EXEC + EXECUTE EXIT EXTERNAL FETCH FILE FILLFACTOR FREETEXT FREETEXTTABLE + FULL FUNCTION GOTO GRANT HOLDLOCK IDENTITY IDENTITY_INSERT IDENTITYCOL + IF INTERSECT KILL LINENO LOAD MERGE NATIONAL NOCHECK NONCLUSTERED + NULLIF OF OFF OFFSETS OPEN OPENDATASOURCE OPENQUERY OPENROWSET OPENXML + OPTION OVER PERCENT PIVOT PLAN PRECISION PRINT PROC PROCEDURE PUBLIC + RAISERROR READ READTEXT RECONFIGURE REPLICATION RESTORE RETURN REVERT + REVOKE ROLLBACK ROWCOUNT ROWGUIDCOL RULE SAVE SCHEMA SECURITYAUDIT + SEMANTICKEYPHRASETABLE SEMANTICSIMILARITYDETAILSTABLE + SEMANTICSIMILARITYTABLE SESSION_USER SETUSER SHUTDOWN SOME STATISTICS + SYSTEM_USER TABLESAMPLE TEXTSIZE TOP TRAN TRANSACTION TRIGGER TRUNCATE + TRY_CONVERT TSEQUAL UNPIVOT UPDATETEXT USE USER VARYING VIEW WAITFOR + WHILE WITHIN GROUP WRITETEXT/ ); + $this->{text_type} = 'VARCHAR(MAX)'; + $this->{true_value} = 'CAST(1 AS BIT)'; + $this->{true_type} = + Foswiki::Contrib::DBIStoreContrib::HoistSQL::PSEUDO_BOOL; + $this->{requires_COMMIT} = 0; + return $this; } @@ -59,40 +44,62 @@ sub startup { my $this = shift; $this->{store}->{handle}->do('set QUOTED_IDENTIFIER ON'); - $this->{store}->{handle}->do(<<'SQL'); -ALTER FUNCTION make_number(@Val VARCHAR(MAX)) RETURNS FLOAT AS + + # There's no way in T-SQL to conditionally create a function + # without using dynamic SQL, so we have to do this the hard way. + my $exists = $this->{store}->{handle}->do(<<'SQL'); +SELECT 1 WHERE OBJECT_ID('dbo.foswiki_CONVERT') IS NOT NULL +SQL + unless ($exists) { + + # make_number derived from is_numeric by Dmitri Golovan of Micralyne. + $this->{store}->{handle}->do(<<'SQL'); +CREATE FUNCTION foswiki_CONVERT( @value VARCHAR(MAX) ) RETURNS FLOAT AS BEGIN - DECLARE @Res AS FLOAT - IF ISNUMERIC(@Val) = 1 - BEGIN - SET @Res = CONVERT(FLOAT, @Val) - END - ELSE - SET @Res = 0 - RETURN @Res + ( + CASE + WHEN @value NOT LIKE '%[^-0-9.+]%' + AND ( + CHARINDEX('.', @value) = 0 + OR + CHARINDEX('.', @value) > 0 AND LEN(@value) > 1 + AND LEN(@value) - LEN(REPLACE(@value, '.', '')) = 1 + ) + AND ( + CHARINDEX('-', @value)=0 + OR + CHARINDEX('-', @value) = 1 AND LEN(@value) > 1 + AND CHARINDEX('-', @value, 2) = 0 + ) + THEN CONVERT(FLOAT, @value) + ELSE 0 + END + ) END SQL + } } sub cast_to_numeric { my ( $this, $d ) = @_; - return "dbo.make_number($d)"; + return "dbo.foswiki_CONVERT($d)"; } -sub requires_COMMIT { - return 0; -} +sub regexp { + my ( $this, $lhs, $rhs ) = @_; -sub text_type { - return "VARCHAR(MAX)"; -} + unless ( $rhs =~ s/^'(.*)'$/$1/s ) { + return "dbo.fn_RegExIsMatch($lhs,$rhs,1)=1"; # risky! + } + $rhs =~ s/'/\\'/g; + $rhs =~ s/\\/\\/g; -sub make_comment { - return ''; # no support + # SMELL: + return "dbo.fn_RegExIsMatch($lhs,'$rhs',1)=1"; } -sub true { - return 'CAST(1 AS BIT)'; +sub length { + return "LEN($_[1])"; } 1; diff --git a/lib/Foswiki/Contrib/DBIStoreContrib/Personality/Pg.pm b/lib/Foswiki/Contrib/DBIStoreContrib/Personality/Pg.pm index 22e1d71..879491b 100644 --- a/lib/Foswiki/Contrib/DBIStoreContrib/Personality/Pg.pm +++ b/lib/Foswiki/Contrib/DBIStoreContrib/Personality/Pg.pm @@ -11,22 +11,50 @@ sub new { my ( $class, $dbistore ) = @_; my $this = $class->SUPER::new($dbistore); $this->reserve( - qw( - ABORT ACTION ADD AFTER ALL ALTER ANALYZE AND AS ASC ATTACH - AUTOINCREMENT BEFORE BEGIN BETWEEN BY CASCADE CASE CAST CHECK COLLATE - COLUMN COMMIT CONFLICT CONSTRAINT COVERING CREATE CROSS CURRENT_DATE - CURRENT_TIME CURRENT_TIMESTAMP DATABASE DEFAULT DEFERRABLE DEFERRED - DELETE DESC DETACH DISTINCT DROP EACH ELSE END ESCAPE EXCEPT EXCLUSIVE - EXISTS EXPLAIN FAIL FOR FOREIGN FROM FULL GLOB GROUP HAVING IF IGNORE - IMMEDIATE IN INDEX INDEXED INITIALLY INNER INSERT INSTEAD INTERSECT - INTO IS ISNULL JOIN KEY LEFT LIKE LIMIT MATCH NATURAL NO NOT NOTNULL - NULL OF OFFSET ON OR ORDER OUTER PLAN PRAGMA PRIMARY QUERY RAISE - REFERENCES REGEXP REINDEX RELEASE RENAME REPLACE RESTRICT RIGHT - ROLLBACK ROW SAVEPOINT SELECT SET TABLE TEMP TEMPORARY THEN TO - TRANSACTION TRIGGER UNION UNIQUE UPDATE USING VACUUM VALUES VIEW - VIRTUAL WHEN WHERE WITH WITHOUT - ) + qw/ + ABORT ABSOLUTE ACCESS ACTION ADMIN AFTER AGGREGATE ALSO ALWAYS ANALYSE + ANALYZE ANY ARRAY ASSERTION ASSIGNMENT ASYMMETRIC AT ATTRIBUTE + AUTHORIZATION BACKWARD BEFORE BEGIN BIGINT BINARY BIT BOOLEAN BOTH + CACHE CALLED CASCADED CAST CATALOG CHAIN CHAR CHARACTER + CHARACTERISTICS CHECKPOINT CLASS CLOSE CLUSTER COALESCE COLLATION + COMMENT COMMENTS COMMIT COMMITTED CONCURRENTLY CONFIGURATION + CONNECTION CONSTRAINTS CONTENT CONTINUE CONVERSION COPY COST CSV + CURRENT CURRENT_CATALOG CURRENT_ROLE CURRENT_SCHEMA CURRENT_USER + CURSOR CYCLE DATA DATABASE DAY DEALLOCATE DEC DECIMAL DECLARE DEFAULTS + DEFERRABLE DEFERRED DEFINER DELIMITER DELIMITERS DICTIONARY DISABLE + DISCARD DO DOCUMENT DOMAIN DOUBLE EACH ENABLE ENCODING ENCRYPTED END + ENUM ESCAPE EVENT EXCEPT EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXPLAIN + EXTENSION EXTERNAL EXTRACT FALSE FAMILY FETCH FIRST FLOAT FOLLOWING + FORCE FORWARD FREEZE FULL FUNCTION FUNCTIONS GLOBAL GRANT GRANTED + GREATEST HANDLER HEADER HOLD HOUR IDENTITY IF ILIKE IMMEDIATE + IMMUTABLE IMPLICIT INCLUDING INCREMENT INDEXES INHERIT INHERITS + INITIALLY INLINE INOUT INPUT INSENSITIVE INSTEAD INT INTEGER INTERSECT + INTERVAL INVOKER ISNULL ISOLATION LABEL LANGUAGE LARGE LAST LATERAL + LC_COLLATE LC_CTYPE LEADING LEAKPROOF LEAST LEVEL LIMIT LISTEN LOAD + LOCAL LOCALTIME LOCALTIMESTAMP LOCATION LOCK MAPPING MATCH + MATERIALIZED MAXVALUE MINUTE MINVALUE MODE MONTH MOVE NAME NAMES + NATIONAL NATURAL NCHAR NEXT NO NONE NOTHING NOTIFY NOTNULL NOWAIT + NULLIF NULLS NUMERIC OBJECT OF OFF OFFSET OIDS ONLY OPERATOR OPTION + OPTIONS OUT OVER OVERLAPS OVERLAY OWNED OWNER PARSER PARTIAL PARTITION + PASSING PASSWORD PLACING PLANS POSITION PRECEDING PRECISION PREPARE + PREPARED PRESERVE PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROGRAM QUOTE + RANGE READ REAL REASSIGN RECHECK RECURSIVE REF REFRESH REINDEX + RELATIVE RELEASE RENAME REPEATABLE REPLACE REPLICA RESET RESTART + RETURNING RETURNS REVOKE ROLE ROLLBACK ROW ROWS RULE SAVEPOINT SCHEMA + SCROLL SEARCH SECOND SECURITY SEQUENCE SEQUENCES SERIALIZABLE SERVER + SESSION SESSION_USER SETOF SHARE SHOW SIMILAR SIMPLE SMALLINT SNAPSHOT + SOME STABLE STANDALONE START STATEMENT STATISTICS STDIN STDOUT STORAGE + STRICT STRIP SUBSTRING SYMMETRIC SYSID SYSTEM TABLES TABLESPACE TEMP + TEMPLATE TEMPORARY TEXT TIME TIMESTAMP TRAILING TRANSACTION TREAT + TRIGGER TRIM TRUE TRUNCATE TRUSTED TYPE TYPES UNBOUNDED UNCOMMITTED + UNENCRYPTED UNKNOWN UNLISTEN UNLOGGED UNTIL USER USING VACUUM VALID + VALIDATE VALIDATOR VALUE VARCHAR VARIADIC VARYING VERBOSE VERSION VIEW + VOLATILE WHITESPACE WINDOW WITHOUT WORK WRAPPER WRITE XML + XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLPARSE XMLPI + XMLROOT XMLSERIALIZE YEAR YES ZONE/ ); + $this->{requires_COMMIT} = 0; # AUTOCOMMIT is on + return $this; } @@ -38,8 +66,7 @@ sub startup { $this->{store}->{handle}->do("SET client_min_messages = 'warning'"); $this->{store}->{handle}->do(<<'DO'); CREATE OR REPLACE FUNCTION make_number(TEXT) RETURNS NUMERIC AS $$ -DECLARE -i NUMERIC; +DECLARE i NUMERIC; BEGIN i := $1::NUMERIC; return i; @@ -50,10 +77,6 @@ $$ LANGUAGE PLPGSQL IMMUTABLE STRICT; DO } -sub requires_COMMIT { - return 0; # AUTOCOMMIT is on -} - sub cast_to_numeric { my ( $this, $d ) = @_; return "make_number($d)"; @@ -99,7 +122,7 @@ Author: Crawford Currie http://c-dot.co.uk Module of Foswiki - The Free and Open Source Wiki, http://foswiki.org/, http://Foswiki.org/ -Copyright (C) 2013 Foswiki Contributors. All Rights Reserved. +Copyright (C) 2013-2014 Foswiki Contributors. All Rights Reserved. Foswiki Contributors are listed in the AUTHORS file in the root of this distribution. NOTE: Please extend that file, not this notice. diff --git a/lib/Foswiki/Contrib/DBIStoreContrib/Personality/SQLite.pm b/lib/Foswiki/Contrib/DBIStoreContrib/Personality/SQLite.pm index 6709b72..db38967 100644 --- a/lib/Foswiki/Contrib/DBIStoreContrib/Personality/SQLite.pm +++ b/lib/Foswiki/Contrib/DBIStoreContrib/Personality/SQLite.pm @@ -11,21 +11,14 @@ sub new { my ( $class, $dbistore ) = @_; my $this = $class->SUPER::new($dbistore); $this->reserve( - qw( - ABORT ACTION ADD AFTER ALL ALTER ANALYZE AND AS ASC ATTACH - AUTOINCREMENT BEFORE BEGIN BETWEEN BY CASCADE CASE CAST CHECK COLLATE - COLUMN COMMIT CONFLICT CONSTRAINT COVERING CREATE CROSS CURRENT_DATE - CURRENT_TIME CURRENT_TIMESTAMP DATABASE DEFAULT DEFERRABLE DEFERRED - DELETE DESC DETACH DISTINCT DROP EACH ELSE END ESCAPE EXCEPT EXCLUSIVE - EXISTS EXPLAIN FAIL FOR FOREIGN FROM FULL GLOB GROUP HAVING IF IGNORE - IMMEDIATE IN INDEX INDEXED INITIALLY INNER INSERT INSTEAD INTERSECT - INTO IS ISNULL JOIN KEY LEFT LIKE LIMIT MATCH NATURAL NO NOT NOTNULL - NULL OF OFFSET ON OR ORDER OUTER PLAN PRAGMA PRIMARY QUERY RAISE - REFERENCES REGEXP REINDEX RELEASE RENAME REPLACE RESTRICT RIGHT - ROLLBACK ROW SAVEPOINT SELECT SET TABLE TEMP TEMPORARY THEN TO - TRANSACTION TRIGGER UNION UNIQUE UPDATE USING VACUUM VALUES VIEW - VIRTUAL WHEN WHERE WITH WITHOUT - ) + qw/ + ABORT ACTION AFTER ANALYZE ATTACH AUTOINCREMENT BEFORE BEGIN CAST + COMMIT CONFLICT COVERING DATABASE DATETIME DEFERRABLE DEFERRED DETACH + EACH END ESCAPE EXCEPT EXCLUSIVE EXPLAIN FAIL FULL GLOB IF IGNORE + IMMEDIATE INDEXED INITIALLY INSTEAD INTERSECT ISNULL LIMIT MATCH + NATURAL NO NOTNULL OF OFFSET PLAN PRAGMA QUERY RAISE REGEXP REINDEX + RELEASE RENAME REPLACE ROLLBACK ROW SAVEPOINT TEMP TEMPORARY + TRANSACTION TRIGGER USING VACUUM VIEW VIRTUAL WITHOUT/ ); return $this; } @@ -85,7 +78,7 @@ Author: Crawford Currie http://c-dot.co.uk Module of Foswiki - The Free and Open Source Wiki, http://foswiki.org/, http://Foswiki.org/ -Copyright (C) 2013 Foswiki Contributors. All Rights Reserved. +Copyright (C) 2013-2014 Foswiki Contributors. All Rights Reserved. Foswiki Contributors are listed in the AUTHORS file in the root of this distribution. NOTE: Please extend that file, not this notice. diff --git a/lib/Foswiki/Contrib/DBIStoreContrib/Personality/mysql.pm b/lib/Foswiki/Contrib/DBIStoreContrib/Personality/mysql.pm index f504663..3c2d406 100644 --- a/lib/Foswiki/Contrib/DBIStoreContrib/Personality/mysql.pm +++ b/lib/Foswiki/Contrib/DBIStoreContrib/Personality/mysql.pm @@ -7,6 +7,37 @@ use warnings; use Foswiki::Contrib::DBIStoreContrib::Personality (); our @ISA = ('Foswiki::Contrib::DBIStoreContrib::Personality'); +sub new { + my ( $class, $dbistore ) = @_; + my $this = $class->SUPER::new($dbistore); + $this->reserve( + qw/ + ACCESSIBLE ANALYZE ASENSITIVE BEFORE BIGINT BINARY BLOB BOTH CALL + CHANGE CHAR CHARACTER CONDITION CONTINUE CONVERT CURRENT_USER CURSOR + DATABASE DATABASES DAY_HOUR DAY_MICROSECOND DAY_MINUTE DAY_SECOND DEC + DECIMAL DECLARE DELAYED DESCRIBE DETERMINISTIC DISTINCTROW DIV DOUBLE + DUAL EACH ELSEIF ENCLOSED ESCAPED EXIT EXPLAIN FALSE FETCH FLOAT + FLOAT4 FLOAT8 FORCE FULLTEXT GET GRANT HIGH_PRIORITY HOUR_MICROSECOND + HOUR_MINUTE HOUR_SECOND IF IGNORE INFILE INOUT INSENSITIVE INT INT1 + INT2 INT3 INT4 INT8 INTEGER INTERVAL IO_AFTER_GTIDS IO_BEFORE_GTIDS + ITERATE KEYS KILL LEADING LEAVE LIMIT LINEAR LINES LOAD LOCALTIME + LOCALTIMESTAMP LOCK LONG LONGBLOB LONGTEXT LOOP LOW_PRIORITY + MASTER_BIND MASTER_SSL_VERIFY_SERVER_CERT MATCH MAXVALUE MEDIUMBLOB + MEDIUMINT MEDIUMTEXT MIDDLEINT MINUTE_MICROSECOND MINUTE_SECOND MOD + MODIFIES NATURAL NO_WRITE_TO_BINLOG NONBLOCKING NUMERIC OPTIMIZE + OPTION OPTIONALLY OUT OUTFILE PARTITION PRECISION PROCEDURE PURGE + RANGE READ READ_WRITE READS REAL REGEXP RELEASE RENAME REPEAT REPLACE + REQUIRE RESIGNAL RETURN REVOKE RLIKE SCHEMA SCHEMAS SECOND_MICROSECOND + SENSITIVE SEPARATOR SHOW SIGNAL SMALLINT SPATIAL SPECIFIC SQL + SQL_BIG_RESULT SQL_CALC_FOUND_ROWS SQL_SMALL_RESULT SQLEXCEPTION + SQLSTATE SQLWARNING SSL STARTING STRAIGHT_JOIN TERMINATED TINYBLOB + TINYINT TINYTEXT TRAILING TRIGGER TRUE UNDO UNLOCK UNSIGNED USAGE USE + USING UTC_DATE UTC_TIME UTC_TIMESTAMP VARBINARY VARCHAR VARCHARACTER + VARYING WHILE WRITE XOR YEAR_MONTH ZEROFILL/ + ); + return $this; +} + sub startup { my ($this) = @_; @@ -81,7 +112,7 @@ Author: Crawford Currie http://c-dot.co.uk Module of Foswiki - The Free and Open Source Wiki, http://foswiki.org/, http://Foswiki.org/ -Copyright (C) 2013 Foswiki Contributors. All Rights Reserved. +Copyright (C) 2013-2014 Foswiki Contributors. All Rights Reserved. Foswiki Contributors are listed in the AUTHORS file in the root of this distribution. NOTE: Please extend that file, not this notice.