embulk-output-oracle 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +24 -3
  3. data/build.gradle +3 -0
  4. data/classpath/{embulk-output-jdbc-0.2.1.jar → embulk-output-jdbc-0.2.2.jar} +0 -0
  5. data/classpath/embulk-output-oracle-0.2.2.jar +0 -0
  6. data/lib/embulk/linux_x64/libembulk-output-oracle.so +0 -0
  7. data/lib/embulk/win_x64/embulk-output-oracle.dll +0 -0
  8. data/src/main/cpp/common/dir-path-load.cpp +424 -0
  9. data/src/main/cpp/common/dir-path-load.h +36 -0
  10. data/src/main/cpp/common/embulk-output-oracle.cpp +196 -0
  11. data/src/main/cpp/common/org_embulk_output_oracle_oci_OCI.h +77 -0
  12. data/src/main/cpp/linux/build.sh +21 -0
  13. data/src/main/cpp/win/build.bat +32 -0
  14. data/src/main/cpp/win/dllmain.cpp +25 -0
  15. data/src/main/cpp/win/embulk-output-oracle.sln +39 -0
  16. data/src/main/cpp/win/embulk-output-oracle.vcxproj +176 -0
  17. data/src/main/java/org/embulk/output/OracleOutputPlugin.java +51 -10
  18. data/src/main/java/org/embulk/output/oracle/DirectBatchInsert.java +289 -0
  19. data/src/main/java/org/embulk/output/oracle/InsertMethod.java +8 -0
  20. data/src/main/java/org/embulk/output/oracle/OracleCharset.java +19 -0
  21. data/src/main/java/org/embulk/output/oracle/OracleOutputConnection.java +60 -1
  22. data/src/main/java/org/embulk/output/oracle/OracleOutputConnector.java +7 -5
  23. data/src/main/java/org/embulk/output/oracle/TimestampFormat.java +37 -0
  24. data/src/main/java/org/embulk/output/oracle/oci/ColumnDefinition.java +26 -0
  25. data/src/main/java/org/embulk/output/oracle/oci/OCI.java +139 -0
  26. data/src/main/java/org/embulk/output/oracle/oci/OCIManager.java +64 -0
  27. data/src/main/java/org/embulk/output/oracle/oci/OCIWrapper.java +96 -0
  28. data/src/main/java/org/embulk/output/oracle/oci/RowBuffer.java +99 -0
  29. data/src/main/java/org/embulk/output/oracle/oci/TableDefinition.java +24 -0
  30. data/src/main/java/org/embulk/output/oracle/setter/OracleColumnSetterFactory.java +14 -14
  31. data/src/test/cpp/common/embulk-output-oracle-test.cpp +69 -0
  32. data/src/test/cpp/linux/build.sh +19 -0
  33. data/src/test/cpp/win/build.bat +29 -0
  34. data/src/test/cpp/win/embulk-output-oracle-test.vcxproj +155 -0
  35. data/src/test/java/org/embulk/input/filesplit/LocalFileSplitInputPlugin.java +187 -0
  36. data/src/test/java/org/embulk/input/filesplit/PartialFile.java +50 -0
  37. data/src/test/java/org/embulk/input/filesplit/PartialFileInputStream.java +154 -0
  38. data/src/test/java/org/embulk/output/oracle/ChildFirstClassLoader.java +42 -0
  39. data/src/test/java/org/embulk/output/oracle/EmbulkPluginTester.java +120 -0
  40. data/src/test/java/org/embulk/output/oracle/EmptyConfigSource.java +100 -0
  41. data/src/test/java/org/embulk/output/oracle/OracleOutputPluginTest.java +161 -0
  42. data/src/test/java/org/embulk/output/oracle/OracleOutputPluginTestImpl.java +413 -0
  43. data/src/test/java/org/embulk/output/oracle/TimestampFormatTest.java +57 -0
  44. data/src/test/resources/data/test1/test1.csv +3 -0
  45. data/src/test/resources/yml/test-insert-direct.yml +26 -0
  46. data/src/test/resources/yml/test-insert-oci-split.yml +26 -0
  47. data/src/test/resources/yml/test-insert-oci.yml +26 -0
  48. data/src/test/resources/yml/test-insert.yml +25 -0
  49. data/src/test/resources/yml/test-replace-long-name.yml +25 -0
  50. data/src/test/resources/yml/test-replace.yml +25 -0
  51. data/src/test/resources/yml/test-url.yml +24 -0
  52. metadata +46 -4
  53. data/classpath/embulk-output-oracle-0.2.1.jar +0 -0
@@ -0,0 +1,24 @@
1
+ package org.embulk.output.oracle.oci;
2
+
3
+ import java.util.List;
4
+
5
+ public class TableDefinition
6
+ {
7
+
8
+ public final String tableName;
9
+ public final short charsetId;
10
+ public final ColumnDefinition[] columns;
11
+
12
+
13
+ public TableDefinition(String tableName, short charsetId, ColumnDefinition... columns)
14
+ {
15
+ this.tableName = tableName;
16
+ this.charsetId = charsetId;
17
+ this.columns = columns;
18
+ }
19
+
20
+ public TableDefinition(String tableName, short charsetId, List<ColumnDefinition> columns)
21
+ {
22
+ this(tableName, charsetId, columns.toArray(new ColumnDefinition[columns.size()]));
23
+ }
24
+ }
@@ -12,20 +12,20 @@ import org.embulk.spi.time.TimestampFormatter;
12
12
 
13
13
  public class OracleColumnSetterFactory extends ColumnSetterFactory
14
14
  {
15
- public OracleColumnSetterFactory(BatchInsert batch, PageReader pageReader,
16
- TimestampFormatter timestampFormatter)
17
- {
18
- super(batch, pageReader, timestampFormatter);
19
- }
20
-
21
- @Override
22
- public ColumnSetter newColumnSetter(JdbcColumn column)
15
+ public OracleColumnSetterFactory(BatchInsert batch, PageReader pageReader,
16
+ TimestampFormatter timestampFormatter)
23
17
  {
24
- switch (column.getSqlType()) {
25
- case Types.DECIMAL:
26
- return new StringColumnSetter(batch, pageReader, column, timestampFormatter);
18
+ super(batch, pageReader, timestampFormatter);
19
+ }
20
+
21
+ @Override
22
+ public ColumnSetter newColumnSetter(JdbcColumn column)
23
+ {
24
+ switch (column.getSqlType()) {
25
+ case Types.DECIMAL:
26
+ return new StringColumnSetter(batch, pageReader, column, timestampFormatter);
27
27
  default:
28
- return super.newColumnSetter(column);
29
- }
30
- }
28
+ return super.newColumnSetter(column);
29
+ }
30
+ }
31
31
  }
@@ -0,0 +1,69 @@
1
+ #include <stdio.h>
2
+ #include <string.h>
3
+ #include <dir-path-load.h>
4
+
5
+
6
+ static int test(EMBULK_OUTPUT_ORACLE_OCI_CONTEXT *context, const char *db, const char *user, const char *pass, const char *csvFileName)
7
+ {
8
+ if (embulk_output_oracle_prepareDirPathCtx(context, db, user, pass)) {
9
+ return OCI_ERROR;
10
+ }
11
+
12
+ EMBULK_OUTPUT_ORACLE_OCI_COL_DEF colDefs[] = {
13
+ {"ID", SQLT_INT, 4},
14
+ //{"ID", SQLT_CHR, 8},
15
+ {"NUM", SQLT_INT, 4},
16
+ //{"NUM", SQLT_CHR, 12},
17
+ {"VALUE1", SQLT_CHR, 60},
18
+ {"VALUE2", SQLT_CHR, 60},
19
+ {"VALUE3", SQLT_CHR, 60},
20
+ {"VALUE4", SQLT_CHR, 60},
21
+ {"VALUE5", SQLT_CHR, 60},
22
+ {"VALUE6", SQLT_CHR, 60},
23
+ {"VALUE7", SQLT_CHR, 60},
24
+ {"VALUE8", SQLT_CHR, 60},
25
+ {"VALUE9", SQLT_CHR, 60},
26
+ {"VALUE10", SQLT_CHR, 60},
27
+ {NULL, 0, 0}
28
+ };
29
+ if (embulk_output_oracle_prepareDirPathStream(context, "EXAMPLE", 832, colDefs)) {
30
+ return OCI_ERROR;
31
+ }
32
+
33
+ if (embulk_output_oracle_loadCSV(context, colDefs, csvFileName)) {
34
+ return OCI_ERROR;
35
+ }
36
+
37
+ if (embulk_output_oracle_commitDirPath(context)) {
38
+ return OCI_ERROR;
39
+ }
40
+
41
+ return OCI_SUCCESS;
42
+ }
43
+
44
+
45
+ int main(int argc, char* argv[])
46
+ {
47
+ sword major_version;
48
+ sword minor_version;
49
+ sword update_num;
50
+ sword patch_num;
51
+ sword port_update_num;
52
+ OCIClientVersion(&major_version, &minor_version, &update_num, &patch_num, &port_update_num);
53
+ printf("OCI client version = %d.%d.%d.%d.%d\r\n", major_version, minor_version, update_num, patch_num, port_update_num);
54
+
55
+ if (argc < 5) {
56
+ printf("embulk-output-oracle-test <db> <user> <password> <csv file name>\r\n");
57
+ return OCI_ERROR;
58
+ }
59
+
60
+ EMBULK_OUTPUT_ORACLE_OCI_CONTEXT context;
61
+ memset(&context, 0, sizeof(EMBULK_OUTPUT_ORACLE_OCI_CONTEXT));
62
+ int result = test(&context, argv[1], argv[2], argv[3], argv[4]);
63
+ if (result == OCI_ERROR) {
64
+ printf("%s\r\n", context.message);
65
+ }
66
+ embulk_output_oracle_freeDirPathHandles(&context);
67
+ return result;
68
+ }
69
+
@@ -0,0 +1,19 @@
1
+ # gcc, g++ and Oracle Instant Client SDK are requred.
2
+ #
3
+ # ln libocci.so.x.x libocci.so
4
+ # ln libclntsh.so.x.x libclntsh.so
5
+ #
6
+
7
+ if [ "$JAVA_HOME" = "" ]
8
+ then
9
+ echo "You should set the environment variable 'JAVA_HOME'."
10
+ exit 1
11
+ fi
12
+
13
+ if [ "$OCI_PATH" = "" ]
14
+ then
15
+ echo "You should set the environment variable 'OCI_PATH'."
16
+ exit 1
17
+ fi
18
+
19
+ gcc -I. -I"$JAVA_HOME/include" -I"$OCI_PATH/sdk/include" -I../../../main/cpp/common -L"$OCI_PATH" ../common/embulk-output-oracle-test.cpp ../../../main/cpp/common/embulk-output-oracle.cpp ../../../main/cpp/common/dir-path-load.cpp -locci -lclntsh -lstdc++ -o embulk-output-oracle-test
@@ -0,0 +1,29 @@
1
+ @ECHO OFF
2
+
3
+ REM You should set the environment variable 'PATH' to CL.exe(x86_amd64) of Visual Studio.
4
+
5
+ IF "%JAVA_HOME%" == "" (
6
+ ECHO "You should set the environment variable 'JAVA_HOME'."
7
+ EXIT /B 1
8
+ )
9
+
10
+
11
+ IF "%OCI_SDK_PATH%" == "" (
12
+ ECHO "You should set the environment variable 'OCI_SDK_PATH'."
13
+ EXIT /B 1
14
+ )
15
+
16
+ IF "%MSVC_PATH%" == "" (
17
+ ECHO "You should set the environment variable 'MSVC_PATH'."
18
+ ECHO "For example : SET MSVC_PATH=C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC"
19
+ EXIT /B 1
20
+ )
21
+
22
+ IF "%MSSDK_PATH%" == "" (
23
+ ECHO "You should set the environment variable 'MSSDK_PATH'."
24
+ ECHO "For example : SET MSSDK_PATH=C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A"
25
+ EXIT /B 1
26
+ )
27
+
28
+
29
+ CL /I"..\..\..\main\cpp\common" /I"%MSSDK_PATH%\Include" /I"%MSVC_PATH%\include" /I"%OCI_SDK_PATH%\include" /I"%JAVA_HOME%\include" /I"%JAVA_HOME%\include\win32" /Zi /nologo /W3 /WX- /O2 /Oi /GL /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "EMBULKOUTPUTORACLE_EXPORTS" /D "_WINDLL" /D "_UNICODE" /D "UNICODE" /Gm- /EHsc /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Gd /errorReport:queue ..\common\embulk-output-oracle-test.cpp ..\..\..\main\cpp\common\dir-path-load.cpp /link /LIBPATH:"%MSVC_PATH%\lib\amd64" /LIBPATH:"%MSSDK_PATH%\Lib\x64" /LIBPATH:"%OCI_SDK_PATH%\lib\msvc" /INCREMENTAL:NO /NOLOGO /LIBPATH:"C:\Oracle\instantclient_12_1\x64\sdk\lib\msvc" "oci.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /ALLOWISOLATION /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X64 /ERRORREPORT:QUEUE
@@ -0,0 +1,155 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3
+ <ItemGroup Label="ProjectConfigurations">
4
+ <ProjectConfiguration Include="Debug|Win32">
5
+ <Configuration>Debug</Configuration>
6
+ <Platform>Win32</Platform>
7
+ </ProjectConfiguration>
8
+ <ProjectConfiguration Include="Debug|x64">
9
+ <Configuration>Debug</Configuration>
10
+ <Platform>x64</Platform>
11
+ </ProjectConfiguration>
12
+ <ProjectConfiguration Include="Release|Win32">
13
+ <Configuration>Release</Configuration>
14
+ <Platform>Win32</Platform>
15
+ </ProjectConfiguration>
16
+ <ProjectConfiguration Include="Release|x64">
17
+ <Configuration>Release</Configuration>
18
+ <Platform>x64</Platform>
19
+ </ProjectConfiguration>
20
+ </ItemGroup>
21
+ <ItemGroup>
22
+ <ClInclude Include="..\..\..\main\cpp\common\dir-path-load.h" />
23
+ </ItemGroup>
24
+ <ItemGroup>
25
+ <ClCompile Include="..\..\..\main\cpp\common\dir-path-load.cpp" />
26
+ <ClCompile Include="..\common\embulk-output-oracle-test.cpp" />
27
+ </ItemGroup>
28
+ <PropertyGroup Label="Globals">
29
+ <ProjectGuid>{C14B433B-122A-4BDB-BF50-0673A57E5716}</ProjectGuid>
30
+ <Keyword>Win32Proj</Keyword>
31
+ <RootNamespace>embulkoutputoracletest</RootNamespace>
32
+ </PropertyGroup>
33
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
34
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
35
+ <ConfigurationType>Application</ConfigurationType>
36
+ <UseDebugLibraries>true</UseDebugLibraries>
37
+ <CharacterSet>Unicode</CharacterSet>
38
+ </PropertyGroup>
39
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
40
+ <ConfigurationType>Application</ConfigurationType>
41
+ <UseDebugLibraries>true</UseDebugLibraries>
42
+ <CharacterSet>Unicode</CharacterSet>
43
+ </PropertyGroup>
44
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
45
+ <ConfigurationType>Application</ConfigurationType>
46
+ <UseDebugLibraries>false</UseDebugLibraries>
47
+ <WholeProgramOptimization>true</WholeProgramOptimization>
48
+ <CharacterSet>Unicode</CharacterSet>
49
+ </PropertyGroup>
50
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
51
+ <ConfigurationType>Application</ConfigurationType>
52
+ <UseDebugLibraries>false</UseDebugLibraries>
53
+ <WholeProgramOptimization>true</WholeProgramOptimization>
54
+ <CharacterSet>Unicode</CharacterSet>
55
+ </PropertyGroup>
56
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
57
+ <ImportGroup Label="ExtensionSettings">
58
+ </ImportGroup>
59
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
60
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
61
+ </ImportGroup>
62
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
63
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
64
+ </ImportGroup>
65
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
66
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
67
+ </ImportGroup>
68
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
69
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
70
+ </ImportGroup>
71
+ <PropertyGroup Label="UserMacros" />
72
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
73
+ <LinkIncremental>true</LinkIncremental>
74
+ </PropertyGroup>
75
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
76
+ <LinkIncremental>true</LinkIncremental>
77
+ </PropertyGroup>
78
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
79
+ <LinkIncremental>false</LinkIncremental>
80
+ </PropertyGroup>
81
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
82
+ <LinkIncremental>false</LinkIncremental>
83
+ </PropertyGroup>
84
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
85
+ <ClCompile>
86
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
87
+ <WarningLevel>Level3</WarningLevel>
88
+ <Optimization>Disabled</Optimization>
89
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
90
+ <AdditionalIncludeDirectories>$(OCI_SDK_PATH)\include;..\..\..\main\cpp\common</AdditionalIncludeDirectories>
91
+ </ClCompile>
92
+ <Link>
93
+ <SubSystem>Console</SubSystem>
94
+ <GenerateDebugInformation>true</GenerateDebugInformation>
95
+ <AdditionalLibraryDirectories>$(OCI_SDK_PATH)\lib\msvc</AdditionalLibraryDirectories>
96
+ <AdditionalDependencies>oci.lib;%(AdditionalDependencies)</AdditionalDependencies>
97
+ </Link>
98
+ </ItemDefinitionGroup>
99
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
100
+ <ClCompile>
101
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
102
+ <WarningLevel>Level3</WarningLevel>
103
+ <Optimization>Disabled</Optimization>
104
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
105
+ <AdditionalIncludeDirectories>$(OCI_SDK_PATH)\include;..\..\..\main\cpp\common</AdditionalIncludeDirectories>
106
+ </ClCompile>
107
+ <Link>
108
+ <SubSystem>Console</SubSystem>
109
+ <GenerateDebugInformation>true</GenerateDebugInformation>
110
+ <AdditionalLibraryDirectories>$(OCI_SDK_PATH)\lib\msvc</AdditionalLibraryDirectories>
111
+ <AdditionalDependencies>oci.lib;%(AdditionalDependencies)</AdditionalDependencies>
112
+ </Link>
113
+ </ItemDefinitionGroup>
114
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
115
+ <ClCompile>
116
+ <WarningLevel>Level3</WarningLevel>
117
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
118
+ <Optimization>MaxSpeed</Optimization>
119
+ <FunctionLevelLinking>true</FunctionLevelLinking>
120
+ <IntrinsicFunctions>true</IntrinsicFunctions>
121
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
122
+ <AdditionalIncludeDirectories>$(OCI_SDK_PATH)\include;..\..\..\main\cpp\common</AdditionalIncludeDirectories>
123
+ </ClCompile>
124
+ <Link>
125
+ <SubSystem>Console</SubSystem>
126
+ <GenerateDebugInformation>true</GenerateDebugInformation>
127
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
128
+ <OptimizeReferences>true</OptimizeReferences>
129
+ <AdditionalLibraryDirectories>$(OCI_SDK_PATH)\lib\msvc</AdditionalLibraryDirectories>
130
+ <AdditionalDependencies>oci.lib;%(AdditionalDependencies)</AdditionalDependencies>
131
+ </Link>
132
+ </ItemDefinitionGroup>
133
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
134
+ <ClCompile>
135
+ <WarningLevel>Level3</WarningLevel>
136
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
137
+ <Optimization>MaxSpeed</Optimization>
138
+ <FunctionLevelLinking>true</FunctionLevelLinking>
139
+ <IntrinsicFunctions>true</IntrinsicFunctions>
140
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
141
+ <AdditionalIncludeDirectories>$(OCI_SDK_PATH)\include;..\..\..\main\cpp\common</AdditionalIncludeDirectories>
142
+ </ClCompile>
143
+ <Link>
144
+ <SubSystem>Console</SubSystem>
145
+ <GenerateDebugInformation>true</GenerateDebugInformation>
146
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
147
+ <OptimizeReferences>true</OptimizeReferences>
148
+ <AdditionalLibraryDirectories>$(OCI_SDK_PATH)\lib\msvc</AdditionalLibraryDirectories>
149
+ <AdditionalDependencies>oci.lib;%(AdditionalDependencies)</AdditionalDependencies>
150
+ </Link>
151
+ </ItemDefinitionGroup>
152
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
153
+ <ImportGroup Label="ExtensionTargets">
154
+ </ImportGroup>
155
+ </Project>
@@ -0,0 +1,187 @@
1
+ package org.embulk.input.filesplit;
2
+
3
+ import java.io.BufferedInputStream;
4
+ import java.io.ByteArrayInputStream;
5
+ import java.io.ByteArrayOutputStream;
6
+ import java.io.File;
7
+ import java.io.FileInputStream;
8
+ import java.io.IOException;
9
+ import java.io.InputStream;
10
+ import java.io.SequenceInputStream;
11
+ import java.util.ArrayList;
12
+ import java.util.List;
13
+
14
+ import org.embulk.config.CommitReport;
15
+ import org.embulk.config.Config;
16
+ import org.embulk.config.ConfigDefault;
17
+ import org.embulk.config.ConfigDiff;
18
+ import org.embulk.config.ConfigInject;
19
+ import org.embulk.config.ConfigSource;
20
+ import org.embulk.config.Task;
21
+ import org.embulk.config.TaskSource;
22
+ import org.embulk.spi.BufferAllocator;
23
+ import org.embulk.spi.Exec;
24
+ import org.embulk.spi.FileInputPlugin;
25
+ import org.embulk.spi.TransactionalFileInput;
26
+ import org.embulk.spi.util.InputStreamFileInput;
27
+
28
+ import com.google.common.base.Optional;
29
+
30
+
31
+ public class LocalFileSplitInputPlugin
32
+ implements FileInputPlugin
33
+ {
34
+ public interface PluginTask
35
+ extends Task
36
+ {
37
+ @Config("path")
38
+ public String getPath();
39
+
40
+ @Config("tasks")
41
+ @ConfigDefault("null")
42
+ public Optional<Integer> getTasks();
43
+
44
+ @Config("header_line")
45
+ @ConfigDefault("false")
46
+ public boolean getHeaderLine();
47
+
48
+ public List<PartialFile> getFiles();
49
+ public void setFiles(List<PartialFile> files);
50
+
51
+ @ConfigInject
52
+ public BufferAllocator getBufferAllocator();
53
+ }
54
+
55
+ @Override
56
+ public ConfigDiff transaction(ConfigSource config, FileInputPlugin.Control control)
57
+ {
58
+ PluginTask task = config.loadConfig(PluginTask.class);
59
+
60
+ int tasks;
61
+ if (task.getTasks().isPresent()) {
62
+ tasks = task.getTasks().get();
63
+ if (tasks <= 0) {
64
+ throw new IllegalArgumentException(String.format("'tasks' is %d but must be greater than 0", tasks));
65
+ }
66
+ } else {
67
+ tasks = Runtime.getRuntime().availableProcessors() * 2;
68
+ }
69
+
70
+ long size = new File(task.getPath()).length();
71
+ List<PartialFile> files = new ArrayList<PartialFile>();
72
+ for (int i = 0; i < tasks; i++) {
73
+ long start = size * i / tasks;
74
+ long end = size * (i + 1) / tasks;
75
+ if (start < end) {
76
+ files.add(new PartialFile(task.getPath(), start, end));
77
+ }
78
+ }
79
+
80
+ task.setFiles(files);
81
+
82
+ return resume(task.dump(), task.getFiles().size(), control);
83
+ }
84
+
85
+ @Override
86
+ public ConfigDiff resume(TaskSource taskSource,
87
+ int taskCount,
88
+ FileInputPlugin.Control control)
89
+ {
90
+ control.run(taskSource, taskCount);
91
+
92
+ return Exec.newConfigDiff();
93
+ }
94
+
95
+ @Override
96
+ public void cleanup(TaskSource taskSource,
97
+ int taskCount,
98
+ List<CommitReport> successCommitReports)
99
+ { }
100
+
101
+ @Override
102
+ public TransactionalFileInput open(TaskSource taskSource, int taskIndex)
103
+ {
104
+ PluginTask task = taskSource.loadTask(PluginTask.class);
105
+ return new LocalFileSplitInput(task, taskIndex);
106
+ }
107
+
108
+ public static class LocalFileSplitInput
109
+ extends InputStreamFileInput
110
+ implements TransactionalFileInput
111
+ {
112
+ public static class FileSplitProvider
113
+ implements InputStreamFileInput.Provider
114
+ {
115
+ private final PartialFile file;
116
+ private final boolean hasHeader;
117
+ private boolean opened = false;
118
+
119
+ public FileSplitProvider(PartialFile file, boolean hasHeader)
120
+ {
121
+ this.file = file;
122
+ this.hasHeader = hasHeader;
123
+ }
124
+
125
+ @Override
126
+ public InputStream openNext() throws IOException
127
+ {
128
+ if (opened) {
129
+ return null;
130
+ }
131
+ opened = true;
132
+
133
+ InputStream in = new PartialFileInputStream(new FileInputStream(file.getPath()), file.getStart(), file.getEnd());
134
+ if (file.getStart() > 0 && hasHeader) {
135
+ in = new SequenceInputStream(openHeader(file.getPath()), in);
136
+ }
137
+ return in;
138
+ }
139
+
140
+ @Override
141
+ public void close() { }
142
+
143
+ private InputStream openHeader(String path) throws IOException
144
+ {
145
+ ByteArrayOutputStream header = new ByteArrayOutputStream();
146
+ try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(path))) {
147
+ while (true) {
148
+ int c = in.read();
149
+ if (c < 0) {
150
+ break;
151
+ }
152
+
153
+ header.write(c);
154
+
155
+ if (c == '\n') {
156
+ break;
157
+ }
158
+
159
+ if (c == '\r') {
160
+ int c2 = in.read();
161
+ if (c2 == '\n') {
162
+ header.write(c2);
163
+ }
164
+ break;
165
+ }
166
+ }
167
+ }
168
+ header.close();
169
+ return new ByteArrayInputStream(header.toByteArray());
170
+ }
171
+ }
172
+
173
+ public LocalFileSplitInput(PluginTask task, int taskIndex)
174
+ {
175
+ super(task.getBufferAllocator(), new FileSplitProvider(task.getFiles().get(taskIndex), task.getHeaderLine()));
176
+ }
177
+
178
+ @Override
179
+ public void abort() { }
180
+
181
+ @Override
182
+ public CommitReport commit()
183
+ {
184
+ return Exec.newCommitReport();
185
+ }
186
+ }
187
+ }