Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pgsql数据库多schema支持问题 #544

Open
ZhouSiliang opened this issue Jun 4, 2024 · 0 comments
Open

pgsql数据库多schema支持问题 #544

ZhouSiliang opened this issue Jun 4, 2024 · 0 comments

Comments

@ZhouSiliang
Copy link

ZhouSiliang commented Jun 4, 2024

根据文档所述,在使用pgsql之前需要导入/db/connector/pgsql.sql文件(postgres12以上版本,则使用 /db/connector/pgsql12.sql),查看源码后发现存在以a_schema_name+a_table_name双参数获取表数据的table_msg函数,以及重载后单入参a_table_name的table_msg函数。
但是重载后单入参a_table_name的table_msg函数只获取public模式下的表数据。但查看/db/connector/Pgsql.php源代码第63行
$sql = 'select fields_name as "field",fields_type as "type",fields_not_null as "null",fields_key_name as "key",fields_default as "default",fields_default as "extra" from table_msg(\'' . $tableName . '\');';
发现该处仅使用了单入参a_table_name的table_msg函数进行获取,top-think/think-orm是否可以针对pgsql支持schema多模式。
因为top-think/think-orm仅支持public单模式,如果强行使用多模式,会导致无法获取非public模式表数据,以及无法更改表数据等问题,我尝试将pgsql.sql文件里的单入参table_msg函数:

---重载一个函数
CREATE OR REPLACE FUNCTION "public"."table_msg" (a_table_name varchar) RETURNS SETOF "public"."tablestruct" AS
$body$
DECLARE
    v_ret tablestruct;
BEGIN
    FOR v_ret IN SELECT * FROM table_msg('public',a_table_name) LOOP
        RETURN NEXT v_ret;
    END LOOP;
    RETURN;
END;
$body$
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

COMMENT ON FUNCTION "public"."table_msg"(a_table_name varchar)
IS '获得表信息';

修改为:

---重载一个函数
CREATE OR REPLACE FUNCTION "public"."table_msg" (a_table_name varchar) RETURNS SETOF "public"."tablestruct" AS
$body$
DECLARE
    v_ret tablestruct;
    v_schema varchar;
    v_table varchar;
BEGIN
    IF position('.' IN a_table_name) > 0 THEN
        v_schema := split_part(a_table_name, '.', 1);
        v_table := split_part(a_table_name, '.', 2);
    ELSE
        v_schema := 'public'; -- 默认模式为 public
        v_table := a_table_name;
    END IF;

    FOR v_ret IN SELECT * FROM table_msg(v_schema,v_table) LOOP
        RETURN NEXT v_ret;
    END LOOP;
    RETURN;
END;
$body$
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

COMMENT ON FUNCTION "public"."table_msg"(a_table_name varchar)
IS '获得表信息';

上述改动将支持多schema方案,当需要使用多schema,可以将Model的表名进行调整:
protected $name = 'schema.表名';
如果不进行改动,仍然默认为public模式

@ZhouSiliang ZhouSiliang changed the title pgsql数据库多scheme支持问题 pgsql数据库多schema支持问题 Jul 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants