呼叫位​​于&QUOT一个用户定义的功能; postgres.c"在PostgreSQL利用NetBeans的定义一个GUI [英] Calling a user-defined function located in "postgres.c" in postgreSQL using a GUI defined by netbeans

查看:109
本文介绍了呼叫位​​于&QUOT一个用户定义的功能; postgres.c"在PostgreSQL利用NetBeans的定义一个GUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想3 USER_DEFINED函数添加到PostgreSQL-8.4.15。这里有3个功能:

I' trying to add 3 user_defined function to the PostgreSQL-8.4.15. Here are 3 functions:

(1) start_create_profile();

(2) make_profile();

(3) check_anomaly();

所有这些都写在放在src /后端/ TCOP文件test.c的。我想打电话给(1)和(3)从 exec_simple_query中间() exec_simple_query()是写在放在src /后端/ TCOPpostgres.cPostgreSQL的功能。我想打电话给(2)直接通过我的GUI。

All of them are written in file "test.c" located in src/backend/tcop. I want to call (1) and (3) from the middle of exec_simple_query(). exec_simple_query() is PostgreSQL function that is written in "postgres.c" located in src/backend/tcop. I want to call (2) directly through my GUI.

下面是写在test.c的我的code:

here is the my code written in "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){

}

现在我已经创建了一个非常简单的图形用户界面,包括3个按钮(由NetBeans的在Java)。按钮1,按钮2,按钮3按对应为 start_create_profile(),make_profile, check_anomaly()

Now I've created a very simple GUI including 3 buttons(by netbeans in java). Button1, button2, button3 corresponding by order to start_create_profile(), make_profile, check_anomaly().

我想用一个全局变量(让我们考虑的按钮,可以设置3个不同的值如0,1,2,我想​​,每当我推按钮1或按钮3全局变量成为设定为1或2为了如果使用,我已经写在 exec_simple_query()。这里是如果

I want to use a global variable(Let's consider "button" that can be set to 3 different values like 0, 1, 2. I want that whenever I push the button1 or button3 the global variable become set to 1 or 2 in order to use "if" that I've written in exec_simple_query(). here is "if"

//initially button=0;
//inside exec_simple_query

if(button==1) start_create_profile();
if(button==2) check_anomaly;

,每当我推按钮2,功能(2)必须直接调用。
任何想法,我怎么有设置该变量,使我能够选择使用我的GUI的3个功能之一?我怎么有直接通过我的GUI ??

and whenever I push the button2, the function(2) has to be called directly. Any idea how do I have to set that variable to make me able choosing one of those 3 function using my GUI?? How do I have to call the function(2) directly through my GUI??

推荐答案

这里有几个问题。

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

First, you can't just call arbitrary functions from SQL, you must use PostgreSQL's C extension APIs and macros; look at the existing implementations of SQL-callable functions in the sources for examples.

第二,如果你想要的功能添加到PostgreSQL核心,必须将它们添加到的src /包括/目录/ pg_proc.h 所以,他们在<定义code>在initdb 。

Second, if you want to add functions to the core PostgreSQL, you must add them to src/include/catalog/pg_proc.h so they're defined during initdb.

这是更好的,但是,要使用适当延长装载设备:

It's much better, however, to use the proper extension loading facilities:

  • http://www.postgresql.org/docs/current/static/xfunc-c.html
  • http://www.postgresql.org/docs/current/static/extend-pgxs.html

这种方式可以 LOAD 扩展模块, CREATE FUNCTION C函数按照该文档,和呼叫他们从SQL。

This way you can LOAD an extension module, CREATE FUNCTION the C functions as per the docs, and call them from SQL.

在您的具体情况下,它看起来像你的的需要修改的核心codeBase的,但是这是相当不寻常的,所以我preserving对他人建议。

In your specific case it looks like you do need to modify the core codebase, but this is quite unusual, so I'm preserving this advice for others.

您有一个Java Swing的GUI和你预想莫名其妙地调用C函数在不同的进程,甚至可能在不同的主机上,从之。

You have a Java Swing GUI and you envision somehow calling a C function in a different process, possibly even on a different host, from it.

这将不是一堆工作的原因,其中包括:

This won't work for a bunch of reasons, including:


  • 的Java不能直接调用C函数无胶code像 JNI JNA

  • 这是不可能的调用直接不同进程的C函数;您必须改用进程间通信(共享内存,管道,套接字,共享文件等),以交换信息

  • 虽然你可以嵌入在PG后端一个Java跨preTER并通过JNI样,直接的,调用C函数,你的真正的不想尝试显示一个Swing GUI从PG后端内直接。

  • Java can't directly call C functions without glue code like JNI or JNA.
  • It is not possible to call a C function in a different process directly; you must instead use inter-process communication (shared memory, pipes, sockets, shared files, etc) to exchange information
  • While you could embed a Java interpreter in the Pg backend and call the C function via JNI kind-of-directly, you really don't want to try to display a Swing GUI directly from inside a Pg backend.

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

What you need is a multi-stage process:


  • 收集要在PostgreSQL后端捕捉数据。如果您打算从相同的连接访问它,它的创造,你可以用普通的的palloc 'D缓冲区。否则,你将需要分配一个缓冲区出使用文件系统共享内存或交换数据。

  • Collect the data you wish to capture in the PostgreSQL backend. If you intend to access it from the same connection that it's created in you can use an ordinary palloc'd buffer. Otherwise you will need to allocate a buffer out of shared memory or exchange data using the file system.

访问,从C函数已与一个SQL调用接口按照PostgreSQL的C扩展函数文档创建的数据(上图)

Access that data from a C function that has been created with an SQL-callable interface as per PostgreSQL's C extension function documentation (above)

使用PostgreSQL的连接,从SQL调用的接口函数将数据传送到你的Java应用程序。德code在你的应用程序,并根据需要显示它。

Use a PostgreSQL connection to transfer the data from your SQL-callable interface function to your Java application. Decode it in your application and display it as desired.

或者


  • 要求您的Java程序,或它的代理人,在同一系统PostgreSQL服务器上运行,并有代理的位置写为PG和读取你的程序写入文件。

  • Require that your Java program, or an agent for it, run on the same system as the PostgreSQL server and have the agent write files in a location writable to Pg and readable by your program.

使用你的程序或者其代理人阅读文件,并处理它们显示

Read the files using your program or its agent and process them for display

您甚至可以有PG写入套接字程序正在监听,但我不建议这是在你的程序会导致PostgreSQL中的性能问题一档。

You could even have Pg write to a socket your program is listening on, but I don't recommend this as a stall in your program would cause performance problems in PostgreSQL.

这篇关于呼叫位​​于&QUOT一个用户定义的功能; postgres.c&QUOT;在PostgreSQL利用NetBeans的定义一个GUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆