PostgreSQL之精妙的数据库导入导出工具架构 (三)
来源:互联网 发布:二进制转中文 Java 编辑:程序博客网 时间:2024/04/29 11:30
(三)导出文件的格式与函数指针的使用
海翔语:
本节所描述的,是很精妙的设计。利用函数指针,实现多种文件格式的方便定制。
1 文件格式
PostgreSQL提供四种导出文件格式,具体如下:
1)custom(pg_backup_custom.c):二进制格式的备份文件。有文件头、文件体;文件体是一个链表,各个可备份对象在这个链表上存在;每一个可备份对象都有一套统一的结构标识。支持压缩(压缩功能依赖于系统编译选项和pg_config.h文件中的宏定义开关)。
2)plain(pg_backup_null.c):文本文件格式,默认方式。备份的文件内容是SQL脚本。。
3)file(pg_backup_files.c):备份一个主文件和一些辅助文件;主文件方式类似于custom的文件格式,辅助文件是数据文件,每一个辅助文件对应备份对象中的一个表。
4)tar(pg_backup_tar.c):文件备份基本类似“file”方式,但是,最后备份的所有文件都要归档到一个tar文件中。文件最大大小为8GB(受限于tar file format)。
说明:对于file格式建议如下:
This format is for demonstration purposes; it is not intended for
normal use. Files will be written in the current working directory.
2 函数指针的使用
在pg_backup_archiver.h文件中,定义有大量的函数指针,如:
......
typedef void (*ClosePtr) (struct _archiveHandle * AH);
typedef void (*ReopenPtr) (struct _archiveHandle * AH);
typedef void (*ArchiveEntryPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
......
这些函数指针,被用到了如下文件中
2.1 文件->被调用的函数
pg_backup_custom.c->InitArchiveFmt_Custom(ArchiveHandle *AH)
pg_backup_null.c->InitArchiveFmt_Null(ArchiveHandle *AH)
pg_backup_files.c->InitArchiveFmt_Files(ArchiveHandle *AH)
pg_backup_tar.c->InitArchiveFmt_Tar(ArchiveHandle *AH)
2.2 具体实例
pg_backup_custom.c文件中有如下函数InitArchiveFmt_Custom:
/*
* Init routine required by ALL formats. This is a global routine
* and should be declared in pg_backup_archiver.h
*
* It's task is to create any extra archive context (using AH->formatData),
* and to initialize the supported function pointers.
*
* It should also prepare whatever it's input source is for reading/writing,
* and in the case of a read mode connection, it should load the Header & TOC.
*/
void
InitArchiveFmt_Custom(ArchiveHandle *AH)
{
lclContext *ctx;
/* Assuming static functions, this can be copied for each format. */
AH->ArchiveEntryPtr = _ArchiveEntry;
AH->StartDataPtr = _StartData;
AH->WriteDataPtr = _WriteData;
AH->EndDataPtr = _EndData;
AH->WriteBytePtr = _WriteByte;
AH->ReadBytePtr = _ReadByte;
AH->WriteBufPtr = _WriteBuf;
AH->ReadBufPtr = _ReadBuf;
AH->ClosePtr = _CloseArchive;
AH->ReopenPtr = _ReopenArchive;
AH->PrintTocDataPtr = _PrintTocData;
AH->ReadExtraTocPtr = _ReadExtraToc;
AH->WriteExtraTocPtr = _WriteExtraToc;
AH->PrintExtraTocPtr = _PrintExtraToc;
AH->StartBlobsPtr = _StartBlobs;
AH->StartBlobPtr = _StartBlob;
AH->EndBlobPtr = _EndBlob;
AH->EndBlobsPtr = _EndBlobs;
AH->ClonePtr = _Clone;
AH->DeClonePtr = _DeClone;
......
}
剖析:
在ArchiveHandle结构中,使用了大量的函数指针,目的,是为了在初始化不同文件格式函数中,可以调用各自的函数(有点其他语言中的“接口”的味道)。
在其他格式文件的所有函数指针指向的函数中,具体实现了不同格式所要求的函数功能(有点其他语言中的“继承”的味道)。
这样,在pg_dump.c中,只要根据用户指定的文件格式的参数,决定使用什么格式的文件即可,代码如下:
/* open the output file */
if (pg_strcasecmp(format, "a") == 0 || pg_strcasecmp(format, "append") == 0)
{
/* This is used by pg_dumpall, and is not documented */
plainText = 1;
g_fout = CreateArchive(filename, archNull, 0, archModeAppend);
}
else if (pg_strcasecmp(format, "c") == 0 || pg_strcasecmp(format, "custom") == 0)
g_fout = CreateArchive(filename, archCustom, compressLevel, archModeWrite);
else if (pg_strcasecmp(format, "f") == 0 || pg_strcasecmp(format, "file") == 0)
{
/*
* Dump files into the current directory; for demonstration only, not
* documented.
*/
g_fout = CreateArchive(filename, archFiles, compressLevel, archModeWrite);
}
else if (pg_strcasecmp(format, "p") == 0 || pg_strcasecmp(format, "plain") == 0)
{
plainText = 1;
g_fout = CreateArchive(filename, archNull, 0, archModeWrite);
}
else if (pg_strcasecmp(format, "t") == 0 || pg_strcasecmp(format, "tar") == 0)
g_fout = CreateArchive(filename, archTar, compressLevel, archModeWrite);
else
{
write_msg(NULL, "invalid output format \"%s\" specified\n", format);
exit(1);
}
InitArchiveFmt_Custom函数的调用关系图如下(dump文件格式调用关系.JPG):
根据调用关系,可以看出函数指针的初始化情况。
在具体的使用中,如:导出大对象,则可以调用函数指针,直接导出大对象,但实际调用的,是初始化时,根据具体文件格式、为函数指针赋值的本格式的函数。
如果想品味其精妙处,建议循着如下调用关系仔细看看不同格式的文件导出,是如何进行的?【dumpTableData->ArchiveEntry->_ArchiveEntry(pg_backup_custom.c,二进制格式,调用方式如:(*AH->ArchiveEntryPtr) (AH, newToc))】
海翔语:
本节所描述的,是很精妙的设计。利用函数指针,实现多种文件格式的方便定制。
1 文件格式
PostgreSQL提供四种导出文件格式,具体如下:
1)custom(pg_backup_custom.c):二进制格式的备份文件。有文件头、文件体;文件体是一个链表,各个可备份对象在这个链表上存在;每一个可备份对象都有一套统一的结构标识。支持压缩(压缩功能依赖于系统编译选项和pg_config.h文件中的宏定义开关)。
2)plain(pg_backup_null.c):文本文件格式,默认方式。备份的文件内容是SQL脚本。。
3)file(pg_backup_files.c):备份一个主文件和一些辅助文件;主文件方式类似于custom的文件格式,辅助文件是数据文件,每一个辅助文件对应备份对象中的一个表。
4)tar(pg_backup_tar.c):文件备份基本类似“file”方式,但是,最后备份的所有文件都要归档到一个tar文件中。文件最大大小为8GB(受限于tar file format)。
说明:对于file格式建议如下:
This format is for demonstration purposes; it is not intended for
normal use. Files will be written in the current working directory.
2 函数指针的使用
在pg_backup_archiver.h文件中,定义有大量的函数指针,如:
......
typedef void (*ClosePtr) (struct _archiveHandle * AH);
typedef void (*ReopenPtr) (struct _archiveHandle * AH);
typedef void (*ArchiveEntryPtr) (struct _archiveHandle * AH, struct _tocEntry * te);
......
这些函数指针,被用到了如下文件中
2.1 文件->被调用的函数
pg_backup_custom.c->InitArchiveFmt_Custom(ArchiveHandle *AH)
pg_backup_null.c->InitArchiveFmt_Null(ArchiveHandle *AH)
pg_backup_files.c->InitArchiveFmt_Files(ArchiveHandle *AH)
pg_backup_tar.c->InitArchiveFmt_Tar(ArchiveHandle *AH)
2.2 具体实例
pg_backup_custom.c文件中有如下函数InitArchiveFmt_Custom:
/*
* Init routine required by ALL formats. This is a global routine
* and should be declared in pg_backup_archiver.h
*
* It's task is to create any extra archive context (using AH->formatData),
* and to initialize the supported function pointers.
*
* It should also prepare whatever it's input source is for reading/writing,
* and in the case of a read mode connection, it should load the Header & TOC.
*/
void
InitArchiveFmt_Custom(ArchiveHandle *AH)
{
lclContext *ctx;
/* Assuming static functions, this can be copied for each format. */
AH->ArchiveEntryPtr = _ArchiveEntry;
AH->StartDataPtr = _StartData;
AH->WriteDataPtr = _WriteData;
AH->EndDataPtr = _EndData;
AH->WriteBytePtr = _WriteByte;
AH->ReadBytePtr = _ReadByte;
AH->WriteBufPtr = _WriteBuf;
AH->ReadBufPtr = _ReadBuf;
AH->ClosePtr = _CloseArchive;
AH->ReopenPtr = _ReopenArchive;
AH->PrintTocDataPtr = _PrintTocData;
AH->ReadExtraTocPtr = _ReadExtraToc;
AH->WriteExtraTocPtr = _WriteExtraToc;
AH->PrintExtraTocPtr = _PrintExtraToc;
AH->StartBlobsPtr = _StartBlobs;
AH->StartBlobPtr = _StartBlob;
AH->EndBlobPtr = _EndBlob;
AH->EndBlobsPtr = _EndBlobs;
AH->ClonePtr = _Clone;
AH->DeClonePtr = _DeClone;
......
}
剖析:
在ArchiveHandle结构中,使用了大量的函数指针,目的,是为了在初始化不同文件格式函数中,可以调用各自的函数(有点其他语言中的“接口”的味道)。
在其他格式文件的所有函数指针指向的函数中,具体实现了不同格式所要求的函数功能(有点其他语言中的“继承”的味道)。
这样,在pg_dump.c中,只要根据用户指定的文件格式的参数,决定使用什么格式的文件即可,代码如下:
/* open the output file */
if (pg_strcasecmp(format, "a") == 0 || pg_strcasecmp(format, "append") == 0)
{
/* This is used by pg_dumpall, and is not documented */
plainText = 1;
g_fout = CreateArchive(filename, archNull, 0, archModeAppend);
}
else if (pg_strcasecmp(format, "c") == 0 || pg_strcasecmp(format, "custom") == 0)
g_fout = CreateArchive(filename, archCustom, compressLevel, archModeWrite);
else if (pg_strcasecmp(format, "f") == 0 || pg_strcasecmp(format, "file") == 0)
{
/*
* Dump files into the current directory; for demonstration only, not
* documented.
*/
g_fout = CreateArchive(filename, archFiles, compressLevel, archModeWrite);
}
else if (pg_strcasecmp(format, "p") == 0 || pg_strcasecmp(format, "plain") == 0)
{
plainText = 1;
g_fout = CreateArchive(filename, archNull, 0, archModeWrite);
}
else if (pg_strcasecmp(format, "t") == 0 || pg_strcasecmp(format, "tar") == 0)
g_fout = CreateArchive(filename, archTar, compressLevel, archModeWrite);
else
{
write_msg(NULL, "invalid output format \"%s\" specified\n", format);
exit(1);
}
InitArchiveFmt_Custom函数的调用关系图如下(dump文件格式调用关系.JPG):
在具体的使用中,如:导出大对象,则可以调用函数指针,直接导出大对象,但实际调用的,是初始化时,根据具体文件格式、为函数指针赋值的本格式的函数。
如果想品味其精妙处,建议循着如下调用关系仔细看看不同格式的文件导出,是如何进行的?【dumpTableData->ArchiveEntry->_ArchiveEntry(pg_backup_custom.c,二进制格式,调用方式如:(*AH->ArchiveEntryPtr) (AH, newToc))】
- PostgreSQL之精妙的数据库导入导出工具架构 (三)
- PostgreSQL之精妙的数据库导入导出工具架构 (一)
- PostgreSQL之精妙的数据库导入导出工具架构 (二)
- PostgreSQL之精妙的数据库导入导出工具架构 (四)
- PostgreSQL之精妙的数据库导入导出工具架构 (五)
- PostgreSQL之精妙的数据库导入导出工具架构 (六)
- PostgreSQL之精妙的数据库导入导出工具架构 (七)
- PostgreSQL之精妙的数据库导入导出工具架构 (八)
- PostgreSQL之精妙的数据库导入导出工具架构 (九)
- PostgreSQL之精妙的数据库导入导出工具架构 (十)
- PostgreSQL之精妙的数据库导入导出工具架构 (十一)
- PostgreSQL之精妙的数据库导入导出工具架构 (十二)
- postgresql 数据库导入导出
- postgresql数据库导入导出
- PostgreSQL数据库导出导入
- POSTGRESQL 数据库导入导出
- postgreSQL数据库导入导出
- Postgresql数据库数据简单的导入导出
- 多线程同步问题:主线程不能进入临界区
- java多线程
- 菜鸟学数据库(一)——三范式
- 关于pdf转doc的软件的使用效果
- 再读LVS
- PostgreSQL之精妙的数据库导入导出工具架构 (三)
- LVS大全
- hdu 1875 畅通工程再续
- wince下的快捷方式
- 恼人的尾椎疼痛
- 用gcc编译.cpp文件可能出现"undefined reference to `__gxx_personality_v0'"问题的解决
- 移植wireless tools (iwpriv, iwconfig, iwgetid, iwevents, iwspy, iwlist)到Android
- 作为兼并重组的重要方式之一,企业合并、分立的具体形式?
- 几个常用的shell命令(不断更新中)