【问题标题】:PL/PgSQL - temporarily store extra informationPL/PgSQL - 临时存储额外信息
【发布时间】:2013-09-16 14:32:26
【问题描述】:

我将权限数据存储在数据库中,将会话数据存储在内存/文件系统中。我将每个用户的权限处理形式存储在会话数据中。我想在数据库中更改用户权限后刷新该权限缓存。由于角色权限、用户额外权限和权限详细信息的更改,用户权限可能会发生变化。所以有很多存储过程会导致用户权限的改变。我可以收集该用户的列表,但我应该如何将其发回? (我已经使用返回值发回记录等...)

回答我不确定您到底在问什么:我应该如何将其寄回?请澄清并添加一个代码示例(即使它不起作用)。"

我将会话数据存储在内存或文件系统中,并将用户权限存储在数据库中。授权逻辑非常复杂,因此通过成功的身份验证,我收集用户拥有的每个权限,使用自定义解析器对其进行解析,并将结果作为缓存保存到会话中。之后,我通过权限检查使用该缓存。问题是通过权限更改、角色更改、角色权限更改、角色成员资格更改等...我必须更新会话中的权限缓存。

带有 REST 接口的简化版本:

POST /sessions {email: "", password: ""}
 -> {token: "qwerty", user: {id: 123}}
 -> sessionStore.create("qwerty", {user: {id: 123}, permissions: "abcd"}) 
POST /roles {name: "administrator", permissions: "efgh"}
 -> {id: 567}
POST /roleMmembership {user: {id: 123}, role: {id: 567}}
 -> {id: 890}
 -> sessionStore.update("qwerty", {user: {id: 123}, permissions: "abcdefgh"}) 

正如您所见,在我将用户 123 添加到角色 567 后,会话已更新,并且权限“efgh”已添加到会话权限缓存中。在数据库级别,新成员调用添加成员的存储过程,并返回 id。我可以在此过程中看到哪个用户有权限更改,但我无法发回该信息,因为存储过程只能有一个返回值。使用 notify 发送该信息是一个好主意,因为它应该更像一个事件而不是返回值。可悲的是,在我的数据库驱动程序中,不支持通知,我不想更改驱动程序......所以我需要一个解决方法。它可能是多个返回值、全局变量等...我认为使用临时表是唯一可能的解决方案,但我对 postgres 没有太多经验...

【问题讨论】:

  • 你试过LISTENNOTIFY吗?
  • 我不确定驱动程序是否支持。它是 php 5.3 PDO pgsql 驱动程序。
  • 如果没有,您可以尝试使用其他驱动程序/语言创建一个小型“侦听器”应用程序,以通知您的主应用程序。或者使用 PL/PHP、PL/Python、PL/V8 或任何其他语言在 DB 中编写存储过程来向您的应用发送消息。
  • 目前的项目很遗憾我没有这些选项。顺便说一句,这是个好主意。我想我会尝试临时表。
  • 我不确定你到底在问什么:How should I send it back?。请澄清并添加一个代码示例(即使它不起作用)。

标签: php postgresql pdo plpgsql postgresql-8.4


【解决方案1】:

1.)

LISTEN 和 NOTIFY 将是最好的解决方案,但遗憾的是我的驱动程序(php pdo 驱动程序)不支持,而且我认为它永远不会支持,因为这是 postgres 特有的功能。

2.)

我认为我的驱动程序是使用临时表的唯一选择。我为此创建了以下函数:

初始化

CREATE FUNCTION policy_change_provide_store ()
  RETURNS VOID
AS
  $BODY$
  BEGIN
    CREATE TEMPORARY TABLE policy_change (
      user_id INT4
    );
    EXCEPTION WHEN duplicate_table THEN
      RETURN;
  END;
$BODY$
LANGUAGE plpgsql VOLATILE;

更新

CREATE FUNCTION policy_change_update (
  IN user_ids INT4 []
)
  RETURNS VOID
AS
  $BODY$
  BEGIN
    PERFORM policy_change_provide_store();
    INSERT INTO policy_change
    SELECT inserted_user_id FROM unnest(user_ids) AS inserted_user_id
    WHERE NOT EXISTS(SELECT 1 FROM policy_change WHERE user_id = inserted_user_id);
  END;
  $BODY$
LANGUAGE plpgsql VOLATILE;

阅读

CREATE FUNCTION user_read_all_by_policy_change ()
  RETURNS TABLE (
  user_id INT4
  )
AS
  $BODY$
  BEGIN
    PERFORM policy_change_provide_store();
    RETURN QUERY
    SELECT policy_change.user_id FROM policy_change ORDER BY policy_change.user_id DESC;
  END;
  $BODY$
LANGUAGE plpgsql VOLATILE;

因此,我使用 policy_change_update(user_ids) 从我的 postgres 函数更新策略更改数据,并使用 user_read_all_by_policy_change() 从 http 服务器读取该数据。是的,这很丑陋,但效果很好。如果您有更好的解决方案,请告诉我!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-10
    • 2013-05-29
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    相关资源
    最近更新 更多