Repository: incubator-trafodion Updated Branches: refs/heads/master 0ff0d92a1 -> e1ae98fb0
add json loading function Project: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/commit/2c71ae1d Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/tree/2c71ae1d Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/diff/2c71ae1d Branch: refs/heads/master Commit: 2c71ae1d18ec34e1a58c8bd1db698a9715d5db1b Parents: 574452e Author: SuJinpei <[email protected]> Authored: Mon Sep 18 15:03:07 2017 +0800 Committer: SuJinpei <[email protected]> Committed: Mon Sep 18 15:03:07 2017 +0800 ---------------------------------------------------------------------- core/conn/odb/Makefile | 7 +- core/conn/odb/odb/odb.vcxproj | 342 ++++++++-------- core/conn/odb/odb/odb.vcxproj.filters | 92 +++-- core/conn/odb/src/JsonReader.c | 540 +++++++++++++++++++++++++ core/conn/odb/src/JsonReader.h | 142 +++++++ core/conn/odb/src/odb.c | 609 ++++++++++++++++++++++++++++- 6 files changed, 1516 insertions(+), 216 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/2c71ae1d/core/conn/odb/Makefile ---------------------------------------------------------------------- diff --git a/core/conn/odb/Makefile b/core/conn/odb/Makefile index 09936ce..1911d47 100644 --- a/core/conn/odb/Makefile +++ b/core/conn/odb/Makefile @@ -65,9 +65,9 @@ profile: CFLAGS_LNX += -DODB_PROFILE profile: LIBS_64luo += -lrt profile: generic -odb64luo: odb64luo.o mreadline.o memcpy_wrapper.o versodb.o +odb64luo: odb64luo.o mreadline.o memcpy_wrapper.o versodb.o JsonReader.o gcc -m64 -O2 -mtune=generic -DODBC64 -DHDFS -DXML $(LDFLAGS_LNX) \ - -o $(EXEC_64luo) bin/memcpy_wrapper.o bin/odb64luo.o bin/mreadline.o bin/versodb.o \ + -o $(EXEC_64luo) bin/memcpy_wrapper.o bin/odb64luo.o bin/mreadline.o bin/versodb.o bin/JsonReader.o \ -D ODBBLD=$(ODBBLD_64luo) $(LIBPATH_64luo) $(INCPATH_64luo) $(LIBS_64luo) -o bin/odb64luo tar -czf ../clients/odb64_linux.tar.gz bin/odb64luo README ln -sf $(TRAF_HOME)/../conn/odb/bin/odb64luo $(TRAF_HOME)/export/bin$(SQ_MBTYPE)/odb64luo @@ -92,6 +92,9 @@ memcpy_wrapper.o: memcpy_wrapper.c versodb.o: versodb.c gcc -m64 -O2 -mtune=generic -g -c src/versodb.c $(INCPATH_64luo) -o bin/versodb.o +JsonReader.o: JsonReader.c + gcc $(CFLAGS_LNX) -c src/JsonReader.c -o bin/JsonReader.o + clean: rm -f bin/*.o bin/odb64luo rm -f ../clients/odb64_linux.tar.gz http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/2c71ae1d/core/conn/odb/odb/odb.vcxproj ---------------------------------------------------------------------- diff --git a/core/conn/odb/odb/odb.vcxproj b/core/conn/odb/odb/odb.vcxproj old mode 100644 new mode 100755 index 153cebe..61e964e --- a/core/conn/odb/odb/odb.vcxproj +++ b/core/conn/odb/odb/odb.vcxproj @@ -1,171 +1,173 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{EB971278-DDE8-4A67-8433-D66A54D42FAD}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>odb</RootNamespace> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <IncludePath>C:\zlib\include;$(IncludePath)</IncludePath> - <LibraryPath>C:\zlib\lib;$(LibraryPath)</LibraryPath> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - <IncludePath>C:\zlib\include;$(IncludePath)</IncludePath> - <LibraryPath>C:\zlib\lib;$(LibraryPath)</LibraryPath> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - <IncludePath>C:\zlib\include;$(IncludePath)</IncludePath> - <LibraryPath>C:\zlib\lib;$(LibraryPath)</LibraryPath> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>zlibstat.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader> - </PrecompiledHeader> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <AdditionalIncludeDirectories>$(ZlibIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader> - </PrecompiledHeader> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - </ClCompile> - <Link> - <AdditionalLibraryDirectories>$(ZlibLibDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <AdditionalDependencies>zlibstat.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\src\memcpy_wrapper.c" /> - <ClCompile Include="..\src\mreadline.c" /> - <ClCompile Include="..\src\odb.c" /> - <ClCompile Include="..\src\versodb.c" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\src\verslib.h" /> - <ClInclude Include="resource.h" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="odb.rc" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{EB971278-DDE8-4A67-8433-D66A54D42FAD}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>odb</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <IncludePath>C:\zlib\include;$(IncludePath)</IncludePath> + <LibraryPath>C:\zlib\lib;$(LibraryPath)</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <IncludePath>C:\zlib\include;$(IncludePath)</IncludePath> + <LibraryPath>C:\zlib\lib;$(LibraryPath)</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <IncludePath>C:\zlib\include;$(IncludePath)</IncludePath> + <LibraryPath>C:\zlib\lib;$(LibraryPath)</LibraryPath> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>zlibstat.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <AdditionalIncludeDirectories>$(ZlibIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <AdditionalLibraryDirectories>$(ZlibLibDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>zlibstat.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\src\JsonReader.c" /> + <ClCompile Include="..\src\memcpy_wrapper.c" /> + <ClCompile Include="..\src\mreadline.c" /> + <ClCompile Include="..\src\odb.c" /> + <ClCompile Include="..\src\versodb.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\src\JsonReader.h" /> + <ClInclude Include="..\src\verslib.h" /> + <ClInclude Include="resource.h" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="odb.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/2c71ae1d/core/conn/odb/odb/odb.vcxproj.filters ---------------------------------------------------------------------- diff --git a/core/conn/odb/odb/odb.vcxproj.filters b/core/conn/odb/odb/odb.vcxproj.filters old mode 100644 new mode 100755 index c5a0e1c..50cd90a --- a/core/conn/odb/odb/odb.vcxproj.filters +++ b/core/conn/odb/odb/odb.vcxproj.filters @@ -1,44 +1,50 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\src\memcpy_wrapper.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\src\mreadline.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\src\odb.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\src\versodb.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\src\verslib.h"> - <Filter>Source Files</Filter> - </ClInclude> - <ClInclude Include="resource.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="odb.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\src\memcpy_wrapper.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\src\mreadline.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\src\odb.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\src\versodb.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\src\JsonReader.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\src\verslib.h"> + <Filter>Source Files</Filter> + </ClInclude> + <ClInclude Include="resource.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\src\JsonReader.h"> + <Filter>Source Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="odb.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/2c71ae1d/core/conn/odb/src/JsonReader.c ---------------------------------------------------------------------- diff --git a/core/conn/odb/src/JsonReader.c b/core/conn/odb/src/JsonReader.c new file mode 100755 index 0000000..d118ee8 --- /dev/null +++ b/core/conn/odb/src/JsonReader.c @@ -0,0 +1,540 @@ +#include "JsonReader.h" +#include <errno.h> +#include <string.h> + +JsonReader *jsonReaderNew(const char *path) +{ + JsonReader *pJsonReader = (JsonReader *)calloc(1, sizeof(JsonReader)); + if (!pJsonReader) { + return NULL; + } + + pJsonReader->jsonFile = fopen(path, "r"); + if (!pJsonReader->jsonFile) { + free(pJsonReader); + return NULL; + } + + strncpy(pJsonReader->jsonFileName, path, JSON_PARSER_MAX_FILE_NAME_LEN); + pJsonReader->nestDepth = 0; + pJsonReader->state = JSON_STATE_START; + pJsonReader->errorCode = JSON_SUCCESS; + pJsonReader->currentCharPtr = pJsonReader->buf; + + return pJsonReader; +} + +JsonReaderError jsonMoveCurrentCharPtr(JsonReader *pJsonReader) +{ + if (pJsonReader->isBufReady) { + ++pJsonReader->currentCharPtr; + } + + if (pJsonReader->currentCharPtr == pJsonReader->buf + pJsonReader->numberReadBuf) { + if ((pJsonReader->numberReadBuf = fread(pJsonReader->buf, sizeof(char), JSON_PARSER_BUF_LEN, pJsonReader->jsonFile))) { + pJsonReader->currentCharPtr = pJsonReader->buf; + pJsonReader->isBufReady = true; + } + else { + pJsonReader->errorCode = JSON_ERROR_PARSE_EOF; + } + } + + if (*(pJsonReader->currentCharPtr) == '\n') { + ++pJsonReader->lineNum; + pJsonReader->linePos = 0; + } + else { + ++pJsonReader->linePos; + } + + return pJsonReader->errorCode; +} + +JsonReaderError jsonSaveAndToState(JsonReader *pJsonReader, JsonReaderState state) +{ + if (pJsonReader->nestDepth < JSON_PARSER_MAX_NESTED_NUM) { + pJsonReader->statesSave[(pJsonReader->nestDepth)++] = pJsonReader->state; + pJsonReader->state = state; + } + else { + pJsonReader->errorCode = JSON_ERROR_DEPTH; + } + + return pJsonReader->errorCode; +} + +JsonReaderError jsonReaderSetTmpbuf(JsonReader *pJsonReader, char *buf, size_t len) +{ + pJsonReader->tmpSaveBuf = buf; + pJsonReader->bufLen = len; + return pJsonReader->errorCode; +} + +JsonReaderError jsonReaderUnsetTmpbuf(JsonReader *pJsonReader) +{ + pJsonReader->tmpSaveBuf = NULL; + pJsonReader->bufLen = 0; + return pJsonReader->errorCode; +} + +JsonReaderError jsonParseStateStart(JsonReader *pJsonReader) +{ + while (jsonMoveCurrentCharPtr(pJsonReader) == JSON_SUCCESS) { + if (IS_NOT_WHITE_SPACE(*(pJsonReader->currentCharPtr))) { + if (*pJsonReader->currentCharPtr == '{') { + pJsonReader->state = JSON_STATE_OBJECT_INITIAL; + break; + } + else if (*pJsonReader->currentCharPtr == '[') { + pJsonReader->state = JSON_STATE_ARRAY_INITIAL; + break; + } + else { + pJsonReader->errorCode = JSON_ERROR_BAD_FORMAT; + break; + } + } + } + + return pJsonReader->errorCode; +} + +JsonReaderError jsonParseObjectInitial(JsonReader *pJsonReader) +{ + while (jsonMoveCurrentCharPtr(pJsonReader) == JSON_SUCCESS) { + if (IS_NOT_WHITE_SPACE(*(pJsonReader->currentCharPtr))) { + switch (*pJsonReader->currentCharPtr) + { + case '"': + pJsonReader->state = JSON_STATE_MEMBER_KEY; + goto ret; + case '}': + pJsonReader->state = JSON_STATE_OBJECT_FINISH; + goto ret; + default: + pJsonReader->errorCode = JSON_ERROR_BAD_FORMAT; + goto ret; + } + } + } + +ret: + return pJsonReader->errorCode; +} + +char *jsonGetStringValue(JsonReader *pJsonReader, char *strValue, size_t len) +{ + bool isEscape = 0; + size_t pos = 0; + + while (jsonMoveCurrentCharPtr(pJsonReader) == JSON_SUCCESS) { + if (isEscape) { + if (strValue && pos < len) + strValue[pos++] = *pJsonReader->currentCharPtr; + isEscape = false; + } + else { + switch (*pJsonReader->currentCharPtr) { + case '"': + if (strValue && pos < len) + strValue[pos++] = '\0'; + goto ret; + case '\\': + isEscape = true; + break; + default: + if (strValue && pos < len) + strValue[pos++] = *pJsonReader->currentCharPtr; + break; + } + } + } + +ret: + if (strValue) + strValue[len - 1] = '\0'; + return strValue; +} + +JsonReaderError jsonParseMemberKey(JsonReader *pJsonReader) +{ + jsonGetStringValue(pJsonReader, pJsonReader->tmpSaveBuf, pJsonReader->bufLen); + while (jsonMoveCurrentCharPtr(pJsonReader) == JSON_SUCCESS) { + if (IS_NOT_WHITE_SPACE(*(pJsonReader->currentCharPtr))) { + if (*pJsonReader->currentCharPtr == ':') { + pJsonReader->state = JSON_STATE_KEY_VALUE_DELIMITER; + break; + } + else { + pJsonReader->errorCode = JSON_ERROR_BAD_FORMAT; + break; + } + } + } + + return pJsonReader->errorCode; +} + +JsonReaderError jsonParseKeyValueDelimiter(JsonReader *pJsonReader) +{ + while (jsonMoveCurrentCharPtr(pJsonReader) == JSON_SUCCESS) { + if (IS_NOT_WHITE_SPACE(*(pJsonReader->currentCharPtr))) { + switch (*(pJsonReader->currentCharPtr)) { + CASE_VALUE: + pJsonReader->state = JSON_STATE_MEMBER_VALUE; + goto ret; + case '[': + jsonSaveAndToState(pJsonReader, JSON_STATE_ARRAY_INITIAL); + goto ret; + case '{': + jsonSaveAndToState(pJsonReader, JSON_STATE_OBJECT_INITIAL); + goto ret; + default: + pJsonReader->errorCode = JSON_ERROR_BAD_FORMAT; + goto ret; + } + } + } +ret: + return pJsonReader->errorCode; +} + +JsonReaderError jsonInternalGetValue(JsonReader *pJsonReader, char *endChars, size_t len) +{ + const char *pBooleanOrNull = NULL; + // string + if (*pJsonReader->currentCharPtr == '"' && pJsonReader->tmpSaveBuf) { + jsonGetStringValue(pJsonReader, pJsonReader->tmpSaveBuf, pJsonReader->bufLen); + } + // maybe false,true,null + else if ((*pJsonReader->currentCharPtr == 'f' ? (pBooleanOrNull = "false") : 0) || + (*pJsonReader->currentCharPtr == 't' ? (pBooleanOrNull = "true") : 0) || + (*pJsonReader->currentCharPtr == 'n' ? (pBooleanOrNull = "null") : 0)) { + size_t lenBN = strlen(pBooleanOrNull); + size_t pos = 1; + while ((jsonMoveCurrentCharPtr(pJsonReader) == JSON_SUCCESS) && (pos < lenBN)) { + if (pBooleanOrNull[pos] != *pJsonReader->currentCharPtr) { + break; + } + ++pos; + } + if ((pos < lenBN) || (IS_NOT_WHITE_SPACE(*pJsonReader->currentCharPtr) && + !IN_CHARS(*pJsonReader->currentCharPtr, endChars, lenBN))) { + pJsonReader->errorCode = JSON_ERROR_BAD_FORMAT; + } + if (pJsonReader->tmpSaveBuf) { + strncpy(pJsonReader->tmpSaveBuf, pBooleanOrNull, pJsonReader->bufLen); + } + } + // should be number + else { + size_t pos = 0; + do { + if (IS_NOT_WHITE_SPACE(*pJsonReader->currentCharPtr) && + !IN_CHARS(*pJsonReader->currentCharPtr, endChars, len)) { + if (pJsonReader->tmpSaveBuf && pos < pJsonReader->bufLen) { + pJsonReader->tmpSaveBuf[pos++] = *pJsonReader->currentCharPtr; + } + } + else { + break; + } + } while (jsonMoveCurrentCharPtr(pJsonReader) == JSON_SUCCESS); + if (pJsonReader->tmpSaveBuf) { + pJsonReader->tmpSaveBuf[pos < len ? pos : len] = '\0'; + } + } + return pJsonReader->errorCode; +} + +JsonReaderError jsonParseMemberValueEnd(JsonReader *pJsonReader) +{ + do { + if (IS_NOT_WHITE_SPACE(*pJsonReader->currentCharPtr)) { + if (*pJsonReader->currentCharPtr == ',') { + pJsonReader->state = JSON_STATE_MEMBER_DELIMITER; + break; + } + else if (*pJsonReader->currentCharPtr == '}') { + pJsonReader->state = JSON_STATE_OBJECT_FINISH; + break; + } + else if (*pJsonReader->currentCharPtr != '"') { + pJsonReader->errorCode = JSON_ERROR_BAD_FORMAT; + break; + } + } + } while (jsonMoveCurrentCharPtr(pJsonReader) == JSON_SUCCESS); + return pJsonReader->errorCode; +} + +JsonReaderError jsonParseElementEnd(JsonReader *pJsonReader) +{ + do { + if (IS_NOT_WHITE_SPACE(*pJsonReader->currentCharPtr)) { + if (*pJsonReader->currentCharPtr == ',') { + pJsonReader->state = JSON_STATE_ELEMENT_DELIMITER; + break; + } + else if (*pJsonReader->currentCharPtr == ']') { + pJsonReader->state = JSON_STATE_ARRAY_FINISH; + break; + } + else if (*pJsonReader->currentCharPtr != '"') { + pJsonReader->errorCode = JSON_ERROR_BAD_FORMAT; + break; + } + } + } while (jsonMoveCurrentCharPtr(pJsonReader) == JSON_SUCCESS); + + return pJsonReader->errorCode; +} + +JsonReaderError jsonParseMemberValue(JsonReader *pJsonReader) { + + if (jsonInternalGetValue(pJsonReader, ",}", 2) == JSON_SUCCESS) { + jsonParseMemberValueEnd(pJsonReader); + } + + return pJsonReader->errorCode; +} + +JsonReaderError jsonParseMemberDelimiter(JsonReader *pJsonReader) +{ + while (jsonMoveCurrentCharPtr(pJsonReader) == JSON_SUCCESS) { + if (IS_NOT_WHITE_SPACE(*pJsonReader->currentCharPtr)) { + if (*pJsonReader->currentCharPtr == '"') { + pJsonReader->state = JSON_STATE_MEMBER_KEY; + break; + } + else { + pJsonReader->errorCode = JSON_ERROR_BAD_FORMAT; + break; + } + } + } + + return pJsonReader->errorCode; +} + +JsonReaderError jsonParseObjectFinish(JsonReader *pJsonReader) +{ + if (pJsonReader->nestDepth == 0) { + while (jsonMoveCurrentCharPtr(pJsonReader) == JSON_SUCCESS) { + if (IS_NOT_WHITE_SPACE(*pJsonReader->currentCharPtr)) { + pJsonReader->errorCode = JSON_ERROR_BAD_FORMAT; + break; + } + } + } + else { + switch (pJsonReader->statesSave[--(pJsonReader->nestDepth)]) + { + case JSON_STATE_ARRAY_INITIAL: + case JSON_STATE_ELEMENT_DELIMITER: + jsonMoveCurrentCharPtr(pJsonReader); + jsonParseElementEnd(pJsonReader); + break; + case JSON_STATE_KEY_VALUE_DELIMITER: + jsonMoveCurrentCharPtr(pJsonReader); + jsonParseMemberValueEnd(pJsonReader); + break; + default: + pJsonReader->errorCode = JSON_ERROR_STATE; + break; + } + } + return pJsonReader->errorCode; +} + +JsonReaderError jsonParseArrayInitial(JsonReader *pJsonReader) +{ + while (jsonMoveCurrentCharPtr(pJsonReader) == JSON_SUCCESS) { + if (IS_NOT_WHITE_SPACE(*pJsonReader->currentCharPtr)) { + switch (*pJsonReader->currentCharPtr) + { + case '{': + jsonSaveAndToState(pJsonReader, JSON_STATE_OBJECT_INITIAL); + goto ret; + case '[': + jsonSaveAndToState(pJsonReader, JSON_STATE_ARRAY_INITIAL); + goto ret; + case ']': + pJsonReader->state = JSON_STATE_ARRAY_FINISH; + goto ret; + CASE_VALUE: + pJsonReader->state = JSON_STATE_ELEMENT; + goto ret; + default: + pJsonReader->errorCode = JSON_ERROR_BAD_FORMAT; + goto ret; + } + } + } + +ret: + return pJsonReader->errorCode; +} + +JsonReaderError jsonParseElement(JsonReader *pJsonReader) +{ + if (jsonInternalGetValue(pJsonReader, "],", 2) == JSON_SUCCESS) { + jsonParseElementEnd(pJsonReader); + } + + return pJsonReader->errorCode; +} + +JsonReaderError jsonParseElementDelimiter(JsonReader *pJsonReader) +{ + while (jsonMoveCurrentCharPtr(pJsonReader) == JSON_SUCCESS) { + if (IS_NOT_WHITE_SPACE(*pJsonReader->currentCharPtr)) { + switch (*pJsonReader->currentCharPtr) + { + CASE_VALUE: + pJsonReader->state = JSON_STATE_ELEMENT; + goto ret; + case '[': + jsonSaveAndToState(pJsonReader, JSON_STATE_ARRAY_INITIAL); + goto ret; + case '{': + jsonSaveAndToState(pJsonReader, JSON_STATE_OBJECT_INITIAL); + goto ret; + default: + pJsonReader->errorCode = JSON_ERROR_BAD_FORMAT; + goto ret; + } + } + } + +ret: + return pJsonReader->errorCode; +} + +JsonReaderError jsonParseArrayFinish(JsonReader *pJsonReader) +{ + if (pJsonReader->nestDepth == 0) { + while (jsonMoveCurrentCharPtr(pJsonReader) == JSON_SUCCESS) { + if (IS_NOT_WHITE_SPACE(*pJsonReader->currentCharPtr)) { + pJsonReader->errorCode = JSON_ERROR_BAD_FORMAT; + break; + } + } + } + else { + switch (pJsonReader->statesSave[--(pJsonReader->nestDepth)]) + { + case JSON_STATE_KEY_VALUE_DELIMITER: + jsonMoveCurrentCharPtr(pJsonReader); + jsonParseMemberValueEnd(pJsonReader); + break; + case JSON_STATE_ELEMENT_DELIMITER: + case JSON_STATE_ARRAY_INITIAL: + jsonMoveCurrentCharPtr(pJsonReader); + jsonParseElementEnd(pJsonReader); + break; + default: + pJsonReader->errorCode = JSON_ERROR_BAD_FORMAT; + break; + } + } + + return pJsonReader->errorCode; +} + +JsonReaderError jsonReadKey(JsonReader *pJsonReader, char *keyBuf, size_t len) +{ + if (pJsonReader->state == JSON_STATE_MEMBER_KEY) { + jsonReaderSetTmpbuf(pJsonReader, keyBuf, len); + jsonParseMemberKey(pJsonReader); + jsonReaderUnsetTmpbuf(pJsonReader); + } + else { + pJsonReader->errorCode = JSON_ERROR_STATE; + } + return pJsonReader->errorCode; +} + +JsonReaderError jsonReadMemberValue(JsonReader *pJsonReader, char *memberValbuf, size_t len) +{ + if (pJsonReader->state == JSON_STATE_MEMBER_VALUE) { + jsonReaderSetTmpbuf(pJsonReader, memberValbuf, len); + jsonParseMemberValue(pJsonReader); + jsonReaderUnsetTmpbuf(pJsonReader); + } + else { + pJsonReader->errorCode = JSON_ERROR_STATE; + } + return pJsonReader->errorCode; +} + +JsonReaderError jsonReadArrayValue(JsonReader *pJsonReader, char *arrayValBuf, size_t len) +{ + if (pJsonReader->state == JSON_STATE_ELEMENT) { + jsonReaderSetTmpbuf(pJsonReader, arrayValBuf, len); + jsonParseElement(pJsonReader); + jsonReaderUnsetTmpbuf(pJsonReader); + } + else { + pJsonReader->errorCode = JSON_ERROR_STATE; + } + return pJsonReader->errorCode; +} + +JsonReaderError jsonRead(JsonReader *pJsonReader) { + switch (pJsonReader->state) + { + case JSON_STATE_START: + jsonParseStateStart(pJsonReader); + break; + case JSON_STATE_OBJECT_INITIAL: + jsonParseObjectInitial(pJsonReader); + break; + case JSON_STATE_ARRAY_INITIAL: + jsonParseArrayInitial(pJsonReader); + break; + case JSON_STATE_MEMBER_KEY: + jsonParseMemberKey(pJsonReader); + break; + case JSON_STATE_ELEMENT: + jsonParseElement(pJsonReader); + break; + case JSON_STATE_KEY_VALUE_DELIMITER: + jsonParseKeyValueDelimiter(pJsonReader); + break; + case JSON_STATE_ELEMENT_DELIMITER: + jsonParseElementDelimiter(pJsonReader); + break; + case JSON_STATE_ARRAY_FINISH: + jsonParseArrayFinish(pJsonReader); + break; + case JSON_STATE_MEMBER_VALUE: + jsonParseMemberValue(pJsonReader); + break; + case JSON_STATE_MEMBER_DELIMITER: + jsonParseMemberDelimiter(pJsonReader); + break; + case JSON_STATE_OBJECT_FINISH: + jsonParseObjectFinish(pJsonReader); + break; + default: + break; + } + return pJsonReader->errorCode; +} + +JsonReaderError jsonParse(JsonReader *pJsonReader) +{ + while ((pJsonReader->errorCode == JSON_SUCCESS)) { + jsonRead(pJsonReader); + } + + return pJsonReader->errorCode; +} + +void jsonReaderFree(JsonReader *pJsonReader) +{ + fclose(pJsonReader->jsonFile); + free(pJsonReader); +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/2c71ae1d/core/conn/odb/src/JsonReader.h ---------------------------------------------------------------------- diff --git a/core/conn/odb/src/JsonReader.h b/core/conn/odb/src/JsonReader.h new file mode 100755 index 0000000..d23dc23 --- /dev/null +++ b/core/conn/odb/src/JsonReader.h @@ -0,0 +1,142 @@ +#ifndef JSONREADER_H +#define JSONREADER_H + +#include <stdlib.h> +#include <stdio.h> + +#define JSON_PARSER_BUF_LEN 1024 +#define JSON_PARSER_ERROR_MESSAGE_LEN 512 +#define JSON_PARSER_MAX_FILE_NAME_LEN 256 +#define JSON_PARSER_MAX_NESTED_NUM 100 + +#ifndef bool +#define bool unsigned char +#endif // !_Bool + +#ifndef true +#define true 1 +#endif // !true + +#ifndef false +#define false 0 +#endif // !false + + +enum JsonReaderState_ +{ + JSON_STATE_START, + JSON_STATE_OBJECT_INITIAL, + JSON_STATE_ARRAY_INITIAL, + JSON_STATE_MEMBER_KEY, + JSON_STATE_ELEMENT, + JSON_STATE_KEY_VALUE_DELIMITER, + JSON_STATE_ELEMENT_DELIMITER, + JSON_STATE_ARRAY_FINISH, + JSON_STATE_MEMBER_VALUE, + JSON_STATE_MEMBER_DELIMITER, + JSON_STATE_OBJECT_FINISH, + JSON_STATE_FINISH +}; +typedef enum JsonReaderState_ JsonReaderState; + +enum JsonReaderError_ +{ + JSON_SUCCESS, + JSON_CONTINUE, + JSON_ERROR_DEPTH, + JSON_ERROR_PARSE_EOF, + JSON_ERROR_PARSE_UNEXPECTED, + JSON_ERROR_PARSE_NULL, + JSON_ERROR_PARSE_BOOLEAN, + JSON_ERROR_PARSE_NUMBER, + JSON_ERROR_PARSE_ARRAY, + JSON_ERROR_PARSE_OBJECT_KEY_NAME, + JSON_ERROR_PARSE_OBJECT_KEY_SEP, + JSON_ERROR_PARSE_OBJECT_VALUE_SEP, + JSON_ERROR_PARSE_STRING, + JSON_ERROR_PARSE_COMMENT, + JSON_ERROR_SIZE, + JSON_ERROR_STATE, + JSON_ERROR_BAD_FORMAT +}; +typedef enum JsonReaderError_ JsonReaderError; + +#define IS_NOT_WHITE_SPACE(c) (((c)!=' ') && ((c)!='\t') && ((c)!='\n') && ((c)!='\r')) +// 1 <= len <= 3 +#define IN_CHARS(c, cs, len) (((c) == (cs)[0]) || ((len) > 1 && (c) == (cs)[1]) || ((len) > 2 && (c) == (cs)[2])) +#define CASE_VALUE case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':case '-':case 'f':case 't':case 'n':case '"' + +struct JsonReader_ +{ + bool isBufReady; + FILE *jsonFile; + char *tmpSaveBuf; // save parsed contents. + size_t bufLen; + size_t nestDepth; + JsonReaderState state; + JsonReaderError errorCode; + char errorMsg[JSON_PARSER_ERROR_MESSAGE_LEN]; + char buf[JSON_PARSER_BUF_LEN]; + char *currentCharPtr; + char jsonFileName[JSON_PARSER_MAX_FILE_NAME_LEN]; + size_t numberReadBuf; + size_t lineNum; + size_t linePos; + JsonReaderState statesSave[JSON_PARSER_MAX_NESTED_NUM]; +}; + +typedef struct JsonReader_ JsonReader; + +JsonReader *jsonReaderNew(const char *path); + +JsonReaderError jsonMoveCurrentCharPtr(JsonReader *pJsonReader); + +JsonReaderError jsonSaveAndToState(JsonReader *pJsonReader, JsonReaderState state); + +JsonReaderError jsonReaderSetTmpbuf(JsonReader *pJsonReader, char *buf, size_t len); + +JsonReaderError jsonReaderUnsetTmpbuf(JsonReader *pJsonReader); + +JsonReaderError jsonParseStateStart(JsonReader *pJsonReader); + +JsonReaderError jsonParseObjectInitial(JsonReader *pJsonReader); + +char *jsonGetStringValue(JsonReader *pJsonReader, char *strValue, size_t len); + +JsonReaderError jsonParseMemberKey(JsonReader *pJsonReader); + +JsonReaderError jsonParseKeyValueDelimiter(JsonReader *pJsonReader); + +JsonReaderError jsonInternalGetValue(JsonReader *pJsonReader, char *endChars, size_t len); + +JsonReaderError jsonParseMemberValueEnd(JsonReader *pJsonReader); + +JsonReaderError jsonParseElementEnd(JsonReader *pJsonReader); + +JsonReaderError jsonParseMemberValue(JsonReader *pJsonReader); + +JsonReaderError jsonParseMemberDelimiter(JsonReader *pJsonReader); + +JsonReaderError jsonParseObjectFinish(JsonReader *pJsonReader); + +JsonReaderError jsonParseArrayInitial(JsonReader *pJsonReader); + +JsonReaderError jsonParseElement(JsonReader *pJsonReader); + +JsonReaderError jsonParseElementDelimiter(JsonReader *pJsonReader); + +JsonReaderError jsonParseArrayFinish(JsonReader *pJsonReader); + +JsonReaderError jsonReadKey(JsonReader *pJsonReader, char *keyBuf, size_t len); + +JsonReaderError jsonReadMemberValue(JsonReader *pJsonReader, char *memberValbuf, size_t len); + +JsonReaderError jsonReadArrayValue(JsonReader *pJsonReader, char *arrayValBuf, size_t len); + +JsonReaderError jsonRead(JsonReader *pJsonReader); + +JsonReaderError jsonParse(JsonReader *pJsonReader); + +void jsonReaderFree(JsonReader *pJsonReader); + +#endif //JSONREADER_H \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/2c71ae1d/core/conn/odb/src/odb.c ---------------------------------------------------------------------- diff --git a/core/conn/odb/src/odb.c b/core/conn/odb/src/odb.c index bf72f1b..23f7cad 100755 --- a/core/conn/odb/src/odb.c +++ b/core/conn/odb/src/odb.c @@ -63,6 +63,7 @@ char *odbauth = "Trafodion Dev <[email protected]>"; #define RWBUFF_LEN 262144 /* default read/write buffer length */ #include <zlib.h> +#include "JsonReader.h" #define windowBits 15 #define GZIP_ENCODING 16 #define ENABLE_ZLIB_GZIP 32 @@ -511,6 +512,7 @@ struct execute { #ifdef XML char *xrt; /* load: xml row tag */ #endif + char *jsonKey; /* load: json key */ unsigned int nl; /* Null string length. Copy: number of loaders per extraction thread */ unsigned int el; /* Empty String Length. Copy: total number of loaders per grandparent (ps * nl) */ unsigned int k; /* load lines to skip. extract: returned rsds. Copy: grandparent ID */ @@ -682,6 +684,7 @@ static int etabout ( int eid , char *file ); static void Oload(int eid); /* load tables using etab entries #eid */ static void Oload2(int eid); /* fast load tables using etab entries #eid (only CSV with no map, no string qualifiers no escapes */ static void OloadX(int eid); /* load tables using etab entries #eid (only from XML) */ +static void OloadJson(int eid); /* load tables using etab entries #eid (only from JSON) */ static void Oextract(int eid); /* extract tables using etab entries #eid */ static void strmcpy(char *tgt, char *src, size_t len); static unsigned int strmcat(char *tgt, char *src, size_t len, char cas); @@ -4019,6 +4022,8 @@ static void *Oruncmd(void *tid) #endif if ( etab[eid].flg & 01000000 ) Oload ( eid ) ; /* complex load */ + else if (etab[eid].jsonKey) + OloadJson ( eid ) ; else Oload2 ( eid ); /* simple (fast) CSV load */ break; @@ -9264,6 +9269,604 @@ static void OloadX(int eid) } #endif +/* OloadJson: +* load json files using parameters in etab[eid] +* +* eid (I): etab entry ID to run +* +* return: void +*/ +static void OloadJson(int eid) +{ + int tid = etab[eid].id; /* Thread ID */ + SQLCHAR *Oins = 0; /* INSERT Statement */ + SQLCHAR *Odel = 0; /* DELETE Statement */ + SQLCHAR *O = 0; /* ODBC temp variable for memory realloc */ + SQLRETURN Or = 0; /* ODBC return value */ + unsigned long nw = 0, /* no of wait cycles */ + nt = 0, /* No of total write cycles */ + nrf = 0; /* no of read records */ + long telaps = 0, /* Elapsed time in ms */ + tinit = 0; /* Initialization time in ms */ + size_t nb = 0, /* number of bytes read from input file */ + cl = CMD_CHUNK, /* INSERT command buffer length */ + cmdl = 0, /* INSERT command length */ + dell = CMD_CHUNK, /* DELETE command length */ + ifl = 0; /* input field length */ + int z = 0; /* loop variable */ + unsigned int nldr = 0, /* number of loaders */ + k = 0, /* input file field number */ + m = 0, /* rowset array record index */ + i = 0, /* loop variable */ + pstats = 0, /* Error flag: 0 = print stats, 1 = don't print stats */ + l = 0, /* destination table fields */ + j = 0; /* loop variable */ + int *ldrs = 0; /* pointer to array containing loaders EIDs */ + char buff[128]; /* buffer to build output file name */ + char num[32]; /* Formatted Number String */ + char tim[15]; /* Formatted Time String */ + struct timeval tve; /* timeval struct to define elapesd/timelines */ + SQLCHAR *Odp = 0; /* rowset buffer data pointer */ + double seconds = 0; /* seconds used for timings */ + JsonReader *pJsonReader = 0; /* XML reader */ + int readState = 0; /* 0: look for key, 1: look for array value */ + char keybuf[128]; + char valuebuf[1024]; + /* Check if we have to use another ODBC connection */ + if (thps[tid].cr > 0) { + thps[tid].Oc = thps[thps[tid].cr].Oc; + thps[tid].Os = thps[thps[tid].cr].Os; + } + + /* Set "tgt" variable */ + var_set(&thps[tid].tva, VTYPE_I, "tgt", etab[eid].tgt); + + /* Run "pre" SQL */ + if (etab[eid].pre) { + etab[eid].flg2 |= 020000000; /* Oexec to allocate/use its own handle */ + if (etab[eid].pre[0] == '@') /* run a sql script */ + z = runsql(tid, eid, 0, (etab[eid].pre + 1)); + else /* Run single SQL command */ + z = Oexec(tid, eid, 0, 0, (SQLCHAR *)etab[eid].pre, ""); + etab[eid].flg2 &= ~020000000; /* reset Oexec to allocate/use its own handle */ + if (z && etab[eid].flg & 0004) + goto oloadJson_exit; + etab[eid].nr = 0; /* reset number of resulting rows */ + (void)SQLFreeHandle(SQL_HANDLE_STMT, thps[tid].Os); + if (!SQL_SUCCEEDED(Or = SQLAllocHandle(SQL_HANDLE_STMT, thps[tid].Oc, &thps[tid].Os))) { + Oerr(eid, tid, __LINE__, Oc, SQL_HANDLE_DBC); + goto oloadJson_exit; + } + } + + /* Check database type */ + etab[eid].dbt = checkdb(eid, &thps[tid].Oc, NULL, NULL); + + /* Check if truncate */ + if (etab[eid].flg & 0002) { + etab[eid].flg &= ~0200000; /* if truncate... unset ifempty */ + if ((Odel = malloc(dell)) == (void *)NULL) { + fprintf(stderr, "odb [OloadJson(%d)] - Error allocating Odel memory: [%d] %s\n", + __LINE__, errno, strerror(errno)); + goto oloadJson_exit; + } + strmcpy((char *)Odel, dbscmds[etab[eid].dbt].trunc, dell); + Odel = (SQLCHAR *)var_exp((char *)Odel, &dell, &thps[tid].tva); + } + + /* check ifempty */ + if (etab[eid].flg & 0200000) { /* ifempty is set */ + if (ifempty(eid, etab[eid].tgt)) { + fprintf(stderr, "odb [OloadJson(%d)] - Target table %s is not empty\n", + __LINE__, etab[eid].tgt); + etab[eid].post = 0; /* prevent post SQL execution */ + goto oloadJson_exit; + } + } + + /* Open input file */ + for (i = j = 0; etab[eid].src[i] && i < sizeof(buff); i++) { + switch (etab[eid].src[i]) { + case '%': + switch (etab[eid].src[++i]) { + case 't': + j += strmcat(buff, (char *)etab[eid].Ocso[2], (size_t)etab[eid].buffsz, 2); + break; + case 'T': + j += strmcat(buff, (char *)etab[eid].Ocso[2], (size_t)etab[eid].buffsz, 1); + break; + case 's': + j += strmcat(buff, (char *)etab[eid].Ocso[1], (size_t)etab[eid].buffsz, 2); + break; + case 'S': + j += strmcat(buff, (char *)etab[eid].Ocso[1], (size_t)etab[eid].buffsz, 1); + break; + case 'c': + j += strmcat(buff, (char *)etab[eid].Ocso[0], (size_t)etab[eid].buffsz, 2); + break; + case 'C': + j += strmcat(buff, (char *)etab[eid].Ocso[0], (size_t)etab[eid].buffsz, 1); + break; + default: + fprintf(stderr, "odb [OloadJson(%d)] - Invalid expansion %%%c in %s\n", + __LINE__, etab[eid].src[i], etab[eid].src); + goto oloadJson_exit; + } + break; + default: + buff[j++] = etab[eid].src[i]; + break; + } + } + buff[j] = '\0'; + + /* Open input file */ + if (etab[eid].jsonKey) { + if ((pJsonReader = jsonReaderNew(buff)) == NULL) { + fprintf(stderr, "odb [OloadJson(%d} - Error opening json input file %s\n", __LINE__, etab[eid].src); + goto oloadJson_exit; + } + } + + /* Analyze target table */ + z = Otcol(eid, &thps[tid].Oc); + if (z <= 0) { + fprintf(stderr, "odb [OloadJson(%d)] - Error analyzing target table %s.%s.%s\n", + __LINE__, etab[eid].Ocso[0], etab[eid].Ocso[1], etab[eid].Ocso[2]); + goto oloadJson_exit; + } + else { + l = (unsigned int)z; + } + + /* Adjust Osize for WCHAR field (up to 4 bytes/char). Set buffer size */ + if (etab[eid].dbt != VERTICA) { /* Vertica's CHAR field length is in bytes (not chars) */ + for (j = 0; j < l; j++) { + switch (etab[eid].td[j].Otype) { + case SQL_WCHAR: + case SQL_WVARCHAR: + case SQL_WLONGVARCHAR: + etab[eid].td[j].Osize *= etab[eid].bpwc; /* Space for UTF-8 conversion */ + break; + case SQL_CHAR: + case SQL_VARCHAR: + case SQL_LONGVARCHAR: + etab[eid].td[j].Osize *= etab[eid].bpc;/* Space for UTF-8 conversion */ + break; + } + } + } + + /* Determine buffer start positions and size */ + for (j = 0; j < l; j++) { + etab[eid].td[j].start = etab[eid].s; +#ifdef __hpux + if (etab[eid].td[j].Osize % WORDSZ) + etab[eid].td[j].pad = WORDSZ - etab[eid].td[j].Osize % WORDSZ; +#endif + etab[eid].s += (etab[eid].td[j].Osize + etab[eid].td[j].pad + sizeof(SQLLEN)); /* space for length indicator */ + } + + /* Truncate target table */ + if (etab[eid].flg & 0002) { /* truncate target table */ + if (f & 020000) /* if verbose */ + fprintf(stderr, "odb: Now truncating target table (%s)... ", (char *)Odel); + etab[eid].flg2 |= 020000000; /* Oexec to allocate/use its own handle */ + z = Oexec(tid, eid, 0, 0, Odel, ""); /* Run Truncate */ + etab[eid].flg2 &= ~020000000; /* reset Oexec to allocate/use its own handle */ + if (j && etab[eid].flg & 0004) { + fprintf(stderr, "odb [OloadJson(%d)] - Error truncating Target table. Exiting because Stop On Error was set\n", + __LINE__); + goto oloadJson_exit; + } + if (etab[eid].cmt) { /* Autocommit off: have to commit truncate */ + if (!SQL_SUCCEEDED(Or = SQLEndTran(SQL_HANDLE_DBC, thps[tid].Oc, SQL_COMMIT))) { + Oerr(eid, tid, __LINE__, thps[tid].Oc, SQL_HANDLE_DBC); + goto oloadJson_exit; + } + } + etab[eid].nr = 0; /* reset number of resulting rows */ + if (f & 020000) /* if verbose */ + fprintf(stderr, "done\n"); + } + + /* Calculate rowset if buffer size is set */ + if (etab[eid].rbs) { + etab[eid].r = etab[eid].rbs / etab[eid].s; + etab[eid].r = etab[eid].r < 1 ? 1 : etab[eid].r; /* at least one record at a time */ + } + if (etab[eid].flg2 & 0001) /* commit as multiplier */ + etab[eid].cmt *= (int)etab[eid].r; + + /* Build INSERT statement */ + if ((Oins = malloc(cl)) == (void *)NULL) { + fprintf(stderr, "odb [OloadJson(%d)] - Error allocating Oins memory\n", __LINE__); + goto oloadJson_exit; + } + + if (!strcasecmp(etab[eid].loadcmd, "UL")) + { + cmdl += snprintf((char *)Oins, cl, "UPSERT USING LOAD %s%sINTO %s%c%s%c%s VALUES(", + etab[eid].flg & 040000000 ? "/*+ DIRECT */ " : "", + etab[eid].flg2 & 0002 ? "WITH NO ROLLBACK " : "", + etab[eid].Ocso[0] ? (char *)etab[eid].Ocso[0] : " ", + etab[eid].Ocso[0] ? '.' : ' ', + etab[eid].Ocso[1] ? (char *)etab[eid].Ocso[1] : " ", + etab[eid].Ocso[1] ? '.' : ' ', (char *)etab[eid].Ocso[2]); + } + else if (!strcasecmp(etab[eid].loadcmd, "UP")) + { + cmdl += snprintf((char *)Oins, cl, "UPSERT %s%sINTO %s%c%s%c%s VALUES(", + etab[eid].flg & 040000000 ? "/*+ DIRECT */ " : "", + etab[eid].flg2 & 0002 ? "WITH NO ROLLBACK " : "", + etab[eid].Ocso[0] ? (char *)etab[eid].Ocso[0] : " ", + etab[eid].Ocso[0] ? '.' : ' ', + etab[eid].Ocso[1] ? (char *)etab[eid].Ocso[1] : " ", + etab[eid].Ocso[1] ? '.' : ' ', (char *)etab[eid].Ocso[2]); + } + else if (!strcasecmp(etab[eid].loadcmd, "IN")) + { + cmdl += snprintf((char *)Oins, cl, "INSERT %s%sINTO %s%c%s%c%s VALUES(", + etab[eid].flg & 040000000 ? "/*+ DIRECT */ " : "", + etab[eid].flg2 & 0002 ? "WITH NO ROLLBACK " : "", + etab[eid].Ocso[0] ? (char *)etab[eid].Ocso[0] : " ", + etab[eid].Ocso[0] ? '.' : ' ', + etab[eid].Ocso[1] ? (char *)etab[eid].Ocso[1] : " ", + etab[eid].Ocso[1] ? '.' : ' ', (char *)etab[eid].Ocso[2]); + } + + for (i = 0; i < l; i++) { + if (i) + cl += strmcat((char *)Oins, ",", cl, 0); + cl += strmcat((char *)Oins, "?", cl, 0); + if (cmdl + CMD_CHUNK < cl) { /* increase Oins buffer */ + cl += CMD_CHUNK; + O = Oins; + if ((O = realloc(O, cl)) == (void *)NULL) { + fprintf(stderr, "odb [OloadJson(%d)] - Error re-allocating memory for Ocmd: [%d] %s\n", + __LINE__, errno, strerror(errno)); + goto oloadJson_exit; + } + Oins = O; + } + } + (void)strmcat((char *)Oins, ")", cl, 0); + if (f & 020000) /* if verbose */ + fprintf(stderr, "odb [OloadJson(%d)] - INSERT statement: %s\n", __LINE__, (char *)Oins); + + /* Allocate loader eids array */ + nldr = etab[eid].ps ? etab[eid].ps : 1; + if ((ldrs = (int *)calloc(nldr, sizeof(int))) == (void *)NULL) { + fprintf(stderr, "odb [OloadJson(%d)] - Error allocating loader eids array: [%d] %s\n", + __LINE__, errno, strerror(errno)); + goto oloadJson_exit; + } + + /* Initialize loader eids array */ + if (etab[eid].ps) { + for (i = 0, j = 0; i < (unsigned int)no && j < etab[eid].ps; i++) { + if (etab[i].type == 'L' && etab[i].parent == eid) { + etab[i].r = etab[eid].r; /* adjust rowset when rbs is specified */ + etab[i].cmt = etab[eid].cmt;/* adjust rowset when cmt is a multiplier */ + etab[i].lstat = 0; /* reset buffer status to available */ + etab[i].td = etab[eid].td; /* copy table structure pointer */ + ldrs[j++] = i; + } + } + } + else { + ldrs[0] = eid; + } + + /* Allocate rowset & status memory */ + if ((Odp = etab[eid].Orowsetl = (SQLCHAR *)calloc(etab[eid].r, etab[eid].s)) == (void *)NULL || + (etab[eid].Ostatusl = (SQLUSMALLINT *)calloc(etab[eid].r, sizeof(SQLUSMALLINT))) == (void *)NULL) { + fprintf(stderr, "odb [OloadJson(%d)] - Error allocating rowset memory: [%d] %s\n", + __LINE__, errno, strerror(errno)); + goto oloadJson_exit; + } + if (etab[eid].ps) { + for (j = 0; j < nldr; j++) { /* for all loading threads... */ + if ((etab[ldrs[j]].Orowsetl = (SQLCHAR *)calloc(etab[eid].r, etab[eid].s)) == (void *)NULL || + (etab[ldrs[j]].Ostatusl = (SQLUSMALLINT *)calloc(etab[eid].r, sizeof(SQLUSMALLINT))) == (void *)NULL) { + fprintf(stderr, "odb [OloadJson(%d)] - Error allocating rowset memory: [%d] %s\n", + __LINE__, errno, strerror(errno)); + goto oloadJson_exit; + } + } + } + + /* Set rowset size, bind parameters and prepare INSERT */ + for (j = 0; j < nldr; j++) { + /* Set max commit mode */ + if (etab[eid].cmt) { + if (!SQL_SUCCEEDED(Or = SQLSetConnectAttr(thps[etab[ldrs[j]].id].Oc, + SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_IS_UINTEGER))) { + Oerr(eid, tid, __LINE__, thps[etab[ldrs[j]].id].Oc, SQL_HANDLE_DBC); + goto oloadJson_exit; + } + } + else { + if (!SQL_SUCCEEDED(Or = SQLSetConnectAttr(thps[etab[ldrs[j]].id].Oc, + SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER))) { + Oerr(eid, tid, __LINE__, thps[etab[ldrs[j]].id].Oc, SQL_HANDLE_DBC); + goto oloadJson_exit; + } + } + /* Set max char/varchar/binary column length */ + if (!SQL_SUCCEEDED(Oret = SQLSetStmtAttr(thps[etab[ldrs[j]].id].Os, SQL_ATTR_MAX_LENGTH, + (SQLPOINTER)etab[eid].Omaxl, SQL_IS_UINTEGER))) { + Oerr(eid, tid, __LINE__, thps[etab[ldrs[j]].id].Os, SQL_HANDLE_STMT); + } + /* Bind parameters */ + if (!SQL_SUCCEEDED(Or = SQLSetStmtAttr(thps[etab[ldrs[j]].id].Os, SQL_ATTR_PARAM_BIND_TYPE, + (SQLPOINTER)(etab[eid].s), 0))) { + Oerr(eid, tid, __LINE__, thps[etab[ldrs[j]].id].Os, SQL_HANDLE_STMT); + goto oloadJson_exit; + } + if (!SQL_SUCCEEDED(Or = SQLSetStmtAttr(thps[etab[ldrs[j]].id].Os, SQL_ATTR_PARAMSET_SIZE, + (SQLPOINTER)(etab[eid].r), 0))) { + Oerr(eid, tid, __LINE__, thps[etab[ldrs[j]].id].Os, SQL_HANDLE_STMT); + goto oloadJson_exit; + } + if (!SQL_SUCCEEDED(Or = SQLSetStmtAttr(thps[etab[ldrs[j]].id].Os, SQL_ATTR_PARAM_STATUS_PTR, + etab[ldrs[j]].Ostatusl, 0))) { + Oerr(eid, tid, __LINE__, thps[etab[ldrs[j]].id].Os, SQL_HANDLE_STMT); + goto oloadJson_exit; + } + if (!SQL_SUCCEEDED(Or = SQLSetStmtAttr(thps[etab[ldrs[j]].id].Os, SQL_ATTR_PARAMS_PROCESSED_PTR, + &etab[ldrs[j]].Oresl, 0))) { + Oerr(eid, tid, __LINE__, thps[etab[ldrs[j]].id].Os, SQL_HANDLE_STMT); + goto oloadJson_exit; + } + for (i = 0, z = 1; i < l; i++) { + if (!SQL_SUCCEEDED(Or = SQLBindParameter(thps[etab[ldrs[j]].id].Os, (SQLUSMALLINT)z++, + SQL_PARAM_INPUT, SQL_C_CHAR, etab[eid].td[i].Otype, (SQLULEN)etab[eid].td[i].Osize, + etab[eid].td[i].Odec, &etab[ldrs[j]].Orowsetl[0 + etab[eid].td[i].start], etab[eid].td[i].Osize, + (SQLLEN *)&etab[ldrs[j]].Orowsetl[0 + etab[eid].td[i].start + etab[eid].td[i].Osize + etab[eid].td[i].pad]))) { + Oerr(eid, tid, __LINE__, thps[etab[ldrs[j]].id].Os, SQL_HANDLE_STMT); + goto oloadJson_exit; + } + } + if (!SQL_SUCCEEDED(Or = SQLPrepare(thps[etab[ldrs[j]].id].Os, Oins, SQL_NTS))) { + Oerr(eid, tid, __LINE__, thps[etab[ldrs[j]].id].Os, SQL_HANDLE_STMT); + goto oloadJson_exit; + } + etab[ldrs[j]].sp = l; /* save number of target table fields for prec */ + } + + /* Register Load Start Time */ + gettimeofday(&tve, (void *)NULL); + tinit = 1000 * (tve.tv_sec - tvi.tv_sec) + (tve.tv_usec - tvi.tv_usec) / 1000; + + /* Json load */ + pstats = 1; /* from now on print stats on exit */ + while (pJsonReader->errorCode == JSON_SUCCESS) { + // read start + if (readState == 0) { + while (pJsonReader->errorCode == JSON_SUCCESS) { + if (pJsonReader->state == JSON_STATE_MEMBER_KEY) { + jsonReadKey(pJsonReader, keybuf, sizeof(keybuf)); + if (pJsonReader->errorCode == JSON_SUCCESS && !strmicmp((char *)etab[eid].td[k].Oname, keybuf, strlen(keybuf))) { + readState = 1; + break; + } + } + else { + jsonRead(pJsonReader); + } + } + } + else { + // read rows + while (pJsonReader->errorCode == JSON_SUCCESS) { + if (pJsonReader->state == JSON_STATE_MEMBER_KEY) { + jsonReadKey(pJsonReader, keybuf, sizeof(keybuf)); + } + else if (pJsonReader->state == JSON_STATE_MEMBER_VALUE) { + jsonReadMemberValue(pJsonReader, valuebuf, sizeof(valuebuf)); + ifl = strlen(valuebuf); + + for (k = 0; k < l; k++) { + if (!strmicmp((char *)etab[eid].td[k].Oname, keybuf, strlen(keybuf))) { /* name matches */ + Odp = etab[eid].Orowsetl + m*etab[eid].s + etab[eid].td[k].start; + MEMCPY(Odp, valuebuf, ifl); + Odp += etab[eid].td[k].Osize + etab[eid].td[k].pad; + *((SQLLEN *)(Odp)) = (SQLLEN)(ifl); + break; + } + } + } + else if (pJsonReader->state == JSON_STATE_OBJECT_FINISH) { + ++m; + jsonRead(pJsonReader); + } + else if (pJsonReader->state == JSON_STATE_ARRAY_FINISH) { + readState = 0; + break; + } + else { + jsonRead(pJsonReader); + } + } + } + + if (m == etab[eid].r) { /* Insert rowset */ + nt++; + while (go) { + if (etab[eid].ps) { /* Find a buffer loader thread available */ + MutexLock(&etab[eid].pmutex); + while (go) { + for (i = 0; i < nldr; i++) { /* Look for write_available buffers */ + if (etab[ldrs[i]].lstat == 0) { + etab[ldrs[i]].lstat = 2; /* write_busy */ + break; + } + } + if (etab[eid].flg & 04000) { /* Oloadbuff set error flag */ + break; + } + else if (i >= nldr) { /* nothing available... wait */ + nw++; + CondWait(&etab[eid].pcvp, &etab[eid].pmutex); + } + else { + break; + } + } + MutexUnlock(&etab[eid].pmutex); + if (etab[eid].flg & 04000) /* Oloadbuff set error flag */ + break; + memcpy(etab[ldrs[i]].Orowsetl, etab[eid].Orowsetl, m * etab[eid].s); + etab[ldrs[i]].nbs = nrf - (unsigned long)m; /* pass the input file base row for this rowset */ + etab[ldrs[i]].lstat = 1; /* read_available */ + etab[ldrs[i]].ar = m; + CondWakeAll(&etab[eid].pcvc); + } + else { + etab[ldrs[0]].nbs = nrf - (unsigned long)m; /* pass the input file base row for this rowset */ + etab[ldrs[0]].ar = m; + Oloadbuff(eid); + } + break; + } + if (etab[eid].flg & 04000) /* Oloadbuff set error flag */ + break; + m = 0; + k = 0; + } + } + jsonReaderFree(pJsonReader); + /* load trailing rows */ + if (m) { /* Insert rowset */ + nt++; + while (go) { + if (etab[eid].ps) { /* Find a buffer loader thread available */ + MutexLock(&etab[eid].pmutex); + while (go) { + for (i = 0; i < nldr; i++) { /* Look for write_available buffers */ + if (etab[ldrs[i]].lstat == 0) { + etab[ldrs[i]].lstat = 2; /* write_busy */ + break; + } + } + if (etab[eid].flg & 04000) { /* Oloadbuff set error flag */ + break; + } + else if (i >= nldr) { /* nothing available... wait */ + nw++; + CondWait(&etab[eid].pcvp, &etab[eid].pmutex); + } + else { + break; + } + } + MutexUnlock(&etab[eid].pmutex); + if (etab[eid].flg & 04000) /* Oloadbuff set error flag */ + break; + memcpy(etab[ldrs[i]].Orowsetl, etab[eid].Orowsetl, m * etab[eid].s); + etab[ldrs[i]].nbs = nrf - (unsigned long)m; /* pass the input file base row for this rowset */ + etab[ldrs[i]].lstat = 1; /* read_available */ + etab[ldrs[i]].ar = m; + CondWakeAll(&etab[eid].pcvc); + } + else { + etab[ldrs[0]].nbs = nrf - (unsigned long)m; /* pass the input file base row for this rowset */ + etab[ldrs[0]].ar = m; + Oloadbuff(eid); + } + break; + } + } +oloadJson_exit: + etab[eid].flg |= 02000; /* mark EOF */ + if (etab[eid].ps) { /* wait all loaders to complete */ + CondWakeAll(&etab[eid].pcvc); + MutexLock(&etab[eid].pmutex); + while (go) { + for (i = 0, k = 0; i < nldr; i++) { + k += etab[ldrs[i]].lstat; + } + if (k != nldr * 10) + CondWait(&etab[eid].pcvp, &etab[eid].pmutex); + else + break; + } + MutexUnlock(&etab[eid].pmutex); + } + telaps -= 1000 * tve.tv_sec + tve.tv_usec / 1000; + gettimeofday(&tve, (void *)NULL); /* register end time */ + telaps += 1000 * tve.tv_sec + tve.tv_usec / 1000; + + for (i = 0; i < nldr; i++) + etab[eid].nrt += etab[ldrs[i]].nr; + + /* Print results */ + if (pstats) { + fprintf(stderr, "[%d] %s Load(X) statistics:\n\t[%d] Target table: %s.%s.%s\n", + tid, odbid, tid, etab[eid].Ocso[0], etab[eid].Ocso[1], etab[eid].Ocso[2]); + fprintf(stderr, "\t[%d] Source: %s\n", tid, etab[eid].src); + seconds = (double)tinit / 1000.0; + fprintf(stderr, "\t[%d] Pre-loading time: %s s (%s)\n", tid, + strmnum(seconds, num, sizeof(num), 3), strmtime(seconds, tim)); + seconds = (double)telaps / 1000.0; + fprintf(stderr, "\t[%d] Loading time: %s s(%s)\n", tid, + strmnum(seconds, num, sizeof(num), 3), strmtime(seconds, tim)); + fprintf(stderr, "\t[%d] Total records read: %s\n", tid, strmnum((double)nrf, num, sizeof(num), 0)); + fprintf(stderr, "\t[%d] Total records inserted: %s\n", tid, strmnum((double)etab[eid].nrt, num, sizeof(num), 0)); + fprintf(stderr, "\t[%d] Total number of columns: %s\n", tid, strmnum((double)l, num, sizeof(num), 0)); + fprintf(stderr, "\t[%d] Average input row size: %s B\n", tid, strmnum((double)nb*1.0 / nrf, num, sizeof(num), 1)); + fprintf(stderr, "\t[%d] ODBC row size: %s B (data)", tid, strmnum((double)(etab[eid].s - l * sizeof(SQLLEN)), num, sizeof(num), 0)); + fprintf(stderr, " + %s B (len ind)\n", strmnum((double)(l * sizeof(SQLLEN)), num, sizeof(num), 0)); + fprintf(stderr, "\t[%d] Rowset size: %s\n", tid, strmnum((double)etab[eid].r, num, sizeof(num), 0)); + fprintf(stderr, "\t[%d] Rowset buffer size: %s KiB\n", tid, strmnum((double)etab[eid].s / 1024.0*etab[eid].r, num, sizeof(num), 2)); + fprintf(stderr, "\t[%d] Load throughput (real data): %s KiB/s\n", tid, strmnum((double)nb / 1.024 / telaps, num, sizeof(num), 3)); + fprintf(stderr, "\t[%d] Load throughput (ODBC): %s KiB/s\n", tid, + strmnum((double)((etab[eid].s - l * sizeof(SQLLEN))*etab[eid].nrt) / 1.024 / telaps, num, sizeof(num), 3)); + if (etab[eid].ps) { + fprintf(stderr, "\t[%d] Reader Total/Wait Cycles: %s", tid, strmnum((double)nt, num, sizeof(num), 0)); + fprintf(stderr, "/%s\n", strmnum((double)nw, num, sizeof(num), 0)); + } + } + + /* Unbind parameters (if parallel unbind is executed in Oloadbuff) */ + if (!etab[eid].ps) + (void)SQLFreeStmt(thps[tid].Os, SQL_RESET_PARAMS); + + /* Free Memory */ + if (Odel) + free(Odel); + if (Oins) + free(Oins); + if (ldrs) /* Free ldrs */ + free(ldrs); + if (etab[eid].Orowsetl) /* Free Orowsetl if allocated */ + free(etab[eid].Orowsetl); + if (etab[eid].Ostatusl) /* Free Ostatusl if allocated */ + free(etab[eid].Ostatusl); + if (etab[eid].td) { + for (i = 0; i < l; i++) + free(etab[eid].td[i].Oname); + free(etab[eid].td); + } + + /* Close bad file */ + if (etab[eid].fo != stderr) + fclose(etab[eid].fo); + + /* Run "post" SQL */ + if (etab[eid].post) { + var_set(&thps[tid].tva, VTYPE_I, "tgt", etab[eid].tgt); + etab[eid].flg2 |= 020000000; /* Oexec to allocate/use its own handle */ + if (etab[eid].post[0] == '@') /* run a sql script */ + (void)runsql(tid, eid, 0, (etab[eid].post + 1)); + else /* Run single SQL command */ + (void)Oexec(tid, eid, 0, 0, (SQLCHAR *)etab[eid].post, ""); + etab[eid].flg2 &= ~020000000; /* reset Oexec to allocate/use its own handle */ + } + return; +} + /* Oloadbuff: * load buffer pointed by etab[eid].Orowsetl * @@ -13642,7 +14245,11 @@ static int Otcol(int eid, SQLHDBC *Ocn) //etab[no].loadcmd = &str[l]; strncpy(etab[no].loadcmd, &str[l], 2); etab[no].loadcmd[2] = '\0'; - } else { + } else if (type == 'l' && !strcmp(&str[n], "jsonkey")) { + fprintf(stderr, "odb [parseopt(%d)] - Warning: this function is not fully tested \"%s\"\n", __LINE__, &str[n]); + etab[no].jsonKey = &str[n]; + } + else { fprintf(stderr, "odb [parseopt(%d)] - Error: unknown parameter \"%s\"\n", __LINE__, &str[n]); no = tn = 0; /* reset tn */
