mirror of
https://gitlab.com/davical-project/davical.git
synced 2026-02-21 04:43:35 +00:00
Merge branch 'remove_quoted_sql_identifiers' into 'master'
Remove quotes around sql language identifiers As an reaction on Issue #26, removed quotes around language identifiers in SQL statements See merge request !8
This commit is contained in:
commit
0bbf51f92d
@ -45,7 +45,7 @@ BEGIN
|
||||
RETURN out_bits;
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
-- This legacy conversion function will eventually be removed, once all logic
|
||||
-- has been converted to use bitmaps, or to use the bits_to_priv() output.
|
||||
@ -98,7 +98,7 @@ BEGIN
|
||||
RETURN out_priv;
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
CREATE or REPLACE FUNCTION get_permissions( INT, INT ) RETURNS TEXT AS $$
|
||||
DECLARE
|
||||
@ -151,12 +151,12 @@ BEGIN
|
||||
|
||||
RETURN '';
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
CREATE or REPLACE FUNCTION get_group_role_no() RETURNS INT AS $$
|
||||
SELECT role_no FROM roles WHERE role_name = 'Group'
|
||||
$$ LANGUAGE 'sql' IMMUTABLE;
|
||||
$$ LANGUAGE sql IMMUTABLE;
|
||||
|
||||
CREATE or REPLACE FUNCTION has_legacy_privilege( INT, TEXT, INT ) RETURNS BOOLEAN AS $$
|
||||
DECLARE
|
||||
@ -205,7 +205,7 @@ BEGIN
|
||||
|
||||
RETURN FALSE;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Given a verbose DAV: or CalDAV: privilege name return the bitmask
|
||||
@ -242,7 +242,7 @@ BEGIN
|
||||
ELSE 0 END)::BIT(24);
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Given an array of verbose DAV: or CalDAV: privilege names return the bitmask
|
||||
@ -269,7 +269,7 @@ BEGIN
|
||||
RETURN out_bits;
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- This legacy conversion function will eventually be removed, once all logic
|
||||
@ -368,4 +368,4 @@ BEGIN
|
||||
RETURN out_priv;
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
@ -74,7 +74,7 @@ BEGIN
|
||||
RETURN our_answer;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
CREATE or REPLACE FUNCTION calculate_later_timestamp( TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH TIME ZONE, TEXT ) RETURNS TIMESTAMP WITH TIME ZONE AS $$
|
||||
@ -239,12 +239,12 @@ BEGIN
|
||||
RETURN our_answer;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
CREATE or REPLACE FUNCTION usr_is_role( INT, TEXT ) RETURNS BOOLEAN AS $$
|
||||
SELECT EXISTS( SELECT 1 FROM role_member JOIN roles USING(role_no) WHERE role_member.user_no=$1 AND roles.role_name=$2 )
|
||||
$$ LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE sql IMMUTABLE STRICT;
|
||||
|
||||
CREATE or REPLACE FUNCTION legacy_get_permissions( INT, INT ) RETURNS TEXT AS $$
|
||||
DECLARE
|
||||
@ -333,13 +333,13 @@ BEGIN
|
||||
|
||||
RETURN '';
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Function to convert a PostgreSQL date into UTC + the format used by iCalendar
|
||||
CREATE or REPLACE FUNCTION to_ical_utc( TIMESTAMP WITH TIME ZONE ) RETURNS TEXT AS $$
|
||||
SELECT to_char( $1 at time zone 'UTC', 'YYYYMMDD"T"HH24MISS"Z"' )
|
||||
$$ LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE sql IMMUTABLE STRICT;
|
||||
|
||||
-- Function to set an arbitrary DAV property
|
||||
CREATE or REPLACE FUNCTION set_dav_property( TEXT, INTEGER, TEXT, TEXT ) RETURNS BOOLEAN AS $$
|
||||
@ -365,7 +365,7 @@ BEGIN
|
||||
END IF;
|
||||
RETURN TRUE;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' STRICT;
|
||||
$$ LANGUAGE plpgsql STRICT;
|
||||
|
||||
-- List a user's relationships as a text string
|
||||
CREATE or REPLACE FUNCTION relationship_list( INT8 ) RETURNS TEXT AS $$
|
||||
@ -385,7 +385,7 @@ BEGIN
|
||||
END LOOP;
|
||||
RETURN rlist;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql';
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
DROP FUNCTION rename_davical_user( TEXT, TEXT );
|
||||
DROP TRIGGER usr_modified ON usr CASCADE;
|
||||
@ -518,7 +518,7 @@ CREATE or REPLACE FUNCTION sync_dav_id ( ) RETURNS TRIGGER AS $$
|
||||
RETURN NEW;
|
||||
|
||||
END
|
||||
$$ LANGUAGE 'plpgsql';
|
||||
$$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER caldav_data_sync_dav_id AFTER INSERT OR UPDATE ON caldav_data
|
||||
FOR EACH ROW EXECUTE PROCEDURE sync_dav_id();
|
||||
|
||||
@ -573,7 +573,7 @@ BEGIN
|
||||
RETURN out_bits;
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
-- This legacy conversion function will eventually be removed, once all logic
|
||||
-- has been converted to use bitmaps, or to use the bits_to_priv() output.
|
||||
@ -626,7 +626,7 @@ BEGIN
|
||||
RETURN out_priv;
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
CREATE or REPLACE FUNCTION get_permissions( INT, INT ) RETURNS TEXT AS $$
|
||||
DECLARE
|
||||
@ -679,12 +679,12 @@ BEGIN
|
||||
|
||||
RETURN '';
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
CREATE or REPLACE FUNCTION get_group_role_no() RETURNS INT AS $$
|
||||
SELECT role_no FROM roles WHERE role_name = 'Group'
|
||||
$$ LANGUAGE 'sql' IMMUTABLE;
|
||||
$$ LANGUAGE sql IMMUTABLE;
|
||||
|
||||
CREATE or REPLACE FUNCTION has_legacy_privilege( INT, TEXT, INT ) RETURNS BOOLEAN AS $$
|
||||
DECLARE
|
||||
@ -733,7 +733,7 @@ BEGIN
|
||||
|
||||
RETURN FALSE;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Given a verbose DAV: or CalDAV: privilege name return the bitmask
|
||||
@ -770,7 +770,7 @@ BEGIN
|
||||
ELSE 0 END)::BIT(24);
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Given an array of verbose DAV: or CalDAV: privilege names return the bitmask
|
||||
@ -797,7 +797,7 @@ BEGIN
|
||||
RETURN out_bits;
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- NOTE: Round-trip through this and then back through privilege_to_bits
|
||||
@ -892,7 +892,7 @@ BEGIN
|
||||
RETURN out_priv;
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Expanded group memberships out to some depth
|
||||
@ -902,7 +902,7 @@ CREATE or REPLACE FUNCTION expand_memberships( INT8, INT ) RETURNS SETOF INT8 AS
|
||||
SELECT expanded.g_id FROM (SELECT CASE WHEN $2 > 0 THEN expand_memberships( group_id, $2 - 1) END AS g_id
|
||||
FROM group_member WHERE member_id = $1) AS expanded
|
||||
WHERE expanded.g_id IS NOT NULL;
|
||||
$$ LANGUAGE 'sql' STABLE STRICT;
|
||||
$$ LANGUAGE sql STABLE STRICT;
|
||||
|
||||
-- Expanded group members out to some depth
|
||||
CREATE or REPLACE FUNCTION expand_members( INT8, INT ) RETURNS SETOF INT8 AS $$
|
||||
@ -911,7 +911,7 @@ CREATE or REPLACE FUNCTION expand_members( INT8, INT ) RETURNS SETOF INT8 AS $$
|
||||
SELECT expanded.m_id FROM (SELECT CASE WHEN $2 > 0 THEN expand_members( member_id, $2 - 1) END AS m_id
|
||||
FROM group_member WHERE group_id = $1) AS expanded
|
||||
WHERE expanded.m_id IS NOT NULL;
|
||||
$$ LANGUAGE 'sql' STABLE STRICT;
|
||||
$$ LANGUAGE sql STABLE STRICT;
|
||||
|
||||
|
||||
|
||||
@ -949,7 +949,7 @@ BEGIN
|
||||
|
||||
RETURN out_conferred;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' STABLE STRICT;
|
||||
$$ LANGUAGE plpgsql STABLE STRICT;
|
||||
|
||||
|
||||
-- Privileges from accessor to grantor, by user_no
|
||||
@ -972,7 +972,7 @@ BEGIN
|
||||
|
||||
RETURN out_conferred;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' STABLE STRICT;
|
||||
$$ LANGUAGE plpgsql STABLE STRICT;
|
||||
|
||||
|
||||
-- Privileges from accessor (by principal_id) to path
|
||||
@ -1046,7 +1046,7 @@ BEGIN
|
||||
|
||||
RETURN out_conferred;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' STABLE STRICT;
|
||||
$$ LANGUAGE plpgsql STABLE STRICT;
|
||||
|
||||
|
||||
-- List a user's memberships as a text string
|
||||
@ -1066,7 +1066,7 @@ BEGIN
|
||||
END LOOP;
|
||||
RETURN mlist;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' STRICT;
|
||||
$$ LANGUAGE plpgsql STRICT;
|
||||
|
||||
|
||||
-- List a user's members as a text string
|
||||
@ -1086,7 +1086,7 @@ BEGIN
|
||||
END LOOP;
|
||||
RETURN mlist;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' STRICT;
|
||||
$$ LANGUAGE plpgsql STRICT;
|
||||
|
||||
|
||||
-- List the privileges as a text string
|
||||
@ -1113,7 +1113,7 @@ BEGIN
|
||||
END IF;
|
||||
RETURN plist;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
DROP TRIGGER principal_modified ON principal CASCADE;
|
||||
@ -1175,7 +1175,7 @@ CREATE or REPLACE FUNCTION p_has_proxy_access_to( INT8, INT ) RETURNS SETOF INT8
|
||||
WHERE (default_privileges & 5::BIT(24)) != 0::BIT(24)
|
||||
AND principal_id != $1
|
||||
) subquery;
|
||||
$$ LANGUAGE 'sql' STABLE STRICT;
|
||||
$$ LANGUAGE sql STABLE STRICT;
|
||||
|
||||
|
||||
-- A list of the principals who can proxy to this principal
|
||||
@ -1185,7 +1185,7 @@ CREATE or REPLACE FUNCTION grants_proxy_access_from_p( INT8, INT ) RETURNS SETOF
|
||||
WHERE by_collection IS NULL AND by_principal != $1
|
||||
AND by_principal IN (SELECT expand_members(g2.to_principal,$2) FROM grants g2 WHERE g2.by_principal = $1)
|
||||
;
|
||||
$$ LANGUAGE 'sql' STABLE STRICT;
|
||||
$$ LANGUAGE sql STABLE STRICT;
|
||||
|
||||
|
||||
|
||||
@ -1209,7 +1209,7 @@ BEGIN
|
||||
VALUES( in_collection_id, in_status, tmp_int, in_dav_name);
|
||||
RETURN TRUE;
|
||||
END
|
||||
$$ LANGUAGE 'plpgsql' VOLATILE STRICT;
|
||||
$$ LANGUAGE plpgsql VOLATILE STRICT;
|
||||
|
||||
|
||||
CREATE or REPLACE FUNCTION new_sync_token( INT8, INT8 ) RETURNS INT8 AS $$
|
||||
@ -1254,7 +1254,7 @@ BEGIN
|
||||
-- Returning the new token
|
||||
RETURN new_token;
|
||||
END
|
||||
$$ LANGUAGE 'plpgsql' STRICT;
|
||||
$$ LANGUAGE plpgsql STRICT;
|
||||
|
||||
|
||||
DROP TRIGGER alarm_changed ON calendar_alarm CASCADE;
|
||||
|
||||
@ -36,7 +36,7 @@ BEGIN
|
||||
ELSE 0 END)::BIT(24);
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
-- Given an array of verbose DAV: or CalDAV: privilege names return the bitmask
|
||||
CREATE or REPLACE FUNCTION privilege_to_bits( TEXT[] ) RETURNS BIT(24) AS $$
|
||||
@ -62,7 +62,7 @@ BEGIN
|
||||
RETURN out_bits;
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- This sequence is used in a number of places so that any DAV resource will have a unique ID
|
||||
@ -262,7 +262,7 @@ CREATE or REPLACE FUNCTION sync_dav_id ( ) RETURNS TRIGGER AS $$
|
||||
RETURN NEW;
|
||||
|
||||
END
|
||||
$$ LANGUAGE 'plpgsql';
|
||||
$$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER caldav_data_sync_dav_id AFTER INSERT OR UPDATE ON caldav_data
|
||||
FOR EACH ROW EXECUTE PROCEDURE sync_dav_id();
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ CREATE or REPLACE FUNCTION sync_dav_id ( ) RETURNS TRIGGER AS '
|
||||
RETURN NEW;
|
||||
|
||||
END
|
||||
' LANGUAGE 'plpgsql';
|
||||
' LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER caldav_data_sync_dav_id AFTER INSERT OR UPDATE ON caldav_data
|
||||
FOR EACH ROW EXECUTE PROCEDURE sync_dav_id();
|
||||
|
||||
@ -48,7 +48,7 @@ CREATE or REPLACE FUNCTION sync_dav_id ( ) RETURNS TRIGGER AS '
|
||||
RETURN NEW;
|
||||
|
||||
END
|
||||
' LANGUAGE 'plpgsql';
|
||||
' LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER caldav_data_sync_dav_id AFTER INSERT OR UPDATE ON caldav_data
|
||||
FOR EACH ROW EXECUTE PROCEDURE sync_dav_id();
|
||||
|
||||
@ -42,7 +42,7 @@ CREATE or REPLACE FUNCTION sync_dav_id ( ) RETURNS TRIGGER AS '
|
||||
RETURN NEW;
|
||||
|
||||
END
|
||||
' LANGUAGE 'plpgsql';
|
||||
' LANGUAGE plpgsql;
|
||||
|
||||
-- CREATE TRIGGER caldav_data_sync_dav_id AFTER INSERT OR UPDATE ON caldav_data
|
||||
-- FOR EACH ROW EXECUTE PROCEDURE sync_dav_id();
|
||||
|
||||
@ -28,7 +28,7 @@ CREATE or REPLACE FUNCTION check_db_revision( INT, INT, INT ) RETURNS BOOLEAN AS
|
||||
RAISE EXCEPTION ''Database has not been upgraded to %.%.%'', major, minor, patch;
|
||||
RETURN FALSE;
|
||||
END;
|
||||
' LANGUAGE 'plpgsql';
|
||||
' LANGUAGE plpgsql;
|
||||
|
||||
|
||||
-- Just in case these constraints got added manually, so we won't fail
|
||||
|
||||
@ -42,7 +42,7 @@ CREATE or REPLACE FUNCTION sync_dav_id ( ) RETURNS TRIGGER AS '
|
||||
RETURN NEW;
|
||||
|
||||
END
|
||||
' LANGUAGE 'plpgsql';
|
||||
' LANGUAGE plpgsql;
|
||||
|
||||
-- CREATE TRIGGER caldav_data_sync_dav_id AFTER INSERT OR UPDATE ON caldav_data
|
||||
-- FOR EACH ROW EXECUTE PROCEDURE sync_dav_id();
|
||||
|
||||
@ -42,7 +42,7 @@ CREATE or REPLACE FUNCTION sync_dav_id ( ) RETURNS TRIGGER AS '
|
||||
RETURN NEW;
|
||||
|
||||
END
|
||||
' LANGUAGE 'plpgsql';
|
||||
' LANGUAGE plpgsql;
|
||||
|
||||
-- CREATE TRIGGER caldav_data_sync_dav_id AFTER INSERT OR UPDATE ON caldav_data
|
||||
-- FOR EACH ROW EXECUTE PROCEDURE sync_dav_id();
|
||||
|
||||
@ -50,7 +50,7 @@ BEGIN
|
||||
RETURN out_bits;
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
-- This legacy conversion function will eventually be removed, once all logic
|
||||
-- has been converted to use bitmaps, or to use the bits_to_priv() output.
|
||||
@ -103,7 +103,7 @@ BEGIN
|
||||
RETURN out_priv;
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
CREATE or REPLACE FUNCTION get_permissions( INT, INT ) RETURNS TEXT AS $$
|
||||
DECLARE
|
||||
@ -156,12 +156,12 @@ BEGIN
|
||||
|
||||
RETURN '';
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
CREATE or REPLACE FUNCTION get_group_role_no() RETURNS INT AS $$
|
||||
SELECT role_no FROM roles WHERE role_name = 'Group'
|
||||
$$ LANGUAGE 'sql' IMMUTABLE;
|
||||
$$ LANGUAGE sql IMMUTABLE;
|
||||
|
||||
CREATE or REPLACE FUNCTION has_legacy_privilege( INT, TEXT, INT ) RETURNS BOOLEAN AS $$
|
||||
DECLARE
|
||||
@ -210,7 +210,7 @@ BEGIN
|
||||
|
||||
RETURN FALSE;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Given a verbose DAV: or CalDAV: privilege name return the bitmask
|
||||
@ -247,7 +247,7 @@ BEGIN
|
||||
ELSE 0 END)::BIT(24);
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Given an array of verbose DAV: or CalDAV: privilege names return the bitmask
|
||||
@ -274,7 +274,7 @@ BEGIN
|
||||
RETURN out_bits;
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- This legacy conversion function will eventually be removed, once all logic
|
||||
@ -372,7 +372,7 @@ BEGIN
|
||||
RETURN out_priv;
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
|
||||
@ -491,7 +491,7 @@ BEGIN
|
||||
RETURN out_bits;
|
||||
END
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
ALTER TABLE relationship_type ADD COLUMN bit_confers BIT(24) DEFAULT privilege_to_bits(ARRAY['DAV::read','DAV::write']);
|
||||
|
||||
@ -54,7 +54,7 @@ BEGIN
|
||||
VALUES( in_collection_id, in_status, tmp_int, in_dav_name);
|
||||
RETURN TRUE;
|
||||
END
|
||||
$$ LANGUAGE 'plpgsql' VOLATILE STRICT;
|
||||
$$ LANGUAGE plpgsql VOLATILE STRICT;
|
||||
|
||||
|
||||
CREATE or REPLACE FUNCTION new_sync_token( INT8, INT8 ) RETURNS INT8 AS $$
|
||||
@ -76,4 +76,4 @@ BEGIN
|
||||
INSERT INTO sync_tokens(collection_id, sync_token) VALUES( in_collection_id, tmp_int );
|
||||
RETURN tmp_int;
|
||||
END
|
||||
$$ LANGUAGE 'plpgsql' STRICT;
|
||||
$$ LANGUAGE plpgsql STRICT;
|
||||
|
||||
@ -75,7 +75,7 @@ BEGIN
|
||||
|
||||
RETURN result;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Return a SETOF dates within the month of a particular date which match a string of BYDAY rule specifications
|
||||
@ -170,7 +170,7 @@ BEGIN
|
||||
RETURN;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
-- Return a SETOF dates within the month of a particular date which match a string of BYDAY rule specifications
|
||||
@ -204,7 +204,7 @@ BEGIN
|
||||
RETURN;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Return a SETOF dates within the week of a particular date which match a single BYDAY rule specification
|
||||
@ -238,12 +238,12 @@ BEGIN
|
||||
RETURN;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
CREATE or REPLACE FUNCTION event_has_exceptions( TEXT ) RETURNS BOOLEAN AS $$
|
||||
SELECT $1 ~ E'\nRECURRENCE-ID(;TZID=[^:]+)?:[[:space:]]*[[:digit:]]{8}(T[[:digit:]]{6})?'
|
||||
$$ LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE sql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -261,7 +261,7 @@ BEGIN
|
||||
END IF;
|
||||
RETURN TRUE;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -277,7 +277,7 @@ BEGIN
|
||||
END IF;
|
||||
RETURN TRUE;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -293,7 +293,7 @@ BEGIN
|
||||
END IF;
|
||||
RETURN TRUE;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -309,7 +309,7 @@ BEGIN
|
||||
END IF;
|
||||
RETURN TRUE;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -356,7 +356,7 @@ BEGIN
|
||||
END IF;
|
||||
CLOSE curse;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -396,7 +396,7 @@ BEGIN
|
||||
RETURN NEXT after;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -428,7 +428,7 @@ BEGIN
|
||||
END LOOP;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -473,7 +473,7 @@ BEGIN
|
||||
END LOOP;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -507,7 +507,7 @@ BEGIN
|
||||
END IF;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -535,7 +535,7 @@ BEGIN
|
||||
RETURN NEXT after;
|
||||
END IF;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -632,7 +632,7 @@ BEGIN
|
||||
END LOOP;
|
||||
-- RETURN QUERY;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -651,7 +651,7 @@ BEGIN
|
||||
RETURN NEXT rowvar.d;
|
||||
END LOOP;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -701,9 +701,9 @@ BEGIN
|
||||
RETURN FOUND;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
CREATE or REPLACE FUNCTION icalendar_interval_to_SQL( TEXT ) RETURNS interval AS $function$
|
||||
SELECT CASE WHEN substring($1,1,1) = '-' THEN -1 ELSE 1 END * regexp_replace( regexp_replace($1, '[PT-]', '', 'g'), '([A-Z])', E'\\1 ', 'g')::interval;
|
||||
$function$ LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
$function$ LANGUAGE sql IMMUTABLE STRICT;
|
||||
|
||||
@ -75,7 +75,7 @@ BEGIN
|
||||
|
||||
RETURN result;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Return a SETOF dates within the month of a particular date which match a string of BYDAY rule specifications
|
||||
@ -161,7 +161,7 @@ BEGIN
|
||||
RETURN;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
-- Return a SETOF dates within the month of a particular date which match a string of BYDAY rule specifications
|
||||
@ -195,7 +195,7 @@ BEGIN
|
||||
RETURN;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Return a SETOF dates within the week of a particular date which match a single BYDAY rule specification
|
||||
@ -229,12 +229,12 @@ BEGIN
|
||||
RETURN;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
CREATE or REPLACE FUNCTION event_has_exceptions( TEXT ) RETURNS BOOLEAN AS $$
|
||||
SELECT $1 ~ E'\nRECURRENCE-ID(;TZID=[^:]+)?:[[:space:]]*[[:digit:]]{8}(T[[:digit:]]{6})?'
|
||||
$$ LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE sql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -252,7 +252,7 @@ BEGIN
|
||||
END IF;
|
||||
RETURN TRUE;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -268,7 +268,7 @@ BEGIN
|
||||
END IF;
|
||||
RETURN TRUE;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -284,7 +284,7 @@ BEGIN
|
||||
END IF;
|
||||
RETURN TRUE;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -300,7 +300,7 @@ BEGIN
|
||||
END IF;
|
||||
RETURN TRUE;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -340,7 +340,7 @@ BEGIN
|
||||
END IF;
|
||||
CLOSE curse;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -380,7 +380,7 @@ BEGIN
|
||||
RETURN NEXT after;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -410,7 +410,7 @@ BEGIN
|
||||
RETURN QUERY SELECT d FROM rrule_bysetpos_filter(curse,rrule.bysetpos) d;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -453,7 +453,7 @@ BEGIN
|
||||
RETURN QUERY SELECT d FROM rrule_bysetpos_filter(curse,rrule.bysetpos) d;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -483,7 +483,7 @@ BEGIN
|
||||
END IF;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -510,7 +510,7 @@ BEGIN
|
||||
RETURN NEXT after;
|
||||
END IF;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -610,7 +610,7 @@ BEGIN
|
||||
END LOOP;
|
||||
-- RETURN QUERY;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -626,7 +626,7 @@ BEGIN
|
||||
maxdate := current_date + '10 years'::interval;
|
||||
RETURN QUERY SELECT d FROM rrule_event_instances_range( basedate, repeatrule, basedate, maxdate, 300 ) d;
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------
|
||||
@ -676,7 +676,7 @@ BEGIN
|
||||
RETURN FOUND;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
|
||||
-- Create a composite type for the parts of the RRULE.
|
||||
@ -707,10 +707,10 @@ BEGIN
|
||||
END LOOP;
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
CREATE or REPLACE FUNCTION icalendar_interval_to_SQL( TEXT ) RETURNS interval AS $function$
|
||||
SELECT CASE WHEN substring($1,1,1) = '-' THEN -1 ELSE 1 END * regexp_replace( regexp_replace($1, '[PT-]', '', 'g'), '([A-Z])', E'\\1 ', 'g')::interval;
|
||||
$function$ LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
$function$ LANGUAGE sql IMMUTABLE STRICT;
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ $bad_events = null;
|
||||
/**
|
||||
* A regex which will match most reasonable timezones acceptable to PostgreSQL.
|
||||
*/
|
||||
$tz_regex = ':^(Africa|America|Antarctica|Arctic|Asia|Atlantic|Australia|Brazil|Canada|Chile|Etc|Europe|Indian|Mexico|Mideast|Pacific|US)/[a-z_]+$:i';
|
||||
$GLOBALS['tz_regex'] = ':^(Africa|America|Antarctica|Arctic|Asia|Atlantic|Australia|Brazil|Canada|Chile|Etc|Europe|Indian|Mexico|Mideast|Pacific|US)/[a-z_]+$:i';
|
||||
|
||||
/**
|
||||
* This function launches an error
|
||||
|
||||
@ -134,7 +134,7 @@ $vcard->Write( $row->dav_id, $dest->Exists() );
|
||||
|
||||
$qry->QDo("SELECT write_sync_change( $collection_id, $response_code, :dav_name)", array(':dav_name' => $dest->bound_from() ) );
|
||||
|
||||
if ( isset($log_action) && $log_action && function_exists('log_caldav_action') ) {
|
||||
if ( function_exists('log_caldav_action') ) {
|
||||
log_caldav_action( $put_action_type, $uid, $user_no, $collection_id, $request->path );
|
||||
}
|
||||
else if ( isset($log_action) && $log_action ) {
|
||||
|
||||
@ -88,11 +88,13 @@ function apply_filter( $filters, $item ) {
|
||||
|
||||
/**
|
||||
* Process a filter fragment returning an SQL fragment
|
||||
* Changed by GitHub user moosemark 2013-11-29 to allow multiple text-matches - SQL parameter now has numeric count appended.
|
||||
*/
|
||||
$need_post_filter = false;
|
||||
$range_filter = null;
|
||||
function SqlFilterFragment( $filter, $components, $property = null, $parameter = null ) {
|
||||
global $need_post_filter, $range_filter, $target_collection;
|
||||
$parameter_match_num = 0;
|
||||
function SqlFilterFragment( $filter, $components, $property = null, $parameter = null) {
|
||||
global $need_post_filter, $range_filter, $target_collection, $parameter_match_num;
|
||||
$sql = "";
|
||||
$params = array();
|
||||
if ( !is_array($filter) ) {
|
||||
@ -180,10 +182,13 @@ function SqlFilterFragment( $filter, $components, $property = null, $parameter =
|
||||
$comparison = 'ILIKE';
|
||||
break;
|
||||
}
|
||||
$params[':text_match'] = '%'.$search.'%';
|
||||
$fragment = sprintf( 'AND (%s%s %s :text_match) ',
|
||||
/* Append the match number to the SQL parameter, to allow multiple text match conditions within the same query */
|
||||
$params[':text_match_'.$parameter_match_num] = '%'.$search.'%';
|
||||
$fragment = sprintf( 'AND (%s%s %s :text_match_%s) ',
|
||||
(isset($negate) && strtolower($negate) == "yes" ? $property.' IS NULL OR NOT ': ''),
|
||||
$property, $comparison );
|
||||
$property, $comparison, $parameter_match_num );
|
||||
$parameter_match_num++;
|
||||
|
||||
dbg_error_log('calquery', ' text-match: %s', $fragment );
|
||||
$sql .= $fragment;
|
||||
break;
|
||||
@ -233,6 +238,7 @@ function SqlFilterFragment( $filter, $components, $property = null, $parameter =
|
||||
case 'COMPLETED': /** @todo this should be moved into the properties supported in SQL. */
|
||||
default:
|
||||
$need_post_filter = true;
|
||||
unset($subproperty);
|
||||
dbg_error_log("calquery", "Could not handle 'prop-filter' on %s in SQL", $propertyname );
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -47,13 +47,24 @@ if ( empty($properties) ) $properties['DAV::allprop'] = 1;
|
||||
* There can only be *one* FILTER element.
|
||||
*/
|
||||
$qry_filters = $xmltree->GetPath('/urn:ietf:params:xml:ns:carddav:addressbook-query/urn:ietf:params:xml:ns:carddav:filter/*');
|
||||
if ( count($qry_filters) != 1 ) {
|
||||
/* $qry_filters = $qry_filters[0]; // There can only be one FILTER element
|
||||
}
|
||||
else { */
|
||||
if ( count($qry_filters) == 0 ) {
|
||||
$qry_filters = false;
|
||||
}
|
||||
|
||||
$qry_limit = -1; // everything
|
||||
$qry_filters_combination='OR';
|
||||
if ( is_array($qry_filters) ) {
|
||||
$filters_parent = $xmltree->GetPath('/urn:ietf:params:xml:ns:carddav:addressbook-query/urn:ietf:params:xml:ns:carddav:filter')[0];
|
||||
// only anyof (OR) or allof (AND) allowed, if missing anyof is default (RFC6352 10.5)
|
||||
if ( $filters_parent->GetAttribute("test") == 'allof' ) {
|
||||
$qry_filters_combination='AND';
|
||||
}
|
||||
|
||||
$limits = $xmltree->GetPath('/urn:ietf:params:xml:ns:carddav:addressbook-query/urn:ietf:params:xml:ns:carddav:limit/urn:ietf:params:xml:ns:carddav:nresults');
|
||||
if ( count($limits) == 1) {
|
||||
$qry_limit = intval($limits[0]->GetContent());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* While we can construct our SQL to apply some filters in the query, other filters
|
||||
@ -61,126 +72,174 @@ else { */
|
||||
*
|
||||
* @param array $filter An array of XMLElement which is the filter definition
|
||||
* @param string $item The database row retrieved for this calendar item
|
||||
* @param string $filter_type possible values AND or OR (for OR only one filter fragment must match)
|
||||
*
|
||||
* @return boolean True if the check succeeded, false otherwise.
|
||||
*/
|
||||
function apply_filter( $filters, $item ) {
|
||||
function apply_filter( $filters, $item, $filter_type) {
|
||||
global $session, $c, $request;
|
||||
|
||||
if ( count($filters) == 0 ) return true;
|
||||
|
||||
dbg_error_log("cardquery","Applying filter for item '%s'", $item->dav_name );
|
||||
$vcard = new vComponent( $item->caldav_data );
|
||||
return $vcard->TestFilter($filters);
|
||||
|
||||
if ( $filter_type === 'AND' ) {
|
||||
return $vcard->TestFilter($filters);
|
||||
} else {
|
||||
foreach($filters AS $filter) {
|
||||
$filter_fragment[0] = $filter;
|
||||
if ( $vcard->TestFilter($filter_fragment) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process a filter fragment returning an SQL fragment
|
||||
*/
|
||||
$need_post_filter = false;
|
||||
$post_filters = array();
|
||||
$matchnum = 0;
|
||||
function SqlFilterCardDAV( $filter, $components, $property = null, $parameter = null ) {
|
||||
global $need_post_filter, $target_collection, $matchnum;
|
||||
global $post_filters, $target_collection, $matchnum;
|
||||
$sql = "";
|
||||
$params = array();
|
||||
if ( !is_array($filter) ) {
|
||||
dbg_error_log( "cardquery", "Filter is of type '%s', but should be an array of XML Tags.", gettype($filter) );
|
||||
}
|
||||
|
||||
foreach( $filter AS $k => $v ) {
|
||||
$tag = $v->GetNSTag();
|
||||
dbg_error_log("cardquery", "Processing $tag into SQL - %d, '%s', %d\n", count($components), $property, isset($parameter) );
|
||||
$tag = $filter->GetNSTag();
|
||||
dbg_error_log("cardquery", "Processing $tag into SQL - %d, '%s', %d\n", count($components), $property, isset($parameter) );
|
||||
|
||||
$not_defined = "";
|
||||
switch( $tag ) {
|
||||
case 'urn:ietf:params:xml:ns:carddav:text-match':
|
||||
$search = $v->GetContent();
|
||||
$negate = $v->GetAttribute("negate-condition");
|
||||
$collation = $v->GetAttribute("collation");
|
||||
switch( strtolower($collation) ) {
|
||||
case 'i;octet':
|
||||
$comparison = 'LIKE';
|
||||
break;
|
||||
case 'i;ascii-casemap':
|
||||
case 'i;unicode-casemap':
|
||||
default:
|
||||
$comparison = 'ILIKE';
|
||||
break;
|
||||
$not_defined = "";
|
||||
switch( $tag ) {
|
||||
case 'urn:ietf:params:xml:ns:carddav:is-not-defined':
|
||||
$sql .= $property . 'IS NULL';
|
||||
break;
|
||||
|
||||
case 'urn:ietf:params:xml:ns:carddav:text-match':
|
||||
if ( empty($property) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$collation = $filter->GetAttribute("collation");
|
||||
switch( strtolower($collation) ) {
|
||||
case 'i;octet':
|
||||
$comparison = 'LIKE';
|
||||
break;
|
||||
case 'i;ascii-casemap':
|
||||
case 'i;unicode-casemap':
|
||||
default:
|
||||
$comparison = 'ILIKE';
|
||||
break;
|
||||
}
|
||||
|
||||
$search = $filter->GetContent();
|
||||
$match = $filter->GetAttribute("match-type");
|
||||
switch( strtolower($match) ) {
|
||||
case 'equals':
|
||||
break;
|
||||
case 'starts-with':
|
||||
$search = $search.'%';
|
||||
break;
|
||||
case 'ends-with':
|
||||
$search = $search.'%';
|
||||
break;
|
||||
case 'contains':
|
||||
default:
|
||||
$search = '%'.$search.'%';
|
||||
break;
|
||||
}
|
||||
|
||||
$pname = ':text_match_'.$matchnum++;
|
||||
$params[$pname] = $search;
|
||||
|
||||
$negate = $filter->GetAttribute("negate-condition");
|
||||
$negate = ( (isset($negate) && strtolower($negate) ) == "yes" ) ? "NOT " : "";
|
||||
dbg_error_log("cardquery", " text-match: (%s%s %s '%s') ", $negate, $property, $comparison, $search );
|
||||
$sql .= sprintf( "(%s%s %s $pname)", $negate, $property, $comparison );
|
||||
break;
|
||||
|
||||
case 'urn:ietf:params:xml:ns:carddav:prop-filter':
|
||||
$propertyname = $filter->GetAttribute("name");
|
||||
switch( $propertyname ) {
|
||||
case 'VERSION':
|
||||
case 'UID':
|
||||
case 'NICKNAME':
|
||||
case 'FN':
|
||||
case 'NOTE':
|
||||
case 'ORG':
|
||||
case 'URL':
|
||||
case 'FBURL':
|
||||
case 'CALADRURI':
|
||||
case 'CALURI':
|
||||
$property = strtolower($propertyname);
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
$property = 'name';
|
||||
break;
|
||||
|
||||
default:
|
||||
$post_filters[] = $filter;
|
||||
dbg_error_log("cardquery", "Could not handle 'prop-filter' on %s in SQL", $propertyname );
|
||||
return false;
|
||||
}
|
||||
|
||||
$test_type = $filter->GetAttribute("test");
|
||||
switch( $test_type ) {
|
||||
case 'allOf':
|
||||
$test_type = 'AND';
|
||||
break;
|
||||
case 'anyOf':
|
||||
default:
|
||||
$test_type = 'OR';
|
||||
}
|
||||
|
||||
$subfilters = $filter->GetContent();
|
||||
if (count($subfilters) <= 1) {
|
||||
$success = SqlFilterCardDAV( $subfilters[0], $components, $property, $parameter );
|
||||
if ( $success !== false ) {
|
||||
$sql .= $success['sql'];
|
||||
$params = array_merge( $params, $success['params'] );
|
||||
}
|
||||
$pname = ':text_match_'.$matchnum++;
|
||||
$match_type = $v->GetAttribute("match-type");
|
||||
switch( strtolower($match_type) ) {
|
||||
case 'starts-with':
|
||||
$params[$pname] = $search.'%';
|
||||
break;
|
||||
case 'ends-with':
|
||||
$params[$pname] = '%'.$search;
|
||||
break;
|
||||
case 'equals':
|
||||
$params[$pname] = $search;
|
||||
case 'contains':
|
||||
default:
|
||||
$params[$pname] = '%'.$search.'%';
|
||||
break;
|
||||
} else {
|
||||
$subfilter_added_counter=0;
|
||||
foreach ($subfilters as $subfilter) {
|
||||
$success = SqlFilterCardDAV( $subfilter, $components, $property, $parameter );
|
||||
if ( $success === false ) continue; else {
|
||||
if ($subfilter_added_counter <= 0) {
|
||||
$sql .= '(' . $success['sql'];
|
||||
} else {
|
||||
$sql .= $test_type . ' ' . $success['sql'];
|
||||
}
|
||||
$params = array_merge( $params, $success['params'] );
|
||||
$subfilter_added_counter++;
|
||||
}
|
||||
}
|
||||
dbg_error_log("cardquery", " text-match: (%s%s %s '%s') ", (isset($negate) && strtolower($negate) == "yes" ? "NOT ": ""),
|
||||
$property, $comparison, $params[$pname] );
|
||||
$sql .= sprintf( "AND (%s%s %s $pname) ", (isset($negate) && strtolower($negate) == "yes" ? "NOT ": ""),
|
||||
$property, $comparison );
|
||||
break;
|
||||
|
||||
case 'urn:ietf:params:xml:ns:carddav:prop-filter':
|
||||
$propertyname = $v->GetAttribute("name");
|
||||
switch( $propertyname ) {
|
||||
case 'VERSION':
|
||||
case 'UID':
|
||||
case 'NICKNAME':
|
||||
case 'FN':
|
||||
case 'NOTE':
|
||||
case 'ORG':
|
||||
case 'URL':
|
||||
case 'FBURL':
|
||||
case 'CALADRURI':
|
||||
case 'CALURI':
|
||||
$property = strtolower($propertyname);
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
$property = 'name';
|
||||
break;
|
||||
|
||||
default:
|
||||
$need_post_filter = true;
|
||||
dbg_error_log("cardquery", "Could not handle 'prop-filter' on %s in SQL", $propertyname );
|
||||
continue;
|
||||
if ($subfilter_added_counter > 0) {
|
||||
$sql .= ')';
|
||||
}
|
||||
$subfilter = $v->GetContent();
|
||||
$success = SqlFilterCardDAV( $subfilter, $components, $property, $parameter );
|
||||
if ( $success === false ) continue; else {
|
||||
$sql .= $success['sql'];
|
||||
$params = array_merge( $params, $success['params'] );
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'urn:ietf:params:xml:ns:carddav:param-filter':
|
||||
$need_post_filter = true;
|
||||
return false; /** Figure out how to handle PARAM-FILTER conditions in the SQL */
|
||||
/*
|
||||
$parameter = $v->GetAttribute("name");
|
||||
$subfilter = $v->GetContent();
|
||||
$success = SqlFilterCardDAV( $subfilter, $components, $property, $parameter );
|
||||
if ( $success === false ) continue; else {
|
||||
$sql .= $success['sql'];
|
||||
$params = array_merge( $params, $success['params'] );
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case 'urn:ietf:params:xml:ns:carddav:param-filter':
|
||||
$post_filters[] = $filter;
|
||||
return false; /** Figure out how to handle PARAM-FILTER conditions in the SQL */
|
||||
/*
|
||||
$parameter = $filter->GetAttribute("name");
|
||||
$subfilter = $filter->GetContent();
|
||||
$success = SqlFilterCardDAV( $subfilter, $components, $property, $parameter );
|
||||
if ( $success === false ) continue; else {
|
||||
$sql .= $success['sql'];
|
||||
$params = array_merge( $params, $success['params'] );
|
||||
}
|
||||
break;
|
||||
*/
|
||||
|
||||
default:
|
||||
dbg_error_log("cardquery", "Could not handle unknown tag '%s' in calendar query report", $tag );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dbg_error_log("cardquery", "Could not handle unknown tag '%s' in calendar query report", $tag );
|
||||
break;
|
||||
}
|
||||
dbg_error_log("cardquery", "Generated SQL was '%s'", $sql );
|
||||
return array( 'sql' => $sql, 'params' => $params );
|
||||
@ -213,23 +272,50 @@ $params = array();
|
||||
$where = ' WHERE caldav_data.collection_id = ' . $target_collection->resource_id();
|
||||
if ( is_array($qry_filters) ) {
|
||||
dbg_log_array( 'cardquery', 'qry_filters', $qry_filters, true );
|
||||
$components = array();
|
||||
$filter_fragment = SqlFilterCardDAV( $qry_filters, $components );
|
||||
if ( $filter_fragment !== false ) {
|
||||
$where .= ' '.$filter_fragment['sql'];
|
||||
$params = $filter_fragment['params'];
|
||||
|
||||
$appended_where_counter=0;
|
||||
foreach ($qry_filters as $qry_filter) {
|
||||
$components = array();
|
||||
$filter_fragment = SqlFilterCardDAV( $qry_filter, $components );
|
||||
if ( $filter_fragment !== false ) {
|
||||
$filter_fragment_sql = $filter_fragment['sql'];
|
||||
if ( empty($filter_fragment_sql) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $appended_where_counter == 0 ) {
|
||||
$where .= ' AND (' . $filter_fragment_sql;
|
||||
$params = $filter_fragment['params'];
|
||||
} else {
|
||||
$where .= ' ' . $qry_filters_combination . ' ' . $filter_fragment_sql;
|
||||
$params = array_merge( $params, $filter_fragment['params'] );
|
||||
}
|
||||
$appended_where_counter++;
|
||||
}
|
||||
}
|
||||
if ( $appended_where_counter > 0 ) {
|
||||
$where .= ')';
|
||||
}
|
||||
}
|
||||
else {
|
||||
dbg_error_log( 'cardquery', 'No query filters' );
|
||||
}
|
||||
|
||||
$need_post_filter = !empty($post_filters);
|
||||
if ( $need_post_filter && ( $qry_filters_combination == 'OR' )) {
|
||||
// we need a post_filter step, and it should be sufficient, that only one
|
||||
// filter is enough to display the item => we can't prefilter values via SQL
|
||||
$where = '';
|
||||
$params = array();
|
||||
$post_filters = $qry_filters;
|
||||
}
|
||||
|
||||
$sql = 'SELECT * FROM caldav_data INNER JOIN addressbook_resource USING(dav_id)'. $where;
|
||||
if ( isset($c->strict_result_ordering) && $c->strict_result_ordering ) $sql .= " ORDER BY dav_id";
|
||||
$qry = new AwlQuery( $sql, $params );
|
||||
if ( $qry->Exec("cardquery",__LINE__,__FILE__) && $qry->rows() > 0 ) {
|
||||
while( $address_object = $qry->Fetch() ) {
|
||||
if ( !$need_post_filter || apply_filter( $qry_filters, $address_object ) ) {
|
||||
if ( !$need_post_filter || apply_filter( $post_filters, $address_object, $qry_filters_combination ) ) {
|
||||
if ( $bound_from != $target_collection->dav_name() ) {
|
||||
$address_object->dav_name = str_replace( $bound_from, $target_collection->dav_name(), $address_object->dav_name);
|
||||
}
|
||||
@ -239,9 +325,12 @@ if ( $qry->Exec("cardquery",__LINE__,__FILE__) && $qry->rows() > 0 ) {
|
||||
$address_object->caldav_data = $vcard->Render();
|
||||
}
|
||||
$responses[] = component_to_xml( $properties, $address_object );
|
||||
if ( ($qry_limit > 0) && ( count($responses) >= $qry_limit ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$multistatus = new XMLElement( "multistatus", $responses, $reply->GetXmlNsArray() );
|
||||
|
||||
$request->XMLResponse( 207, $multistatus );
|
||||
$request->XMLResponse( 207, $multistatus );
|
||||
@ -84,10 +84,19 @@ function IMAP_PAM_check($username, $password ){
|
||||
$fullname = $username;
|
||||
}
|
||||
|
||||
// ensure email domain is not doubled in email field
|
||||
@list($tmp_user, $tmp_domain) = explode('@', $username);
|
||||
if( empty($tmp_domain) ) {
|
||||
$email_address = $username . "@" . $c->authenticate_hook['config']['email_base'];
|
||||
}
|
||||
else {
|
||||
$email_address = $username;
|
||||
}
|
||||
|
||||
$principal->Create( array(
|
||||
'username' => $username,
|
||||
'user_active' => true,
|
||||
'email' => $username . "@" . $c->authenticate_hook['config']['email_base'],
|
||||
'email' => $email_address,
|
||||
'modified' => date('c'),
|
||||
'fullname' => $fullname
|
||||
));
|
||||
|
||||
@ -119,6 +119,7 @@ class ldapDrivers
|
||||
global $c;
|
||||
|
||||
$query = $this->ldap_query_all;
|
||||
$ret = array();
|
||||
|
||||
foreach($this->baseDNUsers as $baseDNUsers) {
|
||||
$entry = $query($this->connect,$baseDNUsers,$this->filterUsers,$attributes);
|
||||
@ -150,6 +151,7 @@ class ldapDrivers
|
||||
global $c;
|
||||
|
||||
$query = $this->ldap_query_all;
|
||||
$ret = array();
|
||||
|
||||
foreach($this->baseDNGroups as $baseDNGroups) {
|
||||
$entry = $query($this->connect,$baseDNGroups,$this->filterGroups,$attributes);
|
||||
@ -412,6 +414,16 @@ function LDAP_check($username, $password ){
|
||||
|
||||
}
|
||||
|
||||
function fix_unique_member($list) {
|
||||
$fixed_list = array();
|
||||
foreach ( $list as $member ){
|
||||
list( $mem, $rest ) = explode(",", $member );
|
||||
$member = str_replace( 'uid=', '', $mem );
|
||||
array_unshift( $fixed_list, $member );
|
||||
}
|
||||
return $fixed_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* sync LDAP Groups against the DB
|
||||
*/
|
||||
@ -502,6 +514,10 @@ function sync_LDAP_groups(){
|
||||
Principal::cacheDelete('username', $group);
|
||||
$c->messages[] = sprintf(i18n('- adding users %s to group : %s'),join(',',$ldap_groups_info[$group][$mapping['members']]),$group);
|
||||
foreach ( $ldap_groups_info[$group][$mapping['members']] as $member ){
|
||||
if ( $member_field == 'uniqueMember' ) {
|
||||
list( $mem, $rest ) = explode(",", $member );
|
||||
$member = str_replace( 'uid=', '', $mem );
|
||||
}
|
||||
$qry = new AwlQuery( "INSERT INTO group_member SELECT g.principal_id AS group_id,u.principal_id AS member_id FROM dav_principal g, dav_principal u WHERE g.username=:group AND u.username=:member;",array (':group'=>$group,':member'=>$member) );
|
||||
$qry->Exec('sync_LDAP_groups',__LINE__,__FILE__);
|
||||
Principal::cacheDelete('username', $member);
|
||||
@ -514,6 +530,9 @@ function sync_LDAP_groups(){
|
||||
foreach ( $groups_to_update as $group ){
|
||||
$db_members = array_values ( $db_group_members[$group] );
|
||||
$ldap_members = array_values ( $ldap_groups_info[$group][$member_field] );
|
||||
if ( $member_field == 'uniqueMember' ) {
|
||||
$ldap_members = fix_unique_member( $ldap_members );
|
||||
}
|
||||
$add_users = array_diff ( $ldap_members, $db_members );
|
||||
if ( sizeof ( $add_users ) ){
|
||||
$c->messages[] = sprintf(i18n('- adding %s to group : %s'),join(', ', $add_users ), $group);
|
||||
|
||||
@ -22,9 +22,9 @@ function create_external ( $path,$is_calendar,$is_addressbook )
|
||||
if ($is_calendar) $resourcetypes .= '<urn:ietf:params:xml:ns:caldav:calendar/>';
|
||||
$qry = new AwlQuery();
|
||||
if ( ! $qry->QDo( 'INSERT INTO collection ( user_no, parent_container, dav_name, dav_etag, dav_displayname,
|
||||
is_calendar, is_addressbook, resourcetypes, created, modified )
|
||||
is_calendar, is_addressbook, resourcetypes, created )
|
||||
VALUES( :user_no, :parent_container, :dav_name, :dav_etag, :dav_displayname,
|
||||
:is_calendar, :is_addressbook, :resourcetypes, current_timestamp, current_timestamp )',
|
||||
:is_calendar, :is_addressbook, :resourcetypes, current_timestamp )',
|
||||
array(
|
||||
':user_no' => $request->user_no,
|
||||
':parent_container' => '/.external/',
|
||||
@ -55,43 +55,48 @@ function fetch_external ( $bind_id, $min_age = '1 hour' )
|
||||
$sql .= ' ORDER BY modified DESC LIMIT 1';
|
||||
$qry = new AwlQuery( $sql, $params );
|
||||
if ( $qry->Exec('DAVResource') && $qry->rows() > 0 && $row = $qry->Fetch() ) {
|
||||
$local_ts = new DateTime($row->modified);
|
||||
$curl = curl_init ( $row->external_url );
|
||||
curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, true );
|
||||
curl_setopt ( $curl, CURLOPT_HEADER, true );
|
||||
curl_setopt ( $curl, CURLOPT_FILETIME, true );
|
||||
curl_setopt ( $curl, CURLOPT_NOBODY, true );
|
||||
curl_setopt ( $curl, CURLOPT_TIMEVALUE, $local_ts->format("U") );
|
||||
curl_setopt ( $curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE );
|
||||
dbg_error_log("external", "checking external resource for remote changes " . $row->external_url );
|
||||
$ics = curl_exec ( $curl );
|
||||
$info = curl_getinfo ( $curl );
|
||||
if ( $info['http_code'] === 304 || isset($info['filetime']) && new DateTime("@" . $info['filetime']) <= $local_ts ) {
|
||||
dbg_error_log("external", "external resource unchanged " . $info['filetime'] . ' < ' . $local_ts->getTimestamp() );
|
||||
curl_close ( $curl );
|
||||
// BUGlet: should track server-time instead of local-time
|
||||
$qry = new AwlQuery( 'UPDATE collection SET modified=NOW() WHERE collection_id = :cid', array ( ':cid' => $row->collection_id ) );
|
||||
$qry->Exec('DAVResource');
|
||||
return true;
|
||||
if ( $row->modified ) {
|
||||
$local_ts = new DateTime($row->modified);
|
||||
curl_setopt ( $curl, CURLOPT_HEADER, true );
|
||||
curl_setopt ( $curl, CURLOPT_FILETIME, true );
|
||||
curl_setopt ( $curl, CURLOPT_NOBODY, true );
|
||||
curl_setopt ( $curl, CURLOPT_TIMEVALUE, $local_ts->format("U") );
|
||||
curl_setopt ( $curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE );
|
||||
dbg_error_log("external", "checking external resource for remote changes " . $row->external_url );
|
||||
$ics = curl_exec ( $curl );
|
||||
$info = curl_getinfo ( $curl );
|
||||
if ( $info['http_code'] === 304 || (isset($info['filetime']) && $info['filetime'] != -1 && new DateTime("@" . $info['filetime']) <= $local_ts )) {
|
||||
dbg_error_log("external", "external resource unchanged " . $info['filetime'] . ' < ' . $local_ts->getTimestamp() . ' (' . $info['http_code'] . ')');
|
||||
curl_close ( $curl );
|
||||
// BUGlet: should track server-time instead of local-time
|
||||
$qry = new AwlQuery( 'UPDATE collection SET modified=NOW() WHERE collection_id = :cid', array ( ':cid' => $row->collection_id ) );
|
||||
$qry->Exec('DAVResource');
|
||||
return true;
|
||||
}
|
||||
dbg_error_log("external", "external resource changed, re importing" . $info['filetime'] );
|
||||
}
|
||||
else {
|
||||
dbg_error_log("external", "fetching external resource for the first time " . $row->external_url );
|
||||
}
|
||||
dbg_error_log("external", "external resource changed, re importing" . $info['filetime'] );
|
||||
curl_setopt ( $curl, CURLOPT_NOBODY, false );
|
||||
curl_setopt ( $curl, CURLOPT_HEADER, false );
|
||||
$ics = curl_exec ( $curl );
|
||||
curl_close ( $curl );
|
||||
if ( is_string ( $ics ) && strlen ( $ics ) > 20 ) {
|
||||
// BUGlet: should track server-time instead of local-time
|
||||
$qry = new AwlQuery( 'UPDATE collection SET modified=NOW(), dav_etag=:etag WHERE collection_id = :cid',
|
||||
array ( ':cid' => $row->collection_id, ':etag' => md5($ics) ) );
|
||||
$qry->Exec('DAVResource');
|
||||
// BUGlet: should track server-time instead of local-time
|
||||
$qry = new AwlQuery( 'UPDATE collection SET modified=NOW(), dav_etag=:etag WHERE collection_id = :cid',
|
||||
array ( ':cid' => $row->collection_id, ':etag' => md5($ics) ) );
|
||||
$qry->Exec('DAVResource');
|
||||
require_once ( 'caldav-PUT-functions.php');
|
||||
import_collection ( $ics , $row->user_no, $row->path, 'External Fetch' , false ) ;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
dbg_error_log("external", "external resource up to date or not found id(%s)", $bind_id );
|
||||
}
|
||||
}
|
||||
else {
|
||||
dbg_error_log("external", "external resource up to date or not found id(%s)", $bind_id );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user