麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 數據庫 > PostgreSQL > 正文

PostgreSQL7.0手冊-接口-50. 函數 51. 大對象

2019-09-08 23:34:15
字體:
來源:轉載
供稿:網友
第五十章. 函數
用戶可調用的函數的參考.
注意:本節需要人來寫.愿當支援者嗎?


第五十一章. 大對象
內容 
歷史信息 
實現的特點 
接口 
內建的已注冊函數 
從 LIBPQ 里訪問大對象 
例子程序 
在 Postgres 里,記錄存儲在數據頁面里并且單個記錄里的數據大小不能超過數據頁面的大小.因為數據頁面大小是 8192 字節,所以數據值的大小是相當小的.為了存儲更大的不可分割數值(原子數值),Postgres 提供了大對象接口.這個接口給用戶提供對定義為大對象的用戶數據的面向文件的接口.本節描述 Postgres 大對象數據的實現,編程和查詢語言接口. 
歷史信息
最初,Postgres 4.2 支持三種大對象的標準實現:作為 Postgres 的文件擴展,作為由 Postgres 管理的 UNIX 文件,以及作為存儲在 Postgres 數據庫里面的數據.這樣做容易導致用戶的迷惑.結果是,我們只支持把大對象作為數據存儲在Postgres 數據庫里,即使這樣做令數據訪問變得有些慢,但卻保證了更嚴格的數據完整性.由于歷史原因,這種存儲機制被稱為倒轉大對象.(我們將在本章中交互使用倒轉和大對象來表示同一個意思)。
--------------------------------------------------------------------------------

實現的特點
倒轉大對象把大對象分解成"塊" ("chunks"),然后把塊存放在數據庫記錄里面.在隨機讀寫時使用一個B-tree 索引保證對正確的塊(chunk)號的檢索.

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

接口
Postgres 提供的用于訪問大對象的機制,包括作為用戶定義函數的后端的一部分或者作為使用接口的前端應用的一部分,都在下面描述.對于熟悉 Postgres 4.2 的用戶,PostgreSQL 有一套新的函數提供更連貫的接口. 
注意:所有大對象的操作都必須在一個SQL事務里實現。這在 Postgres v6.5 里有嚴格的要求,盡管在以前的版本里就隱含這樣的要求,如果忽略這一點會導致錯誤的表現。
Postgres 大對象接口是對 UNIX 文件系統的模仿,有仿真的 open(2),read(2),write(2),lseek(2),等.用戶函數調用這些路徑從一個大對象中檢索她們感興趣的數據.例如,如果一個名為 mugshot 的大對象類型存在,在其中保存面孔的圖象,那么可以在 mugshot 數據上定義一個叫 beard (胡子)的函數.Beard (胡子函數)會檢查圖片的下三分之一區域,并且如果存在胡子的話判斷胡子的顏色.整個大對象的值不需要被 brard 函數緩存起來或者甚至是作些檢查.大對象可以從動態裝載的 C 函數或者是鏈接該庫的數據庫客戶程序訪問.Postgres 提供一套過程支持對大對象的打開,讀,寫,關閉和搜索。 
創建大對象
過程 
Oid lo_creat(PGconn *conn, int mode)
創建一個新的大對象.mode 是一個位掩碼,描述新對象的不同屬性.這里列出的符號常量在 $PGROOT/src/backend/libpq/libpq-fs.h.訪問類型(讀,寫或者兩者)是對位 INV_READ 和 INV_WRITE進行 OR (或)操作構成的.如果大對象應被歸檔--也就是說,如果因歷史原因它應該被周期地移到一個特殊的歸檔關系(表)中--那么就要設置 INV_ARCHIVE 位.掩碼的低十六位是大對象要存放于內的存儲管理器號.對于除 Berkeley (伯克利)以外的節點,這些位都應總是零.下面的命令創建一個(倒轉的)大對象: 
inv_oid = lo_creat(INV_READ|INV_WRITE|INV_ARCHIVE);
輸入大對象
要把一個 UNIX 文件輸入成為大對象,調用 
Oid lo_import(PGconn *conn, const char *filename)
filename 參數指明要被輸入成為大對象的 UNIX 文件路徑名. 
輸出大對象
要把一個大對象輸出為 UNIX 文件,調用 
int lo_export(PGconn *conn, Oid lobjId, const char *filename)
lobjId 參數指明要輸出的大對象 Oid,filename 參數指明 UNIX 文件的路徑名.
打開一個現有的大對象
要打開一個現存的大對象,調用 
int lo_open(PGconn *conn, Oid lobjId, int mode)
參數 lobjId 指明要打開的大對象的 Oid (對象標識).mode 位控制該對象是用于讀(INV_READ),寫還是讀寫.一個大對象在其創建之前不能被打開.lo_open 返回一個大對象標識用于以后的 lo_read,lo_write,lo_lseek,lo_tell,and lo_close。
向大對象中寫數據
過程 
int lo_write(PGconn *conn, int fd, const char *buf, size_t len)
從 buf 中向大對象 fd 中寫 len 字節.參數 fd 必須是前面一個 lo_open 的返回.返回實際寫的字節數.出錯時返回負數.
從大對象中讀取數據
過程 
int lo_read(PGconn *conn, int fd, char *buf, size_t len)
從大對象中讀取 len 字節數據到 buf 中。fd 參數必須是前面的一個 lo_open 調用的返回。返回實際讀取的字節數。出錯時,返回一個負數。
對大對象中數據的查找
要改變當前大對象的讀或寫位置,調用 
int lo_lseek(PGconn *conn, int fd, int offset, int whence)
這個過程把當前 fd 代表的大對象位置指針移動到 offset 指明的新的位置.參數 whence 的合法的取值是 SEEK_SET SEEK_CUR 和 SEEK_END.
關閉一個大對象描述符
可以通過調用 
int lo_close(PGconn *conn, int fd)
關閉一個大對象,這里 fd 是 lo_open 返回的大對象的描述符.成功時,lo_close 返回零.錯誤時,返回值是負數.

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

內建的已注冊函數
有兩個內建的已注冊函數,lo_import 和 lo_export 可以很方便的在 SQL 查詢里面使用.下面是一些例子 
CREATE TABLE image (
    name            text,
    raster          oid
);

INSERT INTO image (name, raster)
    VALUES ('beautiful image', lo_import('/etc/motd'));

SELECT lo_export(image.raster, '/tmp/motd') from image
    WHERE name = 'beautiful image';

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

通過 LIBPQ 訪問大對象
下面是一個例子程序,顯示如何使用 LIBPQ 里大對象接口的.程序的一部分是注釋掉的,但仍然保留在源碼里面供讀者參考.這個程序可以在 ../src/test/examples 里找到.使用 LIBPQ 里大對象接口的前端應用應該包括頭文件libpq/libpq-fs.h 并且聯接 libpq 庫.

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

例子程序
/*--------------------------------------------------------------
 *
 * testlo.c--
 *    test using large objects with libpq
 *
 * Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *    /usr/local/devel/pglite/cvs/src/doc/manual.me,v 1.16 1995/09/01 23:55:00 jolly Exp
 *
 *--------------------------------------------------------------
 */
#include 
#include "libpq-fe.h"
#include "libpq/libpq-fs.h"

#define BUFSIZE          1024

/*
 * importFile *    import file "in_filename" into database as large object "lobjOid"
 *
 */
Oid importFile(PGconn *conn, char *filename)
{
    Oid lobjId;
    int lobj_fd;
    char buf[BUFSIZE];
    int nbytes, tmp;
    int fd;

    /*
     * open the file to be read in
     */
    fd = open(filename, O_RDONLY, 0666);
    if (fd < 0)  {   /* error */
     fprintf(stderr, "can't open unix file %s/n", filename);
    }

    /*
     * create the large object
     */
    lobjId = lo_creat(conn, INV_READ|INV_WRITE);
    if (lobjId == 0) {
     fprintf(stderr, "can't create large object/n");
    }

    lobj_fd = lo_open(conn, lobjId, INV_WRITE);
    /*
     * read in from the Unix file and write to the inversion file
     */
    while ((nbytes = read(fd, buf, BUFSIZE)) > 0) {
     tmp = lo_write(conn, lobj_fd, buf, nbytes);
     if (tmp < nbytes) {
         fprintf(stderr, "error while reading large object/n");
     }
    }

    (void) close(fd);
    (void) lo_close(conn, lobj_fd);

    return lobjId;
}

void pickout(PGconn *conn, Oid lobjId, int start, int len)
{
    int lobj_fd;
    char* buf;
    int nbytes;
    int nread;

    lobj_fd = lo_open(conn, lobjId, INV_READ);
    if (lobj_fd < 0) {
     fprintf(stderr,"can't open large object %d/n",
          lobjId);
    }

    lo_lseek(conn, lobj_fd, start, SEEK_SET);
    buf = malloc(len+1);

    nread = 0;
    while (len - nread > 0) {
     nbytes = lo_read(conn, lobj_fd, buf, len - nread);
     buf[nbytes] = ' ';
     fprintf(stderr,">>> %s", buf);
     nread += nbytes;
    }
    fprintf(stderr,"/n");
    lo_close(conn, lobj_fd);
}

void overwrite(PGconn *conn, Oid lobjId, int start, int len)
{
    int lobj_fd;
    char* buf;
    int nbytes;
    int nwritten;
    int i;

    lobj_fd = lo_open(conn, lobjId, INV_READ);
    if (lobj_fd < 0) {
     fprintf(stderr,"can't open large object %d/n",
          lobjId);
    }

    lo_lseek(conn, lobj_fd, start, SEEK_SET);
    buf = malloc(len+1);

    for (i=0;i     buf = 'X';
    buf = ' ';

    nwritten = 0;
    while (len - nwritten > 0) {
     nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
     nwritten += nbytes;
    }
    fprintf(stderr,"/n");
    lo_close(conn, lobj_fd);
}

/*
 * exportFile *    export large object "lobjOid" to file "out_filename"
 *
 */
void exportFile(PGconn *conn, Oid lobjId, char *filename)
{
    int lobj_fd;
    char buf[BUFSIZE];
    int nbytes, tmp;
    int fd;

    /*
     * create an inversion "object"
     */
    lobj_fd = lo_open(conn, lobjId, INV_READ);
    if (lobj_fd < 0) {
     fprintf(stderr,"can't open large object %d/n",
          lobjId);
    }

    /*
     * open the file to be written to
     */
    fd = open(filename, O_CREAT|O_WRONLY, 0666);
    if (fd < 0)  {   /* error */
     fprintf(stderr, "can't open unix file %s/n",
          filename);
    }

    /*
     * read in from the Unix file and write to the inversion file
     */
    while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0) {
     tmp = write(fd, buf, nbytes);
        if (tmp < nbytes) {
         fprintf(stderr,"error while writing %s/n",
              filename);
     }
    }

    (void) lo_close(conn, lobj_fd);
    (void) close(fd);

    return;
}

void
exit_nicely(PGconn* conn)
{
  PQfinish(conn);
  exit(1);
}

int
main(int argc, char **argv)
{
    char *in_filename, *out_filename;
    char *database;
    Oid lobjOid;
    PGconn *conn;
    PGresult *res;

    if (argc != 4) {
     fprintf(stderr, "Usage: %s database_name in_filename out_filename/n",
          argv[0]);
     exit(1);
    }

    database = argv[1];
    in_filename = argv[2];
    out_filename = argv[3];

    /*
     * set up the connection
     */
    conn = PQsetdb(NULL, NULL, NULL, NULL, database);

    /* check to see that the backend connection was successfully made */
    if (PQstatus(conn) == CONNECTION_BAD) {
     fprintf(stderr,"Connection to database '%s' failed./n", database);
     fprintf(stderr,"%s",PQerrorMessage(conn));
     exit_nicely(conn);
    }

    res = PQexec(conn, "begin");
    PQclear(res);

    printf("importing file %s/n", in_filename);
/*  lobjOid = importFile(conn, in_filename); */
    lobjOid = lo_import(conn, in_filename);
/*
    printf("as large object %d./n", lobjOid);

    printf("picking out bytes 1000-2000 of the large object/n");
    pickout(conn, lobjOid, 1000, 1000);

    printf("overwriting bytes 1000-2000 of the large object with X's/n");
    overwrite(conn, lobjOid, 1000, 1000);
*/

    printf("exporting large object to file %s/n", out_filename);
/*    exportFile(conn, lobjOid, out_filename); */
    lo_export(conn, lobjOid,out_filename);

    res = PQexec(conn, "end");
    PQclear(res);
    PQfinish(conn);
    exit(0);
}

------------------------------------------------------------------------------
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 午夜在线观看视频网站 | 精品小视频 | 久久成人免费观看 | 色人阁五月天 | 欧美一级黑人 | 黄色成人短视频 | 亚洲日韩中文字幕一区 | 国产亚色 | 免费人成在线播放 | 日本一区二区在线看 | 亚洲免费观看视频 | 欧美色视| 性感美女一级毛片 | 一夜新娘第三季免费观看 | 久久精品久久久久 | 日韩美香港a一级毛片 | 成人在线视频免费观看 | 最新av网址在线观看 | 欧美日韩免费在线观看视频 | 欧美性生视频 | 精品一区二区三区免费爱 | 国产99视频精品免视看9 | 中国字幕av| 精品亚洲一区二区三区 | 久久精品re | 久久亚洲精选 | 一区二区三区在线视频观看58 | 高清国产午夜精品久久久久久 | 毛片在线看免费 | 中文字幕欧美亚洲 | 羞羞的小视频 | 99精彩视频在线观看 | 国产91丝袜在线播放 | 激情在线观看视频 | 2019天天干夜夜操 | 国产片91 | 成码无人av片在线观看网站 | 在线 日本 制服 中文 欧美 | 国产一级免费不卡 | 国产人成精品一区二区三 | 最新中文字幕日本 |