From f02299cc1a6eca40c051d3322d602923271a724a Mon Sep 17 00:00:00 2001 From: Max Satula Date: Tue, 22 Jul 2014 22:01:18 -0400 Subject: [PATCH] Implemented -ls DIRECTORY Resolves #1 Chosen option "Self made stored procedure written in Java" --- main.c | 82 ++++++++++++++++++++++++++++++++++++++++++++-- ocp_ls_objects.sql | 74 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 3 deletions(-) create mode 100755 ocp_ls_objects.sql diff --git a/main.c b/main.c index 5f6b3cb..01b2a87 100755 --- a/main.c +++ b/main.c @@ -39,7 +39,7 @@ enum PROGRAM_ACTION { ACTION_READ, ACTION_WRITE, ACTION_LSDIR, ACTION_LS }; void LsDir(struct ORACLEALLINONE *oraAllInOne) { sword ociResult; - char vDirectory[MAX_FMT_SIZE]; + char vDirectory[31]; char vDirectoryPath[MAX_FMT_SIZE]; char vGrantable1[MAX_FMT_SIZE]; char vGrantable2[MAX_FMT_SIZE]; @@ -96,6 +96,82 @@ SELECT d.directory_name,\ ReleaseStmt(oraAllInOne); } +void Ls(struct ORACLEALLINONE *oraAllInOne, char* pDirectory) +{ + sword ociResult; + char vDirectory[31]; + char vFileName[MAX_FMT_SIZE]; + ub8 vBytes; + char vLastModified[7]; + int i; + long totalBytes; + + struct BINDVARIABLE oraBindsLs[] = + { + { 0, SQLT_STR, ":directory", vDirectory, sizeof(vDirectory)-1 } + }; + + struct ORACLEDEFINE oraDefinesLs[] = + { + { 0, SQLT_STR, vFileName, sizeof(vFileName)-1, 0 }, + { 0, SQLT_INT, &vBytes, sizeof(vBytes), 0 }, + { 0, SQLT_DAT, vLastModified, sizeof(vLastModified), 0 } + }; + + struct ORACLESTATEMENT oraStmtLs = { "\ +SELECT t.file_name,\ + t.bytes,\ + t.last_modified\ + FROM all_directories d,\ + TABLE(f_ocp_dir_list(d.directory_path)) t\ + WHERE d.directory_name = :directory", + 0, oraBindsLs, sizeof(oraBindsLs)/sizeof(struct BINDVARIABLE), + oraDefinesLs, sizeof(oraDefinesLs)/sizeof(struct ORACLEDEFINE) }; + + strncpy(vDirectory, pDirectory, sizeof(vDirectory)); + if (vDirectory[sizeof(vDirectory) - 1]) + ExitWithError(oraAllInOne, 1, ERROR_NONE, "Oracle directory name is too long\n"); + + PrepareStmtAndBind(oraAllInOne, &oraStmtLs); + + if (ExecuteStmt(oraAllInOne)) + ExitWithError(oraAllInOne, 4, ERROR_OCI, "Failed to list files in oracle directory\n"); + + printf("Contents of %s directory\n\ +%-40s %-12s %s\n\ +---------------------------------------- ------------ -------------------\n", + vDirectory, "File Name", " Size", "Last Modified"); + + i = 0; + totalBytes = 0; + do + { + printf("%-40s %12ld %02d/%02d/%d %02d:%02d:%02d\n", + vFileName, + vBytes, + (int)vLastModified[2], + (int)vLastModified[3], + ((int)vLastModified[0]-100) * 100 + ((int)vLastModified[1] - 100), + (int)vLastModified[4] - 1, + (int)vLastModified[5] - 1, + (int)vLastModified[6] - 1); + i++; + totalBytes += vBytes; + + ociResult = OCIStmtFetch2(oraStmtLs.stmthp, oraAllInOne->errhp, 1, + OCI_FETCH_NEXT, 1, OCI_DEFAULT); + } + while (ociResult == OCI_SUCCESS); + + if (ociResult != OCI_NO_DATA) + ExitWithError(oraAllInOne, 4, ERROR_OCI, "Failed to list files in oracle directory\n"); + + printf("---------------------------------------- ------------ -------------------\n\ +%5d File(s) %39ld\n", i, totalBytes); + + ReleaseStmt(oraAllInOne); +} + void TransferFile(struct ORACLEALLINONE *oraAllInOne, int readingDirection, char* pDirectory, char* pRemoteFile, char* pLocalFile) { @@ -282,7 +358,7 @@ int main(int argc, char *argv[]) char connectionString[MAX_FMT_SIZE]; char *pwdptr, *dbconptr; enum PROGRAM_ACTION programAction; - char vDirectory[MAX_FMT_SIZE]; + char vDirectory[31]; char vLocalFile[MAX_FMT_SIZE]; char vRemoteFile[MAX_FMT_SIZE]; char* fileNamePtr; @@ -358,7 +434,7 @@ int main(int argc, char *argv[]) LsDir(&oraAllInOne); break; case ACTION_LS: - ExitWithError(&oraAllInOne, 5, ERROR_NONE, "Not implemented yet: -ls DIRECTORY\n"); + Ls(&oraAllInOne, argv[3]); break; case ACTION_READ: case ACTION_WRITE: diff --git a/ocp_ls_objects.sql b/ocp_ls_objects.sql new file mode 100755 index 0000000..7048bdb --- /dev/null +++ b/ocp_ls_objects.sql @@ -0,0 +1,74 @@ +/***************************************************************************** +Copyright (C) 2014 Max Satula + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*****************************************************************************/ + +-- Requires CREATE TYPE, CREATE PROCEDURE + +DROP TYPE t_ocp_file_list +/ + +CREATE OR REPLACE + TYPE t_ocp_file AS OBJECT ( + file_name VARCHAR2(200), + bytes NUMBER, + last_modified DATE); +/ + +CREATE OR REPLACE + TYPE t_ocp_file_list IS TABLE OF t_ocp_file +/ + +CREATE OR REPLACE + AND COMPILE + JAVA SOURCE NAMED "j_ocp_DirList" +AS +import java.io.File; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Timestamp; +import oracle.sql.ARRAY; +import oracle.sql.ArrayDescriptor; +import oracle.jdbc.driver.OracleDriver; + +public class j_ocp_DirList +{ + public static ARRAY getList(String directory) + throws SQLException + { + Connection conn = new OracleDriver().defaultConnection(); + ArrayDescriptor arrayDescriptor = new ArrayDescriptor("T_OCP_FILE_LIST", conn); + File path = new File(directory); + File[] files = path.listFiles(); + Object[][] result = new Object[files.length][3]; + for (int i = 0; i < files.length; i++) + { + result[i][0] = files[i].getName(); + result[i][1] = files[i].length(); + result[i][2] = new Timestamp(files[i].lastModified()); + } + return new ARRAY(arrayDescriptor, conn, result); + } +} +/ + +CREATE OR REPLACE + FUNCTION f_ocp_dir_list(p_directory IN VARCHAR2) +RETURN t_ocp_file_list +AS LANGUAGE JAVA +NAME 'j_ocp_DirList.getList( java.lang.String ) return oracle.sql.ARRAY'; +/