1

PostgreSQL-8.4.15 に 3 つの user_defined 関数を追加しようとしています。ここに3つの機能があります:

(1)start_create_profile();

(2)make_profile();

(3)check_anomaly();

それらはすべて、src/backend/tcop にあるファイル「test.c」に書き込まれます。の途中から(1)と(3)を呼びたいexec_simple_query()exec_simple_query()src/backend/tcop にある「postgres.c」に記述されている PostgreSQL の関数です。(2) を GUI から直接呼び出したい。

「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 つのボタンを含む非常に単純な GUI を作成しました (Java の netbeans による)。、make_profile、、の順に対応するボタン1、ボタン2、start_create_profile()ボタン3 check_anomaly()

グローバル変数を使用したい (0、1、2 のような 3 つの異なる値に設定できる「ボタン」を考えてみましょう。button1 または button3 を押すたびにグローバル変数が 1 または 2 に設定されるようにしたい私が書いた「if」を使ってexec_simple_query()ください。

//initially button=0;
//inside exec_simple_query

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

そして、button2 を押すたびに、function(2) を直接呼び出す必要があります。GUI を使用してこれらの 3 つの関数のいずれかを選択できるようにするには、その変数をどのように設定する必要がありますか?? GUI から関数 (2) を直接呼び出すにはどうすればよいですか??

4

1 に答える 1

4

ここにはいくつかの問題があります。

SQL から C 関数だけを呼び出すことはできません

まず、SQL から任意の関数を呼び出すことはできません。PostgreSQL の C 拡張 API とマクロを使用する必要があります。例として、ソース内の SQL 呼び出し可能関数の既存の実装を見てください。

通常、コア コードを変更する必要はありません。多くの場合、拡張機能で十分です。

src/include/catalog/pg_proc.h第 2 に、コア PostgreSQL に関数を追加する場合は、.NET で定義されるように追加する必要がありますinitdb

ただし、適切な拡張機能の読み込み機能を使用する方がはるかに優れています。

このようにして、ドキュメントに従ってLOAD拡張モジュール、 C 関数を作成し、それらを SQL から呼び出すことができます。CREATE FUNCTION

あなたの特定のケースでは、コア コードベースを変更する必要があるように見えますが、これは非常に珍しいことなので、他の人のためにこのアドバイスを保持しています。

PostgreSQL バックエンドの AC 関数を GUI から「直接」呼び出すことができない

あなたは Java Swing GUI を持っていて、別のプロセスで C 関数を呼び出すことを思い描いています。

これは、次のような多くの理由で機能しません。

  • JNIJava は、またはのようなグルー コードなしでは C 関数を直接呼び出すことはできませんJNA
  • 別のプロセスで C 関数を直接呼び出すことはできません。代わりに、プロセス間通信 (共有メモリ、パイプ、ソケット、共有ファイルなど) を使用して情報を交換する必要があります。
  • Java インタープリターを Pg バックエンドに組み込み、JNI を介して直接 C 関数を呼び出すことはできますが、Pg バックエンド内から直接 Swing GUI を表示しようとするのは望ましくありません

必要なのは、多段階のプロセスです。

  • PostgreSQL バックエンドでキャプチャしたいデータを収集します。作成されたのと同じ接続からアクセスする場合は、通常pallocの 'd バッファーを使用できます。それ以外の場合は、共有メモリからバッファを割り当てるか、ファイル システムを使用してデータを交換する必要があります。

  • PostgreSQL の C 拡張関数のドキュメント (上記) に従って、SQL 呼び出し可能なインターフェイスで作成された C 関数からそのデータにアクセスします。

  • PostgreSQL 接続を使用して、SQL 呼び出し可能インターフェース関数から Java アプリケーションにデータを転送します。アプリケーションでデコードし、必要に応じて表示します。

別の方法:

  • Java プログラムまたはそのエージェントが PostgreSQL サーバーと同じシステムで実行され、エージェントが Pg に書き込み可能でプログラムが読み取り可能な場所にファイルを書き込むようにする必要があります。

  • プログラムまたはそのエージェントを使用してファイルを読み取り、表示用に処理します

プログラムがリッスンしているソケットに Pg を書き込むこともできますが、プログラムが停止すると PostgreSQL でパフォーマンスの問題が発生するため、これはお勧めしません。

于 2013-02-22T08:18:12.707 に答える