使用netbeans定义的GUI在postgreSQL中调用位于“postgres.c”中的用户定义函数

我想在PostgreSQL-8.4.15中添加3个user_defined函数。 这里有3个function:

(1) start_create_profile();

(2) make_profile();

(3) check_anomaly();

所有这些都写在位于src / backend / tcop的文件“test.c”中。 我想从exec_simple_query()的中间调用(1)和(3 exec_simple_query()exec_simple_query()是PostgreSQL函数,它写在位于src / backend / tcop的“postgres.c”中。 我想直接通过我的GUI调用(2)。

这是我在“test.c”中编写的代码:

 #include "postgres.h" #ifndef PROGPROFILE_H_ #define PROGPROFILE_H_ /* interfaces */ extern void start_create_profile(List *querytree_list); extern void create_profile(); extern void check_anomaly(List *querytree_list); #endif /* Test ProgProf */ void start_create_profile(List *querytree_list){ ListCell *l; ListCell *tl; FILE *f; //if the file exist just open and write //else create and write f = fopen ("QueryParsed.txt", "a+"); Query *query_idr = (Query *)linitial(querytree_list); // CMD_SELECT=0 CMD_INSERT=1 CMD_UPDATE=2 switch (query_idr->commandType) { case CMD_SELECT: fputs("CMD_SELECT, ", f); break; case CMD_INSERT: fputs("CMD_INSERT, ", f); break; case CMD_UPDATE: fputs("CMD_UPDATE, ", f); break; default: break; } //to have the ID of the table foreach(l, query_idr->rtable){ Oid tab_idT = ((RangeTblEntry *) lfirst(l)) ->relid; //char temp1[10]; char *tab_idTConverted = itoa(tab_idT); /* This is not a table */ if (tab_idT == 0) continue; fputs(" tab_id: , ", f); fputs(tab_idTConverted, f); } //to have the name of the targer list foreach(tl, query_idr->targetList){ TargetEntry *tle = (TargetEntry *) lfirst(tl); Oid tab_id = tle->resorigtbl; int tab_idCast=(int)tab_id; //char temp[10]; char *tab_idConverted = itoa(tab_idCast); char *resname=tle->resname; fputs("Name of column: ", f); fputs(resname, f); fputs(" ID: ", f); fputs(tab_idConverted, f); fputs("\n", f); } //close the file that we write fputs("$", f); fclose (f); } void create_profile(){ } void check_anomaly(List *querytree_list){ } 

现在我创建了一个非常简单的GUI,包括3个按钮(通过java中的netbeans)。 Button1,button2,button3按顺序对应start_create_profile() ,make_profile, check_anomaly()

我想使用一个全局变量(让我们考虑“按钮”,可以设置为3个不同的值,如0,1,2。我希望每当我按下button1或button3时全局变量设置为1或2,以便使用我在exec_simple_query()编写的“if”。这里是“if”

 //initially button=0; //inside exec_simple_query if(button==1) start_create_profile(); if(button==2) check_anomaly; 

每当我按下按钮2时,必须直接调用函数(2)。 任何想法我如何设置该变量,使我能够使用我的GUI选择这3个function之一? 如何通过我的GUI直接调用函数(2)?

这里有几个问题。

你不能只从SQL调用任何C函数

首先,你不能只从SQL调用任意函数,你必须使用PostgreSQL的C扩展API和宏; 查看示例源中SQL可调用函数的现有实现。

您通常不必修改核心代码,扩展通常就足够了

其次,如果要向PostgreSQL核心添加函数,必须将它们添加到src/include/catalog/pg_proc.h以便在initdb期间定义initdb

但是,使用适当的扩展加载设备要好得多:

这样你就可以LOAD扩展模块,根据文档CREATE FUNCTION C函数,然后从SQL调用它们。

在你的具体情况下,你看起来确实需要修改核心代码库,但这很不寻常,所以我会为其他人保留这个建议。

PostgreSQL后端的AC函数不能从GUI“直接”调用

你有一个Java Swing GUI,你可以设想在不同的进程中调用C函数,甚至可能在不同的主机上调用它。

这不会出于多种原因,包括:

  • 如果没有像JNIJNA这样的粘合代码,Java就无法直接调用C函数。
  • 不可能直接在不同的进程中调用C函数; 您必须使用进程间通信(共享内存,管道,套接字,共享文件等)来交换信息
  • 虽然您可以在Pg后端嵌入Java解释器并通过JNI直接调用C函数,但您真的不想尝试直接从Pg后端内部显示Swing GUI。

您需要的是一个多阶段过程:

  • 收集您希望在PostgreSQL后端捕获的数据。 如果您打算从它在其中创建的同一连接访问它,则可以使用普通的palloc缓冲区。 否则,您将需要从共享内存中分配缓冲区或使用文件系统交换数据。

  • 根据PostgreSQL的C扩展函数文档(上面)访问使用SQL可调用接口创建的C函数中的数据

  • 使用PostgreSQL连接将数据从SQL可调用接口函数传输到Java应用程序。 在您的应用程序中解码它并根据需要显示它。

交替:

  • 要求您的Java程序或其代理程序在与PostgreSQL服务器相同的系统上运行,并让代理程序将文件写入可写入Pg且可由程序读取的位置。

  • 使用您的程序或其代理读取文件并处理它们以供显示

你甚至可以让Pg写入你的程序正在监听的套接字,但我不建议这样做,因为程序中的停顿会导致PostgreSQL中的性能问题。