Skip to content
This repository has been archived by the owner on Mar 28, 2019. It is now read-only.

Commit

Permalink
Revert "Merge pull request #510 from mozilla-services/a-transaction-p…
Browse files Browse the repository at this point in the history
…er-request"

This reverts commit f5dfeb5, reversing
changes made to 2cb2436.
  • Loading branch information
leplatrem committed Nov 13, 2015
1 parent 71c1dac commit 76b760a
Show file tree
Hide file tree
Showing 20 changed files with 165 additions and 383 deletions.
8 changes: 0 additions & 8 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,9 @@ This document describes changes between each past release.

- ``_since`` and ``_before`` now accepts an integer value between quotes ``"``,
as it would be returned in the ``ETag`` response header.
- A batch request now fails if one of the subrequests fails (#510)
(*see new feature about transactions*)

**New features**

- A transaction now covers the whole request/response cycle (#510, Kinto/kinto#194).
If an error occurs during the request processing, every operation performed
is rolled back. **Note:** This is only enabled with *PostgreSQL* backends. In
other words, the rollback has no effect on backends like *Redis* or *Memory*.

- Add the ``protocol_version`` to tell which protocol version is
implemented by the service. (#324)

Expand All @@ -43,7 +36,6 @@ This document describes changes between each past release.
- Switch to SQLAlchemy for smarter connections pools.
- Added a simple end-to-end test on a *Cliquet* sample application, using
`Loads <http://github.com/loads/>`_ (fixes #512)
- Switched to SQLAlchemy sessions instead of raw connections and cursors (#510)
- Refactor Redis clients instantiation to avoid repeated defaults (#567, #568)


Expand Down
4 changes: 0 additions & 4 deletions cliquet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@
'storage_url': '',
'storage_max_fetch_size': 10000,
'storage_pool_size': 25,
'transaction_per_request': True,
'userid_hmac_secret': '',
'version_prefix_redirect_enabled': True,
'trailing_slash_redirect_enabled': True,
Expand Down Expand Up @@ -111,9 +110,6 @@ def includeme(config):
# Setup cornice.
config.include("cornice")

# Per-request transaction.
config.include("pyramid_tm")

# Include cliquet plugins after init, unlike pyramid includes.
includes = aslist(settings['includes'])
for app in includes:
Expand Down
28 changes: 13 additions & 15 deletions cliquet/cache/postgresql/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,48 +62,46 @@ def initialize_schema(self):
# Create schema
here = os.path.abspath(os.path.dirname(__file__))
schema = open(os.path.join(here, 'schema.sql')).read()
# Since called outside request, force commit.
with self.client.connect(force_commit=True) as conn:
with self.client.connect() as conn:
conn.execute(schema)
logger.info('Created PostgreSQL cache tables')

def flush(self):
query = """
DELETE FROM cache;
"""
# Since called outside request (e.g. tests), force commit.
with self.client.connect(force_commit=True) as conn:
with self.client.connect() as conn:
conn.execute(query)
logger.debug('Flushed PostgreSQL cache tables')

def ttl(self, key):
query = """
SELECT EXTRACT(SECOND FROM (ttl - now())) AS ttl
FROM cache
WHERE key = :key
WHERE key = %s
AND ttl IS NOT NULL;
"""
with self.client.connect() as conn:
result = conn.execute(query, dict(key=key))
result = conn.execute(query, (key,))
if result.rowcount > 0:
return result.fetchone()['ttl']
return -1

def expire(self, key, ttl):
query = """
UPDATE cache SET ttl = sec2ttl(:ttl) WHERE key = :key;
UPDATE cache SET ttl = sec2ttl(%s) WHERE key = %s;
"""
with self.client.connect() as conn:
conn.execute(query, dict(ttl=ttl, key=key))
conn.execute(query, (ttl, key,))

def set(self, key, value, ttl=None):
query = """
WITH upsert AS (
UPDATE cache SET value = :value, ttl = sec2ttl(:ttl)
WHERE key=:key
UPDATE cache SET value = %(value)s, ttl = sec2ttl(%(ttl)s)
WHERE key=%(key)s
RETURNING *)
INSERT INTO cache (key, value, ttl)
SELECT :key, :value, sec2ttl(:ttl)
SELECT %(key)s, %(value)s, sec2ttl(%(ttl)s)
WHERE NOT EXISTS (SELECT * FROM upsert)
"""
value = json.dumps(value)
Expand All @@ -112,18 +110,18 @@ def set(self, key, value, ttl=None):

def get(self, key):
purge = "DELETE FROM cache WHERE ttl IS NOT NULL AND now() > ttl;"
query = "SELECT value FROM cache WHERE key = :key;"
query = "SELECT value FROM cache WHERE key = %s;"
with self.client.connect() as conn:
conn.execute(purge)
result = conn.execute(query, dict(key=key))
result = conn.execute(query, (key,))
if result.rowcount > 0:
value = result.fetchone()['value']
return json.loads(value)

def delete(self, key):
query = "DELETE FROM cache WHERE key = :key"
query = "DELETE FROM cache WHERE key = %s"
with self.client.connect() as conn:
conn.execute(query, dict(key=key))
conn.execute(query, (key,))


def load_from_config(config):
Expand Down
50 changes: 24 additions & 26 deletions cliquet/permission/postgresql/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ def initialize_schema(self):
# Create schema
here = os.path.abspath(os.path.dirname(__file__))
schema = open(os.path.join(here, 'schema.sql')).read()
# Since called outside request, force commit.
with self.client.connect(force_commit=True) as conn:
with self.client.connect() as conn:
conn.execute(schema)
logger.info('Created PostgreSQL permission tables')

Expand All @@ -73,37 +72,36 @@ def flush(self):
DELETE FROM user_principals;
DELETE FROM access_control_entries;
"""
# Since called outside request (e.g. tests), force commit.
with self.client.connect(force_commit=True) as conn:
with self.client.connect() as conn:
conn.execute(query)
logger.debug('Flushed PostgreSQL permission tables')

def add_user_principal(self, user_id, principal):
query = """
INSERT INTO user_principals (user_id, principal)
SELECT :user_id, :principal
SELECT %(user_id)s, %(principal)s
WHERE NOT EXISTS (
SELECT principal
FROM user_principals
WHERE user_id = :user_id
AND principal = :principal
WHERE user_id = %(user_id)s
AND principal = %(principal)s
);"""
with self.client.connect() as conn:
conn.execute(query, dict(user_id=user_id, principal=principal))

def remove_user_principal(self, user_id, principal):
query = """
DELETE FROM user_principals
WHERE user_id = :user_id
AND principal = :principal;"""
WHERE user_id = %(user_id)s
AND principal = %(principal)s;"""
with self.client.connect() as conn:
conn.execute(query, dict(user_id=user_id, principal=principal))

def user_principals(self, user_id):
query = """
SELECT principal
FROM user_principals
WHERE user_id = :user_id;"""
WHERE user_id = %(user_id)s;"""
with self.client.connect() as conn:
result = conn.execute(query, dict(user_id=user_id))
results = result.fetchall()
Expand All @@ -112,13 +110,13 @@ def user_principals(self, user_id):
def add_principal_to_ace(self, object_id, permission, principal):
query = """
INSERT INTO access_control_entries (object_id, permission, principal)
SELECT :object_id, :permission, :principal
SELECT %(object_id)s, %(permission)s, %(principal)s
WHERE NOT EXISTS (
SELECT principal
FROM access_control_entries
WHERE object_id = :object_id
AND permission = :permission
AND principal = :principal
WHERE object_id = %(object_id)s
AND permission = %(permission)s
AND principal = %(principal)s
);"""
with self.client.connect() as conn:
conn.execute(query, dict(object_id=object_id,
Expand All @@ -128,9 +126,9 @@ def add_principal_to_ace(self, object_id, permission, principal):
def remove_principal_from_ace(self, object_id, permission, principal):
query = """
DELETE FROM access_control_entries
WHERE object_id = :object_id
AND permission = :permission
AND principal = :principal;"""
WHERE object_id = %(object_id)s
AND permission = %(permission)s
AND principal = %(principal)s;"""
with self.client.connect() as conn:
conn.execute(query, dict(object_id=object_id,
permission=permission,
Expand All @@ -140,8 +138,8 @@ def object_permission_principals(self, object_id, permission):
query = """
SELECT principal
FROM access_control_entries
WHERE object_id = :object_id
AND permission = :permission;"""
WHERE object_id = %(object_id)s
AND permission = %(permission)s;"""
with self.client.connect() as conn:
result = conn.execute(query, dict(object_id=object_id,
permission=permission))
Expand Down Expand Up @@ -254,12 +252,12 @@ def object_permissions(self, object_id, permissions=None):
query = """
SELECT permission, principal
FROM access_control_entries
WHERE object_id = :object_id"""
WHERE object_id = %(object_id)s"""

placeholders = dict(object_id=object_id)
if permissions is not None:
query += """
AND permission IN :permissions;"""
AND permission IN %(permissions)s;"""
placeholders["permissions"] = tuple(permissions)
with self.client.connect() as conn:
result = conn.execute(query, placeholders)
Expand All @@ -281,27 +279,27 @@ def replace_object_permissions(self, object_id, permissions):
specified_perms = []
for i, (perm, principals) in enumerate(permissions.items()):
placeholders['perm_%s' % i] = perm
specified_perms.append("(:perm_%s)" % i)
specified_perms.append("(%%(perm_%s)s)" % i)
for principal in principals:
j = len(new_perms)
placeholders['principal_%s' % j] = principal
new_perms.append("(:perm_%s, :principal_%s)" % (i, j))
new_perms.append("(%%(perm_%s)s, %%(principal_%s)s)" % (i, j))

delete_query = """
WITH specified_perms AS (
VALUES %(specified_perms)s
)
DELETE FROM access_control_entries
USING specified_perms
WHERE object_id = :object_id AND permission = column1
WHERE object_id = %%(object_id)s AND permission = column1
""" % dict(specified_perms=','.join(specified_perms))

insert_query = """
WITH new_aces AS (
VALUES %(new_perms)s
)
INSERT INTO access_control_entries(object_id, permission, principal)
SELECT :object_id, column1, column2
SELECT %%(object_id)s, column1, column2
FROM new_aces;
""" % dict(new_perms=','.join(new_perms))

Expand All @@ -315,7 +313,7 @@ def delete_object_permissions(self, *object_id_list):

query = """
DELETE FROM access_control_entries
WHERE object_id IN :object_id_list;"""
WHERE object_id IN %(object_id_list)s;"""
with self.client.connect() as conn:
conn.execute(query, dict(object_id_list=tuple(object_id_list)))

Expand Down
Loading

0 comments on commit 76b760a

Please sign in to comment.