{"id":17196393,"url":"https://github.com/darold/external_file","last_synced_at":"2025-04-13T19:52:46.169Z","repository":{"id":26247954,"uuid":"29695023","full_name":"darold/external_file","owner":"darold","description":"Allow access to \"external files\" from PostgreSQL server file systems.","archived":false,"fork":false,"pushed_at":"2023-01-14T14:52:47.000Z","size":28,"stargazers_count":24,"open_issues_count":2,"forks_count":8,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-27T10:38:14.466Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Raku","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/darold.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-22T19:08:39.000Z","updated_at":"2024-10-10T10:22:24.000Z","dependencies_parsed_at":"2023-01-16T22:30:16.049Z","dependency_job_id":null,"html_url":"https://github.com/darold/external_file","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darold%2Fexternal_file","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darold%2Fexternal_file/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darold%2Fexternal_file/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darold%2Fexternal_file/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/darold","download_url":"https://codeload.github.com/darold/external_file/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248773889,"owners_count":21159523,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-15T01:53:06.090Z","updated_at":"2025-04-13T19:52:46.147Z","avatar_url":"https://github.com/darold.png","language":"Raku","funding_links":[],"categories":[],"sub_categories":[],"readme":"External file access extension\n==============================\n\nAllow access to \"external files\" from PostgreSQL server file systems.\n\nThis extension adds the same functionalities given by the Oracle's BFILE data\ntype that stores unstructured binary data in flat files outside the database.\nA BFILE column stores a file locator that points to an external file containing\nthe data: (DIRECTORY, FILENAME). Here the data type is called EFILE.\n\nThe extension access to external files using secure call to the server side `lo_*`\nfunctions and not by directly reading/writing to files.\n\nInstallation requirements\n-------------------------\n\nPostgreSQL 9.1 or better are required.\nUser with PostgreSQL superuser role for creating extension.\n\nInstallation\n------------\n\nexternal_file has been written as a PostgreSQL extension and uses the Extension\nBuilding Infrastructure \"PGXS\".\n\nYou will need PostgreSQL headers and PGXS installed (if your PostgreSQL was\ninstalled with packages, install the development package).\n\nGet/Unpack the source code in a fresh directory Then the software installation\nshould be as simple as\n\n\t$ make (In these version do nothing)\n\t$ make install\n\nTo install the extension in a database, connect as superuser and\n\n\tCREATE EXTENSION external_file;\n\nBy default all objects of the extension are created in the `external_file` schema.\nIf you want to change the schema name you must edit the `external_file.control`\nfile. Note that this schema must not be writable by normal user to not allow\nbypassing of the search path set with the security definer.\n\n\nWhen using schema with extension, it's better to include this schema in the\ndefault search path. For example:\n\n\tALTER DATABASE \u003cmydb\u003e SET search_path=\"$user\",public,external_file;\n\nAlso you can restrict USAGE grant on `external_file` schema to specific user and\nchange the default search path at user level too.\n\n\tGRANT USAGE ON SCHEMA external_file TO \u003cusername\u003e;\n\nPlease refer to the PostgreSQL documentation for more information.\n\n\nUsage\n-----\n\nExternal file are accessed using two values, an alias for the path of the\ndirectory where the file is, and the file name.\n\nSo, first, alias must be defined for the path. This definition is performed\nusing the \"directories\" table. For security reason, only superuser can insert,\nupdate, delete directory definition. It's possible, with GRANT command, to\nchange this but it's NOT recommended.\n\nExample:\n\n\tINSERT INTO directories(directory_name,directory_path) VALUES ('temporary','/tmp/');\n\nATTENTION:\n * the directory path must use the terminal file system separator!\n * the system user running PostgreSQL server (generally postgres) must have the\n   system rights to read and/or write files. See `pg_read_server_files` and\n   `pg_write_server_files` privileges introduced in PostgreSQL 11.\n * the filename don't include any / or \\ character for security reason\n\nSecond, rights for user and/or role are defined using the \"directory_access\"\ntable.\n\nExample:\n\n\tINSERT INTO directory_roles(directory_name,directory_role,directory_read,directory_write) VALUES ('temporary','a_role',true,false);\n\nNow standard user can use external files.\n\nExample:\n\n\t-- Store a new external file blahblah.txt into the directory\n\tSELECT writeEfile('\\x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a', ('temporary', 'blahblah.txt'));\n\n\tls -la /tmp/blahblah.txt \n\t-rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt\n\n\t-- Create a table that will use external files\n\tCREATE TABLE efile_test ( id smallint primary key, the_file efile);\n\t-- Insert a row to access the external file called blahblah.txt\n\tINSERT INTO efile_test VALUES (1,('temporary','blahblah.txt'));\n\t-- Assuming user has right to read, and the file exists\n\tSELECT id, readefile(the_file) FROM efile_test;\n\t-- Make a physical copy of the external file assuming user has right to read AND write\n\tSELECT copyefile(('temporary','blahblah.txt'),('temporary','copy_blahblah.txt'));\n\tINSERT INTO efile_test VALUES (2, ('temporary','copy_blahblah.txt'):::efile);\n\t-- or the equivalent using efilename()\n\tINSERT INTO efile_test VALUES (3, efilename('temporary','copy_blahblah.txt'));\n\n\tls /tmp/*blahblah.txt\n\t-rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt\n\t-rw-r--r-- 1 postgres postgres 47 janv. 22 19:24 /tmp/copy_blahblah.txt\n\n\tfile=# SELECT id, readefile(the_file) FROM efile_test;\n\t id |                                            readefile                                             \n\t----+--------------------------------------------------------------------------------------------------\n\t  1 | \\x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a\n\t  2 | \\x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a\n\t(2 lines)\n\n\nFunction reference\n------------------\n\n* **efilename(directory in name, filename in varchar(256)) returns efile**\n\n  Returns an EFILE data type that is referencing the external file on the server filesystem.\n  Returns NULL on null imput.\n\n\n* **readEfile(e_file in efile) returns bytea**\n\n  copy the external file into a bytea.\n  Error will be generated if something wrong.\n\n* **writeEfile(buffer in bytea, e_file in efile) returns void**\n\n  copy a bytea into a external file.\n  Error will be generated if something wrong.\n\n* **copyEfile(src in efile, dest in efile) returns void**\n\n  duplicate file defined by src into file dest\n  Error will be generated if something wrong.\n\n* **getEfilePath(e_file efile, need_read in boolean, need_write in boolean) returns text**\n\n  giving an efile and booleans, one for read and one for write need, return the\n  full path for the file, otherwise an error is generated \n  useful to check if session user has access to this external file\n\nAuthors\n-------\n\n* Dominique Legendre\n* Gilles Darold\n\nLicense\n-------\n\nexternal_file is free software distributed under the PostgreSQL Licence.\n\n* Copyright (c) 2012-2018 Brgm - All rights reserved.\n* Copyright (c) 2022 MigOps Inc - All rights reserved.\n\nSee LICENSE file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarold%2Fexternal_file","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdarold%2Fexternal_file","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarold%2Fexternal_file/lists"}