├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── fio--1.0.sql ├── fio.control └── src ├── chmod.c ├── fio.c ├── fio.h ├── mkdir.c ├── readdir.c ├── readfile.c ├── removefile.c ├── renamefile.c ├── utils.c ├── utils.h └── writefile.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | src/*.bc 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Cafer Şimşek 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of pgsql-fio nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | MODULE_big = fio 2 | 3 | OBJS = src/fio.o \ 4 | src/renamefile.o \ 5 | src/removefile.o \ 6 | src/writefile.o \ 7 | src/readfile.o \ 8 | src/readdir.o \ 9 | src/mkdir.o \ 10 | src/chmod.o \ 11 | src/utils.o 12 | 13 | EXTENSION = fio 14 | DATA = fio--1.0.sql 15 | EXTRA-CLEAN = 16 | 17 | #PG_CONFIG = /usr/pgsql-9.3/bin/pg_config 18 | PG_CONFIG = pg_config 19 | 20 | SHLIB_LINK := $(LIBS) 21 | 22 | PGXS := $(shell $(PG_CONFIG) --pgxs) 23 | include $(PGXS) 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PostgreSQL "basic" File I/O Functions 2 | 3 | ## Quick Start 4 | 5 | This extension for some basic file system functions. 6 | 7 | After checkout the code run that command: 8 | 9 | `make install` 10 | 11 | *Please note: Do not forget edit `Makefile` for `PG_CONFIG` entry.* 12 | 13 | And then go to `psql` console and install the extension for your db 14 | 15 | `$ psql dbname` 16 | 17 | `dbname# CREATE EXTENSION fio;` 18 | 19 | After creating extension, you can use functions with `fio_` prefix. 20 | 21 | For example: 22 | 23 | dbname=# select fio_readdir('/usr/', '*'); 24 | fio_readdir 25 | ------------- 26 | (include) 27 | (src) 28 | (lib64) 29 | (.) 30 | (tmp) 31 | (pgsql-9.3) 32 | (bin) 33 | (..) 34 | (libexec) 35 | (local) 36 | (lib) 37 | (share) 38 | (games) 39 | (pgsql-9.4) 40 | (etc) 41 | (java) 42 | (sbin) 43 | (17 rows) 44 | dbname=# 45 | 46 | ## Functions 47 | 48 | ##### `fio_chmod(pathname varchar, mode varchar);` 49 | - **pathname**: the path's name you want to change mode 50 | - **mode**: string for mode (ex: '0777') 51 | 52 | ##### `fio_mkdir(pathname varchar, mode varchar, recursive boolean default false)` 53 | - **pathname**: the path's name you want to create 54 | - **mode**: string for mode (ex: '0777') 55 | - **recursive**: create directory recursion 56 | 57 | ##### `fio_readdir(pathname varchar, pattern varchar default '*')` 58 | - **pathname**: the path's name you want to list of files/directories 59 | - **pattern**: shell like pattern you want to filter (ex: '*.jpg') 60 | 61 | ##### `fio_readfile(filename varchar)` 62 | - **filename**: The file's name you want to read. Return type is `bytea`. 63 | 64 | ##### `fio_writefile(filename varchar, content bytea, mkdir boolean default false, overwrite boolean DEFAULT false)` 65 | - **filename**: The file's name you want to create/write. 66 | - **content**: What content you want to write the file. 67 | - **mkdir**: If `true`, it creates directory with given `filename`. Creates directory with recursion option. 68 | - **overwrite**: If `true` overwrite file if already exists. If `false` and file exists it fails. 69 | 70 | 71 | ##### `fio_removefile(filename varchar)` 72 | - **filename**: The file's name you want to remove. 73 | 74 | ##### `fio_renamefile(filename varchar, newfilename varchar)` 75 | - **filename**: The file's name you want to rename. 76 | - **newfilename**: The new file's name 77 | 78 | -------------------------------------------------------------------------------- /fio--1.0.sql: -------------------------------------------------------------------------------- 1 | -- complain if script is sourced in psql, rather than via CREATE EXTENSION 2 | \echo Use "CREATE EXTENSION fio" to load this file. \quit 3 | 4 | CREATE OR REPLACE FUNCTION fio_writefile(filename varchar, content bytea, mkdir boolean default false, overwrite boolean default false) 5 | RETURNS integer 6 | AS 'MODULE_PATHNAME', 'fio_writefile' 7 | LANGUAGE 'c'; 8 | CREATE OR REPLACE FUNCTION fio_readfile(filename varchar) 9 | RETURNS bytea 10 | AS 'MODULE_PATHNAME', 'fio_readfile' 11 | LANGUAGE 'c'; 12 | CREATE OR REPLACE FUNCTION fio_removefile(filename varchar) 13 | RETURNS void 14 | AS 'MODULE_PATHNAME', 'fio_removefile' 15 | LANGUAGE 'c'; 16 | CREATE OR REPLACE FUNCTION fio_renamefile(filename varchar, newfilename varchar) 17 | RETURNS void 18 | AS 'MODULE_PATHNAME', 'fio_renamefile' 19 | LANGUAGE 'c'; 20 | CREATE TYPE readdirresult AS ( 21 | dirname varchar 22 | ); 23 | CREATE OR REPLACE FUNCTION fio_readdir(pathname varchar, pattern varchar default '*') 24 | RETURNS SETOF readdirresult 25 | AS 'MODULE_PATHNAME', 'fio_readdir' 26 | LANGUAGE 'c'; 27 | CREATE OR REPLACE FUNCTION fio_mkdir(pathname varchar, mode varchar, recursive boolean default false) 28 | RETURNS integer 29 | AS 'MODULE_PATHNAME', 'fio_mkdir' 30 | LANGUAGE 'c'; 31 | CREATE OR REPLACE FUNCTION fio_chmod(pathname varchar, mode varchar) 32 | RETURNS integer 33 | AS 'MODULE_PATHNAME', 'fio_chmod' 34 | LANGUAGE 'c'; 35 | -------------------------------------------------------------------------------- /fio.control: -------------------------------------------------------------------------------- 1 | default_version = '1.0' 2 | module_pathname = '$libdir/fio' 3 | relocatable = true 4 | comment = 'PostgreSQL FS I/O Functions' 5 | -------------------------------------------------------------------------------- /src/chmod.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2015, Cafer Şimşek 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of pgsql-fio nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include "fio.h" 31 | 32 | Datum fio_chmod(PG_FUNCTION_ARGS) { 33 | // chmod(pathname varchar, mode varchar); 34 | 35 | text *v_pathname; 36 | char *pathname; 37 | text *vmode; 38 | size_t mode_ch_size; 39 | char *ch_mode; 40 | char *ch_mode_copy; 41 | int mode; 42 | if (PG_ARGISNULL(0)) { 43 | elog(ERROR, "path must be specified"); 44 | return 0; 45 | } 46 | v_pathname = PG_GETARG_TEXT_P(0); 47 | pathname = text_to_cstring(v_pathname); 48 | if (PG_ARGISNULL(1)) { 49 | elog(ERROR, "mode must be specified"); 50 | return 0; 51 | } 52 | vmode = PG_GETARG_TEXT_P(1); 53 | mode_ch_size = VARSIZE(vmode) - VARHDRSZ; 54 | ch_mode = text_to_cstring(vmode); 55 | ch_mode_copy = text_to_cstring(PG_GETARG_TEXT_P(1)); 56 | mode = (int) strtol(ch_mode, &ch_mode_copy, 8); 57 | if (strncmp(ch_mode, ch_mode_copy, mode_ch_size) == 0) { 58 | elog(ERROR, "mode must be specified"); 59 | return 0; 60 | } 61 | return chmod(pathname, mode); 62 | } 63 | -------------------------------------------------------------------------------- /src/fio.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2015, Cafer Şimşek 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of pgsql-fio nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include "fio.h" 31 | 32 | PG_MODULE_MAGIC; 33 | 34 | void _PG_init(void); 35 | void _PG_fini(void); 36 | 37 | void _PG_init(void) 38 | { 39 | } 40 | 41 | void _PG_fini(void) 42 | { 43 | } 44 | 45 | PG_FUNCTION_INFO_V1(fio_removefile); 46 | PG_FUNCTION_INFO_V1(fio_renamefile); 47 | PG_FUNCTION_INFO_V1(fio_writefile); 48 | PG_FUNCTION_INFO_V1(fio_readfile); 49 | PG_FUNCTION_INFO_V1(fio_readdir); 50 | PG_FUNCTION_INFO_V1(fio_mkdir); 51 | PG_FUNCTION_INFO_V1(fio_chmod); 52 | -------------------------------------------------------------------------------- /src/fio.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2015, Cafer Şimşek 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of pgsql-fio nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef __FIO_H 31 | #define __FIO_H 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | #include "utils.h" 56 | 57 | extern PGDLLEXPORT Datum fio_writefile(PG_FUNCTION_ARGS); 58 | extern PGDLLEXPORT Datum fio_readfile(PG_FUNCTION_ARGS); 59 | extern PGDLLEXPORT Datum fio_readdir(PG_FUNCTION_ARGS); 60 | extern PGDLLEXPORT Datum fio_mkdir(PG_FUNCTION_ARGS); 61 | extern PGDLLEXPORT Datum fio_chmod(PG_FUNCTION_ARGS); 62 | extern PGDLLEXPORT Datum fio_removefile(PG_FUNCTION_ARGS); 63 | extern PGDLLEXPORT Datum fio_renamefile(PG_FUNCTION_ARGS); 64 | #endif 65 | 66 | #ifndef FALSE 67 | #define FALSE (0) 68 | #endif 69 | 70 | #ifndef TRUE 71 | #define TRUE (!FALSE) 72 | #endif 73 | -------------------------------------------------------------------------------- /src/mkdir.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2015, Cafer Şimşek 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of pgsql-fio nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include "fio.h" 31 | 32 | Datum fio_mkdir(PG_FUNCTION_ARGS) { 33 | // mkdir(pathname varchar, mode varchar, recursive boolean default false); 34 | 35 | text *v_pathname; 36 | char *pathname; 37 | text *vmode; 38 | size_t mode_ch_size; 39 | char *ch_mode; 40 | char *ch_mode_copy; 41 | int mode; 42 | bool recursive = FALSE; 43 | if (PG_ARGISNULL(0)) { 44 | elog(ERROR, "path must be specified"); 45 | return 0; 46 | } 47 | v_pathname = PG_GETARG_TEXT_P(0); 48 | pathname = text_to_cstring(v_pathname); 49 | if (strlen(pathname) == 0) { 50 | elog(ERROR, "path must be specified"); 51 | return 0; 52 | } 53 | if (PG_ARGISNULL(1)) { 54 | elog(ERROR, "mode must be specified"); 55 | return 0; 56 | } 57 | vmode = PG_GETARG_TEXT_P(1); 58 | mode_ch_size = VARSIZE(vmode) - VARHDRSZ; 59 | ch_mode = text_to_cstring(vmode); 60 | ch_mode_copy= text_to_cstring(PG_GETARG_TEXT_P(1)); 61 | mode = (int) strtol(ch_mode, &ch_mode_copy, 8); 62 | if (strncmp(ch_mode, ch_mode_copy, mode_ch_size) == 0) { 63 | elog(ERROR, "mode must be specified"); 64 | return 0; 65 | } 66 | if (!PG_ARGISNULL(2)) { 67 | recursive = PG_GETARG_BOOL(2); 68 | } 69 | if (recursive) { 70 | mkdir_recursive(pathname, mode); 71 | } else { 72 | mkdir(pathname, mode); 73 | chmod(pathname, mode); 74 | } 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /src/readdir.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2015, Cafer Şimşek 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of pgsql-fio nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include "fio.h" 31 | 32 | struct dircontext { 33 | DIR *dir; 34 | }; 35 | 36 | Datum fio_readdir(PG_FUNCTION_ARGS) { 37 | // readdir(pathname varchar, pattern varchar default '*'); 38 | 39 | FuncCallContext *funcctx; 40 | DIR *dir = NULL; 41 | char *pathname; 42 | char *pattern; 43 | struct dirent *dp; 44 | struct dircontext *dirctx; 45 | if (PG_ARGISNULL(0)) { 46 | elog(ERROR, "path must be specified"); 47 | } 48 | if (PG_ARGISNULL(1)) { 49 | elog(ERROR, "pattern must be specified"); 50 | } 51 | pathname = text_to_cstring(PG_GETARG_TEXT_P(0)); 52 | pattern = text_to_cstring(PG_GETARG_TEXT_P(1)); 53 | if (SRF_IS_FIRSTCALL()) { 54 | MemoryContext oldcontext; 55 | TupleDesc tupdesc; 56 | funcctx = SRF_FIRSTCALL_INIT(); 57 | oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); 58 | if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) 59 | ereport(ERROR, 60 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), 61 | errmsg("function returning record called in context " 62 | "that cannot accept type record"))); 63 | funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc); 64 | dir = opendir(pathname); 65 | if (dir == NULL) { 66 | int err = errno; 67 | elog(ERROR, "cannot open dir: %s (%s)", pathname, strerror(err)); 68 | } 69 | dirctx = (struct dircontext *) palloc(sizeof(struct dircontext *)); 70 | dirctx->dir = dir; 71 | funcctx->user_fctx = (void *) dirctx; 72 | MemoryContextSwitchTo(oldcontext); 73 | } 74 | funcctx = SRF_PERCALL_SETUP(); 75 | dirctx = (struct dircontext *) funcctx->user_fctx; 76 | dir = dirctx->dir; 77 | while ((dp = readdir(dir)) != NULL) { 78 | if (fnmatch(pattern, dp->d_name, FNM_NOESCAPE) == 0) { 79 | HeapTuple tuple; 80 | Datum result; 81 | char *value = (char *) palloc(dp->d_reclen * sizeof(char)); 82 | memcpy(value, dp->d_name, dp->d_reclen); 83 | tuple = BuildTupleFromCStrings(funcctx->attinmeta, &value); 84 | result = HeapTupleGetDatum(tuple); 85 | pfree(value); 86 | SRF_RETURN_NEXT(funcctx, result); 87 | } 88 | } 89 | closedir(dir); 90 | pfree(dirctx); 91 | SRF_RETURN_DONE(funcctx); 92 | } 93 | -------------------------------------------------------------------------------- /src/readfile.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2015, Cafer Şimşek 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of pgsql-fio nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include "fio.h" 31 | 32 | #define BUFFER_SIZE 1024 33 | 34 | Datum fio_readfile(PG_FUNCTION_ARGS) { 35 | // readfile(filename varchar); 36 | 37 | text *v_filename; 38 | char *filename; 39 | char *content; 40 | int totalcount = 0; 41 | char buffer[BUFFER_SIZE]; 42 | FILE *fd; 43 | bytea *result; 44 | long filesize; 45 | int bufferedbytecount; 46 | DIR* dir = NULL; 47 | if (PG_ARGISNULL(0)) { 48 | elog(ERROR, "filename must be specified"); 49 | return 0; 50 | } 51 | v_filename = PG_GETARG_TEXT_P(0); 52 | filename = text_to_cstring(v_filename); 53 | dir = opendir(filename); 54 | if (dir != NULL) { 55 | closedir(dir); 56 | elog(ERROR, "cannot open file: %s (not regular file)", filename); 57 | return 0; 58 | } 59 | if ((fd = fopen(filename, "r")) == NULL) { 60 | int err = errno; 61 | elog(ERROR, "cannot open file: %s (%s)", filename, strerror(err)); 62 | return 0; 63 | } 64 | 65 | filesize = get_file_size(fd); 66 | content = (char *) palloc(filesize); 67 | do { 68 | bufferedbytecount = fread(buffer, 1, BUFFER_SIZE, fd); 69 | memcpy(content + totalcount, buffer, bufferedbytecount); 70 | totalcount += bufferedbytecount; 71 | } while (bufferedbytecount == BUFFER_SIZE); 72 | fclose(fd); 73 | result = (bytea *) palloc(VARHDRSZ + filesize); 74 | memcpy(VARDATA(result), content, filesize); 75 | pfree(content); 76 | SET_VARSIZE(result, filesize + VARHDRSZ); 77 | PG_RETURN_BYTEA_P(result); 78 | } 79 | -------------------------------------------------------------------------------- /src/removefile.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2015, Cafer Şimşek 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of pgsql-fio nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include "fio.h" 31 | 32 | Datum fio_removefile(PG_FUNCTION_ARGS) { 33 | text *vfilename; 34 | char *filename; 35 | 36 | if (PG_ARGISNULL(0)) { 37 | elog(ERROR, "filename must be specified"); 38 | return 0; 39 | } 40 | vfilename = PG_GETARG_TEXT_P(0); 41 | 42 | filename = text_to_cstring(vfilename); 43 | 44 | if (remove(filename) != 0) { 45 | int err = errno; 46 | elog(ERROR, "cannot remove file: %s (%s)", filename, strerror(err)); 47 | return 0; 48 | } 49 | pfree(filename); 50 | PG_RETURN_NULL(); 51 | } 52 | -------------------------------------------------------------------------------- /src/renamefile.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2015, Cafer Şimşek 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of pgsql-fio nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include "fio.h" 31 | 32 | Datum fio_renamefile(PG_FUNCTION_ARGS) { 33 | text *vfilename; 34 | text *vfilename_new; 35 | char *filename; 36 | char *filename_new; 37 | 38 | if (PG_ARGISNULL(0)) { 39 | elog(ERROR, "filename must be specified"); 40 | return 0; 41 | } 42 | vfilename = PG_GETARG_TEXT_P(0); 43 | 44 | if (PG_ARGISNULL(1)) { 45 | elog(ERROR, "new filename must be specified"); 46 | return 0; 47 | } 48 | vfilename_new = PG_GETARG_TEXT_P(1); 49 | 50 | filename = text_to_cstring(vfilename); 51 | filename_new = text_to_cstring(vfilename_new); 52 | 53 | if (access(filename_new, F_OK) != 0) { 54 | if (rename(filename, filename_new) != 0) { 55 | int err = errno; 56 | elog(ERROR, "cannot rename file: %s (%s)", filename, strerror(err)); 57 | return 0; 58 | } 59 | } else { 60 | int err = errno; 61 | elog(ERROR, "new file %s already exists (%s) ", filename, strerror(err)); 62 | return 0; 63 | } 64 | pfree(filename); 65 | pfree(filename_new); 66 | PG_RETURN_NULL(); 67 | } 68 | -------------------------------------------------------------------------------- /src/utils.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2015, Cafer Şimşek 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of pgsql-fio nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include "fio.h" 31 | 32 | int mkdir_recursive(const char *dir, mode_t mode) { 33 | int result; 34 | char tmp[256]; 35 | char *p = NULL; 36 | size_t len; 37 | snprintf(tmp, sizeof(tmp),"%s",dir); 38 | len = strlen(tmp); 39 | if (len < 1) { 40 | elog(ERROR, "directory name not provided"); 41 | return 0; 42 | } 43 | 44 | if(tmp[len - 1] == '/') { 45 | tmp[len - 1] = 0; 46 | } 47 | for(p = tmp + 1; *p; p++) { 48 | if(*p == '/') { 49 | *p = 0; 50 | mkdir(tmp, mode); 51 | chmod(tmp, mode); 52 | *p = '/'; 53 | } 54 | } 55 | result = mkdir(tmp, mode); 56 | chmod(tmp, mode); 57 | return result; 58 | } 59 | 60 | long get_file_size(FILE *fd) { 61 | long result; 62 | long oldpos = ftell(fd); 63 | fseek(fd, 0, SEEK_END); 64 | result = ftell(fd); 65 | fseek(fd, oldpos, SEEK_SET); 66 | return result; 67 | } 68 | -------------------------------------------------------------------------------- /src/utils.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2015, Cafer Şimşek 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of pgsql-fio nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #ifndef __UTILS_H 31 | #define __UTILS_H 32 | int mkdir_recursive(const char *dir, mode_t mode); 33 | long get_file_size(FILE *fd); 34 | #endif 35 | -------------------------------------------------------------------------------- /src/writefile.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2015, Cafer Şimşek 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of pgsql-fio nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | #include "fio.h" 31 | 32 | Datum fio_writefile(PG_FUNCTION_ARGS) { 33 | // writefile(filename varchar, content bytea, mkdir boolean default false); 34 | 35 | text *vfilename; 36 | bytea *vcontent; 37 | char *filename; 38 | size_t contentsize; 39 | FILE *fd; 40 | char *buffer; 41 | size_t writesize; 42 | char *open_flag; 43 | 44 | if (PG_ARGISNULL(0)) { 45 | elog(ERROR, "filename must be specified"); 46 | return 0; 47 | } 48 | vfilename = PG_GETARG_TEXT_P(0); 49 | 50 | if (PG_ARGISNULL(1)) { 51 | elog(ERROR, "content must be specified"); 52 | return 0; 53 | } 54 | vcontent = PG_GETARG_BYTEA_P(1); 55 | 56 | filename = text_to_cstring(vfilename); 57 | contentsize = VARSIZE(vcontent) - VARHDRSZ; 58 | 59 | if (!PG_ARGISNULL(2)) { 60 | if (PG_GETARG_BOOL(2)) { // if it is recursive 61 | char* filename2 = strdup(filename); 62 | mkdir_recursive(dirname(filename2), 0777); 63 | //TODO: Why is this 0777? 64 | free(filename2); 65 | } 66 | } 67 | 68 | open_flag = (char *) palloc(sizeof(char) * 3); 69 | strncpy(open_flag, "wx\0", 3); 70 | if (!PG_ARGISNULL(3)) { 71 | if (PG_GETARG_BOOL(3)) { 72 | strncpy(open_flag, "w\0", 2); 73 | } 74 | } 75 | 76 | if ((fd = fopen(filename, open_flag)) == NULL) { 77 | int err = errno; 78 | elog(ERROR, "cannot open file: %s (%s)", filename, strerror(err)); 79 | return 0; 80 | } 81 | buffer = text_to_cstring(vcontent); 82 | writesize = fwrite(buffer, 1, contentsize, fd); 83 | fclose(fd); 84 | pfree(open_flag); 85 | pfree(filename); 86 | return writesize; 87 | } 88 | --------------------------------------------------------------------------------