diff --git a/Data/Data_vs90.sln b/Data/Data_vs90.sln new file mode 100644 index 000000000..ea0714b7e --- /dev/null +++ b/Data/Data_vs90.sln @@ -0,0 +1,28 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Data", "Data_vs90.vcproj", "{240E83C3-368D-11DB-9FBC-00123FC423B5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestSuite", "testsuite\TestSuite_vs90.vcproj", "{24134877-368D-11DB-9FBC-00123FC423B5}" + ProjectSection(ProjectDependencies) = postProject + {240E83C3-368D-11DB-9FBC-00123FC423B5} = {240E83C3-368D-11DB-9FBC-00123FC423B5} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|Win32 = debug_shared|Win32 + release_shared|Win32 = release_shared|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {240E83C3-368D-11DB-9FBC-00123FC423B5}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {240E83C3-368D-11DB-9FBC-00123FC423B5}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {240E83C3-368D-11DB-9FBC-00123FC423B5}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {240E83C3-368D-11DB-9FBC-00123FC423B5}.release_shared|Win32.Build.0 = release_shared|Win32 + {24134877-368D-11DB-9FBC-00123FC423B5}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {24134877-368D-11DB-9FBC-00123FC423B5}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {24134877-368D-11DB-9FBC-00123FC423B5}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {24134877-368D-11DB-9FBC-00123FC423B5}.release_shared|Win32.Build.0 = release_shared|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Data/Data_vs90.vcproj b/Data/Data_vs90.vcproj new file mode 100644 index 000000000..ddcb4792a --- /dev/null +++ b/Data/Data_vs90.vcproj @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Data/MySQL/MySQL_vs90.sln b/Data/MySQL/MySQL_vs90.sln new file mode 100644 index 000000000..fb807dba0 --- /dev/null +++ b/Data/MySQL/MySQL_vs90.sln @@ -0,0 +1,29 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestSuite", "testsuite\TestSuite_vs90.vcproj", "{1B30A91B-375F-11DB-837B-00123FC423B5}" + ProjectSection(ProjectDependencies) = postProject + {73E19FDE-1570-488C-B3DB-72A60FADD408} = {73E19FDE-1570-488C-B3DB-72A60FADD408} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MySQL", "MySQL_vs90.vcproj", "{73E19FDE-1570-488C-B3DB-72A60FADD408}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|Win32 = debug_shared|Win32 + release_shared|Win32 = release_shared|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1B30A91B-375F-11DB-837B-00123FC423B5}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {1B30A91B-375F-11DB-837B-00123FC423B5}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {1B30A91B-375F-11DB-837B-00123FC423B5}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {1B30A91B-375F-11DB-837B-00123FC423B5}.release_shared|Win32.Build.0 = release_shared|Win32 + {73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {73E19FDE-1570-488C-B3DB-72A60FADD408}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {73E19FDE-1570-488C-B3DB-72A60FADD408}.release_shared|Win32.Build.0 = release_shared|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Data/MySQL/MySQL_vs90.vcproj b/Data/MySQL/MySQL_vs90.vcproj new file mode 100644 index 000000000..408ee79b6 --- /dev/null +++ b/Data/MySQL/MySQL_vs90.vcproj @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Data/MySQL/include/Poco/Data/MySQL/Binder.h b/Data/MySQL/include/Poco/Data/MySQL/Binder.h index a4f33964e..4ac8f0e11 100644 --- a/Data/MySQL/include/Poco/Data/MySQL/Binder.h +++ b/Data/MySQL/include/Poco/Data/MySQL/Binder.h @@ -1,132 +1,132 @@ -// -// Binder.h -// -// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/Binder.h#1 $ -// -// Library: Data -// Package: MySQL -// Module: Binder -// -// Definition of the Binder class. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef Data_MySQL_Binder_INCLUDED -#define Data_MySQL_Binder_INCLUDED - - -#include "Poco/Data/MySQL/MySQL.h" -#include "Poco/Data/AbstractBinder.h" -#include "Poco/Data/BLOB.h" -#include "Poco/Data/MySQL/MySQLException.h" -#include - - -namespace Poco { -namespace Data { -namespace MySQL { - - -class MySQL_API Binder: public Poco::Data::AbstractBinder - /// Binds placeholders in the sql query to the provided values. Performs data types mapping. -{ -public: - Binder(); - /// Creates the Binder. - - virtual ~Binder(); - /// Destroys the Binder. - - virtual void bind(std::size_t pos, const Poco::Int8& val); - /// Binds an Int8. - - virtual void bind(std::size_t pos, const Poco::UInt8& val); - /// Binds an UInt8. - - virtual void bind(std::size_t pos, const Poco::Int16& val); - /// Binds an Int16. - - virtual void bind(std::size_t pos, const Poco::UInt16& val); - /// Binds an UInt16. - - virtual void bind(std::size_t pos, const Poco::Int32& val); - /// Binds an Int32. - - virtual void bind(std::size_t pos, const Poco::UInt32& val); - /// Binds an UInt32. - - virtual void bind(std::size_t pos, const Poco::Int64& val); - /// Binds an Int64. - - virtual void bind(std::size_t pos, const Poco::UInt64& val); - /// Binds an UInt64. - - virtual void bind(std::size_t pos, const bool& val); - /// Binds a boolean. - - virtual void bind(std::size_t pos, const float& val); - /// Binds a float. - - virtual void bind(std::size_t pos, const double& val); - /// Binds a double. - - virtual void bind(std::size_t pos, const char& val); - /// Binds a single character. - - virtual void bind(std::size_t pos, const std::string& val); - /// Binds a string. - - virtual void bind(std::size_t pos, const Poco::Data::BLOB& val); - /// Binds a BLOB. - - size_t size() const; - /// Return count of binded parameters - - MYSQL_BIND* getBindArray() const; - /// Return array - -private: - virtual void bind(std::size_t, const char* const&) - /// Binds a const char ptr. - /// This is a private no-op in this implementation - /// due to security risk. - { - } - - void realBind(std::size_t pos, enum_field_types type, const void* buffer, int length); - /// Common bind implementation - -private: - std::vector _bindArray; -}; - - -} } } // namespace Poco::Data::MySQL - - -#endif // Data_MySQL_Binder_INCLUDED +// +// Binder.h +// +// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/Binder.h#2 $ +// +// Library: Data +// Package: MySQL +// Module: Binder +// +// Definition of the Binder class. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Data_MySQL_Binder_INCLUDED +#define Data_MySQL_Binder_INCLUDED + + +#include "Poco/Data/MySQL/MySQL.h" +#include "Poco/Data/AbstractBinder.h" +#include "Poco/Data/BLOB.h" +#include "Poco/Data/MySQL/MySQLException.h" +#include + + +namespace Poco { +namespace Data { +namespace MySQL { + + +class MySQL_API Binder: public Poco::Data::AbstractBinder + /// Binds placeholders in the sql query to the provided values. Performs data types mapping. +{ +public: + Binder(); + /// Creates the Binder. + + virtual ~Binder(); + /// Destroys the Binder. + + virtual void bind(std::size_t pos, const Poco::Int8& val); + /// Binds an Int8. + + virtual void bind(std::size_t pos, const Poco::UInt8& val); + /// Binds an UInt8. + + virtual void bind(std::size_t pos, const Poco::Int16& val); + /// Binds an Int16. + + virtual void bind(std::size_t pos, const Poco::UInt16& val); + /// Binds an UInt16. + + virtual void bind(std::size_t pos, const Poco::Int32& val); + /// Binds an Int32. + + virtual void bind(std::size_t pos, const Poco::UInt32& val); + /// Binds an UInt32. + + virtual void bind(std::size_t pos, const Poco::Int64& val); + /// Binds an Int64. + + virtual void bind(std::size_t pos, const Poco::UInt64& val); + /// Binds an UInt64. + + virtual void bind(std::size_t pos, const bool& val); + /// Binds a boolean. + + virtual void bind(std::size_t pos, const float& val); + /// Binds a float. + + virtual void bind(std::size_t pos, const double& val); + /// Binds a double. + + virtual void bind(std::size_t pos, const char& val); + /// Binds a single character. + + virtual void bind(std::size_t pos, const std::string& val); + /// Binds a string. + + virtual void bind(std::size_t pos, const Poco::Data::BLOB& val); + /// Binds a BLOB. + + size_t size() const; + /// Return count of binded parameters + + MYSQL_BIND* getBindArray() const; + /// Return array + +private: + virtual void bind(std::size_t, const char* const&) + /// Binds a const char ptr. + /// This is a private no-op in this implementation + /// due to security risk. + { + } + + void realBind(std::size_t pos, enum_field_types type, const void* buffer, int length); + /// Common bind implementation + +private: + std::vector _bindArray; +}; + + +} } } // namespace Poco::Data::MySQL + + +#endif // Data_MySQL_Binder_INCLUDED diff --git a/Data/MySQL/include/Poco/Data/MySQL/Connector.h b/Data/MySQL/include/Poco/Data/MySQL/Connector.h index cf1b4cdb8..4f1eacee3 100644 --- a/Data/MySQL/include/Poco/Data/MySQL/Connector.h +++ b/Data/MySQL/include/Poco/Data/MySQL/Connector.h @@ -1,78 +1,78 @@ -// -// Connector.h -// -// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/Connector.h#1 $ -// -// Library: Data -// Package: MySQL -// Module: Connector -// -// Definition of the Connector class. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef Data_MySQL_Connector_INCLUDED -#define Data_MySQL_Connector_INCLUDED - - -#include "MySQL.h" -#include "Poco/Data/Connector.h" - - -namespace Poco { -namespace Data { -namespace MySQL { - - -class MySQL_API Connector: public Poco::Data::Connector - /// Connector instantiates MySQL SessionImpl objects. -{ -public: - static std::string KEY; - - Connector(); - /// Creates the Connector. - - virtual ~Connector(); - /// Destroys the Connector. - - virtual Poco::AutoPtr createSession(const std::string& connectionString); - /// Creates a MySQL SessionImpl object and initializes it with the given connectionString. - - static void registerConnector(); - /// Registers the Connector under the Keyword Connector::KEY at the Poco::Data::SessionFactory. - - static void unregisterConnector(); - /// Unregisters the Connector under the Keyword Connector::KEY at the Poco::Data::SessionFactory. -}; - - -} } } // namespace Poco::Data::MySQL - - -#endif // Data_MySQL_Connector_INCLUDED +// +// Connector.h +// +// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/Connector.h#2 $ +// +// Library: Data +// Package: MySQL +// Module: Connector +// +// Definition of the Connector class. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Data_MySQL_Connector_INCLUDED +#define Data_MySQL_Connector_INCLUDED + + +#include "MySQL.h" +#include "Poco/Data/Connector.h" + + +namespace Poco { +namespace Data { +namespace MySQL { + + +class MySQL_API Connector: public Poco::Data::Connector + /// Connector instantiates MySQL SessionImpl objects. +{ +public: + static std::string KEY; + + Connector(); + /// Creates the Connector. + + virtual ~Connector(); + /// Destroys the Connector. + + virtual Poco::AutoPtr createSession(const std::string& connectionString); + /// Creates a MySQL SessionImpl object and initializes it with the given connectionString. + + static void registerConnector(); + /// Registers the Connector under the Keyword Connector::KEY at the Poco::Data::SessionFactory. + + static void unregisterConnector(); + /// Unregisters the Connector under the Keyword Connector::KEY at the Poco::Data::SessionFactory. +}; + + +} } } // namespace Poco::Data::MySQL + + +#endif // Data_MySQL_Connector_INCLUDED diff --git a/Data/MySQL/include/Poco/Data/MySQL/Extractor.h b/Data/MySQL/include/Poco/Data/MySQL/Extractor.h index 276049f86..5b9246f25 100644 --- a/Data/MySQL/include/Poco/Data/MySQL/Extractor.h +++ b/Data/MySQL/include/Poco/Data/MySQL/Extractor.h @@ -1,123 +1,123 @@ -// -// Extractor.h -// -// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/Extractor.h#1 $ -// -// Library: Data -// Package: MySQL -// Module: Extractor -// -// Definition of the Extractor class. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef Data_MySQL_Extractor_INCLUDED -#define Data_MySQL_Extractor_INCLUDED - - -#include "Poco/Data/MySQL/MySQL.h" -#include "Poco/Data/MySQL/StatementExecutor.h" -#include "Poco/Data/MySQL/ResultMetadata.h" -#include "Poco/Data/AbstractExtractor.h" -#include "Poco/Data/BLOB.h" - - -namespace Poco { -namespace Data { -namespace MySQL { - - -class MySQL_API Extractor: public Poco::Data::AbstractExtractor - /// Extracts and converts data values from the result row returned by MySQL. - /// If NULL is received, the incoming val value is not changed and false is returned -{ -public: - Extractor(StatementExecutor& st, ResultMetadata& md); - /// Creates the Extractor. - - virtual ~Extractor(); - /// Destroys the Extractor. - - virtual bool extract(std::size_t pos, Poco::Int8& val); - /// Extracts an Int8. - - virtual bool extract(std::size_t pos, Poco::UInt8& val); - /// Extracts an UInt8. - - virtual bool extract(std::size_t pos, Poco::Int16& val); - /// Extracts an Int16. - - virtual bool extract(std::size_t pos, Poco::UInt16& val); - /// Extracts an UInt16. - - virtual bool extract(std::size_t pos, Poco::Int32& val); - /// Extracts an Int32. - - virtual bool extract(std::size_t pos, Poco::UInt32& val); - /// Extracts an UInt32. - - virtual bool extract(std::size_t pos, Poco::Int64& val); - /// Extracts an Int64. - - virtual bool extract(std::size_t pos, Poco::UInt64& val); - /// Extracts an UInt64. - - virtual bool extract(std::size_t pos, bool& val); - /// Extracts a boolean. - - virtual bool extract(std::size_t pos, float& val); - /// Extracts a float. - - virtual bool extract(std::size_t pos, double& val); - /// Extracts a double. - - virtual bool extract(std::size_t pos, char& val); - /// Extracts a single character. - - virtual bool extract(std::size_t pos, std::string& val); - /// Extracts a string. - - virtual bool extract(std::size_t pos, Poco::Data::BLOB& val); - /// Extracts a BLOB. - -private: - bool realExtractFixed(std::size_t pos, enum_field_types type, void* buffer, size_t length = 0); - - // Prevent VC8 warning "operator= could not be generated" - Extractor& operator=(const Extractor&); - -private: - StatementExecutor& _stmt; - ResultMetadata& _metadata; -}; - - -} } } // namespace Poco::Data::MySQL - - -#endif // Data_MySQL_Extractor_INCLUDED +// +// Extractor.h +// +// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/Extractor.h#2 $ +// +// Library: Data +// Package: MySQL +// Module: Extractor +// +// Definition of the Extractor class. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Data_MySQL_Extractor_INCLUDED +#define Data_MySQL_Extractor_INCLUDED + + +#include "Poco/Data/MySQL/MySQL.h" +#include "Poco/Data/MySQL/StatementExecutor.h" +#include "Poco/Data/MySQL/ResultMetadata.h" +#include "Poco/Data/AbstractExtractor.h" +#include "Poco/Data/BLOB.h" + + +namespace Poco { +namespace Data { +namespace MySQL { + + +class MySQL_API Extractor: public Poco::Data::AbstractExtractor + /// Extracts and converts data values from the result row returned by MySQL. + /// If NULL is received, the incoming val value is not changed and false is returned +{ +public: + Extractor(StatementExecutor& st, ResultMetadata& md); + /// Creates the Extractor. + + virtual ~Extractor(); + /// Destroys the Extractor. + + virtual bool extract(std::size_t pos, Poco::Int8& val); + /// Extracts an Int8. + + virtual bool extract(std::size_t pos, Poco::UInt8& val); + /// Extracts an UInt8. + + virtual bool extract(std::size_t pos, Poco::Int16& val); + /// Extracts an Int16. + + virtual bool extract(std::size_t pos, Poco::UInt16& val); + /// Extracts an UInt16. + + virtual bool extract(std::size_t pos, Poco::Int32& val); + /// Extracts an Int32. + + virtual bool extract(std::size_t pos, Poco::UInt32& val); + /// Extracts an UInt32. + + virtual bool extract(std::size_t pos, Poco::Int64& val); + /// Extracts an Int64. + + virtual bool extract(std::size_t pos, Poco::UInt64& val); + /// Extracts an UInt64. + + virtual bool extract(std::size_t pos, bool& val); + /// Extracts a boolean. + + virtual bool extract(std::size_t pos, float& val); + /// Extracts a float. + + virtual bool extract(std::size_t pos, double& val); + /// Extracts a double. + + virtual bool extract(std::size_t pos, char& val); + /// Extracts a single character. + + virtual bool extract(std::size_t pos, std::string& val); + /// Extracts a string. + + virtual bool extract(std::size_t pos, Poco::Data::BLOB& val); + /// Extracts a BLOB. + +private: + bool realExtractFixed(std::size_t pos, enum_field_types type, void* buffer, size_t length = 0); + + // Prevent VC8 warning "operator= could not be generated" + Extractor& operator=(const Extractor&); + +private: + StatementExecutor& _stmt; + ResultMetadata& _metadata; +}; + + +} } } // namespace Poco::Data::MySQL + + +#endif // Data_MySQL_Extractor_INCLUDED diff --git a/Data/MySQL/include/Poco/Data/MySQL/MySQL.h b/Data/MySQL/include/Poco/Data/MySQL/MySQL.h index cf57af789..a3718040a 100644 --- a/Data/MySQL/include/Poco/Data/MySQL/MySQL.h +++ b/Data/MySQL/include/Poco/Data/MySQL/MySQL.h @@ -1,90 +1,90 @@ -// -// MySQL.h -// -// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/MySQL.h#1 $ -// -// Library: Data -// Package: MySQL -// Module: MySQL -// -// Basic definitions for the MySQL library. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef MySQL_MySQL_INCLUDED -#define MySQL_MySQL_INCLUDED - - -#include "Poco/Foundation.h" - - -// -// The following block is the standard way of creating macros which make exporting -// from a DLL simpler. All files within this DLL are compiled with the ODBC_EXPORTS -// symbol defined on the command line. this symbol should not be defined on any project -// that uses this DLL. This way any other project whose source files include this file see -// ODBC_API functions as being imported from a DLL, wheras this DLL sees symbols -// defined with this macro as being exported. -// -#if defined(_WIN32) && defined(POCO_DLL) - #if defined(MYSQL_EXPORTS) - #define MySQL_API __declspec(dllexport) - #else - #define MySQL_API __declspec(dllimport) - #endif -#endif - - -#if !defined(MySQL_API) - #define MySQL_API -#endif - - -// -// Automatically link Data library. -// -#if defined(_MSC_VER) - #if !defined(POCO_NO_AUTOMATIC_LIBS) && !defined(MYSQL_EXPORTS) - #if defined(POCO_DLL) - #if defined(_DEBUG) - #pragma comment(lib, "PocoMySQLd.lib") - #else - #pragma comment(lib, "PocoMySQL.lib") - #endif - #else - #if defined(_DEBUG) - #pragma comment(lib, "PocoMySQLmtd.lib") - #else - #pragma comment(lib, "PocoMySQLmt.lib") - #endif - #endif - #endif -#endif - - -#endif // MySQL_MySQL_INCLUDED +// +// MySQL.h +// +// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/MySQL.h#2 $ +// +// Library: Data +// Package: MySQL +// Module: MySQL +// +// Basic definitions for the MySQL library. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef MySQL_MySQL_INCLUDED +#define MySQL_MySQL_INCLUDED + + +#include "Poco/Foundation.h" + + +// +// The following block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the ODBC_EXPORTS +// symbol defined on the command line. this symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// ODBC_API functions as being imported from a DLL, wheras this DLL sees symbols +// defined with this macro as being exported. +// +#if defined(_WIN32) && defined(POCO_DLL) + #if defined(MYSQL_EXPORTS) + #define MySQL_API __declspec(dllexport) + #else + #define MySQL_API __declspec(dllimport) + #endif +#endif + + +#if !defined(MySQL_API) + #define MySQL_API +#endif + + +// +// Automatically link Data library. +// +#if defined(_MSC_VER) + #if !defined(POCO_NO_AUTOMATIC_LIBS) && !defined(MYSQL_EXPORTS) + #if defined(POCO_DLL) + #if defined(_DEBUG) + #pragma comment(lib, "PocoMySQLd.lib") + #else + #pragma comment(lib, "PocoMySQL.lib") + #endif + #else + #if defined(_DEBUG) + #pragma comment(lib, "PocoMySQLmtd.lib") + #else + #pragma comment(lib, "PocoMySQLmt.lib") + #endif + #endif + #endif +#endif + + +#endif // MySQL_MySQL_INCLUDED diff --git a/Data/MySQL/include/Poco/Data/MySQL/MySQLException.h b/Data/MySQL/include/Poco/Data/MySQL/MySQLException.h index 5cb76f877..50dfeac18 100644 --- a/Data/MySQL/include/Poco/Data/MySQL/MySQLException.h +++ b/Data/MySQL/include/Poco/Data/MySQL/MySQLException.h @@ -1,163 +1,163 @@ -// -// MySQLException.h -// -// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/MySQLException.h#1 $ -// -// Library: Data -// Package: MySQL -// Module: MySQLException -// -// Definition of the MySQLException class. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef Data_MySQL_MySQLException_INCLUDED -#define Data_MySQL_MySQLException_INCLUDED - - -#include "Poco/Data/MySQL/MySQL.h" -#include "Poco/Data/DataException.h" -#include -#include - - -typedef struct st_mysql MYSQL; -typedef struct st_mysql_stmt MYSQL_STMT; - - -namespace Poco { -namespace Data { -namespace MySQL { - - -class MySQL_API MySQLException: public Poco::Data::DataException - /// Base class for all MySQL exceptions -{ -public: - MySQLException(const std::string& msg); - /// Creates MySQLException. - - MySQLException(const MySQLException& exc); - /// Creates MySQLException. - - ~MySQLException() throw(); - /// Destroys MySQLexception. - - MySQLException& operator=(const MySQLException& exc); - /// Assignment operator. - - const char* name() const throw(); - /// Returns exception name. - - const char* className() const throw(); - /// Returns the name of the exception class. - - Poco::Exception* clone() const; - /// Creates an exact copy of the exception. - /// - /// The copy can later be thrown again by - /// invoking rethrow() on it. - - void rethrow() const; - /// (Re)Throws the exception. - /// - /// This is useful for temporarily storing a - /// copy of an exception (see clone()), then - /// throwing it again. -}; - - -class ConnectionException : public MySQLException - /// ConnectionException -{ -public: - ConnectionException(const std::string& msg); - /// Creates ConnectionException. - - ConnectionException(const std::string& text, MYSQL* h); - /// Destroys ConnectionException. - -private: - static std::string compose(const std::string& text, MYSQL* h); - -}; - - -class StatementException : public MySQLException - /// StatementException -{ -public: - StatementException(const std::string& msg); - /// Creates StatementException. - - StatementException(const std::string& text, MYSQL_STMT* h, const std::string& stmt = ""); - /// Destroys StatementException. - -private: - static std::string compose(const std::string& text, MYSQL_STMT* h, const std::string& stmt); -}; - - -// -// inlines -// -inline MySQLException& MySQLException::operator=(const MySQLException& exc) -{ - Poco::Data::DataException::operator=(exc); - return *this; -} - - -inline const char* MySQLException::name() const throw() -{ - return "MySQL"; -} - - -inline const char* MySQLException::className() const throw() -{ - return typeid(*this).name(); -} - - -inline Poco::Exception* MySQLException::clone() const -{ - return new MySQLException(*this); -} - - -inline void MySQLException::rethrow() const -{ - throw *this; -} - - -} } } // namespace Poco::Data::MySQL - - -#endif //Data_MySQL_MySQLException_INCLUDED +// +// MySQLException.h +// +// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/MySQLException.h#2 $ +// +// Library: Data +// Package: MySQL +// Module: MySQLException +// +// Definition of the MySQLException class. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Data_MySQL_MySQLException_INCLUDED +#define Data_MySQL_MySQLException_INCLUDED + + +#include "Poco/Data/MySQL/MySQL.h" +#include "Poco/Data/DataException.h" +#include +#include + + +typedef struct st_mysql MYSQL; +typedef struct st_mysql_stmt MYSQL_STMT; + + +namespace Poco { +namespace Data { +namespace MySQL { + + +class MySQL_API MySQLException: public Poco::Data::DataException + /// Base class for all MySQL exceptions +{ +public: + MySQLException(const std::string& msg); + /// Creates MySQLException. + + MySQLException(const MySQLException& exc); + /// Creates MySQLException. + + ~MySQLException() throw(); + /// Destroys MySQLexception. + + MySQLException& operator=(const MySQLException& exc); + /// Assignment operator. + + const char* name() const throw(); + /// Returns exception name. + + const char* className() const throw(); + /// Returns the name of the exception class. + + Poco::Exception* clone() const; + /// Creates an exact copy of the exception. + /// + /// The copy can later be thrown again by + /// invoking rethrow() on it. + + void rethrow() const; + /// (Re)Throws the exception. + /// + /// This is useful for temporarily storing a + /// copy of an exception (see clone()), then + /// throwing it again. +}; + + +class ConnectionException : public MySQLException + /// ConnectionException +{ +public: + ConnectionException(const std::string& msg); + /// Creates ConnectionException. + + ConnectionException(const std::string& text, MYSQL* h); + /// Destroys ConnectionException. + +private: + static std::string compose(const std::string& text, MYSQL* h); + +}; + + +class StatementException : public MySQLException + /// StatementException +{ +public: + StatementException(const std::string& msg); + /// Creates StatementException. + + StatementException(const std::string& text, MYSQL_STMT* h, const std::string& stmt = ""); + /// Destroys StatementException. + +private: + static std::string compose(const std::string& text, MYSQL_STMT* h, const std::string& stmt); +}; + + +// +// inlines +// +inline MySQLException& MySQLException::operator=(const MySQLException& exc) +{ + Poco::Data::DataException::operator=(exc); + return *this; +} + + +inline const char* MySQLException::name() const throw() +{ + return "MySQL"; +} + + +inline const char* MySQLException::className() const throw() +{ + return typeid(*this).name(); +} + + +inline Poco::Exception* MySQLException::clone() const +{ + return new MySQLException(*this); +} + + +inline void MySQLException::rethrow() const +{ + throw *this; +} + + +} } } // namespace Poco::Data::MySQL + + +#endif //Data_MySQL_MySQLException_INCLUDED diff --git a/Data/MySQL/include/Poco/Data/MySQL/MySQLStatementImpl.h b/Data/MySQL/include/Poco/Data/MySQL/MySQLStatementImpl.h index 40c7117e0..e5cd3ea98 100644 --- a/Data/MySQL/include/Poco/Data/MySQL/MySQLStatementImpl.h +++ b/Data/MySQL/include/Poco/Data/MySQL/MySQLStatementImpl.h @@ -1,117 +1,117 @@ -// -// MySQLstatementImpl.h -// -// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/MySQLStatementImpl.h#1 $ -// -// Library: Data -// Package: MySQL -// Module: MySQLstatementImpl -// -// Definition of the MySQLStatementImpl class. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef Data_MySQL_MySQLStatementImpl_INCLUDED -#define Data_MySQL_MySQLStatementImpl_INCLUDED - - -#include "Poco/Data/MySQL/MySQL.h" -#include "Poco/Data/MySQL/SessionImpl.h" -#include "Poco/Data/MySQL/Binder.h" -#include "Poco/Data/MySQL/Extractor.h" -#include "Poco/Data/MySQL/StatementExecutor.h" -#include "Poco/Data/MySQL/ResultMetadata.h" -#include "Poco/Data/StatementImpl.h" -#include "Poco/SharedPtr.h" -#include "Poco/Format.h" - - -namespace Poco { -namespace Data { -namespace MySQL { - - -class MySQL_API MySQLStatementImpl: public Poco::Data::StatementImpl - /// Implements statement functionality needed for MySQL -{ -public: - MySQLStatementImpl(SessionHandle& h); - /// Creates the MySQLStatementImpl. - - ~MySQLStatementImpl(); - /// Destroys the MySQLStatementImpl. - -protected: - virtual Poco::UInt32 columnsReturned() const; - /// Returns number of columns returned by query. - - virtual const MetaColumn& metaColumn(Poco::UInt32 pos) const; - /// Returns column meta data. - - virtual bool hasNext(); - /// Returns true if a call to next() will return data. - - virtual void next(); - /// Retrieves the next row from the resultset. - /// Will throw, if the resultset is empty. - - virtual bool canBind() const; - /// Returns true if a valid statement is set and we can bind. - - virtual void compileImpl(); - /// Compiles the statement, doesn't bind yet - - virtual void bindImpl(); - /// Binds parameters - - virtual AbstractExtractor& extractor(); - /// Returns the concrete extractor used by the statement. - - virtual AbstractBinder& binder(); - /// Returns the concrete binder used by the statement. - -private: - enum - { - NEXT_DONTKNOW, - NEXT_TRUE, - NEXT_FALSE - }; - - StatementExecutor _stmt; - ResultMetadata _metadata; - Binder _binder; - Extractor _extractor; - int _hasNext; -}; - - -} } } // namespace Poco::Data::MySQL - - -#endif // Data_MySQL_MySQLStatementImpl_INCLUDED +// +// MySQLstatementImpl.h +// +// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/MySQLStatementImpl.h#2 $ +// +// Library: Data +// Package: MySQL +// Module: MySQLstatementImpl +// +// Definition of the MySQLStatementImpl class. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Data_MySQL_MySQLStatementImpl_INCLUDED +#define Data_MySQL_MySQLStatementImpl_INCLUDED + + +#include "Poco/Data/MySQL/MySQL.h" +#include "Poco/Data/MySQL/SessionImpl.h" +#include "Poco/Data/MySQL/Binder.h" +#include "Poco/Data/MySQL/Extractor.h" +#include "Poco/Data/MySQL/StatementExecutor.h" +#include "Poco/Data/MySQL/ResultMetadata.h" +#include "Poco/Data/StatementImpl.h" +#include "Poco/SharedPtr.h" +#include "Poco/Format.h" + + +namespace Poco { +namespace Data { +namespace MySQL { + + +class MySQL_API MySQLStatementImpl: public Poco::Data::StatementImpl + /// Implements statement functionality needed for MySQL +{ +public: + MySQLStatementImpl(SessionHandle& h); + /// Creates the MySQLStatementImpl. + + ~MySQLStatementImpl(); + /// Destroys the MySQLStatementImpl. + +protected: + virtual Poco::UInt32 columnsReturned() const; + /// Returns number of columns returned by query. + + virtual const MetaColumn& metaColumn(Poco::UInt32 pos) const; + /// Returns column meta data. + + virtual bool hasNext(); + /// Returns true if a call to next() will return data. + + virtual void next(); + /// Retrieves the next row from the resultset. + /// Will throw, if the resultset is empty. + + virtual bool canBind() const; + /// Returns true if a valid statement is set and we can bind. + + virtual void compileImpl(); + /// Compiles the statement, doesn't bind yet + + virtual void bindImpl(); + /// Binds parameters + + virtual AbstractExtractor& extractor(); + /// Returns the concrete extractor used by the statement. + + virtual AbstractBinder& binder(); + /// Returns the concrete binder used by the statement. + +private: + enum + { + NEXT_DONTKNOW, + NEXT_TRUE, + NEXT_FALSE + }; + + StatementExecutor _stmt; + ResultMetadata _metadata; + Binder _binder; + Extractor _extractor; + int _hasNext; +}; + + +} } } // namespace Poco::Data::MySQL + + +#endif // Data_MySQL_MySQLStatementImpl_INCLUDED diff --git a/Data/MySQL/include/Poco/Data/MySQL/ResultMetadata.h b/Data/MySQL/include/Poco/Data/MySQL/ResultMetadata.h index 275a17b3b..b627c5116 100644 --- a/Data/MySQL/include/Poco/Data/MySQL/ResultMetadata.h +++ b/Data/MySQL/include/Poco/Data/MySQL/ResultMetadata.h @@ -1,93 +1,93 @@ -// -// ResultMetadata.h -// -// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/ResultMetadata.h#1 $ -// -// Library: Data -// Package: MySQL -// Module: ResultMetadata -// -// Definition of the ResultMetadata class. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef Data_MySQL_ResultMetadata_INCLUDED -#define Data_MySQL_ResultMetadata_INCLUDED - - -#include -#include -#include "Poco/Data/MetaColumn.h" - - -namespace Poco { -namespace Data { -namespace MySQL { - - -class ResultMetadata - /// MySQL result metadata -{ -public: - void reset(); - /// Resets the metadata. - - void init(MYSQL_STMT* stmt); - /// Initializes the metadata. - - Poco::UInt32 columnsReturned() const; - /// Returns the number of columns in resultset. - - const MetaColumn& metaColumn(Poco::UInt32 pos) const; - /// Returns the reference to the specified metacolumn. - - MYSQL_BIND* row(); - /// Returns pointer to native row. - - std::size_t length(std::size_t pos) const; - /// Returns the length. - - const char* rawData(std::size_t pos) const; - /// Returns raw data. - - bool isNull(std::size_t pos) const; - /// Returns true if value at pos is null. - -private: - std::vector _columns; - std::vector _row; - std::vector _buffer; - std::vector _lengths; - std::vector _isNull; -}; - - -} } } // namespace Poco::Data::MySQL - - -#endif //Data_MySQL_ResultMetadata_INCLUDED +// +// ResultMetadata.h +// +// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/ResultMetadata.h#2 $ +// +// Library: Data +// Package: MySQL +// Module: ResultMetadata +// +// Definition of the ResultMetadata class. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Data_MySQL_ResultMetadata_INCLUDED +#define Data_MySQL_ResultMetadata_INCLUDED + + +#include +#include +#include "Poco/Data/MetaColumn.h" + + +namespace Poco { +namespace Data { +namespace MySQL { + + +class ResultMetadata + /// MySQL result metadata +{ +public: + void reset(); + /// Resets the metadata. + + void init(MYSQL_STMT* stmt); + /// Initializes the metadata. + + Poco::UInt32 columnsReturned() const; + /// Returns the number of columns in resultset. + + const MetaColumn& metaColumn(Poco::UInt32 pos) const; + /// Returns the reference to the specified metacolumn. + + MYSQL_BIND* row(); + /// Returns pointer to native row. + + std::size_t length(std::size_t pos) const; + /// Returns the length. + + const char* rawData(std::size_t pos) const; + /// Returns raw data. + + bool isNull(std::size_t pos) const; + /// Returns true if value at pos is null. + +private: + std::vector _columns; + std::vector _row; + std::vector _buffer; + std::vector _lengths; + std::vector _isNull; +}; + + +} } } // namespace Poco::Data::MySQL + + +#endif //Data_MySQL_ResultMetadata_INCLUDED diff --git a/Data/MySQL/include/Poco/Data/MySQL/SessionHandle.h b/Data/MySQL/include/Poco/Data/MySQL/SessionHandle.h index c7ec26f91..96a9d613e 100644 --- a/Data/MySQL/include/Poco/Data/MySQL/SessionHandle.h +++ b/Data/MySQL/include/Poco/Data/MySQL/SessionHandle.h @@ -1,94 +1,94 @@ -// -// SesssionHandle.h -// -// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/SessionHandle.h#1 $ -// -// Library: Data -// Package: MySQL -// Module: SessionHandle -// -// Definition of the SessionHandle class. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef Data_MySQL_SessionHandle_INCLUDED -#define Data_MySQL_SessionHandle_INCLUDED - - -#include -#include "Poco/Data/MySQL/MySQLException.h" -#include - - -namespace Poco { -namespace Data { -namespace MySQL { - - -class SessionHandle - /// MySQL session handle -{ -public: - explicit SessionHandle(MYSQL* mysql); - - ~SessionHandle(); - - void options(mysql_option opt); - - void options(mysql_option opt, bool b); - - void connect(const char* host, const char* user, const char* password, const char* db, unsigned int port); - - void close(); - - void query(const char* str); - - operator MYSQL* (); - -private: - SessionHandle(const SessionHandle&); - SessionHandle& operator=(const SessionHandle&); - -private: - MYSQL* h; -}; - - -// -// inlines -// -inline SessionHandle::operator MYSQL* () -{ - return h; -} - - -} } } // namespace Poco::Data::MySQL - - -#endif // Data_MySQL_SessionHandle_INCLUDED +// +// SesssionHandle.h +// +// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/SessionHandle.h#2 $ +// +// Library: Data +// Package: MySQL +// Module: SessionHandle +// +// Definition of the SessionHandle class. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Data_MySQL_SessionHandle_INCLUDED +#define Data_MySQL_SessionHandle_INCLUDED + + +#include +#include "Poco/Data/MySQL/MySQLException.h" +#include + + +namespace Poco { +namespace Data { +namespace MySQL { + + +class SessionHandle + /// MySQL session handle +{ +public: + explicit SessionHandle(MYSQL* mysql); + + ~SessionHandle(); + + void options(mysql_option opt); + + void options(mysql_option opt, bool b); + + void connect(const char* host, const char* user, const char* password, const char* db, unsigned int port); + + void close(); + + void query(const char* str); + + operator MYSQL* (); + +private: + SessionHandle(const SessionHandle&); + SessionHandle& operator=(const SessionHandle&); + +private: + MYSQL* h; +}; + + +// +// inlines +// +inline SessionHandle::operator MYSQL* () +{ + return h; +} + + +} } } // namespace Poco::Data::MySQL + + +#endif // Data_MySQL_SessionHandle_INCLUDED diff --git a/Data/MySQL/include/Poco/Data/MySQL/SessionImpl.h b/Data/MySQL/include/Poco/Data/MySQL/SessionImpl.h index 87116c9fa..dfa954690 100644 --- a/Data/MySQL/include/Poco/Data/MySQL/SessionImpl.h +++ b/Data/MySQL/include/Poco/Data/MySQL/SessionImpl.h @@ -1,124 +1,124 @@ -// -// SessionImpl.h -// -// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/SessionImpl.h#1 $ -// -// Library: Data -// Package: MySQL -// Module: SessionImpl -// -// Definition of the SessionImpl class. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef Data_MySQL_SessionImpl_INCLUDED -#define Data_MySQL_SessionImpl_INCLUDED - - -#include "Poco/Data/MySQL/MySQL.h" -#include "Poco/Data/AbstractSessionImpl.h" -#include "Poco/Data/MySQL/SessionHandle.h" - - -namespace Poco { -namespace Data { -namespace MySQL { - - -class MySQL_API SessionImpl: public Poco::Data::AbstractSessionImpl - /// Implements SessionImpl interface -{ -public: - SessionImpl(const std::string& connectionString); - /// Creates the SessionImpl. Opens a connection to the database - /// - /// Connection string format: - /// == | ';' - /// == '=' - /// == 'host' | 'port' | 'user' | 'password' | 'db' } 'compress' | 'auto-reconnect' - /// == [~;]* - /// - /// for compress and auto-reconnect correct values are true/false - /// for port - numeric in decimal notation - /// - - ~SessionImpl(); - /// Destroys the SessionImpl. - - virtual Poco::Data::StatementImpl* createStatementImpl(); - /// Returns an MySQL StatementImpl - - virtual void begin(); - /// Starts a transaction - - virtual void commit(); - /// Commits and ends a transaction - - virtual void rollback(); - /// Aborts a transaction - - virtual void close(); - /// Closes the connection - - virtual bool isConnected(); - /// Returns true iff session is connected. - - virtual bool isTransaction(); - /// Returns true iff a transaction is in progress. - - void setInsertId(const std::string&, const Poco::Any&); - /// Try to set insert id - do nothing. - - Poco::Any getInsertId(const std::string&); - /// Get insert id - -private: - SessionHandle _mysql; - bool _connected; - int _inTransaction; -}; - - -// -// inlines -// -inline void SessionImpl::setInsertId(const std::string&, const Poco::Any&) -{ -} - - -inline Poco::Any SessionImpl::getInsertId(const std::string&) -{ - return Poco::Any(Poco::UInt64(mysql_insert_id(_mysql))); -} - - -} } } // namespace Poco::Data::MySQL - - -#endif // Data_MySQL_SessionImpl_INCLUDED +// +// SessionImpl.h +// +// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/SessionImpl.h#2 $ +// +// Library: Data +// Package: MySQL +// Module: SessionImpl +// +// Definition of the SessionImpl class. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Data_MySQL_SessionImpl_INCLUDED +#define Data_MySQL_SessionImpl_INCLUDED + + +#include "Poco/Data/MySQL/MySQL.h" +#include "Poco/Data/AbstractSessionImpl.h" +#include "Poco/Data/MySQL/SessionHandle.h" + + +namespace Poco { +namespace Data { +namespace MySQL { + + +class MySQL_API SessionImpl: public Poco::Data::AbstractSessionImpl + /// Implements SessionImpl interface +{ +public: + SessionImpl(const std::string& connectionString); + /// Creates the SessionImpl. Opens a connection to the database + /// + /// Connection string format: + /// == | ';' + /// == '=' + /// == 'host' | 'port' | 'user' | 'password' | 'db' } 'compress' | 'auto-reconnect' + /// == [~;]* + /// + /// for compress and auto-reconnect correct values are true/false + /// for port - numeric in decimal notation + /// + + ~SessionImpl(); + /// Destroys the SessionImpl. + + virtual Poco::Data::StatementImpl* createStatementImpl(); + /// Returns an MySQL StatementImpl + + virtual void begin(); + /// Starts a transaction + + virtual void commit(); + /// Commits and ends a transaction + + virtual void rollback(); + /// Aborts a transaction + + virtual void close(); + /// Closes the connection + + virtual bool isConnected(); + /// Returns true iff session is connected. + + virtual bool isTransaction(); + /// Returns true iff a transaction is in progress. + + void setInsertId(const std::string&, const Poco::Any&); + /// Try to set insert id - do nothing. + + Poco::Any getInsertId(const std::string&); + /// Get insert id + +private: + SessionHandle _mysql; + bool _connected; + int _inTransaction; +}; + + +// +// inlines +// +inline void SessionImpl::setInsertId(const std::string&, const Poco::Any&) +{ +} + + +inline Poco::Any SessionImpl::getInsertId(const std::string&) +{ + return Poco::Any(Poco::UInt64(mysql_insert_id(_mysql))); +} + + +} } } // namespace Poco::Data::MySQL + + +#endif // Data_MySQL_SessionImpl_INCLUDED diff --git a/Data/MySQL/include/Poco/Data/MySQL/StatementExecutor.h b/Data/MySQL/include/Poco/Data/MySQL/StatementExecutor.h index b5d9df70a..217f3c1f2 100644 --- a/Data/MySQL/include/Poco/Data/MySQL/StatementExecutor.h +++ b/Data/MySQL/include/Poco/Data/MySQL/StatementExecutor.h @@ -1,117 +1,117 @@ -// -// StatementExecutor.h -// -// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/StatementExecutor.h#1 $ -// -// Library: Data -// Package: MySQL -// Module: StatementExecutor -// -// Definition of the StatementExecutor class. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef Data_MySQL_StatementHandle_INCLUDED -#define Data_MySQL_StatementHandle_INCLUDED - - -#include -#include "Poco/Data/MySQL/MySQLException.h" -#include - - -namespace Poco { -namespace Data { -namespace MySQL { - - -class StatementExecutor - /// MySQL statement executor. -{ -public: - enum State - { - STMT_INITED, - STMT_COMPILED, - STMT_EXECUTED - }; - - explicit StatementExecutor(MYSQL* mysql); - /// Creates the StatementExecutor. - - ~StatementExecutor(); - /// Destroys the StatementExecutor. - - int state() const; - /// Returns the current state. - - void prepare(const std::string& query); - /// Prepares the statement for execution. - - void bindParams(MYSQL_BIND* params, size_t count); - /// Binds the params. - - void bindResult(MYSQL_BIND* result); - /// Binds result. - - void execute(); - /// Executes the statement. - - bool fetch(); - /// Fetches the data. - - bool fetchColumn(size_t n, MYSQL_BIND *bind); - /// Fetches the column. - - operator MYSQL_STMT* (); - /// Cast operator to native handle type. - -private: - StatementExecutor(const StatementExecutor&); - StatementExecutor& operator=(const StatementExecutor&); - -private: - MYSQL_STMT* h; - int _state; - std::string _query; -}; - - -// -// inlines -// -inline StatementExecutor::operator MYSQL_STMT* () -{ - return h; -} - - -} } } // namespace Poco::Data::MySQL - - -#endif // Data_MySQL_StatementHandle_INCLUDED +// +// StatementExecutor.h +// +// $Id: //poco/1.3/Data/MySQL/include/Poco/Data/MySQL/StatementExecutor.h#2 $ +// +// Library: Data +// Package: MySQL +// Module: StatementExecutor +// +// Definition of the StatementExecutor class. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Data_MySQL_StatementHandle_INCLUDED +#define Data_MySQL_StatementHandle_INCLUDED + + +#include +#include "Poco/Data/MySQL/MySQLException.h" +#include + + +namespace Poco { +namespace Data { +namespace MySQL { + + +class StatementExecutor + /// MySQL statement executor. +{ +public: + enum State + { + STMT_INITED, + STMT_COMPILED, + STMT_EXECUTED + }; + + explicit StatementExecutor(MYSQL* mysql); + /// Creates the StatementExecutor. + + ~StatementExecutor(); + /// Destroys the StatementExecutor. + + int state() const; + /// Returns the current state. + + void prepare(const std::string& query); + /// Prepares the statement for execution. + + void bindParams(MYSQL_BIND* params, size_t count); + /// Binds the params. + + void bindResult(MYSQL_BIND* result); + /// Binds result. + + void execute(); + /// Executes the statement. + + bool fetch(); + /// Fetches the data. + + bool fetchColumn(size_t n, MYSQL_BIND *bind); + /// Fetches the column. + + operator MYSQL_STMT* (); + /// Cast operator to native handle type. + +private: + StatementExecutor(const StatementExecutor&); + StatementExecutor& operator=(const StatementExecutor&); + +private: + MYSQL_STMT* h; + int _state; + std::string _query; +}; + + +// +// inlines +// +inline StatementExecutor::operator MYSQL_STMT* () +{ + return h; +} + + +} } } // namespace Poco::Data::MySQL + + +#endif // Data_MySQL_StatementHandle_INCLUDED diff --git a/Data/MySQL/src/Binder.cpp b/Data/MySQL/src/Binder.cpp index da991773d..8a4d48ef5 100644 --- a/Data/MySQL/src/Binder.cpp +++ b/Data/MySQL/src/Binder.cpp @@ -1,181 +1,181 @@ -// -// MySQLException.cpp -// -// $Id: //poco/1.3/Data/MySQL/src/Binder.cpp#1 $ -// -// Library: Data -// Package: MySQL -// Module: Binder -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/MySQL/Binder.h" - - -namespace Poco { -namespace Data { -namespace MySQL { - - -Binder::Binder() -{ -} - - -Binder::~Binder() -{ -} - - -void Binder::bind(std::size_t pos, const Poco::Int8& val) -{ - realBind(pos, MYSQL_TYPE_TINY, &val, 0); -} - - -void Binder::bind(std::size_t pos, const Poco::UInt8& val) -{ - realBind(pos, MYSQL_TYPE_TINY, &val, 0); -} - - -void Binder::bind(std::size_t pos, const Poco::Int16& val) -{ - realBind(pos, MYSQL_TYPE_SHORT, &val, 0); -} - - -void Binder::bind(std::size_t pos, const Poco::UInt16& val) -{ - realBind(pos, MYSQL_TYPE_SHORT, &val, 0); -} - - -void Binder::bind(std::size_t pos, const Poco::Int32& val) -{ - realBind(pos, MYSQL_TYPE_LONG, &val, 0); -} - - -void Binder::bind(std::size_t pos, const Poco::UInt32& val) -{ - realBind(pos, MYSQL_TYPE_LONG, &val, 0); -} - - -void Binder::bind(std::size_t pos, const Poco::Int64& val) -{ - realBind(pos, MYSQL_TYPE_LONGLONG, &val, 0); -} - - -void Binder::bind(std::size_t pos, const Poco::UInt64& val) -{ - realBind(pos, MYSQL_TYPE_LONGLONG, &val, 0); -} - - -void Binder::bind(std::size_t pos, const bool& val) -{ - realBind(pos, MYSQL_TYPE_TINY, &val, 0); -} - - -void Binder::bind(std::size_t pos, const float& val) -{ - realBind(pos, MYSQL_TYPE_FLOAT, &val, 0); -} - - -void Binder::bind(std::size_t pos, const double& val) -{ - realBind(pos, MYSQL_TYPE_DOUBLE, &val, 0); -} - - -void Binder::bind(std::size_t pos, const char& val) -{ - realBind(pos, MYSQL_TYPE_TINY, &val, 0); -} - - -void Binder::bind(std::size_t pos, const std::string& val) -{ - realBind(pos, MYSQL_TYPE_STRING, val.c_str(), static_cast(val.length())); -} - - -void Binder::bind(std::size_t pos, const Poco::Data::BLOB& val) -{ - realBind(pos, MYSQL_TYPE_STRING, val.rawContent(), static_cast(val.size())); -} - - -size_t Binder::size() const -{ - return _bindArray.size(); -} - - -MYSQL_BIND* Binder::getBindArray() const -{ - if (_bindArray.size() == 0) - { - return 0; - } - - return const_cast(&_bindArray[0]); -} - - -void Binder::realBind(std::size_t pos, enum_field_types type, const void* buffer, int length) -{ - if (pos > 1024) - { - throw StatementException("too many bind parameters"); - } - - if (pos >= _bindArray.size()) - { - size_t s = _bindArray.size(); - _bindArray.resize(pos + 1); - - memset(&_bindArray[s], 0, sizeof(MYSQL_BIND) * (_bindArray.size() - s)); - } - - MYSQL_BIND b = {0}; - - b.buffer_type = type; - b.buffer = const_cast(buffer); - b.buffer_length = length; - - _bindArray[pos] = b; -} - - -} } } // namespace Poco::Data::MySQL +// +// MySQLException.cpp +// +// $Id: //poco/1.3/Data/MySQL/src/Binder.cpp#2 $ +// +// Library: Data +// Package: MySQL +// Module: Binder +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/MySQL/Binder.h" + + +namespace Poco { +namespace Data { +namespace MySQL { + + +Binder::Binder() +{ +} + + +Binder::~Binder() +{ +} + + +void Binder::bind(std::size_t pos, const Poco::Int8& val) +{ + realBind(pos, MYSQL_TYPE_TINY, &val, 0); +} + + +void Binder::bind(std::size_t pos, const Poco::UInt8& val) +{ + realBind(pos, MYSQL_TYPE_TINY, &val, 0); +} + + +void Binder::bind(std::size_t pos, const Poco::Int16& val) +{ + realBind(pos, MYSQL_TYPE_SHORT, &val, 0); +} + + +void Binder::bind(std::size_t pos, const Poco::UInt16& val) +{ + realBind(pos, MYSQL_TYPE_SHORT, &val, 0); +} + + +void Binder::bind(std::size_t pos, const Poco::Int32& val) +{ + realBind(pos, MYSQL_TYPE_LONG, &val, 0); +} + + +void Binder::bind(std::size_t pos, const Poco::UInt32& val) +{ + realBind(pos, MYSQL_TYPE_LONG, &val, 0); +} + + +void Binder::bind(std::size_t pos, const Poco::Int64& val) +{ + realBind(pos, MYSQL_TYPE_LONGLONG, &val, 0); +} + + +void Binder::bind(std::size_t pos, const Poco::UInt64& val) +{ + realBind(pos, MYSQL_TYPE_LONGLONG, &val, 0); +} + + +void Binder::bind(std::size_t pos, const bool& val) +{ + realBind(pos, MYSQL_TYPE_TINY, &val, 0); +} + + +void Binder::bind(std::size_t pos, const float& val) +{ + realBind(pos, MYSQL_TYPE_FLOAT, &val, 0); +} + + +void Binder::bind(std::size_t pos, const double& val) +{ + realBind(pos, MYSQL_TYPE_DOUBLE, &val, 0); +} + + +void Binder::bind(std::size_t pos, const char& val) +{ + realBind(pos, MYSQL_TYPE_TINY, &val, 0); +} + + +void Binder::bind(std::size_t pos, const std::string& val) +{ + realBind(pos, MYSQL_TYPE_STRING, val.c_str(), static_cast(val.length())); +} + + +void Binder::bind(std::size_t pos, const Poco::Data::BLOB& val) +{ + realBind(pos, MYSQL_TYPE_STRING, val.rawContent(), static_cast(val.size())); +} + + +size_t Binder::size() const +{ + return _bindArray.size(); +} + + +MYSQL_BIND* Binder::getBindArray() const +{ + if (_bindArray.size() == 0) + { + return 0; + } + + return const_cast(&_bindArray[0]); +} + + +void Binder::realBind(std::size_t pos, enum_field_types type, const void* buffer, int length) +{ + if (pos > 1024) + { + throw StatementException("too many bind parameters"); + } + + if (pos >= _bindArray.size()) + { + size_t s = _bindArray.size(); + _bindArray.resize(pos + 1); + + memset(&_bindArray[s], 0, sizeof(MYSQL_BIND) * (_bindArray.size() - s)); + } + + MYSQL_BIND b = {0}; + + b.buffer_type = type; + b.buffer = const_cast(buffer); + b.buffer_length = length; + + _bindArray[pos] = b; +} + + +} } } // namespace Poco::Data::MySQL diff --git a/Data/MySQL/src/Connector.cpp b/Data/MySQL/src/Connector.cpp index 12053ce99..1c4387042 100644 --- a/Data/MySQL/src/Connector.cpp +++ b/Data/MySQL/src/Connector.cpp @@ -1,87 +1,87 @@ -// -// MySQLException.cpp -// -// $Id: //poco/1.3/Data/MySQL/src/Connector.cpp#1 $ -// -// Library: Data -// Package: MySQL -// Module: Connector -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/MySQL/Connector.h" -#include "Poco/Data/MySQL/SessionImpl.h" -#include "Poco/Data/SessionFactory.h" -#include "Poco/Exception.h" -#include - - -namespace Poco { -namespace Data { -namespace MySQL { - - -std::string Connector::KEY("MySQL"); - - -Connector::Connector() -{ -} - - -Connector::~Connector() -{ -} - - -Poco::AutoPtr Connector::createSession(const std::string& connectionString) -{ - return Poco::AutoPtr(new SessionImpl(connectionString)); -} - - -void Connector::registerConnector() -{ - if (mysql_library_init(0, 0, 0) != 0) - { - throw Exception("mysql_library_init error"); - } - - Poco::Data::SessionFactory::instance().add(KEY, new Connector()); -} - - -void Connector::unregisterConnector() -{ - Poco::Data::SessionFactory::instance().remove(KEY); - mysql_library_end(); -} - - -} } } // namespace Poco::Data::MySQL - +// +// MySQLException.cpp +// +// $Id: //poco/1.3/Data/MySQL/src/Connector.cpp#2 $ +// +// Library: Data +// Package: MySQL +// Module: Connector +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/MySQL/Connector.h" +#include "Poco/Data/MySQL/SessionImpl.h" +#include "Poco/Data/SessionFactory.h" +#include "Poco/Exception.h" +#include + + +namespace Poco { +namespace Data { +namespace MySQL { + + +std::string Connector::KEY("MySQL"); + + +Connector::Connector() +{ +} + + +Connector::~Connector() +{ +} + + +Poco::AutoPtr Connector::createSession(const std::string& connectionString) +{ + return Poco::AutoPtr(new SessionImpl(connectionString)); +} + + +void Connector::registerConnector() +{ + if (mysql_library_init(0, 0, 0) != 0) + { + throw Exception("mysql_library_init error"); + } + + Poco::Data::SessionFactory::instance().add(KEY, new Connector()); +} + + +void Connector::unregisterConnector() +{ + Poco::Data::SessionFactory::instance().remove(KEY); + mysql_library_end(); +} + + +} } } // namespace Poco::Data::MySQL + diff --git a/Data/MySQL/src/Extractor.cpp b/Data/MySQL/src/Extractor.cpp index 7ce50fc86..de1af8dc7 100644 --- a/Data/MySQL/src/Extractor.cpp +++ b/Data/MySQL/src/Extractor.cpp @@ -1,177 +1,177 @@ -// -// MySQLException.cpp -// -// $Id: //poco/1.3/Data/MySQL/src/Extractor.cpp#1 $ -// -// Library: Data -// Package: MySQL -// Module: Extractor -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/MySQL/Extractor.h" - - -namespace Poco { -namespace Data { -namespace MySQL { - - -Extractor::Extractor(StatementExecutor& st, ResultMetadata& md): _stmt(st), _metadata(md) -{ -} - - -Extractor::~Extractor() -{ -} - - -bool Extractor::extract(std::size_t pos, Poco::Int8& val) -{ - return realExtractFixed(pos, MYSQL_TYPE_TINY, &val); -} - - -bool Extractor::extract(std::size_t pos, Poco::UInt8& val) -{ - return realExtractFixed(pos, MYSQL_TYPE_TINY, &val); -} - - -bool Extractor::extract(std::size_t pos, Poco::Int16& val) -{ - return realExtractFixed(pos, MYSQL_TYPE_SHORT, &val); -} - - -bool Extractor::extract(std::size_t pos, Poco::UInt16& val) -{ - return realExtractFixed(pos, MYSQL_TYPE_SHORT, &val); -} - - -bool Extractor::extract(std::size_t pos, Poco::Int32& val) -{ - return realExtractFixed(pos, MYSQL_TYPE_LONG, &val); -} - - -bool Extractor::extract(std::size_t pos, Poco::UInt32& val) -{ - return realExtractFixed(pos, MYSQL_TYPE_LONG, &val); -} - - -bool Extractor::extract(std::size_t pos, Poco::Int64& val) -{ - return realExtractFixed(pos, MYSQL_TYPE_LONGLONG, &val); -} - - -bool Extractor::extract(std::size_t pos, Poco::UInt64& val) -{ - return realExtractFixed(pos, MYSQL_TYPE_LONGLONG, &val); -} - - -bool Extractor::extract(std::size_t pos, bool& val) -{ - return realExtractFixed(pos, MYSQL_TYPE_TINY, &val); -} - - -bool Extractor::extract(std::size_t pos, float& val) -{ - return realExtractFixed(pos, MYSQL_TYPE_FLOAT, &val); -} - - -bool Extractor::extract(std::size_t pos, double& val) -{ - return realExtractFixed(pos, MYSQL_TYPE_DOUBLE, &val); -} - - -bool Extractor::extract(std::size_t pos, char& val) -{ - return realExtractFixed(pos, MYSQL_TYPE_TINY, &val); -} - - -bool Extractor::extract(std::size_t pos, std::string& val) -{ - if (_metadata.columnsReturned() <= pos) - throw MySQLException("Extractor: attempt to extract more paremeters, than query result contain"); - - if (_metadata.isNull(static_cast(pos))) - return false; - - if (_metadata.metaColumn(static_cast(pos)).type() != Poco::Data::MetaColumn::FDT_STRING) - throw MySQLException("Extractor: not a string"); - - val.assign(_metadata.rawData(pos), _metadata.length(pos)); - return true; -} - - -bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val) -{ - if (_metadata.columnsReturned() <= pos) - throw MySQLException("Extractor: attempt to extract more paremeters, than query result contain"); - - if (_metadata.isNull(static_cast(pos))) - return false; - - if (_metadata.metaColumn(static_cast(pos)).type() != Poco::Data::MetaColumn::FDT_BLOB) - throw MySQLException("Extractor: not a blob"); - - - val.assignRaw(_metadata.rawData(pos), _metadata.length(pos)); - return true; -} - - -bool Extractor::realExtractFixed(std::size_t pos, enum_field_types type, void* buffer, size_t length) -{ - MYSQL_BIND bind = {0}; - my_bool isNull = 0; - - bind.is_null = &isNull; - bind.buffer_type = type; - bind.buffer = buffer; - bind.buffer_length = static_cast(length); - - if (!_stmt.fetchColumn(pos, &bind)) - return false; - - return isNull == 0; -} - - -} } } // namespace Poco::Data::MySQL +// +// MySQLException.cpp +// +// $Id: //poco/1.3/Data/MySQL/src/Extractor.cpp#2 $ +// +// Library: Data +// Package: MySQL +// Module: Extractor +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/MySQL/Extractor.h" + + +namespace Poco { +namespace Data { +namespace MySQL { + + +Extractor::Extractor(StatementExecutor& st, ResultMetadata& md): _stmt(st), _metadata(md) +{ +} + + +Extractor::~Extractor() +{ +} + + +bool Extractor::extract(std::size_t pos, Poco::Int8& val) +{ + return realExtractFixed(pos, MYSQL_TYPE_TINY, &val); +} + + +bool Extractor::extract(std::size_t pos, Poco::UInt8& val) +{ + return realExtractFixed(pos, MYSQL_TYPE_TINY, &val); +} + + +bool Extractor::extract(std::size_t pos, Poco::Int16& val) +{ + return realExtractFixed(pos, MYSQL_TYPE_SHORT, &val); +} + + +bool Extractor::extract(std::size_t pos, Poco::UInt16& val) +{ + return realExtractFixed(pos, MYSQL_TYPE_SHORT, &val); +} + + +bool Extractor::extract(std::size_t pos, Poco::Int32& val) +{ + return realExtractFixed(pos, MYSQL_TYPE_LONG, &val); +} + + +bool Extractor::extract(std::size_t pos, Poco::UInt32& val) +{ + return realExtractFixed(pos, MYSQL_TYPE_LONG, &val); +} + + +bool Extractor::extract(std::size_t pos, Poco::Int64& val) +{ + return realExtractFixed(pos, MYSQL_TYPE_LONGLONG, &val); +} + + +bool Extractor::extract(std::size_t pos, Poco::UInt64& val) +{ + return realExtractFixed(pos, MYSQL_TYPE_LONGLONG, &val); +} + + +bool Extractor::extract(std::size_t pos, bool& val) +{ + return realExtractFixed(pos, MYSQL_TYPE_TINY, &val); +} + + +bool Extractor::extract(std::size_t pos, float& val) +{ + return realExtractFixed(pos, MYSQL_TYPE_FLOAT, &val); +} + + +bool Extractor::extract(std::size_t pos, double& val) +{ + return realExtractFixed(pos, MYSQL_TYPE_DOUBLE, &val); +} + + +bool Extractor::extract(std::size_t pos, char& val) +{ + return realExtractFixed(pos, MYSQL_TYPE_TINY, &val); +} + + +bool Extractor::extract(std::size_t pos, std::string& val) +{ + if (_metadata.columnsReturned() <= pos) + throw MySQLException("Extractor: attempt to extract more paremeters, than query result contain"); + + if (_metadata.isNull(static_cast(pos))) + return false; + + if (_metadata.metaColumn(static_cast(pos)).type() != Poco::Data::MetaColumn::FDT_STRING) + throw MySQLException("Extractor: not a string"); + + val.assign(_metadata.rawData(pos), _metadata.length(pos)); + return true; +} + + +bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val) +{ + if (_metadata.columnsReturned() <= pos) + throw MySQLException("Extractor: attempt to extract more paremeters, than query result contain"); + + if (_metadata.isNull(static_cast(pos))) + return false; + + if (_metadata.metaColumn(static_cast(pos)).type() != Poco::Data::MetaColumn::FDT_BLOB) + throw MySQLException("Extractor: not a blob"); + + + val.assignRaw(_metadata.rawData(pos), _metadata.length(pos)); + return true; +} + + +bool Extractor::realExtractFixed(std::size_t pos, enum_field_types type, void* buffer, size_t length) +{ + MYSQL_BIND bind = {0}; + my_bool isNull = 0; + + bind.is_null = &isNull; + bind.buffer_type = type; + bind.buffer = buffer; + bind.buffer_length = static_cast(length); + + if (!_stmt.fetchColumn(pos, &bind)) + return false; + + return isNull == 0; +} + + +} } } // namespace Poco::Data::MySQL diff --git a/Data/MySQL/src/MySQLException.cpp b/Data/MySQL/src/MySQLException.cpp index 5e679db44..88d570ee0 100644 --- a/Data/MySQL/src/MySQLException.cpp +++ b/Data/MySQL/src/MySQLException.cpp @@ -1,129 +1,129 @@ -// -// MySQLException.cpp -// -// $Id: //poco/1.3/Data/MySQL/src/MySQLException.cpp#1 $ -// -// Library: Data -// Package: MySQL -// Module: MySQLException -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/MySQL/MySQLException.h" -#include - - -namespace Poco { -namespace Data { -namespace MySQL { - - -MySQLException::MySQLException(const std::string& msg) : Poco::Data::DataException(std::string("[MySQL]: ") + msg) -{ -} - - -MySQLException::MySQLException(const MySQLException& exc) : Poco::Data::DataException(exc) -{ -} - - -MySQLException::~MySQLException() throw() -{ -} - - -ConnectionException::ConnectionException(const std::string& msg) : MySQLException(msg) -{ -} - - -ConnectionException::ConnectionException(const std::string& text, MYSQL* h) : MySQLException(compose(text, h)) -{ -} - - -StatementException::StatementException(const std::string& msg) : MySQLException(msg) -{ -} - - -StatementException::StatementException(const std::string& text, MYSQL_STMT* h, const std::string& stmt) : MySQLException(compose(text, h, stmt)) -{ -} - - -std::string ConnectionException::compose(const std::string& text, MYSQL* h) -{ - std::string str; - str += "[Comment]: "; - str += text; - str += "\t[mysql_error]: "; - str += mysql_error(h); - - str += "\t[mysql_errno]: "; - char buff[30]; - sprintf(buff, "%d", mysql_errno(h)); - str += buff; - - str += "\t[mysql_sqlstate]: "; - str += mysql_sqlstate(h); - return str; -} - -std::string StatementException::compose(const std::string& text, MYSQL_STMT* h, const std::string& stmt) -{ - std::string str; - str += "[Comment]: "; - str += text; - - if (h != 0) - { - str += "\t[mysql_stmt_error]: "; - str += mysql_stmt_error(h); - - str += "\t[mysql_stmt_errno]: "; - char buff[30]; - sprintf(buff, "%d", mysql_stmt_errno(h)); - str += buff; - - str += "\t[mysql_stmt_sqlstate]: "; - str += mysql_stmt_sqlstate(h); - } - - if (stmt.length() > 0) - { - str += "\t[statemnt]: "; - str += stmt; - } - - return str; -} - - -} } } // namespace Poco::Data::MySQL +// +// MySQLException.cpp +// +// $Id: //poco/1.3/Data/MySQL/src/MySQLException.cpp#2 $ +// +// Library: Data +// Package: MySQL +// Module: MySQLException +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/MySQL/MySQLException.h" +#include + + +namespace Poco { +namespace Data { +namespace MySQL { + + +MySQLException::MySQLException(const std::string& msg) : Poco::Data::DataException(std::string("[MySQL]: ") + msg) +{ +} + + +MySQLException::MySQLException(const MySQLException& exc) : Poco::Data::DataException(exc) +{ +} + + +MySQLException::~MySQLException() throw() +{ +} + + +ConnectionException::ConnectionException(const std::string& msg) : MySQLException(msg) +{ +} + + +ConnectionException::ConnectionException(const std::string& text, MYSQL* h) : MySQLException(compose(text, h)) +{ +} + + +StatementException::StatementException(const std::string& msg) : MySQLException(msg) +{ +} + + +StatementException::StatementException(const std::string& text, MYSQL_STMT* h, const std::string& stmt) : MySQLException(compose(text, h, stmt)) +{ +} + + +std::string ConnectionException::compose(const std::string& text, MYSQL* h) +{ + std::string str; + str += "[Comment]: "; + str += text; + str += "\t[mysql_error]: "; + str += mysql_error(h); + + str += "\t[mysql_errno]: "; + char buff[30]; + sprintf(buff, "%d", mysql_errno(h)); + str += buff; + + str += "\t[mysql_sqlstate]: "; + str += mysql_sqlstate(h); + return str; +} + +std::string StatementException::compose(const std::string& text, MYSQL_STMT* h, const std::string& stmt) +{ + std::string str; + str += "[Comment]: "; + str += text; + + if (h != 0) + { + str += "\t[mysql_stmt_error]: "; + str += mysql_stmt_error(h); + + str += "\t[mysql_stmt_errno]: "; + char buff[30]; + sprintf(buff, "%d", mysql_stmt_errno(h)); + str += buff; + + str += "\t[mysql_stmt_sqlstate]: "; + str += mysql_stmt_sqlstate(h); + } + + if (stmt.length() > 0) + { + str += "\t[statemnt]: "; + str += stmt; + } + + return str; +} + + +} } } // namespace Poco::Data::MySQL diff --git a/Data/MySQL/src/MySQLStatementImpl.cpp b/Data/MySQL/src/MySQLStatementImpl.cpp index 4f51ef6b3..37b6913f2 100644 --- a/Data/MySQL/src/MySQLStatementImpl.cpp +++ b/Data/MySQL/src/MySQLStatementImpl.cpp @@ -1,175 +1,175 @@ -// -// MySQLException.cpp -// -// $Id: //poco/1.3/Data/MySQL/src/MySQLStatementImpl.cpp#1 $ -// -// Library: Data -// Package: MySQL -// Module: MySQLStatementImpl -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/MySQL/MySQLStatementImpl.h" - - -namespace Poco { -namespace Data { -namespace MySQL { - - -MySQLStatementImpl::MySQLStatementImpl(SessionHandle& h): - _stmt(h), - _extractor(_stmt, _metadata), - _hasNext(NEXT_DONTKNOW) -{ -} - - -MySQLStatementImpl::~MySQLStatementImpl() -{ -} - - -Poco::UInt32 MySQLStatementImpl::columnsReturned() const -{ - return _metadata.columnsReturned(); -} - - -const MetaColumn& MySQLStatementImpl::metaColumn(Poco::UInt32 pos) const -{ - return _metadata.metaColumn(pos); -} - - -bool MySQLStatementImpl::hasNext() -{ - if (_hasNext == NEXT_DONTKNOW) - { - if (_metadata.columnsReturned() == 0) - { - return false; - } - - if (_stmt.fetch()) - { - _hasNext = NEXT_TRUE; - return true; - } - - _hasNext = NEXT_FALSE; - return false; - } - else if (_hasNext == NEXT_TRUE) - { - return true; - } - - return false; -} - - -void MySQLStatementImpl::next() -{ - if (!hasNext()) - throw StatementException("No data received"); - - Poco::Data::AbstractExtractionVec::iterator it = extractions().begin(); - Poco::Data::AbstractExtractionVec::iterator itEnd = extractions().end(); - std::size_t pos = 0; - - for (; it != itEnd; ++it) - { - (*it)->extract(pos); - pos += (*it)->numOfColumnsHandled(); - } - - _hasNext = NEXT_DONTKNOW; -} - - -bool MySQLStatementImpl::canBind() const -{ - bool ret = false; - - if ((_stmt.state() >= StatementExecutor::STMT_COMPILED) && !bindings().empty()) - ret = (*bindings().begin())->canBind(); - - return ret; -} - - -void MySQLStatementImpl::compileImpl() -{ - _metadata.reset(); - _stmt.prepare(toString()); - _metadata.init(_stmt); - - if (_metadata.columnsReturned() > 0) - { - _stmt.bindResult(_metadata.row()); - } -} - - -void MySQLStatementImpl::bindImpl() -{ - { - Poco::Data::AbstractBindingVec& binds = bindings(); - size_t pos = 0; - Poco::Data::AbstractBindingVec::iterator it = binds.begin(); - Poco::Data::AbstractBindingVec::iterator itEnd = binds.end(); - - for (; it != itEnd && (*it)->canBind(); ++it) - { - (*it)->bind(pos); - pos += (*it)->numOfColumnsHandled(); - } - } - - _stmt.bindParams(_binder.getBindArray(), _binder.size()); - - _stmt.execute(); - - _hasNext = NEXT_DONTKNOW; -} - - -AbstractExtractor& MySQLStatementImpl::extractor() -{ - return _extractor; -} - - -AbstractBinder& MySQLStatementImpl::binder() -{ - return _binder; -} - - -} } } // namespace Poco::Data::MySQL +// +// MySQLException.cpp +// +// $Id: //poco/1.3/Data/MySQL/src/MySQLStatementImpl.cpp#2 $ +// +// Library: Data +// Package: MySQL +// Module: MySQLStatementImpl +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/MySQL/MySQLStatementImpl.h" + + +namespace Poco { +namespace Data { +namespace MySQL { + + +MySQLStatementImpl::MySQLStatementImpl(SessionHandle& h): + _stmt(h), + _extractor(_stmt, _metadata), + _hasNext(NEXT_DONTKNOW) +{ +} + + +MySQLStatementImpl::~MySQLStatementImpl() +{ +} + + +Poco::UInt32 MySQLStatementImpl::columnsReturned() const +{ + return _metadata.columnsReturned(); +} + + +const MetaColumn& MySQLStatementImpl::metaColumn(Poco::UInt32 pos) const +{ + return _metadata.metaColumn(pos); +} + + +bool MySQLStatementImpl::hasNext() +{ + if (_hasNext == NEXT_DONTKNOW) + { + if (_metadata.columnsReturned() == 0) + { + return false; + } + + if (_stmt.fetch()) + { + _hasNext = NEXT_TRUE; + return true; + } + + _hasNext = NEXT_FALSE; + return false; + } + else if (_hasNext == NEXT_TRUE) + { + return true; + } + + return false; +} + + +void MySQLStatementImpl::next() +{ + if (!hasNext()) + throw StatementException("No data received"); + + Poco::Data::AbstractExtractionVec::iterator it = extractions().begin(); + Poco::Data::AbstractExtractionVec::iterator itEnd = extractions().end(); + std::size_t pos = 0; + + for (; it != itEnd; ++it) + { + (*it)->extract(pos); + pos += (*it)->numOfColumnsHandled(); + } + + _hasNext = NEXT_DONTKNOW; +} + + +bool MySQLStatementImpl::canBind() const +{ + bool ret = false; + + if ((_stmt.state() >= StatementExecutor::STMT_COMPILED) && !bindings().empty()) + ret = (*bindings().begin())->canBind(); + + return ret; +} + + +void MySQLStatementImpl::compileImpl() +{ + _metadata.reset(); + _stmt.prepare(toString()); + _metadata.init(_stmt); + + if (_metadata.columnsReturned() > 0) + { + _stmt.bindResult(_metadata.row()); + } +} + + +void MySQLStatementImpl::bindImpl() +{ + { + Poco::Data::AbstractBindingVec& binds = bindings(); + size_t pos = 0; + Poco::Data::AbstractBindingVec::iterator it = binds.begin(); + Poco::Data::AbstractBindingVec::iterator itEnd = binds.end(); + + for (; it != itEnd && (*it)->canBind(); ++it) + { + (*it)->bind(pos); + pos += (*it)->numOfColumnsHandled(); + } + } + + _stmt.bindParams(_binder.getBindArray(), _binder.size()); + + _stmt.execute(); + + _hasNext = NEXT_DONTKNOW; +} + + +AbstractExtractor& MySQLStatementImpl::extractor() +{ + return _extractor; +} + + +AbstractBinder& MySQLStatementImpl::binder() +{ + return _binder; +} + + +} } } // namespace Poco::Data::MySQL diff --git a/Data/MySQL/src/ResultMetadata.cpp b/Data/MySQL/src/ResultMetadata.cpp index 59c6a5c18..fe3a9701c 100644 --- a/Data/MySQL/src/ResultMetadata.cpp +++ b/Data/MySQL/src/ResultMetadata.cpp @@ -1,279 +1,279 @@ -// -// MySQLException.cpp -// -// $Id: //poco/1.3/Data/MySQL/src/ResultMetadata.cpp#1 $ -// -// Library: Data -// Package: MySQL -// Module: ResultMetadata -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/MySQL/ResultMetadata.h" -#include "Poco/Data/MySQL/MySQLException.h" - - -namespace -{ - class ResultMetadataHandle - /// Simple exception-safe wrapper - { - public: - - explicit ResultMetadataHandle(MYSQL_STMT* stmt) - { - h = mysql_stmt_result_metadata(stmt); - } - - ~ResultMetadataHandle() - { - if (h) - { - mysql_free_result(h); - } - } - - operator MYSQL_RES* () - { - return h; - } - - private: - - MYSQL_RES* h; - }; - - size_t fieldSize(const MYSQL_FIELD& field) - /// Convert field MySQL-type and field MySQL-length to actual field length - { - switch (field.type) - { - case MYSQL_TYPE_TINY: return sizeof(char); - case MYSQL_TYPE_SHORT: return sizeof(short); - case MYSQL_TYPE_LONG: return sizeof(Poco::Int32); - case MYSQL_TYPE_FLOAT: return sizeof(float); - case MYSQL_TYPE_DOUBLE: return sizeof(double); - case MYSQL_TYPE_LONGLONG: return sizeof(Poco::Int64); - - case MYSQL_TYPE_DECIMAL: - case MYSQL_TYPE_NEWDECIMAL: - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_VAR_STRING: - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_NULL: - case MYSQL_TYPE_TIMESTAMP: - case MYSQL_TYPE_INT24: - case MYSQL_TYPE_DATE: - case MYSQL_TYPE_TIME: - case MYSQL_TYPE_DATETIME: - case MYSQL_TYPE_YEAR: - case MYSQL_TYPE_NEWDATE: - case MYSQL_TYPE_VARCHAR: - case MYSQL_TYPE_BIT: - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - case MYSQL_TYPE_GEOMETRY: - default: - return field.length; - } - - throw Poco::Data::MySQL::StatementException("unknown field type"); - } - - Poco::Data::MetaColumn::ColumnDataType fieldType(const MYSQL_FIELD& field) - /// Convert field MySQL-type to Poco-type - { - bool unsig = ((field.flags & UNSIGNED_FLAG) == UNSIGNED_FLAG); - - switch (field.type) - { - case MYSQL_TYPE_TINY: - if (unsig) return Poco::Data::MetaColumn::FDT_UINT8; - return Poco::Data::MetaColumn::FDT_INT8; - - case MYSQL_TYPE_SHORT: - if (unsig) return Poco::Data::MetaColumn::FDT_UINT16; - return Poco::Data::MetaColumn::FDT_INT16; - - case MYSQL_TYPE_LONG: - if (unsig) return Poco::Data::MetaColumn::FDT_UINT32; - return Poco::Data::MetaColumn::FDT_INT32; - - case MYSQL_TYPE_FLOAT: - return Poco::Data::MetaColumn::FDT_FLOAT; - - case MYSQL_TYPE_DOUBLE: - return Poco::Data::MetaColumn::FDT_DOUBLE; - - case MYSQL_TYPE_LONGLONG: - if (unsig) return Poco::Data::MetaColumn::FDT_UINT64; - return Poco::Data::MetaColumn::FDT_INT64; - - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_VAR_STRING: - return Poco::Data::MetaColumn::FDT_STRING; - - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_BLOB: - return Poco::Data::MetaColumn::FDT_BLOB; - - case MYSQL_TYPE_DECIMAL: - case MYSQL_TYPE_NEWDECIMAL: - case MYSQL_TYPE_NULL: - case MYSQL_TYPE_TIMESTAMP: - case MYSQL_TYPE_INT24: - case MYSQL_TYPE_DATE: - case MYSQL_TYPE_TIME: - case MYSQL_TYPE_DATETIME: - case MYSQL_TYPE_YEAR: - case MYSQL_TYPE_NEWDATE: - case MYSQL_TYPE_VARCHAR: - case MYSQL_TYPE_BIT: - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - case MYSQL_TYPE_GEOMETRY: - default: - return Poco::Data::MetaColumn::FDT_UNKNOWN; - } - - return Poco::Data::MetaColumn::FDT_UNKNOWN; - } -} // namespace - - -namespace Poco { -namespace Data { -namespace MySQL { - - -void ResultMetadata::reset() -{ - _columns.resize(0); - _row.resize(0); - _buffer.resize(0); - _lengths.resize(0); - _isNull.resize(0); -} - - -void ResultMetadata::init(MYSQL_STMT* stmt) -{ - ResultMetadataHandle h(stmt); - - if (!h) - { - // all right, it is normal - // querys such an "INSERT INTO" just does not have result at all - reset(); - return; - } - - size_t count = mysql_num_fields(h); - MYSQL_FIELD* fields = mysql_fetch_fields(h); - - size_t commonSize = 0; - _columns.reserve(count); - - for (size_t i = 0; i < count; i++) - { - _columns.push_back(MetaColumn( - i, // position - fields[i].name, // name - fieldType(fields[i]), // type - fieldSize(fields[i]), // length - 0, // TODO: precision (Now I dont know how to get it) - !IS_NOT_NULL(fields[i].flags) // nullable - )); - - commonSize += _columns[i].length(); - } - - _buffer.resize(commonSize); - _row.resize(count); - _lengths.resize(count); - _isNull.resize(count); - - size_t offset = 0; - - for (size_t i = 0; i < count; i++) - { - memset(&_row[i], 0, sizeof(MYSQL_BIND)); - - _row[i].buffer_type = fields[i].type; - _row[i].buffer_length = static_cast(_columns[i].length()); - _row[i].buffer = &_buffer[0] + offset; - _row[i].length = &_lengths[i]; - _row[i].is_null = &_isNull[i]; - - offset += _row[i].buffer_length; - } -} - - -Poco::UInt32 ResultMetadata::columnsReturned() const -{ - return static_cast(_columns.size()); -} - - -const MetaColumn& ResultMetadata::metaColumn(Poco::UInt32 pos) const -{ - return _columns[pos]; -} - - -MYSQL_BIND* ResultMetadata::row() -{ - return &_row[0]; -} - - -size_t ResultMetadata::length(size_t pos) const -{ - return _lengths[pos]; -} - - -const char* ResultMetadata::rawData(size_t pos) const -{ - return reinterpret_cast(_row[pos].buffer); -} - - -bool ResultMetadata::isNull(size_t pos) const -{ - return (_isNull[pos] != 0); -} - - -} } } // namespace Poco::Data::MySQL +// +// MySQLException.cpp +// +// $Id: //poco/1.3/Data/MySQL/src/ResultMetadata.cpp#2 $ +// +// Library: Data +// Package: MySQL +// Module: ResultMetadata +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/MySQL/ResultMetadata.h" +#include "Poco/Data/MySQL/MySQLException.h" + + +namespace +{ + class ResultMetadataHandle + /// Simple exception-safe wrapper + { + public: + + explicit ResultMetadataHandle(MYSQL_STMT* stmt) + { + h = mysql_stmt_result_metadata(stmt); + } + + ~ResultMetadataHandle() + { + if (h) + { + mysql_free_result(h); + } + } + + operator MYSQL_RES* () + { + return h; + } + + private: + + MYSQL_RES* h; + }; + + size_t fieldSize(const MYSQL_FIELD& field) + /// Convert field MySQL-type and field MySQL-length to actual field length + { + switch (field.type) + { + case MYSQL_TYPE_TINY: return sizeof(char); + case MYSQL_TYPE_SHORT: return sizeof(short); + case MYSQL_TYPE_LONG: return sizeof(Poco::Int32); + case MYSQL_TYPE_FLOAT: return sizeof(float); + case MYSQL_TYPE_DOUBLE: return sizeof(double); + case MYSQL_TYPE_LONGLONG: return sizeof(Poco::Int64); + + case MYSQL_TYPE_DECIMAL: + case MYSQL_TYPE_NEWDECIMAL: + case MYSQL_TYPE_STRING: + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_NULL: + case MYSQL_TYPE_TIMESTAMP: + case MYSQL_TYPE_INT24: + case MYSQL_TYPE_DATE: + case MYSQL_TYPE_TIME: + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_YEAR: + case MYSQL_TYPE_NEWDATE: + case MYSQL_TYPE_VARCHAR: + case MYSQL_TYPE_BIT: + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_SET: + case MYSQL_TYPE_GEOMETRY: + default: + return field.length; + } + + throw Poco::Data::MySQL::StatementException("unknown field type"); + } + + Poco::Data::MetaColumn::ColumnDataType fieldType(const MYSQL_FIELD& field) + /// Convert field MySQL-type to Poco-type + { + bool unsig = ((field.flags & UNSIGNED_FLAG) == UNSIGNED_FLAG); + + switch (field.type) + { + case MYSQL_TYPE_TINY: + if (unsig) return Poco::Data::MetaColumn::FDT_UINT8; + return Poco::Data::MetaColumn::FDT_INT8; + + case MYSQL_TYPE_SHORT: + if (unsig) return Poco::Data::MetaColumn::FDT_UINT16; + return Poco::Data::MetaColumn::FDT_INT16; + + case MYSQL_TYPE_LONG: + if (unsig) return Poco::Data::MetaColumn::FDT_UINT32; + return Poco::Data::MetaColumn::FDT_INT32; + + case MYSQL_TYPE_FLOAT: + return Poco::Data::MetaColumn::FDT_FLOAT; + + case MYSQL_TYPE_DOUBLE: + return Poco::Data::MetaColumn::FDT_DOUBLE; + + case MYSQL_TYPE_LONGLONG: + if (unsig) return Poco::Data::MetaColumn::FDT_UINT64; + return Poco::Data::MetaColumn::FDT_INT64; + + case MYSQL_TYPE_STRING: + case MYSQL_TYPE_VAR_STRING: + return Poco::Data::MetaColumn::FDT_STRING; + + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_BLOB: + return Poco::Data::MetaColumn::FDT_BLOB; + + case MYSQL_TYPE_DECIMAL: + case MYSQL_TYPE_NEWDECIMAL: + case MYSQL_TYPE_NULL: + case MYSQL_TYPE_TIMESTAMP: + case MYSQL_TYPE_INT24: + case MYSQL_TYPE_DATE: + case MYSQL_TYPE_TIME: + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_YEAR: + case MYSQL_TYPE_NEWDATE: + case MYSQL_TYPE_VARCHAR: + case MYSQL_TYPE_BIT: + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_SET: + case MYSQL_TYPE_GEOMETRY: + default: + return Poco::Data::MetaColumn::FDT_UNKNOWN; + } + + return Poco::Data::MetaColumn::FDT_UNKNOWN; + } +} // namespace + + +namespace Poco { +namespace Data { +namespace MySQL { + + +void ResultMetadata::reset() +{ + _columns.resize(0); + _row.resize(0); + _buffer.resize(0); + _lengths.resize(0); + _isNull.resize(0); +} + + +void ResultMetadata::init(MYSQL_STMT* stmt) +{ + ResultMetadataHandle h(stmt); + + if (!h) + { + // all right, it is normal + // querys such an "INSERT INTO" just does not have result at all + reset(); + return; + } + + size_t count = mysql_num_fields(h); + MYSQL_FIELD* fields = mysql_fetch_fields(h); + + size_t commonSize = 0; + _columns.reserve(count); + + for (size_t i = 0; i < count; i++) + { + _columns.push_back(MetaColumn( + i, // position + fields[i].name, // name + fieldType(fields[i]), // type + fieldSize(fields[i]), // length + 0, // TODO: precision (Now I dont know how to get it) + !IS_NOT_NULL(fields[i].flags) // nullable + )); + + commonSize += _columns[i].length(); + } + + _buffer.resize(commonSize); + _row.resize(count); + _lengths.resize(count); + _isNull.resize(count); + + size_t offset = 0; + + for (size_t i = 0; i < count; i++) + { + memset(&_row[i], 0, sizeof(MYSQL_BIND)); + + _row[i].buffer_type = fields[i].type; + _row[i].buffer_length = static_cast(_columns[i].length()); + _row[i].buffer = &_buffer[0] + offset; + _row[i].length = &_lengths[i]; + _row[i].is_null = &_isNull[i]; + + offset += _row[i].buffer_length; + } +} + + +Poco::UInt32 ResultMetadata::columnsReturned() const +{ + return static_cast(_columns.size()); +} + + +const MetaColumn& ResultMetadata::metaColumn(Poco::UInt32 pos) const +{ + return _columns[pos]; +} + + +MYSQL_BIND* ResultMetadata::row() +{ + return &_row[0]; +} + + +size_t ResultMetadata::length(size_t pos) const +{ + return _lengths[pos]; +} + + +const char* ResultMetadata::rawData(size_t pos) const +{ + return reinterpret_cast(_row[pos].buffer); +} + + +bool ResultMetadata::isNull(size_t pos) const +{ + return (_isNull[pos] != 0); +} + + +} } } // namespace Poco::Data::MySQL diff --git a/Data/MySQL/src/SessionHandle.cpp b/Data/MySQL/src/SessionHandle.cpp index 34ef75e12..56123080d 100644 --- a/Data/MySQL/src/SessionHandle.cpp +++ b/Data/MySQL/src/SessionHandle.cpp @@ -1,119 +1,119 @@ -// -// SesssionHandle.cpp -// -// $Id: //poco/1.3/Data/MySQL/src/SessionHandle.cpp#1 $ -// -// Library: Data -// Package: MySQL -// Module: SessionHandle -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/MySQL/SessionHandle.h" - - -namespace Poco { -namespace Data { -namespace MySQL { - - -SessionHandle::SessionHandle(MYSQL* mysql) -{ - h = mysql_init(mysql); - - if (!h) - { - throw ConnectionException("mysql_init error"); - } -} - - -SessionHandle::~SessionHandle() -{ - close(); -} - - -void SessionHandle::options(mysql_option opt) -{ - int res = mysql_options(h, opt, 0); - - if (res != 0) - { - throw ConnectionException("mysql_options error", h); - } -} - - -void SessionHandle::options(mysql_option opt, bool b) -{ - my_bool tmp = b; - int res = mysql_options(h, opt, &tmp); - - if (res != 0) - { - throw ConnectionException("mysql_options error", h); - } -} - - -void SessionHandle::connect(const char* host, const char* user, const char* password, const char* db, unsigned int port) -{ - if (!mysql_real_connect(h, host, user, password, db, port, 0, 0)) - { - throw ConnectionException("create session: mysql_real_connect error", h); - } -} - - -void SessionHandle::close() -{ - if (h) - { - mysql_close(h); - h = 0; - } -} - - -void SessionHandle::query(const char* str) -{ - int res = mysql_real_query(h, str, static_cast(strlen(str))); - - if (res != 0) - { - std::string msg; - msg += "mysql_real_query('"; - msg += str; - msg += "') error"; - throw ConnectionException(msg, h); - } -} - - -} } } // namespace Poco::Data::MySQL +// +// SesssionHandle.cpp +// +// $Id: //poco/1.3/Data/MySQL/src/SessionHandle.cpp#2 $ +// +// Library: Data +// Package: MySQL +// Module: SessionHandle +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/MySQL/SessionHandle.h" + + +namespace Poco { +namespace Data { +namespace MySQL { + + +SessionHandle::SessionHandle(MYSQL* mysql) +{ + h = mysql_init(mysql); + + if (!h) + { + throw ConnectionException("mysql_init error"); + } +} + + +SessionHandle::~SessionHandle() +{ + close(); +} + + +void SessionHandle::options(mysql_option opt) +{ + int res = mysql_options(h, opt, 0); + + if (res != 0) + { + throw ConnectionException("mysql_options error", h); + } +} + + +void SessionHandle::options(mysql_option opt, bool b) +{ + my_bool tmp = b; + int res = mysql_options(h, opt, &tmp); + + if (res != 0) + { + throw ConnectionException("mysql_options error", h); + } +} + + +void SessionHandle::connect(const char* host, const char* user, const char* password, const char* db, unsigned int port) +{ + if (!mysql_real_connect(h, host, user, password, db, port, 0, 0)) + { + throw ConnectionException("create session: mysql_real_connect error", h); + } +} + + +void SessionHandle::close() +{ + if (h) + { + mysql_close(h); + h = 0; + } +} + + +void SessionHandle::query(const char* str) +{ + int res = mysql_real_query(h, str, static_cast(strlen(str))); + + if (res != 0) + { + std::string msg; + msg += "mysql_real_query('"; + msg += str; + msg += "') error"; + throw ConnectionException(msg, h); + } +} + + +} } } // namespace Poco::Data::MySQL diff --git a/Data/MySQL/src/SessionImpl.cpp b/Data/MySQL/src/SessionImpl.cpp index d82e8d20f..41c8ead0e 100644 --- a/Data/MySQL/src/SessionImpl.cpp +++ b/Data/MySQL/src/SessionImpl.cpp @@ -1,232 +1,232 @@ -// -// MySQLException.cpp -// -// $Id: //poco/1.3/Data/MySQL/src/SessionImpl.cpp#1 $ -// -// Library: Data -// Package: MySQL -// Module: SessionImpl -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/MySQL/SessionImpl.h" -#include "Poco/Data/MySQL/MySQLStatementImpl.h" - - -namespace -{ - std::string copyStripped(std::string::const_iterator from, std::string::const_iterator to) - { - // skip leading spaces - while ((from != to) && isspace(*from)) from++; - // skip trailing spaces - while ((from != to) && isspace(*(to - 1))) to--; - - return std::string(from, to); - } -} - - -namespace Poco { -namespace Data { -namespace MySQL { - - -SessionImpl::SessionImpl(const std::string& connectionString) : _mysql(0), _connected(false), _inTransaction(0) -{ - addProperty("insertId", - &SessionImpl::setInsertId, - &SessionImpl::getInsertId); - - std::map options; - - // Default values - options["host"] = "localhost"; - options["port"] = "3306"; - options["user"] = ""; - options["password"] = ""; - options["db"] = ""; - options["compress"] = ""; - options["auto-reconnect"] = ""; - - // - // Parse string - // - - for (std::string::const_iterator start = connectionString.begin();;) - { - // find next ';' - std::string::const_iterator finish = std::find(start, connectionString.end(), ';'); - - // find '=' - std::string::const_iterator middle = std::find(start, finish, '='); - - if (middle == finish) - { - throw MySQLException("create session: bad connection string format, can not find '='"); - } - - // Parse name and value, skip all spaces - options[copyStripped(start, middle)] = copyStripped(middle + 1, finish); - - if (finish == connectionString.end()) - { - // end of parse - break; - } - - // move start position after ';' - start = finish + 1; - } - - // - // Checking - // - - if (options["user"] == "") - { - throw MySQLException("create session: specify user name"); - } - - if (options["db"] == "") - { - throw MySQLException("create session: specify database"); - } - - if (atoi(options["port"].c_str()) == 0) - { - throw MySQLException("create session: specify correct port (numeric in decimal notation)"); - } - - // - // Options - // - - if (options["compress"] == "true") - { - _mysql.options(MYSQL_OPT_COMPRESS); - } - else if (options["compress"] == "false") - { - // do nothing - } - else if (options["compress"] != "") - { - throw MySQLException("create session: specify correct compress option (true or false) or skip it"); - } - - if (options["auto-reconnect"] == "true") - { - _mysql.options(MYSQL_OPT_RECONNECT, true); - } - else if (options["auto-reconnect"] == "false") - { - _mysql.options(MYSQL_OPT_RECONNECT, false); - } - else if (options["auto-reconnect"] != "") - { - throw MySQLException("create session: specify correct auto-reconnect option (true or false) or skip it"); - } - - // - // Real connect - // - - _mysql.connect( - options["host"].c_str(), - options["user"].c_str(), - options["password"].c_str(), - options["db"].c_str(), - atoi(options["port"].c_str())); - - _connected = true; -} - - -SessionImpl::~SessionImpl() -{ - close(); -} - - -Poco::Data::StatementImpl* SessionImpl::createStatementImpl() -{ - return new MySQLStatementImpl(_mysql); -} - - -void SessionImpl::begin() -{ - _mysql.query("START TRANSACTION"); - _inTransaction++; -} - - -void SessionImpl::commit() -{ - _mysql.query("COMMIT"); - _inTransaction--; - - // ? - // mysql_commit(fMysql); -} - - -void SessionImpl::rollback() -{ - _mysql.query("ROLLBACK"); - _inTransaction--; - - // ? - // mysql_commit(fMysql); -} - - -void SessionImpl::close() -{ - if (_connected) - { - _mysql.close(); - _connected = false; - } -} - - -bool SessionImpl::isConnected() -{ - return _connected; -} - - -bool SessionImpl::isTransaction() -{ - return (_inTransaction > 0); -} - - -} } } // namespace Poco::Data::MySQL +// +// MySQLException.cpp +// +// $Id: //poco/1.3/Data/MySQL/src/SessionImpl.cpp#2 $ +// +// Library: Data +// Package: MySQL +// Module: SessionImpl +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/MySQL/SessionImpl.h" +#include "Poco/Data/MySQL/MySQLStatementImpl.h" + + +namespace +{ + std::string copyStripped(std::string::const_iterator from, std::string::const_iterator to) + { + // skip leading spaces + while ((from != to) && isspace(*from)) from++; + // skip trailing spaces + while ((from != to) && isspace(*(to - 1))) to--; + + return std::string(from, to); + } +} + + +namespace Poco { +namespace Data { +namespace MySQL { + + +SessionImpl::SessionImpl(const std::string& connectionString) : _mysql(0), _connected(false), _inTransaction(0) +{ + addProperty("insertId", + &SessionImpl::setInsertId, + &SessionImpl::getInsertId); + + std::map options; + + // Default values + options["host"] = "localhost"; + options["port"] = "3306"; + options["user"] = ""; + options["password"] = ""; + options["db"] = ""; + options["compress"] = ""; + options["auto-reconnect"] = ""; + + // + // Parse string + // + + for (std::string::const_iterator start = connectionString.begin();;) + { + // find next ';' + std::string::const_iterator finish = std::find(start, connectionString.end(), ';'); + + // find '=' + std::string::const_iterator middle = std::find(start, finish, '='); + + if (middle == finish) + { + throw MySQLException("create session: bad connection string format, can not find '='"); + } + + // Parse name and value, skip all spaces + options[copyStripped(start, middle)] = copyStripped(middle + 1, finish); + + if (finish == connectionString.end()) + { + // end of parse + break; + } + + // move start position after ';' + start = finish + 1; + } + + // + // Checking + // + + if (options["user"] == "") + { + throw MySQLException("create session: specify user name"); + } + + if (options["db"] == "") + { + throw MySQLException("create session: specify database"); + } + + if (atoi(options["port"].c_str()) == 0) + { + throw MySQLException("create session: specify correct port (numeric in decimal notation)"); + } + + // + // Options + // + + if (options["compress"] == "true") + { + _mysql.options(MYSQL_OPT_COMPRESS); + } + else if (options["compress"] == "false") + { + // do nothing + } + else if (options["compress"] != "") + { + throw MySQLException("create session: specify correct compress option (true or false) or skip it"); + } + + if (options["auto-reconnect"] == "true") + { + _mysql.options(MYSQL_OPT_RECONNECT, true); + } + else if (options["auto-reconnect"] == "false") + { + _mysql.options(MYSQL_OPT_RECONNECT, false); + } + else if (options["auto-reconnect"] != "") + { + throw MySQLException("create session: specify correct auto-reconnect option (true or false) or skip it"); + } + + // + // Real connect + // + + _mysql.connect( + options["host"].c_str(), + options["user"].c_str(), + options["password"].c_str(), + options["db"].c_str(), + atoi(options["port"].c_str())); + + _connected = true; +} + + +SessionImpl::~SessionImpl() +{ + close(); +} + + +Poco::Data::StatementImpl* SessionImpl::createStatementImpl() +{ + return new MySQLStatementImpl(_mysql); +} + + +void SessionImpl::begin() +{ + _mysql.query("START TRANSACTION"); + _inTransaction++; +} + + +void SessionImpl::commit() +{ + _mysql.query("COMMIT"); + _inTransaction--; + + // ? + // mysql_commit(fMysql); +} + + +void SessionImpl::rollback() +{ + _mysql.query("ROLLBACK"); + _inTransaction--; + + // ? + // mysql_commit(fMysql); +} + + +void SessionImpl::close() +{ + if (_connected) + { + _mysql.close(); + _connected = false; + } +} + + +bool SessionImpl::isConnected() +{ + return _connected; +} + + +bool SessionImpl::isTransaction() +{ + return (_inTransaction > 0); +} + + +} } } // namespace Poco::Data::MySQL diff --git a/Data/MySQL/src/StatementExecutor.cpp b/Data/MySQL/src/StatementExecutor.cpp index 166a75080..29a26ab19 100644 --- a/Data/MySQL/src/StatementExecutor.cpp +++ b/Data/MySQL/src/StatementExecutor.cpp @@ -1,195 +1,195 @@ -// -// StatementExecutor.cpp -// -// $Id: //poco/1.3/Data/MySQL/src/StatementExecutor.cpp#1 $ -// -// Library: Data -// Package: MySQL -// Module: StatementExecutor -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include -#include "Poco/Data/MySQL/StatementExecutor.h" - - -namespace Poco { -namespace Data { -namespace MySQL { - - -StatementExecutor::StatementExecutor(MYSQL* mysql) -{ - h = mysql_stmt_init(mysql); - - if (!h) - { - throw StatementException("mysql_stmt_init error"); - } - - _state = STMT_INITED; -} - - -StatementExecutor::~StatementExecutor() -{ - mysql_stmt_close(h); -} - - -int StatementExecutor::state() const -{ - return _state; -} - - -void StatementExecutor::prepare(const std::string& query) -{ - if (_state >= STMT_COMPILED) - { - throw StatementException("Satement is already compiled"); - } - - // compile - int res = mysql_stmt_prepare(h, query.c_str(), static_cast(query.length())); - - if (res != 0) - { - throw StatementException("mysql_stmt_prepare error", h, query); - } - - _query = query; - _state = STMT_COMPILED; -} - - -void StatementExecutor::bindParams(MYSQL_BIND* params, size_t count) -{ - if (_state < STMT_COMPILED) - { - throw StatementException("Satement is not compiled yet"); - } - - if (count != mysql_stmt_param_count(h)) - { - throw StatementException("wrong bind parameters count", 0, _query); - } - - if (count == 0) - { - return; - } - - int res = mysql_stmt_bind_param(h, params); - - if (res != 0) - { - throw StatementException("mysql_stmt_bind_param() error ", h, _query); - } -} - - -void StatementExecutor::bindResult(MYSQL_BIND* result) -{ - if (_state < STMT_COMPILED) - { - throw StatementException("Satement is not compiled yet"); - } - - int res = mysql_stmt_bind_result(h, result); - - if (res != 0) - { - throw StatementException("mysql_stmt_bind_result error ", h, _query); - } -} - - -void StatementExecutor::execute() -{ - if (_state < STMT_COMPILED) - { - throw StatementException("Satement is not compiled yet"); - } - - int res = mysql_stmt_execute(h); - - if (res != 0) - { - throw StatementException("mysql_stmt_execute error", h, _query); - } - - _state = STMT_EXECUTED; -} - - -bool StatementExecutor::fetch() -{ - if (_state < STMT_EXECUTED) - { - throw StatementException("Satement is not executed yet"); - } - - int res = mysql_stmt_fetch(h); - - if ((res != 0) && (res != MYSQL_NO_DATA)) - { - throw StatementException("mysql_stmt_fetch error", h, _query); - } - - return (res == 0); -} - - -bool StatementExecutor::fetchColumn(size_t n, MYSQL_BIND *bind) -{ - if (_state < STMT_EXECUTED) - { - throw StatementException("Satement is not executed yet"); - } - - int res = mysql_stmt_fetch_column(h, bind, static_cast(n), 0); - - if ((res != 0) && (res != MYSQL_NO_DATA)) - { - std::string msg; - msg += "mysql_stmt_fetch_column("; - - char buff[30]; - sprintf(buff, "%d", n); - msg += buff; - - msg += ") error"; - throw StatementException(msg, h, _query); - } - - return (res == 0); -} - - -} } } // namespace Poco::Data::MySQL +// +// StatementExecutor.cpp +// +// $Id: //poco/1.3/Data/MySQL/src/StatementExecutor.cpp#2 $ +// +// Library: Data +// Package: MySQL +// Module: StatementExecutor +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include +#include "Poco/Data/MySQL/StatementExecutor.h" + + +namespace Poco { +namespace Data { +namespace MySQL { + + +StatementExecutor::StatementExecutor(MYSQL* mysql) +{ + h = mysql_stmt_init(mysql); + + if (!h) + { + throw StatementException("mysql_stmt_init error"); + } + + _state = STMT_INITED; +} + + +StatementExecutor::~StatementExecutor() +{ + mysql_stmt_close(h); +} + + +int StatementExecutor::state() const +{ + return _state; +} + + +void StatementExecutor::prepare(const std::string& query) +{ + if (_state >= STMT_COMPILED) + { + throw StatementException("Satement is already compiled"); + } + + // compile + int res = mysql_stmt_prepare(h, query.c_str(), static_cast(query.length())); + + if (res != 0) + { + throw StatementException("mysql_stmt_prepare error", h, query); + } + + _query = query; + _state = STMT_COMPILED; +} + + +void StatementExecutor::bindParams(MYSQL_BIND* params, size_t count) +{ + if (_state < STMT_COMPILED) + { + throw StatementException("Satement is not compiled yet"); + } + + if (count != mysql_stmt_param_count(h)) + { + throw StatementException("wrong bind parameters count", 0, _query); + } + + if (count == 0) + { + return; + } + + int res = mysql_stmt_bind_param(h, params); + + if (res != 0) + { + throw StatementException("mysql_stmt_bind_param() error ", h, _query); + } +} + + +void StatementExecutor::bindResult(MYSQL_BIND* result) +{ + if (_state < STMT_COMPILED) + { + throw StatementException("Satement is not compiled yet"); + } + + int res = mysql_stmt_bind_result(h, result); + + if (res != 0) + { + throw StatementException("mysql_stmt_bind_result error ", h, _query); + } +} + + +void StatementExecutor::execute() +{ + if (_state < STMT_COMPILED) + { + throw StatementException("Satement is not compiled yet"); + } + + int res = mysql_stmt_execute(h); + + if (res != 0) + { + throw StatementException("mysql_stmt_execute error", h, _query); + } + + _state = STMT_EXECUTED; +} + + +bool StatementExecutor::fetch() +{ + if (_state < STMT_EXECUTED) + { + throw StatementException("Satement is not executed yet"); + } + + int res = mysql_stmt_fetch(h); + + if ((res != 0) && (res != MYSQL_NO_DATA)) + { + throw StatementException("mysql_stmt_fetch error", h, _query); + } + + return (res == 0); +} + + +bool StatementExecutor::fetchColumn(size_t n, MYSQL_BIND *bind) +{ + if (_state < STMT_EXECUTED) + { + throw StatementException("Satement is not executed yet"); + } + + int res = mysql_stmt_fetch_column(h, bind, static_cast(n), 0); + + if ((res != 0) && (res != MYSQL_NO_DATA)) + { + std::string msg; + msg += "mysql_stmt_fetch_column("; + + char buff[30]; + sprintf(buff, "%d", n); + msg += buff; + + msg += ") error"; + throw StatementException(msg, h, _query); + } + + return (res == 0); +} + + +} } } // namespace Poco::Data::MySQL diff --git a/Data/MySQL/testsuite/TestSuite_vs90.vcproj b/Data/MySQL/testsuite/TestSuite_vs90.vcproj new file mode 100644 index 000000000..bfd302227 --- /dev/null +++ b/Data/MySQL/testsuite/TestSuite_vs90.vcproj @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Data/MySQL/testsuite/src/Driver.cpp b/Data/MySQL/testsuite/src/Driver.cpp index c9c5e58ff..a3e15409f 100644 --- a/Data/MySQL/testsuite/src/Driver.cpp +++ b/Data/MySQL/testsuite/src/Driver.cpp @@ -1,39 +1,39 @@ -// -// Driver.cpp -// -// $Id: //poco/1.3/Data/MySQL/testsuite/src/Driver.cpp#1 $ -// -// Console-based test driver for Poco SQLite. -// -// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "CppUnit/TestRunner.h" -#include "MySQLTestSuite.h" - - -CppUnitMain(MySQLTestSuite) +// +// Driver.cpp +// +// $Id: //poco/1.3/Data/MySQL/testsuite/src/Driver.cpp#2 $ +// +// Console-based test driver for Poco SQLite. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "CppUnit/TestRunner.h" +#include "MySQLTestSuite.h" + + +CppUnitMain(MySQLTestSuite) diff --git a/Data/MySQL/testsuite/src/MySQLTest.cpp b/Data/MySQL/testsuite/src/MySQLTest.cpp index b68c2d300..e3f050620 100644 --- a/Data/MySQL/testsuite/src/MySQLTest.cpp +++ b/Data/MySQL/testsuite/src/MySQLTest.cpp @@ -1,640 +1,640 @@ -// -// MySQLTest.cpp -// -// $Id: //poco/1.3/Data/MySQL/testsuite/src/MySQLTest.cpp#1 $ -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "MySQLTest.h" -#include "CppUnit/TestCaller.h" -#include "CppUnit/TestSuite.h" -#include "Poco/String.h" -#include "Poco/Format.h" -#include "Poco/Exception.h" -#include "Poco/Data/Common.h" -#include "Poco/Data/BLOB.h" -#include "Poco/Data/StatementImpl.h" -#include "Poco/Data/MySQL/Connector.h" -#include "Poco/Data/MySQL/MySQLException.h" -#include - - -using namespace Poco::Data; -using Poco::Data::MySQL::ConnectionException; -using Poco::Data::MySQL::StatementException; -using Poco::format; -using Poco::NotFoundException; - - -Poco::SharedPtr MySQLTest::_pSession = 0; -Poco::SharedPtr MySQLTest::_pExecutor = 0; - - -// Parameters for barebone-test -#define MYSQL_USER "root" -#define MYSQL_PWD "" -#define MYSQL_HOST "localhost" -#define MYSQL_PORT 3306 -#define MYSQL_DB "test" - - -// Connection string to POCO -std::string MySQLTest::_dbConnString = "user=root;password=;db=test;compress=true;auto-reconnect=true"; - - -MySQLTest::MySQLTest(const std::string& name): - CppUnit::TestCase(name) -{ - static bool beenHere = false; - MySQL::Connector::registerConnector(); - - if (!beenHere) - { - try - { - _pSession = new Session(SessionFactory::instance().create(MySQL::Connector::KEY, _dbConnString)); - }catch (ConnectionException& ex) - { - std::cout << "!!! WARNING: Connection failed. MySQL tests will fail !!!" << std::endl; - std::cout << ex.displayText() << std::endl; - } - - if (_pSession && _pSession->isConnected()) - std::cout << "*** Connected to " << '(' << _dbConnString << ')' << std::endl; - if (!_pExecutor) _pExecutor = new SQLExecutor("MySQL SQL Executor", _pSession); - } - - beenHere = true; -} - - -MySQLTest::~MySQLTest() -{ - MySQL::Connector::unregisterConnector(); -} - - -void MySQLTest::testBareboneMySQL() -{ - if (!_pSession) fail ("Test not available."); - - std::string tableCreateString = "CREATE TABLE Test " - "(First VARCHAR(30)," - "Second VARCHAR(30)," - "Third VARBINARY(30)," - "Fourth INTEGER," - "Fifth FLOAT)"; - - _pExecutor->bareboneMySQLTest(MYSQL_HOST, MYSQL_USER, MYSQL_PWD, MYSQL_DB, MYSQL_PORT, tableCreateString.c_str()); -} - - -void MySQLTest::testSimpleAccess() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->simpleAccess(); -} - - -void MySQLTest::testComplexType() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->complexType(); -} - - -void MySQLTest::testSimpleAccessVector() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->simpleAccessVector(); -} - - -void MySQLTest::testComplexTypeVector() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->complexTypeVector(); -} - - -void MySQLTest::testInsertVector() -{ - if (!_pSession) fail ("Test not available."); - - recreateStringsTable(); - _pExecutor->insertVector(); -} - - -void MySQLTest::testInsertEmptyVector() -{ - if (!_pSession) fail ("Test not available."); - - recreateStringsTable(); - _pExecutor->insertEmptyVector(); -} - - -void MySQLTest::testInsertSingleBulk() -{ - if (!_pSession) fail ("Test not available."); - - recreateIntsTable(); - _pExecutor->insertSingleBulk(); -} - - -void MySQLTest::testInsertSingleBulkVec() -{ - if (!_pSession) fail ("Test not available."); - - recreateIntsTable(); - _pExecutor->insertSingleBulkVec(); -} - - -void MySQLTest::testLimit() -{ - if (!_pSession) fail ("Test not available."); - - recreateIntsTable(); - _pExecutor->limits(); -} - - -void MySQLTest::testLimitZero() -{ - if (!_pSession) fail ("Test not available."); - - recreateIntsTable(); - _pExecutor->limitZero(); -} - - -void MySQLTest::testLimitOnce() -{ - if (!_pSession) fail ("Test not available."); - - recreateIntsTable(); - _pExecutor->limitOnce(); - -} - - -void MySQLTest::testLimitPrepare() -{ - if (!_pSession) fail ("Test not available."); - - recreateIntsTable(); - _pExecutor->limitPrepare(); -} - - - -void MySQLTest::testPrepare() -{ - if (!_pSession) fail ("Test not available."); - - recreateIntsTable(); - _pExecutor->prepare(); -} - - -void MySQLTest::testSetSimple() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->setSimple(); -} - - -void MySQLTest::testSetComplex() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->setComplex(); -} - - -void MySQLTest::testSetComplexUnique() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->setComplexUnique(); -} - -void MySQLTest::testMultiSetSimple() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->multiSetSimple(); -} - - -void MySQLTest::testMultiSetComplex() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->multiSetComplex(); -} - - -void MySQLTest::testMapComplex() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->mapComplex(); -} - - -void MySQLTest::testMapComplexUnique() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->mapComplexUnique(); -} - - -void MySQLTest::testMultiMapComplex() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->multiMapComplex(); -} - - -void MySQLTest::testSelectIntoSingle() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->selectIntoSingle(); -} - - -void MySQLTest::testSelectIntoSingleStep() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->selectIntoSingleStep(); -} - - -void MySQLTest::testSelectIntoSingleFail() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->selectIntoSingleFail(); -} - - -void MySQLTest::testLowerLimitOk() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->lowerLimitOk(); -} - - -void MySQLTest::testSingleSelect() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->singleSelect(); -} - - -void MySQLTest::testLowerLimitFail() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->lowerLimitFail(); -} - - -void MySQLTest::testCombinedLimits() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->combinedLimits(); -} - - -void MySQLTest::testRange() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->ranges(); -} - - -void MySQLTest::testCombinedIllegalLimits() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->combinedIllegalLimits(); -} - - - -void MySQLTest::testIllegalRange() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->illegalRange(); -} - - -void MySQLTest::testEmptyDB() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonTable(); - _pExecutor->emptyDB(); -} - - -void MySQLTest::testBLOB() -{ - if (!_pSession) fail ("Test not available."); - - const std::size_t maxFldSize = 65534; - _pSession->setProperty("maxFieldSize", Poco::Any(maxFldSize-1)); - recreatePersonBLOBTable(); - - try - { - _pExecutor->blob(maxFldSize); - fail ("must fail"); - } - catch (DataException&) - { - _pSession->setProperty("maxFieldSize", Poco::Any(maxFldSize)); - } - - recreatePersonBLOBTable(); - _pExecutor->blob(maxFldSize); - - recreatePersonBLOBTable(); - - try - { - _pExecutor->blob(maxFldSize+1); - fail ("must fail"); - } - catch (DataException&) { } -} - - -void MySQLTest::testBLOBStmt() -{ - if (!_pSession) fail ("Test not available."); - - recreatePersonBLOBTable(); - _pExecutor->blobStmt(); -} - - -void MySQLTest::testFloat() -{ - if (!_pSession) fail ("Test not available."); - - recreateFloatsTable(); - _pExecutor->floats(); -} - - -void MySQLTest::testDouble() -{ - if (!_pSession) fail ("Test not available."); - - recreateFloatsTable(); - _pExecutor->doubles(); -} - - -void MySQLTest::testTuple() -{ - if (!_pSession) fail ("Test not available."); - - recreateTuplesTable(); - _pExecutor->tuples(); -} - - -void MySQLTest::testTupleVector() -{ - if (!_pSession) fail ("Test not available."); - - recreateTuplesTable(); - _pExecutor->tupleVector(); -} - - -void MySQLTest::testInternalExtraction() -{ - if (!_pSession) fail ("Test not available."); - - recreateVectorsTable(); - _pExecutor->internalExtraction(); -} - - -void MySQLTest::testNull() -{ - if (!_pSession) fail ("Test not available."); - - recreateVectorsTable(); - _pExecutor->doNull(); -} - - -void MySQLTest::dropTable(const std::string& tableName) -{ - try - { - *_pSession << format("DROP TABLE %s", tableName), now; - } - catch (StatementException& ) - { - //throw; - } -} - - -void MySQLTest::recreatePersonTable() -{ - dropTable("Person"); - try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Age INTEGER)", now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreatePersonTable()"); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreatePersonTable()"); } -} - - -void MySQLTest::recreatePersonBLOBTable() -{ - dropTable("Person"); - try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image BLOB)", now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreatePersonBLOBTable()"); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreatePersonBLOBTable()"); } -} - - -void MySQLTest::recreateIntsTable() -{ - dropTable("Strings"); - try { *_pSession << "CREATE TABLE Strings (str INTEGER)", now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateIntsTable()"); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateIntsTable()"); } -} - - -void MySQLTest::recreateStringsTable() -{ - dropTable("Strings"); - try { *_pSession << "CREATE TABLE Strings (str VARCHAR(30))", now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateStringsTable()"); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateStringsTable()"); } -} - - -void MySQLTest::recreateFloatsTable() -{ - dropTable("Strings"); - try { *_pSession << "CREATE TABLE Strings (str FLOAT)", now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateFloatsTable()"); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateFloatsTable()"); } -} - - -void MySQLTest::recreateTuplesTable() -{ - dropTable("Tuples"); - try { *_pSession << "CREATE TABLE Tuples " - "(i0 INTEGER, i1 INTEGER, i2 INTEGER, i3 INTEGER, i4 INTEGER, i5 INTEGER, i6 INTEGER, " - "i7 INTEGER, i8 INTEGER, i9 INTEGER, i10 INTEGER, i11 INTEGER, i12 INTEGER, i13 INTEGER," - "i14 INTEGER, i15 INTEGER, i16 INTEGER, i17 INTEGER, i18 INTEGER, i19 INTEGER)", now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateTuplesTable()"); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateTuplesTable()"); } -} - - -void MySQLTest::recreateVectorsTable() -{ - dropTable("Vectors"); - try { *_pSession << "CREATE TABLE Vectors (i0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateVectorsTable()"); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateVectorsTable()"); } -} - - -void MySQLTest::setUp() -{ -} - - -void MySQLTest::tearDown() -{ - dropTable("Person"); - dropTable("Strings"); -} - - -CppUnit::Test* MySQLTest::suite() -{ - CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("MySQLTest"); - - CppUnit_addTest(pSuite, MySQLTest, testBareboneMySQL); - CppUnit_addTest(pSuite, MySQLTest, testSimpleAccess); - CppUnit_addTest(pSuite, MySQLTest, testComplexType); - CppUnit_addTest(pSuite, MySQLTest, testSimpleAccessVector); - CppUnit_addTest(pSuite, MySQLTest, testComplexTypeVector); - CppUnit_addTest(pSuite, MySQLTest, testInsertVector); - CppUnit_addTest(pSuite, MySQLTest, testInsertEmptyVector); - CppUnit_addTest(pSuite, MySQLTest, testInsertSingleBulk); - CppUnit_addTest(pSuite, MySQLTest, testInsertSingleBulkVec); - CppUnit_addTest(pSuite, MySQLTest, testLimit); - CppUnit_addTest(pSuite, MySQLTest, testLimitOnce); - CppUnit_addTest(pSuite, MySQLTest, testLimitPrepare); - CppUnit_addTest(pSuite, MySQLTest, testLimitZero); - CppUnit_addTest(pSuite, MySQLTest, testPrepare); - CppUnit_addTest(pSuite, MySQLTest, testSetSimple); - CppUnit_addTest(pSuite, MySQLTest, testSetComplex); - CppUnit_addTest(pSuite, MySQLTest, testSetComplexUnique); - CppUnit_addTest(pSuite, MySQLTest, testMultiSetSimple); - CppUnit_addTest(pSuite, MySQLTest, testMultiSetComplex); - CppUnit_addTest(pSuite, MySQLTest, testMapComplex); - CppUnit_addTest(pSuite, MySQLTest, testMapComplexUnique); - CppUnit_addTest(pSuite, MySQLTest, testMultiMapComplex); - CppUnit_addTest(pSuite, MySQLTest, testSelectIntoSingle); - CppUnit_addTest(pSuite, MySQLTest, testSelectIntoSingleStep); - CppUnit_addTest(pSuite, MySQLTest, testSelectIntoSingleFail); - CppUnit_addTest(pSuite, MySQLTest, testLowerLimitOk); - CppUnit_addTest(pSuite, MySQLTest, testLowerLimitFail); - CppUnit_addTest(pSuite, MySQLTest, testCombinedLimits); - CppUnit_addTest(pSuite, MySQLTest, testCombinedIllegalLimits); - CppUnit_addTest(pSuite, MySQLTest, testRange); - CppUnit_addTest(pSuite, MySQLTest, testIllegalRange); - CppUnit_addTest(pSuite, MySQLTest, testSingleSelect); - CppUnit_addTest(pSuite, MySQLTest, testEmptyDB); - //CppUnit_addTest(pSuite, MySQLTest, testBLOB); - CppUnit_addTest(pSuite, MySQLTest, testBLOBStmt); - CppUnit_addTest(pSuite, MySQLTest, testFloat); - CppUnit_addTest(pSuite, MySQLTest, testDouble); - CppUnit_addTest(pSuite, MySQLTest, testTuple); - CppUnit_addTest(pSuite, MySQLTest, testTupleVector); - CppUnit_addTest(pSuite, MySQLTest, testInternalExtraction); - CppUnit_addTest(pSuite, MySQLTest, testNull); - - return pSuite; -} +// +// MySQLTest.cpp +// +// $Id: //poco/1.3/Data/MySQL/testsuite/src/MySQLTest.cpp#2 $ +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "MySQLTest.h" +#include "CppUnit/TestCaller.h" +#include "CppUnit/TestSuite.h" +#include "Poco/String.h" +#include "Poco/Format.h" +#include "Poco/Exception.h" +#include "Poco/Data/Common.h" +#include "Poco/Data/BLOB.h" +#include "Poco/Data/StatementImpl.h" +#include "Poco/Data/MySQL/Connector.h" +#include "Poco/Data/MySQL/MySQLException.h" +#include + + +using namespace Poco::Data; +using Poco::Data::MySQL::ConnectionException; +using Poco::Data::MySQL::StatementException; +using Poco::format; +using Poco::NotFoundException; + + +Poco::SharedPtr MySQLTest::_pSession = 0; +Poco::SharedPtr MySQLTest::_pExecutor = 0; + + +// Parameters for barebone-test +#define MYSQL_USER "root" +#define MYSQL_PWD "" +#define MYSQL_HOST "localhost" +#define MYSQL_PORT 3306 +#define MYSQL_DB "test" + + +// Connection string to POCO +std::string MySQLTest::_dbConnString = "user=root;password=;db=test;compress=true;auto-reconnect=true"; + + +MySQLTest::MySQLTest(const std::string& name): + CppUnit::TestCase(name) +{ + static bool beenHere = false; + MySQL::Connector::registerConnector(); + + if (!beenHere) + { + try + { + _pSession = new Session(SessionFactory::instance().create(MySQL::Connector::KEY, _dbConnString)); + }catch (ConnectionException& ex) + { + std::cout << "!!! WARNING: Connection failed. MySQL tests will fail !!!" << std::endl; + std::cout << ex.displayText() << std::endl; + } + + if (_pSession && _pSession->isConnected()) + std::cout << "*** Connected to " << '(' << _dbConnString << ')' << std::endl; + if (!_pExecutor) _pExecutor = new SQLExecutor("MySQL SQL Executor", _pSession); + } + + beenHere = true; +} + + +MySQLTest::~MySQLTest() +{ + MySQL::Connector::unregisterConnector(); +} + + +void MySQLTest::testBareboneMySQL() +{ + if (!_pSession) fail ("Test not available."); + + std::string tableCreateString = "CREATE TABLE Test " + "(First VARCHAR(30)," + "Second VARCHAR(30)," + "Third VARBINARY(30)," + "Fourth INTEGER," + "Fifth FLOAT)"; + + _pExecutor->bareboneMySQLTest(MYSQL_HOST, MYSQL_USER, MYSQL_PWD, MYSQL_DB, MYSQL_PORT, tableCreateString.c_str()); +} + + +void MySQLTest::testSimpleAccess() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->simpleAccess(); +} + + +void MySQLTest::testComplexType() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->complexType(); +} + + +void MySQLTest::testSimpleAccessVector() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->simpleAccessVector(); +} + + +void MySQLTest::testComplexTypeVector() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->complexTypeVector(); +} + + +void MySQLTest::testInsertVector() +{ + if (!_pSession) fail ("Test not available."); + + recreateStringsTable(); + _pExecutor->insertVector(); +} + + +void MySQLTest::testInsertEmptyVector() +{ + if (!_pSession) fail ("Test not available."); + + recreateStringsTable(); + _pExecutor->insertEmptyVector(); +} + + +void MySQLTest::testInsertSingleBulk() +{ + if (!_pSession) fail ("Test not available."); + + recreateIntsTable(); + _pExecutor->insertSingleBulk(); +} + + +void MySQLTest::testInsertSingleBulkVec() +{ + if (!_pSession) fail ("Test not available."); + + recreateIntsTable(); + _pExecutor->insertSingleBulkVec(); +} + + +void MySQLTest::testLimit() +{ + if (!_pSession) fail ("Test not available."); + + recreateIntsTable(); + _pExecutor->limits(); +} + + +void MySQLTest::testLimitZero() +{ + if (!_pSession) fail ("Test not available."); + + recreateIntsTable(); + _pExecutor->limitZero(); +} + + +void MySQLTest::testLimitOnce() +{ + if (!_pSession) fail ("Test not available."); + + recreateIntsTable(); + _pExecutor->limitOnce(); + +} + + +void MySQLTest::testLimitPrepare() +{ + if (!_pSession) fail ("Test not available."); + + recreateIntsTable(); + _pExecutor->limitPrepare(); +} + + + +void MySQLTest::testPrepare() +{ + if (!_pSession) fail ("Test not available."); + + recreateIntsTable(); + _pExecutor->prepare(); +} + + +void MySQLTest::testSetSimple() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->setSimple(); +} + + +void MySQLTest::testSetComplex() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->setComplex(); +} + + +void MySQLTest::testSetComplexUnique() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->setComplexUnique(); +} + +void MySQLTest::testMultiSetSimple() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->multiSetSimple(); +} + + +void MySQLTest::testMultiSetComplex() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->multiSetComplex(); +} + + +void MySQLTest::testMapComplex() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->mapComplex(); +} + + +void MySQLTest::testMapComplexUnique() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->mapComplexUnique(); +} + + +void MySQLTest::testMultiMapComplex() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->multiMapComplex(); +} + + +void MySQLTest::testSelectIntoSingle() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->selectIntoSingle(); +} + + +void MySQLTest::testSelectIntoSingleStep() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->selectIntoSingleStep(); +} + + +void MySQLTest::testSelectIntoSingleFail() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->selectIntoSingleFail(); +} + + +void MySQLTest::testLowerLimitOk() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->lowerLimitOk(); +} + + +void MySQLTest::testSingleSelect() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->singleSelect(); +} + + +void MySQLTest::testLowerLimitFail() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->lowerLimitFail(); +} + + +void MySQLTest::testCombinedLimits() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->combinedLimits(); +} + + +void MySQLTest::testRange() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->ranges(); +} + + +void MySQLTest::testCombinedIllegalLimits() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->combinedIllegalLimits(); +} + + + +void MySQLTest::testIllegalRange() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->illegalRange(); +} + + +void MySQLTest::testEmptyDB() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonTable(); + _pExecutor->emptyDB(); +} + + +void MySQLTest::testBLOB() +{ + if (!_pSession) fail ("Test not available."); + + const std::size_t maxFldSize = 65534; + _pSession->setProperty("maxFieldSize", Poco::Any(maxFldSize-1)); + recreatePersonBLOBTable(); + + try + { + _pExecutor->blob(maxFldSize); + fail ("must fail"); + } + catch (DataException&) + { + _pSession->setProperty("maxFieldSize", Poco::Any(maxFldSize)); + } + + recreatePersonBLOBTable(); + _pExecutor->blob(maxFldSize); + + recreatePersonBLOBTable(); + + try + { + _pExecutor->blob(maxFldSize+1); + fail ("must fail"); + } + catch (DataException&) { } +} + + +void MySQLTest::testBLOBStmt() +{ + if (!_pSession) fail ("Test not available."); + + recreatePersonBLOBTable(); + _pExecutor->blobStmt(); +} + + +void MySQLTest::testFloat() +{ + if (!_pSession) fail ("Test not available."); + + recreateFloatsTable(); + _pExecutor->floats(); +} + + +void MySQLTest::testDouble() +{ + if (!_pSession) fail ("Test not available."); + + recreateFloatsTable(); + _pExecutor->doubles(); +} + + +void MySQLTest::testTuple() +{ + if (!_pSession) fail ("Test not available."); + + recreateTuplesTable(); + _pExecutor->tuples(); +} + + +void MySQLTest::testTupleVector() +{ + if (!_pSession) fail ("Test not available."); + + recreateTuplesTable(); + _pExecutor->tupleVector(); +} + + +void MySQLTest::testInternalExtraction() +{ + if (!_pSession) fail ("Test not available."); + + recreateVectorsTable(); + _pExecutor->internalExtraction(); +} + + +void MySQLTest::testNull() +{ + if (!_pSession) fail ("Test not available."); + + recreateVectorsTable(); + _pExecutor->doNull(); +} + + +void MySQLTest::dropTable(const std::string& tableName) +{ + try + { + *_pSession << format("DROP TABLE %s", tableName), now; + } + catch (StatementException& ) + { + //throw; + } +} + + +void MySQLTest::recreatePersonTable() +{ + dropTable("Person"); + try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Age INTEGER)", now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreatePersonTable()"); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreatePersonTable()"); } +} + + +void MySQLTest::recreatePersonBLOBTable() +{ + dropTable("Person"); + try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image BLOB)", now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreatePersonBLOBTable()"); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreatePersonBLOBTable()"); } +} + + +void MySQLTest::recreateIntsTable() +{ + dropTable("Strings"); + try { *_pSession << "CREATE TABLE Strings (str INTEGER)", now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateIntsTable()"); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateIntsTable()"); } +} + + +void MySQLTest::recreateStringsTable() +{ + dropTable("Strings"); + try { *_pSession << "CREATE TABLE Strings (str VARCHAR(30))", now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateStringsTable()"); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateStringsTable()"); } +} + + +void MySQLTest::recreateFloatsTable() +{ + dropTable("Strings"); + try { *_pSession << "CREATE TABLE Strings (str FLOAT)", now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateFloatsTable()"); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateFloatsTable()"); } +} + + +void MySQLTest::recreateTuplesTable() +{ + dropTable("Tuples"); + try { *_pSession << "CREATE TABLE Tuples " + "(i0 INTEGER, i1 INTEGER, i2 INTEGER, i3 INTEGER, i4 INTEGER, i5 INTEGER, i6 INTEGER, " + "i7 INTEGER, i8 INTEGER, i9 INTEGER, i10 INTEGER, i11 INTEGER, i12 INTEGER, i13 INTEGER," + "i14 INTEGER, i15 INTEGER, i16 INTEGER, i17 INTEGER, i18 INTEGER, i19 INTEGER)", now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateTuplesTable()"); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateTuplesTable()"); } +} + + +void MySQLTest::recreateVectorsTable() +{ + dropTable("Vectors"); + try { *_pSession << "CREATE TABLE Vectors (i0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreateVectorsTable()"); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreateVectorsTable()"); } +} + + +void MySQLTest::setUp() +{ +} + + +void MySQLTest::tearDown() +{ + dropTable("Person"); + dropTable("Strings"); +} + + +CppUnit::Test* MySQLTest::suite() +{ + CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("MySQLTest"); + + CppUnit_addTest(pSuite, MySQLTest, testBareboneMySQL); + CppUnit_addTest(pSuite, MySQLTest, testSimpleAccess); + CppUnit_addTest(pSuite, MySQLTest, testComplexType); + CppUnit_addTest(pSuite, MySQLTest, testSimpleAccessVector); + CppUnit_addTest(pSuite, MySQLTest, testComplexTypeVector); + CppUnit_addTest(pSuite, MySQLTest, testInsertVector); + CppUnit_addTest(pSuite, MySQLTest, testInsertEmptyVector); + CppUnit_addTest(pSuite, MySQLTest, testInsertSingleBulk); + CppUnit_addTest(pSuite, MySQLTest, testInsertSingleBulkVec); + CppUnit_addTest(pSuite, MySQLTest, testLimit); + CppUnit_addTest(pSuite, MySQLTest, testLimitOnce); + CppUnit_addTest(pSuite, MySQLTest, testLimitPrepare); + CppUnit_addTest(pSuite, MySQLTest, testLimitZero); + CppUnit_addTest(pSuite, MySQLTest, testPrepare); + CppUnit_addTest(pSuite, MySQLTest, testSetSimple); + CppUnit_addTest(pSuite, MySQLTest, testSetComplex); + CppUnit_addTest(pSuite, MySQLTest, testSetComplexUnique); + CppUnit_addTest(pSuite, MySQLTest, testMultiSetSimple); + CppUnit_addTest(pSuite, MySQLTest, testMultiSetComplex); + CppUnit_addTest(pSuite, MySQLTest, testMapComplex); + CppUnit_addTest(pSuite, MySQLTest, testMapComplexUnique); + CppUnit_addTest(pSuite, MySQLTest, testMultiMapComplex); + CppUnit_addTest(pSuite, MySQLTest, testSelectIntoSingle); + CppUnit_addTest(pSuite, MySQLTest, testSelectIntoSingleStep); + CppUnit_addTest(pSuite, MySQLTest, testSelectIntoSingleFail); + CppUnit_addTest(pSuite, MySQLTest, testLowerLimitOk); + CppUnit_addTest(pSuite, MySQLTest, testLowerLimitFail); + CppUnit_addTest(pSuite, MySQLTest, testCombinedLimits); + CppUnit_addTest(pSuite, MySQLTest, testCombinedIllegalLimits); + CppUnit_addTest(pSuite, MySQLTest, testRange); + CppUnit_addTest(pSuite, MySQLTest, testIllegalRange); + CppUnit_addTest(pSuite, MySQLTest, testSingleSelect); + CppUnit_addTest(pSuite, MySQLTest, testEmptyDB); + //CppUnit_addTest(pSuite, MySQLTest, testBLOB); + CppUnit_addTest(pSuite, MySQLTest, testBLOBStmt); + CppUnit_addTest(pSuite, MySQLTest, testFloat); + CppUnit_addTest(pSuite, MySQLTest, testDouble); + CppUnit_addTest(pSuite, MySQLTest, testTuple); + CppUnit_addTest(pSuite, MySQLTest, testTupleVector); + CppUnit_addTest(pSuite, MySQLTest, testInternalExtraction); + CppUnit_addTest(pSuite, MySQLTest, testNull); + + return pSuite; +} diff --git a/Data/MySQL/testsuite/src/MySQLTest.h b/Data/MySQL/testsuite/src/MySQLTest.h index d2bb2ec1e..b3191ff93 100644 --- a/Data/MySQL/testsuite/src/MySQLTest.h +++ b/Data/MySQL/testsuite/src/MySQLTest.h @@ -1,132 +1,132 @@ -// -// ODBCMySQLTest.h -// -// $Id: //poco/1.3/Data/MySQL/testsuite/src/MySQLTest.h#1 $ -// -// Definition of the MySQLTest class. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef MySQLTest_INCLUDED -#define MySQLTest_INCLUDED - - -#include "Poco/Data/MySQL/MySQL.h" -#include "Poco/Data/Session.h" -#include "Poco/SharedPtr.h" -#include "CppUnit/TestCase.h" -#include "SQLExecutor.h" - - -class MySQLTest: public CppUnit::TestCase - /// MySQL test class - /// Tested: - /// - /// Driver | DB | OS - /// ----------------+---------------------------+------------------------------------------ - /// 03.51.12.00 | MySQL 5.0.27-community-nt | MS Windows XP Professional x64 v.2003/SP1 - /// -{ -public: - MySQLTest(const std::string& name); - ~MySQLTest(); - - void testBareboneMySQL(); - - void testSimpleAccess(); - void testComplexType(); - void testSimpleAccessVector(); - void testComplexTypeVector(); - void testInsertVector(); - void testInsertEmptyVector(); - - void testInsertSingleBulk(); - void testInsertSingleBulkVec(); - - void testLimit(); - void testLimitOnce(); - void testLimitPrepare(); - void testLimitZero(); - void testPrepare(); - - void testSetSimple(); - void testSetComplex(); - void testSetComplexUnique(); - void testMultiSetSimple(); - void testMultiSetComplex(); - void testMapComplex(); - void testMapComplexUnique(); - void testMultiMapComplex(); - void testSelectIntoSingle(); - void testSelectIntoSingleStep(); - void testSelectIntoSingleFail(); - void testLowerLimitOk(); - void testLowerLimitFail(); - void testCombinedLimits(); - void testCombinedIllegalLimits(); - void testRange(); - void testIllegalRange(); - void testSingleSelect(); - void testEmptyDB(); - - void testBLOB(); - void testBLOBStmt(); - - void testFloat(); - void testDouble(); - - void testTuple(); - void testTupleVector(); - - void testInternalExtraction(); - void testNull(); - - void setUp(); - void tearDown(); - - static CppUnit::Test* suite(); - -private: - - void dropTable(const std::string& tableName); - void recreatePersonTable(); - void recreatePersonBLOBTable(); - void recreateStringsTable(); - void recreateIntsTable(); - void recreateFloatsTable(); - void recreateTuplesTable(); - void recreateVectorsTable(); - - static std::string _dbConnString; - static Poco::SharedPtr _pSession; - static Poco::SharedPtr _pExecutor; - static const bool bindValues[8]; -}; - - -#endif // MySQLTest_INCLUDED +// +// ODBCMySQLTest.h +// +// $Id: //poco/1.3/Data/MySQL/testsuite/src/MySQLTest.h#2 $ +// +// Definition of the MySQLTest class. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef MySQLTest_INCLUDED +#define MySQLTest_INCLUDED + + +#include "Poco/Data/MySQL/MySQL.h" +#include "Poco/Data/Session.h" +#include "Poco/SharedPtr.h" +#include "CppUnit/TestCase.h" +#include "SQLExecutor.h" + + +class MySQLTest: public CppUnit::TestCase + /// MySQL test class + /// Tested: + /// + /// Driver | DB | OS + /// ----------------+---------------------------+------------------------------------------ + /// 03.51.12.00 | MySQL 5.0.27-community-nt | MS Windows XP Professional x64 v.2003/SP1 + /// +{ +public: + MySQLTest(const std::string& name); + ~MySQLTest(); + + void testBareboneMySQL(); + + void testSimpleAccess(); + void testComplexType(); + void testSimpleAccessVector(); + void testComplexTypeVector(); + void testInsertVector(); + void testInsertEmptyVector(); + + void testInsertSingleBulk(); + void testInsertSingleBulkVec(); + + void testLimit(); + void testLimitOnce(); + void testLimitPrepare(); + void testLimitZero(); + void testPrepare(); + + void testSetSimple(); + void testSetComplex(); + void testSetComplexUnique(); + void testMultiSetSimple(); + void testMultiSetComplex(); + void testMapComplex(); + void testMapComplexUnique(); + void testMultiMapComplex(); + void testSelectIntoSingle(); + void testSelectIntoSingleStep(); + void testSelectIntoSingleFail(); + void testLowerLimitOk(); + void testLowerLimitFail(); + void testCombinedLimits(); + void testCombinedIllegalLimits(); + void testRange(); + void testIllegalRange(); + void testSingleSelect(); + void testEmptyDB(); + + void testBLOB(); + void testBLOBStmt(); + + void testFloat(); + void testDouble(); + + void testTuple(); + void testTupleVector(); + + void testInternalExtraction(); + void testNull(); + + void setUp(); + void tearDown(); + + static CppUnit::Test* suite(); + +private: + + void dropTable(const std::string& tableName); + void recreatePersonTable(); + void recreatePersonBLOBTable(); + void recreateStringsTable(); + void recreateIntsTable(); + void recreateFloatsTable(); + void recreateTuplesTable(); + void recreateVectorsTable(); + + static std::string _dbConnString; + static Poco::SharedPtr _pSession; + static Poco::SharedPtr _pExecutor; + static const bool bindValues[8]; +}; + + +#endif // MySQLTest_INCLUDED diff --git a/Data/MySQL/testsuite/src/MySQLTestSuite.cpp b/Data/MySQL/testsuite/src/MySQLTestSuite.cpp index 145d24b5e..7850e70f0 100644 --- a/Data/MySQL/testsuite/src/MySQLTestSuite.cpp +++ b/Data/MySQL/testsuite/src/MySQLTestSuite.cpp @@ -1,42 +1,42 @@ -// -// ODBCTestSuite.cpp -// -// $Id: //poco/1.3/Data/MySQL/testsuite/src/MySQLTestSuite.cpp#1 $ -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "MySQLTestSuite.h" -#include "MySQLTest.h" - - -CppUnit::Test* MySQLTestSuite::suite() -{ - CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("MySQLTestSuite"); - pSuite->addTest(MySQLTest::suite()); - return pSuite; -} +// +// ODBCTestSuite.cpp +// +// $Id: //poco/1.3/Data/MySQL/testsuite/src/MySQLTestSuite.cpp#2 $ +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "MySQLTestSuite.h" +#include "MySQLTest.h" + + +CppUnit::Test* MySQLTestSuite::suite() +{ + CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("MySQLTestSuite"); + pSuite->addTest(MySQLTest::suite()); + return pSuite; +} diff --git a/Data/MySQL/testsuite/src/MySQLTestSuite.h b/Data/MySQL/testsuite/src/MySQLTestSuite.h index 4ac8b5846..65335a10a 100644 --- a/Data/MySQL/testsuite/src/MySQLTestSuite.h +++ b/Data/MySQL/testsuite/src/MySQLTestSuite.h @@ -1,49 +1,49 @@ -// -// ODBCTestSuite.h -// -// $Id: //poco/1.3/Data/MySQL/testsuite/src/MySQLTestSuite.h#1 $ -// -// Definition of the ODBCTestSuite class. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef MySQLTestSuite_INCLUDED -#define MySQLTestSuite_INCLUDED - - -#include "CppUnit/TestSuite.h" - - -class MySQLTestSuite -{ -public: - static CppUnit::Test* suite(); -}; - - -#endif // MySQLTestSuite_INCLUDED +// +// ODBCTestSuite.h +// +// $Id: //poco/1.3/Data/MySQL/testsuite/src/MySQLTestSuite.h#2 $ +// +// Definition of the ODBCTestSuite class. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef MySQLTestSuite_INCLUDED +#define MySQLTestSuite_INCLUDED + + +#include "CppUnit/TestSuite.h" + + +class MySQLTestSuite +{ +public: + static CppUnit::Test* suite(); +}; + + +#endif // MySQLTestSuite_INCLUDED diff --git a/Data/MySQL/testsuite/src/SQLExecutor.cpp b/Data/MySQL/testsuite/src/SQLExecutor.cpp index b3852c33f..19167506d 100644 --- a/Data/MySQL/testsuite/src/SQLExecutor.cpp +++ b/Data/MySQL/testsuite/src/SQLExecutor.cpp @@ -1,1513 +1,1513 @@ -// -// SQLExecutor.cpp -// -// $Id: //poco/1.3/Data/MySQL/testsuite/src/SQLExecutor.cpp#1 $ -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "CppUnit/TestCase.h" -#include "SQLExecutor.h" -#include "Poco/String.h" -#include "Poco/Format.h" -#include "Poco/Tuple.h" -#include "Poco/Any.h" -#include "Poco/Exception.h" -#include "Poco/Data/Common.h" -#include "Poco/Data/BLOB.h" -#include "Poco/Data/StatementImpl.h" -#include "Poco/Data/RecordSet.h" -#include "Poco/Data/MySQL/Connector.h" -#include "Poco/Data/MySQL/MySQLException.h" -#ifdef _WIN32 -#include -#endif -#include -#include - - -using namespace Poco::Data; -using Poco::Data::MySQL::ConnectionException; -using Poco::Data::MySQL::StatementException; -using Poco::format; -using Poco::Tuple; -using Poco::Any; -using Poco::AnyCast; -using Poco::NotFoundException; -using Poco::InvalidAccessException; -using Poco::BadCastException; -using Poco::RangeException; - - -struct Person -{ - std::string lastName; - std::string firstName; - std::string address; - int age; - Person(){age = 0;} - Person(const std::string& ln, const std::string& fn, const std::string& adr, int a):lastName(ln), firstName(fn), address(adr), age(a) - { - } - bool operator==(const Person& other) const - { - return lastName == other.lastName && firstName == other.firstName && address == other.address && age == other.age; - } - - bool operator < (const Person& p) const - { - if (age < p.age) - return true; - if (lastName < p.lastName) - return true; - if (firstName < p.firstName) - return true; - return (address < p.address); - } - - const std::string& operator () () const - /// This method is required so we can extract data to a map! - { - // we choose the lastName as examplary key - return lastName; - } -}; - - -namespace Poco { -namespace Data { - - -template <> -class TypeHandler -{ -public: - static void bind(std::size_t pos, const Person& obj, AbstractBinder* pBinder) - { - // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3)) - poco_assert_dbg (pBinder != 0); - pBinder->bind(pos++, obj.lastName); - pBinder->bind(pos++, obj.firstName); - pBinder->bind(pos++, obj.address); - pBinder->bind(pos++, obj.age); - } - - static void prepare(std::size_t pos, const Person& obj, AbstractPreparation* pPrepare) - { - // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3)) - poco_assert_dbg (pPrepare != 0); - pPrepare->prepare(pos++, obj.lastName); - pPrepare->prepare(pos++, obj.firstName); - pPrepare->prepare(pos++, obj.address); - pPrepare->prepare(pos++, obj.age); - } - - static std::size_t size() - { - return 4; - } - - static void extract(std::size_t pos, Person& obj, const Person& defVal, AbstractExtractor* pExt) - { - poco_assert_dbg (pExt != 0); - if (!pExt->extract(pos++, obj.lastName)) - obj.lastName = defVal.lastName; - if (!pExt->extract(pos++, obj.firstName)) - obj.firstName = defVal.firstName; - if (!pExt->extract(pos++, obj.address)) - obj.address = defVal.address; - if (!pExt->extract(pos++, obj.age)) - obj.age = defVal.age; - } - -private: - TypeHandler(); - ~TypeHandler(); - TypeHandler(const TypeHandler&); - TypeHandler& operator=(const TypeHandler&); -}; - - -} } // namespace Poco::Data - - -SQLExecutor::SQLExecutor(const std::string& name, Poco::Data::Session* pSession): - CppUnit::TestCase(name), - _pSession(pSession) -{ -} - - -SQLExecutor::~SQLExecutor() -{ -} - - -void SQLExecutor::bareboneMySQLTest(const char* host, const char* user, const char* pwd, const char* db, int port, const char* tableCreateString) -{ - int rc; - MYSQL* hsession = mysql_init(0); - assert (hsession != 0); - - MYSQL* tmp = mysql_real_connect(hsession, host, user, pwd, db, port, 0, 0); - assert(tmp == hsession); - - MYSQL_STMT* hstmt = mysql_stmt_init(hsession); - assert(hstmt != 0); - - std::string sql = "DROP TABLE Test"; - mysql_real_query(hsession, sql.c_str(), static_cast(sql.length())); - - sql = tableCreateString; - rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast(sql.length())); - assert(rc == 0); - - rc = mysql_stmt_execute(hstmt); - assert(rc == 0); - - sql = "INSERT INTO Test VALUES (?,?,?,?,?)"; - rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast(sql.length())); - assert(rc == 0); - - std::string str[3] = { "111", "222", "333" }; - int fourth = 4; - float fifth = 1.5; - - MYSQL_BIND bind_param[5] = {{0}}; - - bind_param[0].buffer = const_cast(str[0].c_str()); - bind_param[0].buffer_length = static_cast(str[0].length()); - bind_param[0].buffer_type = MYSQL_TYPE_STRING; - - bind_param[1].buffer = const_cast(str[1].c_str()); - bind_param[1].buffer_length = static_cast(str[1].length()); - bind_param[1].buffer_type = MYSQL_TYPE_STRING; - - bind_param[2].buffer = const_cast(str[2].c_str()); - bind_param[2].buffer_length = static_cast(str[2].length()); - bind_param[2].buffer_type = MYSQL_TYPE_STRING; - - bind_param[3].buffer = &fourth; - bind_param[3].buffer_type = MYSQL_TYPE_LONG; - - bind_param[4].buffer = &fifth; - bind_param[4].buffer_type = MYSQL_TYPE_FLOAT; - - rc = mysql_stmt_bind_param(hstmt, bind_param); - assert (rc == 0); - - rc = mysql_stmt_execute(hstmt); - assert (rc == 0); - - sql = "SELECT * FROM Test"; - rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast(sql.length())); - assert (rc == 0); - - char chr[3][5] = {{ 0 }}; - unsigned long lengths[5] = { 0 }; - fourth = 0; - fifth = 0.0f; - - MYSQL_BIND bind_result[5] = {{0}}; - - bind_result[0].buffer = chr[0]; - bind_result[0].buffer_length = sizeof(chr[0]); - bind_result[0].buffer_type = MYSQL_TYPE_STRING; - bind_result[0].length = &lengths[0]; - - bind_result[1].buffer = chr[1]; - bind_result[1].buffer_length = sizeof(chr[1]); - bind_result[1].buffer_type = MYSQL_TYPE_STRING; - bind_result[1].length = &lengths[1]; - - bind_result[2].buffer = chr[2]; - bind_result[2].buffer_length = sizeof(chr[2]); - bind_result[2].buffer_type = MYSQL_TYPE_STRING; - bind_result[2].length = &lengths[2]; - - bind_result[3].buffer = &fourth; - bind_result[3].buffer_type = MYSQL_TYPE_LONG; - bind_result[3].length = &lengths[3]; - - bind_result[4].buffer = &fifth; - bind_result[4].buffer_type = MYSQL_TYPE_FLOAT; - bind_result[4].length = &lengths[4]; - - rc = mysql_stmt_bind_result(hstmt, bind_result); - assert (rc == 0); - - rc = mysql_stmt_execute(hstmt); - assert (rc == 0); - rc = mysql_stmt_fetch(hstmt); - assert (rc == 0); - - assert (0 == strncmp("111", chr[0], 3)); - assert (0 == strncmp("222", chr[1], 3)); - assert (0 == strncmp("333", chr[2], 3)); - assert (4 == fourth); - assert (1.5 == fifth); - - rc = mysql_stmt_close(hstmt); - assert(rc == 0); - - sql = "DROP TABLE Test"; - rc = mysql_real_query(hsession, sql.c_str(), static_cast(sql.length())); - assert(rc == 0); - - mysql_close(hsession); -} - - -void SQLExecutor::simpleAccess() -{ - std::string funct = "simpleAccess()"; - std::string lastName = "lastName"; - std::string firstName("firstName"); - std::string address("Address"); - int age = 133132; - int count = 0; - std::string result; - - count = 0; - try - { - Statement stmt(*_pSession); - stmt << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(age);//, now; - stmt.execute(); - } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - assert (count == 1); - - try { *_pSession << "SELECT LastName FROM Person", into(result), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (lastName == result); - - try { *_pSession << "SELECT Age FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == age); -} - - -void SQLExecutor::complexType() -{ - std::string funct = "complexType()"; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(p1), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(p2), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - - Person c1; - Person c2; - try { *_pSession << "SELECT * FROM Person WHERE LastName = 'LN1'", into(c1), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (c1 == p1); -} - - -void SQLExecutor::simpleAccessVector() -{ - std::string funct = "simpleAccessVector()"; - std::vector lastNames; - std::vector firstNames; - std::vector addresses; - std::vector ages; - std::string tableName("Person"); - lastNames.push_back("LN1"); - lastNames.push_back("LN2"); - firstNames.push_back("FN1"); - firstNames.push_back("FN2"); - addresses.push_back("ADDR1"); - addresses.push_back("ADDR2"); - ages.push_back(1); - ages.push_back(2); - int count = 0; - std::string result; - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - - std::vector lastNamesR; - std::vector firstNamesR; - std::vector addressesR; - std::vector agesR; - try { *_pSession << "SELECT * FROM Person", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (ages == agesR); - assert (lastNames == lastNamesR); - assert (firstNames == firstNamesR); - assert (addresses == addressesR); -} - - -void SQLExecutor::complexTypeVector() -{ - std::string funct = "complexTypeVector()"; - std::vector people; - people.push_back(Person("LN1", "FN1", "ADDR1", 1)); - people.push_back(Person("LN2", "FN2", "ADDR2", 2)); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - - std::vector result; - try { *_pSession << "SELECT * FROM Person", into(result), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (result == people); -} - - -void SQLExecutor::insertVector() -{ - std::string funct = "insertVector()"; - std::vector str; - str.push_back("s1"); - str.push_back("s2"); - str.push_back("s3"); - str.push_back("s3"); - int count = 100; - - { - Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(str))); - try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 0); - - try { stmt.execute(); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 4); - } - count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 4); -} - - -void SQLExecutor::insertEmptyVector() -{ - std::string funct = "insertEmptyVector()"; - std::vector str; - - try - { - *_pSession << "INSERT INTO Strings VALUES (?)", use(str), now; - fail("empty collections should not work"); - } - catch (Poco::Exception&) - { - } -} - - -void SQLExecutor::insertSingleBulk() -{ - std::string funct = "insertSingleBulk()"; - int x = 0; - Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(x))); - - for (x = 0; x < 100; ++x) - { - int i = stmt.execute(); - assert (i == 0); - } - - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 100); - - try { *_pSession << "SELECT SUM(str) FROM Strings", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == ((0+99)*100/2)); -} - - -void SQLExecutor::floats() -{ - std::string funct = "floats()"; - float data = 1.5f; - float ret = 0.0f; - - try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 1); - - try { *_pSession << "SELECT str FROM Strings", into(ret), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (ret == data); -} - - -void SQLExecutor::doubles() -{ - std::string funct = "floats()"; - double data = 1.5; - double ret = 0.0; - - try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 1); - - try { *_pSession << "SELECT str FROM Strings", into(ret), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (ret == data); -} - - -void SQLExecutor::insertSingleBulkVec() -{ - std::string funct = "insertSingleBulkVec()"; - std::vector data; - - for (int x = 0; x < 100; ++x) - data.push_back(x); - - Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(data))); - stmt.execute(); - - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - assert (count == 100); - try { *_pSession << "SELECT SUM(str) FROM Strings", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == ((0+99)*100/2)); -} - - -void SQLExecutor::limits() -{ - std::string funct = "limit()"; - std::vector data; - for (int x = 0; x < 100; ++x) - { - data.push_back(x); - } - - try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - std::vector retData; - try { *_pSession << "SELECT * FROM Strings", into(retData), limit(50), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (retData.size() == 50); - for (int x = 0; x < 50; ++x) - { - assert(data[x] == retData[x]); - } -} - - -void SQLExecutor::limitZero() -{ - std::string funct = "limitZero()"; - std::vector data; - for (int x = 0; x < 100; ++x) - { - data.push_back(x); - } - - try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - std::vector retData; - try { *_pSession << "SELECT * FROM Strings", into(retData), limit(0), now; }// stupid test, but at least we shouldn't crash - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (retData.size() == 0); -} - - -void SQLExecutor::limitOnce() -{ - std::string funct = "limitOnce()"; - std::vector data; - for (int x = 0; x < 101; ++x) - { - data.push_back(x); - } - - try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - std::vector retData; - Statement stmt = (*_pSession << "SELECT * FROM Strings", into(retData), limit(50), now); - assert (!stmt.done()); - assert (retData.size() == 50); - stmt.execute(); - assert (!stmt.done()); - assert (retData.size() == 100); - stmt.execute(); - assert (stmt.done()); - assert (retData.size() == 101); - - for (int x = 0; x < 101; ++x) - { - assert(data[x] == retData[x]); - } -} - - -void SQLExecutor::limitPrepare() -{ - std::string funct = "limitPrepare()"; - std::vector data; - for (int x = 0; x < 100; ++x) - { - data.push_back(x); - } - - try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - std::vector retData; - Statement stmt = (*_pSession << "SELECT * FROM Strings", into(retData), limit(50)); - assert (retData.size() == 0); - assert (!stmt.done()); - - try { stmt.execute(); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (!stmt.done()); - assert (retData.size() == 50); - - try { stmt.execute(); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (stmt.done()); - assert (retData.size() == 100); - - try { stmt.execute(); }// will restart execution! - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (!stmt.done()); - assert (retData.size() == 150); - for (int x = 0; x < 150; ++x) - { - assert(data[x%100] == retData[x]); - } -} - - -void SQLExecutor::prepare() -{ - std::string funct = "prepare()"; - std::vector data; - for (int x = 0; x < 100; x += 2) - { - data.push_back(x); - } - - { - Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(data))); - } - // stmt should not have been executed when destroyed - int count = 100; - try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 0); -} - - -void SQLExecutor::setSimple() -{ - std::string funct = "setSimple()"; - std::set lastNames; - std::set firstNames; - std::set addresses; - std::set ages; - std::string tableName("Person"); - lastNames.insert("LN1"); - lastNames.insert("LN2"); - firstNames.insert("FN1"); - firstNames.insert("FN2"); - addresses.insert("ADDR1"); - addresses.insert("ADDR2"); - ages.insert(1); - ages.insert(2); - int count = 0; - std::string result; - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - - std::set lastNamesR; - std::set firstNamesR; - std::set addressesR; - std::set agesR; - try { *_pSession << "SELECT * FROM Person", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (ages == agesR); - assert (lastNames == lastNamesR); - assert (firstNames == firstNamesR); - assert (addresses == addressesR); -} - - -void SQLExecutor::setComplex() -{ - std::string funct = "setComplex()"; - std::set people; - people.insert(Person("LN1", "FN1", "ADDR1", 1)); - people.insert(Person("LN2", "FN2", "ADDR2", 2)); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - - std::set result; - try { *_pSession << "SELECT * FROM Person", into(result), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (result == people); -} - - -void SQLExecutor::setComplexUnique() -{ - std::string funct = "setComplexUnique()"; - std::vector people; - Person p1("LN1", "FN1", "ADDR1", 1); - people.push_back(p1); - people.push_back(p1); - people.push_back(p1); - people.push_back(p1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.push_back(p2); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 5); - - std::set result; - try { *_pSession << "SELECT * FROM Person", into(result), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (result.size() == 2); - assert (*result.begin() == p1); - assert (*++result.begin() == p2); -} - -void SQLExecutor::multiSetSimple() -{ - std::string funct = "multiSetSimple()"; - std::multiset lastNames; - std::multiset firstNames; - std::multiset addresses; - std::multiset ages; - std::string tableName("Person"); - lastNames.insert("LN1"); - lastNames.insert("LN2"); - firstNames.insert("FN1"); - firstNames.insert("FN2"); - addresses.insert("ADDR1"); - addresses.insert("ADDR2"); - ages.insert(1); - ages.insert(2); - int count = 0; - std::string result; - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - - std::multiset lastNamesR; - std::multiset firstNamesR; - std::multiset addressesR; - std::multiset agesR; - try { *_pSession << "SELECT * FROM Person", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (ages.size() == agesR.size()); - assert (lastNames.size() == lastNamesR.size()); - assert (firstNames.size() == firstNamesR.size()); - assert (addresses.size() == addressesR.size()); -} - - -void SQLExecutor::multiSetComplex() -{ - std::string funct = "multiSetComplex()"; - std::multiset people; - Person p1("LN1", "FN1", "ADDR1", 1); - people.insert(p1); - people.insert(p1); - people.insert(p1); - people.insert(p1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(p2); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 5); - - std::multiset result; - try { *_pSession << "SELECT * FROM Person", into(result), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (result.size() == people.size()); -} - - -void SQLExecutor::mapComplex() -{ - std::string funct = "mapComplex()"; - std::map people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN2", p2)); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - - std::map result; - try { *_pSession << "SELECT * FROM Person", into(result), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (result == people); -} - - -void SQLExecutor::mapComplexUnique() -{ - std::string funct = "mapComplexUnique()"; - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN2", p2)); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 5); - - std::map result; - try { *_pSession << "SELECT * FROM Person", into(result), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (result.size() == 2); -} - - -void SQLExecutor::multiMapComplex() -{ - std::string funct = "multiMapComplex()"; - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN2", p2)); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 5); - - std::multimap result; - try { *_pSession << "SELECT * FROM Person", into(result), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (result.size() == people.size()); -} - - -void SQLExecutor::selectIntoSingle() -{ - std::string funct = "selectIntoSingle()"; - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - Person result; - try { *_pSession << "SELECT * FROM Person", into(result), limit(1), now; }// will return 1 object into one single result - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (result == p1); -} - - -void SQLExecutor::selectIntoSingleStep() -{ - std::string funct = "selectIntoSingleStep()"; - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - Person result; - Statement stmt = (*_pSession << "SELECT * FROM Person", into(result), limit(1)); - stmt.execute(); - assert (result == p1); - assert (!stmt.done()); - stmt.execute(); - assert (result == p2); - assert (stmt.done()); -} - - -void SQLExecutor::selectIntoSingleFail() -{ - std::string funct = "selectIntoSingleFail()"; - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), limit(2, true), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - Person result; - try - { - *_pSession << "SELECT * FROM Person", into(result), limit(1, true), now; // will fail now - fail("hardLimit is set: must fail"); - } - catch(Poco::Data::LimitException&) - { - } -} - - -void SQLExecutor::lowerLimitOk() -{ - std::string funct = "lowerLimitOk()"; - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - Person result; - try - { - *_pSession << "SELECT * FROM Person", into(result), lowerLimit(2), now; // will return 2 objects into one single result but only room for one! - fail("Not enough space for results"); - } - catch(Poco::Exception&) - { - } -} - - -void SQLExecutor::singleSelect() -{ - std::string funct = "singleSelect()"; - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - Person result; - Statement stmt = (*_pSession << "SELECT * FROM Person", into(result), limit(1)); - stmt.execute(); - assert (result == p1); - assert (!stmt.done()); - stmt.execute(); - assert (result == p2); - assert (stmt.done()); -} - - -void SQLExecutor::lowerLimitFail() -{ - std::string funct = "lowerLimitFail()"; - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - Person result; - try - { - *_pSession << "SELECT * FROM Person", into(result), lowerLimit(3), now; // will fail - fail("should fail. not enough data"); - } - catch(Poco::Exception&) - { - } -} - - -void SQLExecutor::combinedLimits() -{ - std::string funct = "combinedLimits()"; - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - std::vector result; - try { *_pSession << "SELECT * FROM Person", into(result), lowerLimit(2), upperLimit(2), now; }// will return 2 objects - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (result.size() == 2); - assert (result[0] == p1); - assert (result[1] == p2); -} - - - -void SQLExecutor::ranges() -{ - std::string funct = "range()"; - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - std::vector result; - try { *_pSession << "SELECT * FROM Person", into(result), range(2, 2), now; }// will return 2 objects - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (result.size() == 2); - assert (result[0] == p1); - assert (result[1] == p2); -} - - -void SQLExecutor::combinedIllegalLimits() -{ - std::string funct = "combinedIllegalLimits()"; - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - Person result; - try - { - *_pSession << "SELECT * FROM Person", into(result), lowerLimit(3), upperLimit(2), now; - fail("lower > upper is not allowed"); - } - catch(LimitException&) - { - } -} - - -void SQLExecutor::illegalRange() -{ - std::string funct = "illegalRange()"; - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 2); - Person result; - try - { - *_pSession << "SELECT * FROM Person", into(result), range(3, 2), now; - fail("lower > upper is not allowed"); - } - catch(LimitException&) - { - } -} - - -void SQLExecutor::emptyDB() -{ - std::string funct = "emptyDB()"; - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 0); - - Person result; - Statement stmt = (*_pSession << "SELECT * FROM Person", into(result), limit(1)); - stmt.execute(); - assert (result.firstName.empty()); - assert (stmt.done()); -} - - -void SQLExecutor::blob(int bigSize) -{ - std::string funct = "blob()"; - std::string lastName("lastname"); - std::string firstName("firstname"); - std::string address("Address"); - - Poco::Data::BLOB img("0123456789", 10); - int count = 0; - try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(img), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 1); - - Poco::Data::BLOB res; - assert (res.size() == 0); - try { *_pSession << "SELECT Image FROM Person", into(res), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (res == img); - - Poco::Data::BLOB big; - std::vector v(bigSize, 'x'); - big.assignRaw(&v[0], v.size()); - - assert (big.size() == bigSize); - - try { *_pSession << "DELETE FROM Person", now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - try { *_pSession << "INSERT INTO Person VALUES(?,?,?,?)", use(lastName), use(firstName), use(address), use(big), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - try { *_pSession << "SELECT Image FROM Person", into(res), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (res == big); -} - -void SQLExecutor::blobStmt() -{ - std::string funct = "blobStmt()"; - std::string lastName("lastname"); - std::string firstName("firstname"); - std::string address("Address"); - Poco::Data::BLOB blob("0123456789", 10); - - int count = 0; - Statement ins = (*_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(blob)); - ins.execute(); - try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 1); - - Poco::Data::BLOB res; - poco_assert (res.size() == 0); - Statement stmt = (*_pSession << "SELECT Image FROM Person", into(res)); - try { stmt.execute(); } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - poco_assert (res == blob); -} - -void SQLExecutor::tuples() -{ - typedef Tuple TupleType; - std::string funct = "tuples()"; - TupleType t(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19); - - try { *_pSession << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", use(t), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - TupleType ret(-10,-11,-12,-13,-14,-15,-16,-17,-18,-19); - assert (ret != t); - try { *_pSession << "SELECT * FROM Tuples", into(ret), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (ret == t); -} - -void SQLExecutor::tupleVector() -{ - typedef Tuple TupleType; - std::string funct = "tupleVector()"; - TupleType t(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19); - Tuple - t10(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29); - TupleType t100(100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119); - std::vector v; - v.push_back(t); - v.push_back(t10); - v.push_back(t100); - - try { *_pSession << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", use(v), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Tuples", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (v.size() == count); - - std::vector > ret; - try { *_pSession << "SELECT * FROM Tuples", into(ret), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (ret == v); -} - - -void SQLExecutor::internalExtraction() -{ - std::string funct = "internalExtraction()"; - std::vector > v; - v.push_back(Tuple(1, 1.5f, "3")); - v.push_back(Tuple(2, 2.5f, "4")); - v.push_back(Tuple(3, 3.5f, "5")); - v.push_back(Tuple(4, 4.5f, "6")); - - try { *_pSession << "INSERT INTO Vectors VALUES (?,?,?)", use(v), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - - try - { - Statement stmt = (*_pSession << "SELECT * FROM Vectors", now); - RecordSet rset(stmt); - - assert (3 == rset.columnCount()); - assert (4 == rset.rowCount()); - - int curVal = 3; - do - { - assert (rset["str0"] == curVal); - ++curVal; - } while (rset.moveNext()); - - rset.moveFirst(); - assert (rset["str0"] == "3"); - rset.moveLast(); - assert (rset["str0"] == "6"); - - RecordSet rset2(rset); - assert (3 == rset2.columnCount()); - assert (4 == rset2.rowCount()); - - int i = rset.value(0,0); - assert (1 == i); - - std::string s = rset.value(0,0); - assert ("1" == s); - - int a = rset.value(0,2); - assert (3 == a); - - try - { - double d = rset.value(1,1); - assert (2.5 == d); - } - catch (BadCastException&) - { - float f = rset.value(1,1); - assert (2.5 == f); - } - - s = rset.value(2,2); - assert ("5" == s); - i = rset.value("str0", 2); - assert (5 == i); - - const Column& col = rset.column(0); - Column::Iterator it = col.begin(); - Column::Iterator end = col.end(); - for (int i = 1; it != end; ++it, ++i) - assert (*it == i); - - rset = (*_pSession << "SELECT COUNT(*) AS cnt FROM Vectors", now); - - //various results for COUNT(*) are received from different drivers - try - { - //this is what most drivers will return - int i = rset.value(0,0); - assert (4 == i); - } - catch(BadCastException&) - { - try - { - //this is for Oracle - double i = rset.value(0,0); - assert (4 == int(i)); - } - catch(BadCastException&) - { - //this is for PostgreSQL - Poco::Int64 big = rset.value(0,0); - assert (4 == big); - } - } - - s = rset.value("cnt", 0).convert(); - assert ("4" == s); - - try { const Column& col1 = rset.column(100); fail ("must fail"); } - catch (RangeException&) { } - - try { rset.value(0,0); fail ("must fail"); } - catch (BadCastException&) { } - - stmt = (*_pSession << "DELETE FROM Vectors", now); - rset = stmt; - - try { const Column& col1 = rset.column(0); fail ("must fail"); } - catch (RangeException&) { } - } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } -} - - -void SQLExecutor::doNull() -{ - std::string funct = "null()"; - - *_pSession << "INSERT INTO Vectors VALUES (null, null, null)", now; - - int count = 0; - try { *_pSession << "SELECT COUNT(*) FROM Vectors", into(count), now; } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - assert (count == 1); - - int i0 = 0; - Statement stmt1 = (*_pSession << "SELECT i0 FROM Vectors", into(i0, -1)); - try { stmt1.execute(); } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - poco_assert (i0 == -1); - - float flt0 = 0; - Statement stmt2 = (*_pSession << "SELECT flt0 FROM Vectors", into(flt0, 3.25f)); - try { stmt2.execute(); } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - poco_assert (flt0 == 3.25); - - std::string str0("string"); - Statement stmt3 = (*_pSession << "SELECT str0 FROM Vectors", into(str0, std::string("DEFAULT"))); - try { stmt3.execute(); } - catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } - catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } - poco_assert (str0 == "DEFAULT"); -} +// +// SQLExecutor.cpp +// +// $Id: //poco/1.3/Data/MySQL/testsuite/src/SQLExecutor.cpp#2 $ +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "CppUnit/TestCase.h" +#include "SQLExecutor.h" +#include "Poco/String.h" +#include "Poco/Format.h" +#include "Poco/Tuple.h" +#include "Poco/Any.h" +#include "Poco/Exception.h" +#include "Poco/Data/Common.h" +#include "Poco/Data/BLOB.h" +#include "Poco/Data/StatementImpl.h" +#include "Poco/Data/RecordSet.h" +#include "Poco/Data/MySQL/Connector.h" +#include "Poco/Data/MySQL/MySQLException.h" +#ifdef _WIN32 +#include +#endif +#include +#include + + +using namespace Poco::Data; +using Poco::Data::MySQL::ConnectionException; +using Poco::Data::MySQL::StatementException; +using Poco::format; +using Poco::Tuple; +using Poco::Any; +using Poco::AnyCast; +using Poco::NotFoundException; +using Poco::InvalidAccessException; +using Poco::BadCastException; +using Poco::RangeException; + + +struct Person +{ + std::string lastName; + std::string firstName; + std::string address; + int age; + Person(){age = 0;} + Person(const std::string& ln, const std::string& fn, const std::string& adr, int a):lastName(ln), firstName(fn), address(adr), age(a) + { + } + bool operator==(const Person& other) const + { + return lastName == other.lastName && firstName == other.firstName && address == other.address && age == other.age; + } + + bool operator < (const Person& p) const + { + if (age < p.age) + return true; + if (lastName < p.lastName) + return true; + if (firstName < p.firstName) + return true; + return (address < p.address); + } + + const std::string& operator () () const + /// This method is required so we can extract data to a map! + { + // we choose the lastName as examplary key + return lastName; + } +}; + + +namespace Poco { +namespace Data { + + +template <> +class TypeHandler +{ +public: + static void bind(std::size_t pos, const Person& obj, AbstractBinder* pBinder) + { + // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3)) + poco_assert_dbg (pBinder != 0); + pBinder->bind(pos++, obj.lastName); + pBinder->bind(pos++, obj.firstName); + pBinder->bind(pos++, obj.address); + pBinder->bind(pos++, obj.age); + } + + static void prepare(std::size_t pos, const Person& obj, AbstractPreparation* pPrepare) + { + // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3)) + poco_assert_dbg (pPrepare != 0); + pPrepare->prepare(pos++, obj.lastName); + pPrepare->prepare(pos++, obj.firstName); + pPrepare->prepare(pos++, obj.address); + pPrepare->prepare(pos++, obj.age); + } + + static std::size_t size() + { + return 4; + } + + static void extract(std::size_t pos, Person& obj, const Person& defVal, AbstractExtractor* pExt) + { + poco_assert_dbg (pExt != 0); + if (!pExt->extract(pos++, obj.lastName)) + obj.lastName = defVal.lastName; + if (!pExt->extract(pos++, obj.firstName)) + obj.firstName = defVal.firstName; + if (!pExt->extract(pos++, obj.address)) + obj.address = defVal.address; + if (!pExt->extract(pos++, obj.age)) + obj.age = defVal.age; + } + +private: + TypeHandler(); + ~TypeHandler(); + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + + +} } // namespace Poco::Data + + +SQLExecutor::SQLExecutor(const std::string& name, Poco::Data::Session* pSession): + CppUnit::TestCase(name), + _pSession(pSession) +{ +} + + +SQLExecutor::~SQLExecutor() +{ +} + + +void SQLExecutor::bareboneMySQLTest(const char* host, const char* user, const char* pwd, const char* db, int port, const char* tableCreateString) +{ + int rc; + MYSQL* hsession = mysql_init(0); + assert (hsession != 0); + + MYSQL* tmp = mysql_real_connect(hsession, host, user, pwd, db, port, 0, 0); + assert(tmp == hsession); + + MYSQL_STMT* hstmt = mysql_stmt_init(hsession); + assert(hstmt != 0); + + std::string sql = "DROP TABLE Test"; + mysql_real_query(hsession, sql.c_str(), static_cast(sql.length())); + + sql = tableCreateString; + rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast(sql.length())); + assert(rc == 0); + + rc = mysql_stmt_execute(hstmt); + assert(rc == 0); + + sql = "INSERT INTO Test VALUES (?,?,?,?,?)"; + rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast(sql.length())); + assert(rc == 0); + + std::string str[3] = { "111", "222", "333" }; + int fourth = 4; + float fifth = 1.5; + + MYSQL_BIND bind_param[5] = {{0}}; + + bind_param[0].buffer = const_cast(str[0].c_str()); + bind_param[0].buffer_length = static_cast(str[0].length()); + bind_param[0].buffer_type = MYSQL_TYPE_STRING; + + bind_param[1].buffer = const_cast(str[1].c_str()); + bind_param[1].buffer_length = static_cast(str[1].length()); + bind_param[1].buffer_type = MYSQL_TYPE_STRING; + + bind_param[2].buffer = const_cast(str[2].c_str()); + bind_param[2].buffer_length = static_cast(str[2].length()); + bind_param[2].buffer_type = MYSQL_TYPE_STRING; + + bind_param[3].buffer = &fourth; + bind_param[3].buffer_type = MYSQL_TYPE_LONG; + + bind_param[4].buffer = &fifth; + bind_param[4].buffer_type = MYSQL_TYPE_FLOAT; + + rc = mysql_stmt_bind_param(hstmt, bind_param); + assert (rc == 0); + + rc = mysql_stmt_execute(hstmt); + assert (rc == 0); + + sql = "SELECT * FROM Test"; + rc = mysql_stmt_prepare(hstmt, sql.c_str(), static_cast(sql.length())); + assert (rc == 0); + + char chr[3][5] = {{ 0 }}; + unsigned long lengths[5] = { 0 }; + fourth = 0; + fifth = 0.0f; + + MYSQL_BIND bind_result[5] = {{0}}; + + bind_result[0].buffer = chr[0]; + bind_result[0].buffer_length = sizeof(chr[0]); + bind_result[0].buffer_type = MYSQL_TYPE_STRING; + bind_result[0].length = &lengths[0]; + + bind_result[1].buffer = chr[1]; + bind_result[1].buffer_length = sizeof(chr[1]); + bind_result[1].buffer_type = MYSQL_TYPE_STRING; + bind_result[1].length = &lengths[1]; + + bind_result[2].buffer = chr[2]; + bind_result[2].buffer_length = sizeof(chr[2]); + bind_result[2].buffer_type = MYSQL_TYPE_STRING; + bind_result[2].length = &lengths[2]; + + bind_result[3].buffer = &fourth; + bind_result[3].buffer_type = MYSQL_TYPE_LONG; + bind_result[3].length = &lengths[3]; + + bind_result[4].buffer = &fifth; + bind_result[4].buffer_type = MYSQL_TYPE_FLOAT; + bind_result[4].length = &lengths[4]; + + rc = mysql_stmt_bind_result(hstmt, bind_result); + assert (rc == 0); + + rc = mysql_stmt_execute(hstmt); + assert (rc == 0); + rc = mysql_stmt_fetch(hstmt); + assert (rc == 0); + + assert (0 == strncmp("111", chr[0], 3)); + assert (0 == strncmp("222", chr[1], 3)); + assert (0 == strncmp("333", chr[2], 3)); + assert (4 == fourth); + assert (1.5 == fifth); + + rc = mysql_stmt_close(hstmt); + assert(rc == 0); + + sql = "DROP TABLE Test"; + rc = mysql_real_query(hsession, sql.c_str(), static_cast(sql.length())); + assert(rc == 0); + + mysql_close(hsession); +} + + +void SQLExecutor::simpleAccess() +{ + std::string funct = "simpleAccess()"; + std::string lastName = "lastName"; + std::string firstName("firstName"); + std::string address("Address"); + int age = 133132; + int count = 0; + std::string result; + + count = 0; + try + { + Statement stmt(*_pSession); + stmt << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(age);//, now; + stmt.execute(); + } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + assert (count == 1); + + try { *_pSession << "SELECT LastName FROM Person", into(result), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (lastName == result); + + try { *_pSession << "SELECT Age FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == age); +} + + +void SQLExecutor::complexType() +{ + std::string funct = "complexType()"; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(p1), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(p2), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + + Person c1; + Person c2; + try { *_pSession << "SELECT * FROM Person WHERE LastName = 'LN1'", into(c1), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (c1 == p1); +} + + +void SQLExecutor::simpleAccessVector() +{ + std::string funct = "simpleAccessVector()"; + std::vector lastNames; + std::vector firstNames; + std::vector addresses; + std::vector ages; + std::string tableName("Person"); + lastNames.push_back("LN1"); + lastNames.push_back("LN2"); + firstNames.push_back("FN1"); + firstNames.push_back("FN2"); + addresses.push_back("ADDR1"); + addresses.push_back("ADDR2"); + ages.push_back(1); + ages.push_back(2); + int count = 0; + std::string result; + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + + std::vector lastNamesR; + std::vector firstNamesR; + std::vector addressesR; + std::vector agesR; + try { *_pSession << "SELECT * FROM Person", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (ages == agesR); + assert (lastNames == lastNamesR); + assert (firstNames == firstNamesR); + assert (addresses == addressesR); +} + + +void SQLExecutor::complexTypeVector() +{ + std::string funct = "complexTypeVector()"; + std::vector people; + people.push_back(Person("LN1", "FN1", "ADDR1", 1)); + people.push_back(Person("LN2", "FN2", "ADDR2", 2)); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + + std::vector result; + try { *_pSession << "SELECT * FROM Person", into(result), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (result == people); +} + + +void SQLExecutor::insertVector() +{ + std::string funct = "insertVector()"; + std::vector str; + str.push_back("s1"); + str.push_back("s2"); + str.push_back("s3"); + str.push_back("s3"); + int count = 100; + + { + Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(str))); + try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 0); + + try { stmt.execute(); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 4); + } + count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 4); +} + + +void SQLExecutor::insertEmptyVector() +{ + std::string funct = "insertEmptyVector()"; + std::vector str; + + try + { + *_pSession << "INSERT INTO Strings VALUES (?)", use(str), now; + fail("empty collections should not work"); + } + catch (Poco::Exception&) + { + } +} + + +void SQLExecutor::insertSingleBulk() +{ + std::string funct = "insertSingleBulk()"; + int x = 0; + Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(x))); + + for (x = 0; x < 100; ++x) + { + int i = stmt.execute(); + assert (i == 0); + } + + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 100); + + try { *_pSession << "SELECT SUM(str) FROM Strings", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == ((0+99)*100/2)); +} + + +void SQLExecutor::floats() +{ + std::string funct = "floats()"; + float data = 1.5f; + float ret = 0.0f; + + try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 1); + + try { *_pSession << "SELECT str FROM Strings", into(ret), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (ret == data); +} + + +void SQLExecutor::doubles() +{ + std::string funct = "floats()"; + double data = 1.5; + double ret = 0.0; + + try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 1); + + try { *_pSession << "SELECT str FROM Strings", into(ret), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (ret == data); +} + + +void SQLExecutor::insertSingleBulkVec() +{ + std::string funct = "insertSingleBulkVec()"; + std::vector data; + + for (int x = 0; x < 100; ++x) + data.push_back(x); + + Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(data))); + stmt.execute(); + + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + assert (count == 100); + try { *_pSession << "SELECT SUM(str) FROM Strings", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == ((0+99)*100/2)); +} + + +void SQLExecutor::limits() +{ + std::string funct = "limit()"; + std::vector data; + for (int x = 0; x < 100; ++x) + { + data.push_back(x); + } + + try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + std::vector retData; + try { *_pSession << "SELECT * FROM Strings", into(retData), limit(50), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (retData.size() == 50); + for (int x = 0; x < 50; ++x) + { + assert(data[x] == retData[x]); + } +} + + +void SQLExecutor::limitZero() +{ + std::string funct = "limitZero()"; + std::vector data; + for (int x = 0; x < 100; ++x) + { + data.push_back(x); + } + + try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + std::vector retData; + try { *_pSession << "SELECT * FROM Strings", into(retData), limit(0), now; }// stupid test, but at least we shouldn't crash + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (retData.size() == 0); +} + + +void SQLExecutor::limitOnce() +{ + std::string funct = "limitOnce()"; + std::vector data; + for (int x = 0; x < 101; ++x) + { + data.push_back(x); + } + + try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + std::vector retData; + Statement stmt = (*_pSession << "SELECT * FROM Strings", into(retData), limit(50), now); + assert (!stmt.done()); + assert (retData.size() == 50); + stmt.execute(); + assert (!stmt.done()); + assert (retData.size() == 100); + stmt.execute(); + assert (stmt.done()); + assert (retData.size() == 101); + + for (int x = 0; x < 101; ++x) + { + assert(data[x] == retData[x]); + } +} + + +void SQLExecutor::limitPrepare() +{ + std::string funct = "limitPrepare()"; + std::vector data; + for (int x = 0; x < 100; ++x) + { + data.push_back(x); + } + + try { *_pSession << "INSERT INTO Strings VALUES (?)", use(data), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + std::vector retData; + Statement stmt = (*_pSession << "SELECT * FROM Strings", into(retData), limit(50)); + assert (retData.size() == 0); + assert (!stmt.done()); + + try { stmt.execute(); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (!stmt.done()); + assert (retData.size() == 50); + + try { stmt.execute(); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (stmt.done()); + assert (retData.size() == 100); + + try { stmt.execute(); }// will restart execution! + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (!stmt.done()); + assert (retData.size() == 150); + for (int x = 0; x < 150; ++x) + { + assert(data[x%100] == retData[x]); + } +} + + +void SQLExecutor::prepare() +{ + std::string funct = "prepare()"; + std::vector data; + for (int x = 0; x < 100; x += 2) + { + data.push_back(x); + } + + { + Statement stmt((*_pSession << "INSERT INTO Strings VALUES (?)", use(data))); + } + // stmt should not have been executed when destroyed + int count = 100; + try { *_pSession << "SELECT COUNT(*) FROM Strings", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 0); +} + + +void SQLExecutor::setSimple() +{ + std::string funct = "setSimple()"; + std::set lastNames; + std::set firstNames; + std::set addresses; + std::set ages; + std::string tableName("Person"); + lastNames.insert("LN1"); + lastNames.insert("LN2"); + firstNames.insert("FN1"); + firstNames.insert("FN2"); + addresses.insert("ADDR1"); + addresses.insert("ADDR2"); + ages.insert(1); + ages.insert(2); + int count = 0; + std::string result; + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + + std::set lastNamesR; + std::set firstNamesR; + std::set addressesR; + std::set agesR; + try { *_pSession << "SELECT * FROM Person", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (ages == agesR); + assert (lastNames == lastNamesR); + assert (firstNames == firstNamesR); + assert (addresses == addressesR); +} + + +void SQLExecutor::setComplex() +{ + std::string funct = "setComplex()"; + std::set people; + people.insert(Person("LN1", "FN1", "ADDR1", 1)); + people.insert(Person("LN2", "FN2", "ADDR2", 2)); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + + std::set result; + try { *_pSession << "SELECT * FROM Person", into(result), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (result == people); +} + + +void SQLExecutor::setComplexUnique() +{ + std::string funct = "setComplexUnique()"; + std::vector people; + Person p1("LN1", "FN1", "ADDR1", 1); + people.push_back(p1); + people.push_back(p1); + people.push_back(p1); + people.push_back(p1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.push_back(p2); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 5); + + std::set result; + try { *_pSession << "SELECT * FROM Person", into(result), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (result.size() == 2); + assert (*result.begin() == p1); + assert (*++result.begin() == p2); +} + +void SQLExecutor::multiSetSimple() +{ + std::string funct = "multiSetSimple()"; + std::multiset lastNames; + std::multiset firstNames; + std::multiset addresses; + std::multiset ages; + std::string tableName("Person"); + lastNames.insert("LN1"); + lastNames.insert("LN2"); + firstNames.insert("FN1"); + firstNames.insert("FN2"); + addresses.insert("ADDR1"); + addresses.insert("ADDR2"); + ages.insert(1); + ages.insert(2); + int count = 0; + std::string result; + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + + std::multiset lastNamesR; + std::multiset firstNamesR; + std::multiset addressesR; + std::multiset agesR; + try { *_pSession << "SELECT * FROM Person", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (ages.size() == agesR.size()); + assert (lastNames.size() == lastNamesR.size()); + assert (firstNames.size() == firstNamesR.size()); + assert (addresses.size() == addressesR.size()); +} + + +void SQLExecutor::multiSetComplex() +{ + std::string funct = "multiSetComplex()"; + std::multiset people; + Person p1("LN1", "FN1", "ADDR1", 1); + people.insert(p1); + people.insert(p1); + people.insert(p1); + people.insert(p1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(p2); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 5); + + std::multiset result; + try { *_pSession << "SELECT * FROM Person", into(result), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (result.size() == people.size()); +} + + +void SQLExecutor::mapComplex() +{ + std::string funct = "mapComplex()"; + std::map people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN2", p2)); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + + std::map result; + try { *_pSession << "SELECT * FROM Person", into(result), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (result == people); +} + + +void SQLExecutor::mapComplexUnique() +{ + std::string funct = "mapComplexUnique()"; + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN2", p2)); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 5); + + std::map result; + try { *_pSession << "SELECT * FROM Person", into(result), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (result.size() == 2); +} + + +void SQLExecutor::multiMapComplex() +{ + std::string funct = "multiMapComplex()"; + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN2", p2)); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 5); + + std::multimap result; + try { *_pSession << "SELECT * FROM Person", into(result), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (result.size() == people.size()); +} + + +void SQLExecutor::selectIntoSingle() +{ + std::string funct = "selectIntoSingle()"; + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + Person result; + try { *_pSession << "SELECT * FROM Person", into(result), limit(1), now; }// will return 1 object into one single result + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (result == p1); +} + + +void SQLExecutor::selectIntoSingleStep() +{ + std::string funct = "selectIntoSingleStep()"; + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + Person result; + Statement stmt = (*_pSession << "SELECT * FROM Person", into(result), limit(1)); + stmt.execute(); + assert (result == p1); + assert (!stmt.done()); + stmt.execute(); + assert (result == p2); + assert (stmt.done()); +} + + +void SQLExecutor::selectIntoSingleFail() +{ + std::string funct = "selectIntoSingleFail()"; + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), limit(2, true), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + Person result; + try + { + *_pSession << "SELECT * FROM Person", into(result), limit(1, true), now; // will fail now + fail("hardLimit is set: must fail"); + } + catch(Poco::Data::LimitException&) + { + } +} + + +void SQLExecutor::lowerLimitOk() +{ + std::string funct = "lowerLimitOk()"; + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + Person result; + try + { + *_pSession << "SELECT * FROM Person", into(result), lowerLimit(2), now; // will return 2 objects into one single result but only room for one! + fail("Not enough space for results"); + } + catch(Poco::Exception&) + { + } +} + + +void SQLExecutor::singleSelect() +{ + std::string funct = "singleSelect()"; + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + Person result; + Statement stmt = (*_pSession << "SELECT * FROM Person", into(result), limit(1)); + stmt.execute(); + assert (result == p1); + assert (!stmt.done()); + stmt.execute(); + assert (result == p2); + assert (stmt.done()); +} + + +void SQLExecutor::lowerLimitFail() +{ + std::string funct = "lowerLimitFail()"; + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + Person result; + try + { + *_pSession << "SELECT * FROM Person", into(result), lowerLimit(3), now; // will fail + fail("should fail. not enough data"); + } + catch(Poco::Exception&) + { + } +} + + +void SQLExecutor::combinedLimits() +{ + std::string funct = "combinedLimits()"; + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + std::vector result; + try { *_pSession << "SELECT * FROM Person", into(result), lowerLimit(2), upperLimit(2), now; }// will return 2 objects + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (result.size() == 2); + assert (result[0] == p1); + assert (result[1] == p2); +} + + + +void SQLExecutor::ranges() +{ + std::string funct = "range()"; + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + std::vector result; + try { *_pSession << "SELECT * FROM Person", into(result), range(2, 2), now; }// will return 2 objects + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (result.size() == 2); + assert (result[0] == p1); + assert (result[1] == p2); +} + + +void SQLExecutor::combinedIllegalLimits() +{ + std::string funct = "combinedIllegalLimits()"; + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + Person result; + try + { + *_pSession << "SELECT * FROM Person", into(result), lowerLimit(3), upperLimit(2), now; + fail("lower > upper is not allowed"); + } + catch(LimitException&) + { + } +} + + +void SQLExecutor::illegalRange() +{ + std::string funct = "illegalRange()"; + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 2); + Person result; + try + { + *_pSession << "SELECT * FROM Person", into(result), range(3, 2), now; + fail("lower > upper is not allowed"); + } + catch(LimitException&) + { + } +} + + +void SQLExecutor::emptyDB() +{ + std::string funct = "emptyDB()"; + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 0); + + Person result; + Statement stmt = (*_pSession << "SELECT * FROM Person", into(result), limit(1)); + stmt.execute(); + assert (result.firstName.empty()); + assert (stmt.done()); +} + + +void SQLExecutor::blob(int bigSize) +{ + std::string funct = "blob()"; + std::string lastName("lastname"); + std::string firstName("firstname"); + std::string address("Address"); + + Poco::Data::BLOB img("0123456789", 10); + int count = 0; + try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(img), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 1); + + Poco::Data::BLOB res; + assert (res.size() == 0); + try { *_pSession << "SELECT Image FROM Person", into(res), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (res == img); + + Poco::Data::BLOB big; + std::vector v(bigSize, 'x'); + big.assignRaw(&v[0], v.size()); + + assert (big.size() == bigSize); + + try { *_pSession << "DELETE FROM Person", now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + try { *_pSession << "INSERT INTO Person VALUES(?,?,?,?)", use(lastName), use(firstName), use(address), use(big), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + try { *_pSession << "SELECT Image FROM Person", into(res), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (res == big); +} + +void SQLExecutor::blobStmt() +{ + std::string funct = "blobStmt()"; + std::string lastName("lastname"); + std::string firstName("firstname"); + std::string address("Address"); + Poco::Data::BLOB blob("0123456789", 10); + + int count = 0; + Statement ins = (*_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(blob)); + ins.execute(); + try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 1); + + Poco::Data::BLOB res; + poco_assert (res.size() == 0); + Statement stmt = (*_pSession << "SELECT Image FROM Person", into(res)); + try { stmt.execute(); } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + poco_assert (res == blob); +} + +void SQLExecutor::tuples() +{ + typedef Tuple TupleType; + std::string funct = "tuples()"; + TupleType t(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19); + + try { *_pSession << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", use(t), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + TupleType ret(-10,-11,-12,-13,-14,-15,-16,-17,-18,-19); + assert (ret != t); + try { *_pSession << "SELECT * FROM Tuples", into(ret), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (ret == t); +} + +void SQLExecutor::tupleVector() +{ + typedef Tuple TupleType; + std::string funct = "tupleVector()"; + TupleType t(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19); + Tuple + t10(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29); + TupleType t100(100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119); + std::vector v; + v.push_back(t); + v.push_back(t10); + v.push_back(t100); + + try { *_pSession << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", use(v), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Tuples", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (v.size() == count); + + std::vector > ret; + try { *_pSession << "SELECT * FROM Tuples", into(ret), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (ret == v); +} + + +void SQLExecutor::internalExtraction() +{ + std::string funct = "internalExtraction()"; + std::vector > v; + v.push_back(Tuple(1, 1.5f, "3")); + v.push_back(Tuple(2, 2.5f, "4")); + v.push_back(Tuple(3, 3.5f, "5")); + v.push_back(Tuple(4, 4.5f, "6")); + + try { *_pSession << "INSERT INTO Vectors VALUES (?,?,?)", use(v), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + + try + { + Statement stmt = (*_pSession << "SELECT * FROM Vectors", now); + RecordSet rset(stmt); + + assert (3 == rset.columnCount()); + assert (4 == rset.rowCount()); + + int curVal = 3; + do + { + assert (rset["str0"] == curVal); + ++curVal; + } while (rset.moveNext()); + + rset.moveFirst(); + assert (rset["str0"] == "3"); + rset.moveLast(); + assert (rset["str0"] == "6"); + + RecordSet rset2(rset); + assert (3 == rset2.columnCount()); + assert (4 == rset2.rowCount()); + + int i = rset.value(0,0); + assert (1 == i); + + std::string s = rset.value(0,0); + assert ("1" == s); + + int a = rset.value(0,2); + assert (3 == a); + + try + { + double d = rset.value(1,1); + assert (2.5 == d); + } + catch (BadCastException&) + { + float f = rset.value(1,1); + assert (2.5 == f); + } + + s = rset.value(2,2); + assert ("5" == s); + i = rset.value("str0", 2); + assert (5 == i); + + const Column& col = rset.column(0); + Column::Iterator it = col.begin(); + Column::Iterator end = col.end(); + for (int i = 1; it != end; ++it, ++i) + assert (*it == i); + + rset = (*_pSession << "SELECT COUNT(*) AS cnt FROM Vectors", now); + + //various results for COUNT(*) are received from different drivers + try + { + //this is what most drivers will return + int i = rset.value(0,0); + assert (4 == i); + } + catch(BadCastException&) + { + try + { + //this is for Oracle + double i = rset.value(0,0); + assert (4 == int(i)); + } + catch(BadCastException&) + { + //this is for PostgreSQL + Poco::Int64 big = rset.value(0,0); + assert (4 == big); + } + } + + s = rset.value("cnt", 0).convert(); + assert ("4" == s); + + try { const Column& col1 = rset.column(100); fail ("must fail"); } + catch (RangeException&) { } + + try { rset.value(0,0); fail ("must fail"); } + catch (BadCastException&) { } + + stmt = (*_pSession << "DELETE FROM Vectors", now); + rset = stmt; + + try { const Column& col1 = rset.column(0); fail ("must fail"); } + catch (RangeException&) { } + } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } +} + + +void SQLExecutor::doNull() +{ + std::string funct = "null()"; + + *_pSession << "INSERT INTO Vectors VALUES (null, null, null)", now; + + int count = 0; + try { *_pSession << "SELECT COUNT(*) FROM Vectors", into(count), now; } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + assert (count == 1); + + int i0 = 0; + Statement stmt1 = (*_pSession << "SELECT i0 FROM Vectors", into(i0, -1)); + try { stmt1.execute(); } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + poco_assert (i0 == -1); + + float flt0 = 0; + Statement stmt2 = (*_pSession << "SELECT flt0 FROM Vectors", into(flt0, 3.25f)); + try { stmt2.execute(); } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + poco_assert (flt0 == 3.25); + + std::string str0("string"); + Statement stmt3 = (*_pSession << "SELECT str0 FROM Vectors", into(str0, std::string("DEFAULT"))); + try { stmt3.execute(); } + catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); } + catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); } + poco_assert (str0 == "DEFAULT"); +} diff --git a/Data/MySQL/testsuite/src/SQLExecutor.h b/Data/MySQL/testsuite/src/SQLExecutor.h index 6bcf0da41..3456bf875 100644 --- a/Data/MySQL/testsuite/src/SQLExecutor.h +++ b/Data/MySQL/testsuite/src/SQLExecutor.h @@ -1,119 +1,119 @@ -// -// SQLExecutor.h -// -// $Id: //poco/1.3/Data/MySQL/testsuite/src/SQLExecutor.h#1 $ -// -// Definition of the SQLExecutor class. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef SQLExecutor_INCLUDED -#define SQLExecutor_INCLUDED - - -#include "Poco/Data/MySQL/MySQL.h" -#include "Poco/Data/Session.h" - - -class SQLExecutor: public CppUnit::TestCase -{ -public: - enum DataBinding - { - PB_IMMEDIATE, - PB_AT_EXEC - }; - - enum DataExtraction - { - DE_MANUAL, - DE_BOUND - }; - - SQLExecutor(const std::string& name, Poco::Data::Session* _pSession); - ~SQLExecutor(); - - void bareboneMySQLTest(const char* host, const char* user, const char* pwd, const char* db, int port, const char* tableCreateString); - /// This function uses "bare bone" MySQL API calls (i.e. calls are not - /// "wrapped" in PocoData framework structures). - /// The purpose of the function is to verify that driver behaves - /// correctly. If this test passes, subsequent tests failures are likely ours. - - void simpleAccess(); - void complexType(); - void simpleAccessVector(); - void complexTypeVector(); - void insertVector(); - void insertEmptyVector(); - - void insertSingleBulk(); - void insertSingleBulkVec(); - - void limits(); - void limitOnce(); - void limitPrepare(); - void limitZero(); - void prepare(); - - void setSimple(); - void setComplex(); - void setComplexUnique(); - void multiSetSimple(); - void multiSetComplex(); - void mapComplex(); - void mapComplexUnique(); - void multiMapComplex(); - void selectIntoSingle(); - void selectIntoSingleStep(); - void selectIntoSingleFail(); - void lowerLimitOk(); - void lowerLimitFail(); - void combinedLimits(); - void combinedIllegalLimits(); - void ranges(); - void illegalRange(); - void singleSelect(); - void emptyDB(); - - void blob(int bigSize = 1024); - void blobStmt(); - - void floats(); - void doubles(); - void tuples(); - void tupleVector(); - - void internalExtraction(); - void doNull(); - -private: - Poco::Data::Session* _pSession; -}; - - -#endif // SQLExecutor_INCLUDED +// +// SQLExecutor.h +// +// $Id: //poco/1.3/Data/MySQL/testsuite/src/SQLExecutor.h#2 $ +// +// Definition of the SQLExecutor class. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef SQLExecutor_INCLUDED +#define SQLExecutor_INCLUDED + + +#include "Poco/Data/MySQL/MySQL.h" +#include "Poco/Data/Session.h" + + +class SQLExecutor: public CppUnit::TestCase +{ +public: + enum DataBinding + { + PB_IMMEDIATE, + PB_AT_EXEC + }; + + enum DataExtraction + { + DE_MANUAL, + DE_BOUND + }; + + SQLExecutor(const std::string& name, Poco::Data::Session* _pSession); + ~SQLExecutor(); + + void bareboneMySQLTest(const char* host, const char* user, const char* pwd, const char* db, int port, const char* tableCreateString); + /// This function uses "bare bone" MySQL API calls (i.e. calls are not + /// "wrapped" in PocoData framework structures). + /// The purpose of the function is to verify that driver behaves + /// correctly. If this test passes, subsequent tests failures are likely ours. + + void simpleAccess(); + void complexType(); + void simpleAccessVector(); + void complexTypeVector(); + void insertVector(); + void insertEmptyVector(); + + void insertSingleBulk(); + void insertSingleBulkVec(); + + void limits(); + void limitOnce(); + void limitPrepare(); + void limitZero(); + void prepare(); + + void setSimple(); + void setComplex(); + void setComplexUnique(); + void multiSetSimple(); + void multiSetComplex(); + void mapComplex(); + void mapComplexUnique(); + void multiMapComplex(); + void selectIntoSingle(); + void selectIntoSingleStep(); + void selectIntoSingleFail(); + void lowerLimitOk(); + void lowerLimitFail(); + void combinedLimits(); + void combinedIllegalLimits(); + void ranges(); + void illegalRange(); + void singleSelect(); + void emptyDB(); + + void blob(int bigSize = 1024); + void blobStmt(); + + void floats(); + void doubles(); + void tuples(); + void tupleVector(); + + void internalExtraction(); + void doNull(); + +private: + Poco::Data::Session* _pSession; +}; + + +#endif // SQLExecutor_INCLUDED diff --git a/Data/MySQL/testsuite/src/WinDriver.cpp b/Data/MySQL/testsuite/src/WinDriver.cpp index ae21045ab..aded24557 100644 --- a/Data/MySQL/testsuite/src/WinDriver.cpp +++ b/Data/MySQL/testsuite/src/WinDriver.cpp @@ -1,50 +1,50 @@ -// -// WinDriver.cpp -// -// $Id: //poco/1.3/Data/MySQL/testsuite/src/WinDriver.cpp#1 $ -// -// Windows test driver for Poco MySQL. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "WinTestRunner/WinTestRunner.h" -#include "MySQLTestSuite.h" - - -class TestDriver: public CppUnit::WinTestRunnerApp -{ - void TestMain() - { - CppUnit::WinTestRunner runner; - runner.addTest(MySQLTestSuite::suite()); - runner.run(); - } -}; - - -TestDriver theDriver; +// +// WinDriver.cpp +// +// $Id: //poco/1.3/Data/MySQL/testsuite/src/WinDriver.cpp#2 $ +// +// Windows test driver for Poco MySQL. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "WinTestRunner/WinTestRunner.h" +#include "MySQLTestSuite.h" + + +class TestDriver: public CppUnit::WinTestRunnerApp +{ + void TestMain() + { + CppUnit::WinTestRunner runner; + runner.addTest(MySQLTestSuite::suite()); + runner.run(); + } +}; + + +TestDriver theDriver; diff --git a/Data/ODBC/ODBC_vs90.sln b/Data/ODBC/ODBC_vs90.sln new file mode 100644 index 000000000..6921511eb --- /dev/null +++ b/Data/ODBC/ODBC_vs90.sln @@ -0,0 +1,28 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestSuite", "testsuite\TestSuite_vs90.vcproj", "{1B30A91B-375F-11DB-837B-00123FC423B5}" + ProjectSection(ProjectDependencies) = postProject + {1B29820D-375F-11DB-837B-00123FC423B5} = {1B29820D-375F-11DB-837B-00123FC423B5} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ODBC", "ODBC_vs90.vcproj", "{1B29820D-375F-11DB-837B-00123FC423B5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|Win32 = debug_shared|Win32 + release_shared|Win32 = release_shared|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1B30A91B-375F-11DB-837B-00123FC423B5}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {1B30A91B-375F-11DB-837B-00123FC423B5}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {1B30A91B-375F-11DB-837B-00123FC423B5}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {1B30A91B-375F-11DB-837B-00123FC423B5}.release_shared|Win32.Build.0 = release_shared|Win32 + {1B29820D-375F-11DB-837B-00123FC423B5}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {1B29820D-375F-11DB-837B-00123FC423B5}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {1B29820D-375F-11DB-837B-00123FC423B5}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {1B29820D-375F-11DB-837B-00123FC423B5}.release_shared|Win32.Build.0 = release_shared|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Data/ODBC/ODBC_vs90.vcproj b/Data/ODBC/ODBC_vs90.vcproj new file mode 100644 index 000000000..d8af71a7a --- /dev/null +++ b/Data/ODBC/ODBC_vs90.vcproj @@ -0,0 +1,341 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Data/ODBC/src/DataTypes.cpp b/Data/ODBC/src/DataTypes.cpp index e51b8e279..e01f9010e 100644 --- a/Data/ODBC/src/DataTypes.cpp +++ b/Data/ODBC/src/DataTypes.cpp @@ -1,118 +1,118 @@ -// -// DataTypes.cpp -// -// $Id: //poco/1.3/Data/ODBC/src/DataTypes.cpp#3 $ -// -// Library: ODBC -// Package: ODBC -// Module: DataTypes -// -// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/ODBC/DataTypes.h" -#include "Poco/Format.h" -#include "Poco/Exception.h" - - -namespace Poco { -namespace Data { -namespace ODBC { - - -DataTypes::DataTypes() -{ - _cDataTypes.insert(ValueType(SQL_CHAR, SQL_C_CHAR)); - _cDataTypes.insert(ValueType(SQL_VARCHAR, SQL_C_CHAR)); - _cDataTypes.insert(ValueType(SQL_LONGVARCHAR, SQL_C_CHAR)); - _cDataTypes.insert(ValueType(SQL_DECIMAL, SQL_C_DOUBLE)); - _cDataTypes.insert(ValueType(SQL_NUMERIC, SQL_C_DOUBLE)); - _cDataTypes.insert(ValueType(SQL_BIT, SQL_C_BIT)); - _cDataTypes.insert(ValueType(SQL_TINYINT, SQL_C_STINYINT)); - _cDataTypes.insert(ValueType(SQL_SMALLINT, SQL_C_SSHORT)); - _cDataTypes.insert(ValueType(SQL_INTEGER, SQL_C_SLONG)); - _cDataTypes.insert(ValueType(SQL_BIGINT, SQL_C_SBIGINT)); - _cDataTypes.insert(ValueType(SQL_REAL, SQL_C_FLOAT)); - _cDataTypes.insert(ValueType(SQL_FLOAT, SQL_C_DOUBLE)); - _cDataTypes.insert(ValueType(SQL_DOUBLE, SQL_C_DOUBLE)); - _cDataTypes.insert(ValueType(SQL_BINARY, SQL_C_BINARY)); - _cDataTypes.insert(ValueType(SQL_VARBINARY, SQL_C_BINARY)); - _cDataTypes.insert(ValueType(SQL_LONGVARBINARY, SQL_C_BINARY)); - _cDataTypes.insert(ValueType(SQL_TYPE_DATE, SQL_C_TYPE_DATE)); - _cDataTypes.insert(ValueType(SQL_TYPE_TIME, SQL_C_TYPE_TIME)); - _cDataTypes.insert(ValueType(SQL_TYPE_TIMESTAMP, SQL_C_TYPE_TIMESTAMP)); - - _sqlDataTypes.insert(ValueType(SQL_C_CHAR, SQL_LONGVARCHAR)); - _sqlDataTypes.insert(ValueType(SQL_C_BIT, SQL_BIT)); - _sqlDataTypes.insert(ValueType(SQL_C_TINYINT, SQL_TINYINT)); - _sqlDataTypes.insert(ValueType(SQL_C_STINYINT, SQL_TINYINT)); - _sqlDataTypes.insert(ValueType(SQL_C_UTINYINT, SQL_TINYINT)); - _sqlDataTypes.insert(ValueType(SQL_C_SHORT, SQL_SMALLINT)); - _sqlDataTypes.insert(ValueType(SQL_C_SSHORT, SQL_SMALLINT)); - _sqlDataTypes.insert(ValueType(SQL_C_USHORT, SQL_SMALLINT)); - _sqlDataTypes.insert(ValueType(SQL_C_LONG, SQL_INTEGER)); - _sqlDataTypes.insert(ValueType(SQL_C_SLONG, SQL_INTEGER)); - _sqlDataTypes.insert(ValueType(SQL_C_ULONG, SQL_INTEGER)); - _sqlDataTypes.insert(ValueType(SQL_C_SBIGINT, SQL_BIGINT)); - _sqlDataTypes.insert(ValueType(SQL_C_UBIGINT, SQL_BIGINT)); - _sqlDataTypes.insert(ValueType(SQL_C_FLOAT, SQL_REAL)); - _sqlDataTypes.insert(ValueType(SQL_C_DOUBLE, SQL_DOUBLE)); - _sqlDataTypes.insert(ValueType(SQL_C_BINARY, SQL_LONGVARBINARY)); - _sqlDataTypes.insert(ValueType(SQL_C_TYPE_DATE, SQL_TYPE_DATE)); - _sqlDataTypes.insert(ValueType(SQL_C_TYPE_TIME, SQL_TYPE_TIME)); - _sqlDataTypes.insert(ValueType(SQL_C_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP)); -} - - -DataTypes::~DataTypes() -{ -} - - -int DataTypes::cDataType(int sqlDataType) const -{ - DataTypeMap::const_iterator it = _cDataTypes.find(sqlDataType); - - if (_cDataTypes.end() == it) - throw NotFoundException(format("C data type not found for SQL data type: %d", sqlDataType)); - - return it->second; -} - - -int DataTypes::sqlDataType(int cDataType) const -{ - DataTypeMap::const_iterator it = _sqlDataTypes.find(cDataType); - - if (_sqlDataTypes.end() == it) - throw NotFoundException(format("SQL data type not found for C data type: %d", cDataType)); - - return it->second; -} - - -} } } // namespace Poco::Data::ODBC +// +// DataTypes.cpp +// +// $Id: //poco/1.3/Data/ODBC/src/DataTypes.cpp#4 $ +// +// Library: ODBC +// Package: ODBC +// Module: DataTypes +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/ODBC/DataTypes.h" +#include "Poco/Format.h" +#include "Poco/Exception.h" + + +namespace Poco { +namespace Data { +namespace ODBC { + + +DataTypes::DataTypes() +{ + _cDataTypes.insert(ValueType(SQL_CHAR, SQL_C_CHAR)); + _cDataTypes.insert(ValueType(SQL_VARCHAR, SQL_C_CHAR)); + _cDataTypes.insert(ValueType(SQL_LONGVARCHAR, SQL_C_CHAR)); + _cDataTypes.insert(ValueType(SQL_DECIMAL, SQL_C_DOUBLE)); + _cDataTypes.insert(ValueType(SQL_NUMERIC, SQL_C_DOUBLE)); + _cDataTypes.insert(ValueType(SQL_BIT, SQL_C_BIT)); + _cDataTypes.insert(ValueType(SQL_TINYINT, SQL_C_STINYINT)); + _cDataTypes.insert(ValueType(SQL_SMALLINT, SQL_C_SSHORT)); + _cDataTypes.insert(ValueType(SQL_INTEGER, SQL_C_SLONG)); + _cDataTypes.insert(ValueType(SQL_BIGINT, SQL_C_SBIGINT)); + _cDataTypes.insert(ValueType(SQL_REAL, SQL_C_FLOAT)); + _cDataTypes.insert(ValueType(SQL_FLOAT, SQL_C_DOUBLE)); + _cDataTypes.insert(ValueType(SQL_DOUBLE, SQL_C_DOUBLE)); + _cDataTypes.insert(ValueType(SQL_BINARY, SQL_C_BINARY)); + _cDataTypes.insert(ValueType(SQL_VARBINARY, SQL_C_BINARY)); + _cDataTypes.insert(ValueType(SQL_LONGVARBINARY, SQL_C_BINARY)); + _cDataTypes.insert(ValueType(SQL_TYPE_DATE, SQL_C_TYPE_DATE)); + _cDataTypes.insert(ValueType(SQL_TYPE_TIME, SQL_C_TYPE_TIME)); + _cDataTypes.insert(ValueType(SQL_TYPE_TIMESTAMP, SQL_C_TYPE_TIMESTAMP)); + + _sqlDataTypes.insert(ValueType(SQL_C_CHAR, SQL_LONGVARCHAR)); + _sqlDataTypes.insert(ValueType(SQL_C_BIT, SQL_BIT)); + _sqlDataTypes.insert(ValueType(SQL_C_TINYINT, SQL_TINYINT)); + _sqlDataTypes.insert(ValueType(SQL_C_STINYINT, SQL_TINYINT)); + _sqlDataTypes.insert(ValueType(SQL_C_UTINYINT, SQL_TINYINT)); + _sqlDataTypes.insert(ValueType(SQL_C_SHORT, SQL_SMALLINT)); + _sqlDataTypes.insert(ValueType(SQL_C_SSHORT, SQL_SMALLINT)); + _sqlDataTypes.insert(ValueType(SQL_C_USHORT, SQL_SMALLINT)); + _sqlDataTypes.insert(ValueType(SQL_C_LONG, SQL_INTEGER)); + _sqlDataTypes.insert(ValueType(SQL_C_SLONG, SQL_INTEGER)); + _sqlDataTypes.insert(ValueType(SQL_C_ULONG, SQL_INTEGER)); + _sqlDataTypes.insert(ValueType(SQL_C_SBIGINT, SQL_BIGINT)); + _sqlDataTypes.insert(ValueType(SQL_C_UBIGINT, SQL_BIGINT)); + _sqlDataTypes.insert(ValueType(SQL_C_FLOAT, SQL_REAL)); + _sqlDataTypes.insert(ValueType(SQL_C_DOUBLE, SQL_DOUBLE)); + _sqlDataTypes.insert(ValueType(SQL_C_BINARY, SQL_LONGVARBINARY)); + _sqlDataTypes.insert(ValueType(SQL_C_TYPE_DATE, SQL_TYPE_DATE)); + _sqlDataTypes.insert(ValueType(SQL_C_TYPE_TIME, SQL_TYPE_TIME)); + _sqlDataTypes.insert(ValueType(SQL_C_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP)); +} + + +DataTypes::~DataTypes() +{ +} + + +int DataTypes::cDataType(int sqlDataType) const +{ + DataTypeMap::const_iterator it = _cDataTypes.find(sqlDataType); + + if (_cDataTypes.end() == it) + throw NotFoundException(format("C data type not found for SQL data type: %d", sqlDataType)); + + return it->second; +} + + +int DataTypes::sqlDataType(int cDataType) const +{ + DataTypeMap::const_iterator it = _sqlDataTypes.find(cDataType); + + if (_sqlDataTypes.end() == it) + throw NotFoundException(format("SQL data type not found for C data type: %d", cDataType)); + + return it->second; +} + + +} } } // namespace Poco::Data::ODBC diff --git a/Data/ODBC/src/Extractor.cpp b/Data/ODBC/src/Extractor.cpp index ac8790399..5ccc8bde4 100644 --- a/Data/ODBC/src/Extractor.cpp +++ b/Data/ODBC/src/Extractor.cpp @@ -1,383 +1,383 @@ -// -// Extractor.cpp -// -// $Id: //poco/1.3/Data/ODBC/src/Extractor.cpp#4 $ -// -// Library: ODBC -// Package: ODBC -// Module: Extractor -// -// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/ODBC/Extractor.h" -#include "Poco/Data/ODBC/ODBCColumn.h" -#include "Poco/Data/ODBC/Utility.h" -#include "Poco/Data/ODBC/ODBCException.h" -#include "Poco/Data/BLOB.h" -#include "Poco/Buffer.h" -#include "Poco/Exception.h" - - -namespace Poco { -namespace Data { -namespace ODBC { - - -const std::string Extractor::FLD_SIZE_EXCEEDED_FMT = "Specified data size (%z bytes) " - "exceeds maximum value (%z).\n" - "Use Session.setProperty(\"maxFieldSize\", value) " - "to increase the maximum allowed data size\n"; - - -Extractor::Extractor(const StatementHandle& rStmt, - Preparation& rPreparation): - _rStmt(rStmt), - _rPreparation(rPreparation), - _dataExtraction(rPreparation.getDataExtraction()) -{ -} - - -Extractor::~Extractor() -{ -} - - -template<> -bool Extractor::extractBoundImpl(std::size_t pos, std::string& val) -{ - std::size_t dataSize = _rPreparation.actualDataSize(pos); - char*& sp = RefAnyCast(_rPreparation[pos]); - poco_check_ptr (sp); - std::size_t len = strlen(sp); - if (len < dataSize) dataSize = len; - checkDataSize(dataSize); - val.assign(sp, dataSize); - return true; -} - - -template<> -bool Extractor::extractBoundImpl(std::size_t pos, Poco::Data::BLOB& val) -{ - std::size_t dataSize = _rPreparation.actualDataSize(pos); - checkDataSize(dataSize); - char*& sp = RefAnyCast(_rPreparation[pos]); - poco_check_ptr (sp); - val.assignRaw(sp, dataSize); - return true; -} - - -template<> -bool Extractor::extractManualImpl(std::size_t pos, std::string& val, SQLSMALLINT cType) -{ - std::size_t maxSize = _rPreparation.getMaxFieldSize(); - std::size_t fetchedSize = 0; - std::size_t totalSize = 0; - - SQLLEN len; - Poco::Buffer apChar(CHUNK_SIZE); - char* pChar = apChar.begin(); - SQLRETURN rc = 0; - val.clear(); - - do - { - memset(pChar, 0, CHUNK_SIZE); - len = 0; - rc = SQLGetData(_rStmt, - (SQLUSMALLINT) pos + 1, - cType, //C data type - pChar, //returned value - CHUNK_SIZE, //buffer length - &len); //length indicator - - if (SQL_NO_DATA != rc && Utility::isError(rc)) - throw StatementException(_rStmt, "SQLGetData()"); - - if (SQL_NO_TOTAL == len)//unknown length, throw - throw UnknownDataLengthException("Could not determine returned data length."); - - if (SQL_NO_DATA == rc || SQL_NULL_DATA == len || !len) - break; - - fetchedSize = len > CHUNK_SIZE ? CHUNK_SIZE : len; - totalSize += fetchedSize; - if (totalSize <= maxSize) val.append(pChar, fetchedSize); - else throw DataException(format(FLD_SIZE_EXCEEDED_FMT, - fetchedSize, - maxSize)); - - }while (true); - - return true; -} - - -template<> -bool Extractor::extractManualImpl(std::size_t pos, - Poco::Data::BLOB& val, - SQLSMALLINT cType) -{ - std::size_t maxSize = _rPreparation.getMaxFieldSize(); - std::size_t fetchedSize = 0; - std::size_t totalSize = 0; - - SQLLEN len; - Poco::Buffer apChar(CHUNK_SIZE); - char* pChar = apChar.begin(); - SQLRETURN rc = 0; - val.clear(); - - do - { - memset(pChar, 0, CHUNK_SIZE); - len = 0; - rc = SQLGetData(_rStmt, - (SQLUSMALLINT) pos + 1, - cType, //C data type - pChar, //returned value - CHUNK_SIZE, //buffer length - &len); //length indicator - - if (SQL_NO_DATA != rc && Utility::isError(rc)) - throw StatementException(_rStmt, "SQLGetData()"); - - if (SQL_NO_TOTAL == len)//unknown length, throw - throw UnknownDataLengthException("Could not determine returned data length."); - - if (SQL_NO_DATA == rc || SQL_NULL_DATA == len || !len) - break; - - fetchedSize = len > CHUNK_SIZE ? CHUNK_SIZE : len; - totalSize += fetchedSize; - if (totalSize <= maxSize) val.appendRaw(pChar, fetchedSize); - else throw DataException(format(FLD_SIZE_EXCEEDED_FMT, - fetchedSize, - maxSize)); - - }while (true); - - return true; -} - - -bool Extractor::extract(std::size_t pos, Poco::Int32& val) -{ - if (Preparation::DE_MANUAL == _dataExtraction) - return extractManualImpl(pos, val, SQL_C_SLONG); - else - return extractBoundImpl(pos, val); - -} - - -bool Extractor::extract(std::size_t pos, Poco::Int64& val) -{ - if (Preparation::DE_MANUAL == _dataExtraction) - return extractManualImpl(pos, val, SQL_C_SBIGINT); - else - return extractBoundImpl(pos, val); -} - - -bool Extractor::extract(std::size_t pos, double& val) -{ - if (Preparation::DE_MANUAL == _dataExtraction) - return extractManualImpl(pos, val, SQL_C_DOUBLE); - else - return extractBoundImpl(pos, val); -} - - -bool Extractor::extract(std::size_t pos, std::string& val) -{ - if (Preparation::DE_MANUAL == _dataExtraction) - return extractManualImpl(pos, val, SQL_C_CHAR); - else - return extractBoundImpl(pos, val); -} - - -bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val) -{ - if (Preparation::DE_MANUAL == _dataExtraction) - return extractManualImpl(pos, val, SQL_C_BINARY); - else - return extractBoundImpl(pos, val); -} - - -bool Extractor::extract(std::size_t pos, Poco::Int8& val) -{ - if (Preparation::DE_MANUAL == _dataExtraction) - return extractManualImpl(pos, val, SQL_C_STINYINT); - else - return extractBoundImpl(pos, val); -} - - -bool Extractor::extract(std::size_t pos, Poco::UInt8& val) -{ - if (Preparation::DE_MANUAL == _dataExtraction) - return extractManualImpl(pos, val, SQL_C_UTINYINT); - else - return extractBoundImpl(pos, val); -} - - -bool Extractor::extract(std::size_t pos, Poco::Int16& val) -{ - if (Preparation::DE_MANUAL == _dataExtraction) - return extractManualImpl(pos, val, SQL_C_SSHORT); - else - return extractBoundImpl(pos, val); -} - - -bool Extractor::extract(std::size_t pos, Poco::UInt16& val) -{ - if (Preparation::DE_MANUAL == _dataExtraction) - return extractManualImpl(pos, val, SQL_C_USHORT); - else - return extractBoundImpl(pos, val); -} - - -bool Extractor::extract(std::size_t pos, Poco::UInt32& val) -{ - if (Preparation::DE_MANUAL == _dataExtraction) - return extractManualImpl(pos, val, SQL_C_ULONG); - else - return extractBoundImpl(pos, val); -} - - -bool Extractor::extract(std::size_t pos, Poco::UInt64& val) -{ - if (Preparation::DE_MANUAL == _dataExtraction) - return extractManualImpl(pos, val, SQL_C_SBIGINT); - else - return extractBoundImpl(pos, val); -} - - -bool Extractor::extract(std::size_t pos, bool& val) -{ - if (Preparation::DE_MANUAL == _dataExtraction) - return extractManualImpl(pos, val, Utility::boolDataType); - else - return extractBoundImpl(pos, val); -} - - -bool Extractor::extract(std::size_t pos, float& val) -{ - if (Preparation::DE_MANUAL == _dataExtraction) - return extractManualImpl(pos, val, SQL_C_FLOAT); - else - return extractBoundImpl(pos, val); -} - - -bool Extractor::extract(std::size_t pos, char& val) -{ - if (Preparation::DE_MANUAL == _dataExtraction) - return extractManualImpl(pos, val, SQL_C_STINYINT); - else - return extractBoundImpl(pos, val); -} - - -bool Extractor::extract(std::size_t pos, Poco::Any& val) -{ - ODBCColumn column(_rStmt, pos); - - switch (column.type()) - { - case MetaColumn::FDT_INT8: - { Poco::Int8 i = 0; extract(pos, i); val = i; return true; } - - case MetaColumn::FDT_UINT8: - { Poco::UInt8 i = 0; extract(pos, i); val = i; return true; } - - case MetaColumn::FDT_INT16: - { Poco::Int16 i = 0; extract(pos, i); val = i; return true; } - - case MetaColumn::FDT_UINT16: - { Poco::UInt16 i = 0; extract(pos, i); val = i; return true; } - - case MetaColumn::FDT_INT32: - { Poco::Int32 i = 0; extract(pos, i); val = i; return true; } - - case MetaColumn::FDT_UINT32: - { Poco::UInt32 i = 0; extract(pos, i); val = i; return true; } - - case MetaColumn::FDT_INT64: - { Poco::Int64 i = 0; extract(pos, i); val = i; return true; } - - case MetaColumn::FDT_UINT64: - { Poco::UInt64 i = 0; extract(pos, i); val = i; return true; } - - case MetaColumn::FDT_BOOL: - { bool b; extract(pos, b); val = b; return true; } - - case MetaColumn::FDT_FLOAT: - { float f; extract(pos, f); val = f; return true; } - - case MetaColumn::FDT_DOUBLE: - { double d; extract(pos, d); val = d; return true; } - - case MetaColumn::FDT_STRING: - { std::string s; extract(pos, s); val = s; return true; } - - case MetaColumn::FDT_BLOB: - { Poco::Data::BLOB b; extract(pos, b); val = b; return true; } - - default: - throw DataFormatException("Unsupported data type."); - } - - return false; -} - - -void Extractor::checkDataSize(std::size_t size) -{ - std::size_t maxSize = _rPreparation.getMaxFieldSize(); - if (size > maxSize) - { - throw DataException(format(FLD_SIZE_EXCEEDED_FMT, - size, - maxSize)); - } -} - - -} } } // namespace Poco::Data::ODBC +// +// Extractor.cpp +// +// $Id: //poco/1.3/Data/ODBC/src/Extractor.cpp#5 $ +// +// Library: ODBC +// Package: ODBC +// Module: Extractor +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/ODBC/Extractor.h" +#include "Poco/Data/ODBC/ODBCColumn.h" +#include "Poco/Data/ODBC/Utility.h" +#include "Poco/Data/ODBC/ODBCException.h" +#include "Poco/Data/BLOB.h" +#include "Poco/Buffer.h" +#include "Poco/Exception.h" + + +namespace Poco { +namespace Data { +namespace ODBC { + + +const std::string Extractor::FLD_SIZE_EXCEEDED_FMT = "Specified data size (%z bytes) " + "exceeds maximum value (%z).\n" + "Use Session.setProperty(\"maxFieldSize\", value) " + "to increase the maximum allowed data size\n"; + + +Extractor::Extractor(const StatementHandle& rStmt, + Preparation& rPreparation): + _rStmt(rStmt), + _rPreparation(rPreparation), + _dataExtraction(rPreparation.getDataExtraction()) +{ +} + + +Extractor::~Extractor() +{ +} + + +template<> +bool Extractor::extractBoundImpl(std::size_t pos, std::string& val) +{ + std::size_t dataSize = _rPreparation.actualDataSize(pos); + char*& sp = RefAnyCast(_rPreparation[pos]); + poco_check_ptr (sp); + std::size_t len = strlen(sp); + if (len < dataSize) dataSize = len; + checkDataSize(dataSize); + val.assign(sp, dataSize); + return true; +} + + +template<> +bool Extractor::extractBoundImpl(std::size_t pos, Poco::Data::BLOB& val) +{ + std::size_t dataSize = _rPreparation.actualDataSize(pos); + checkDataSize(dataSize); + char*& sp = RefAnyCast(_rPreparation[pos]); + poco_check_ptr (sp); + val.assignRaw(sp, dataSize); + return true; +} + + +template<> +bool Extractor::extractManualImpl(std::size_t pos, std::string& val, SQLSMALLINT cType) +{ + std::size_t maxSize = _rPreparation.getMaxFieldSize(); + std::size_t fetchedSize = 0; + std::size_t totalSize = 0; + + SQLLEN len; + Poco::Buffer apChar(CHUNK_SIZE); + char* pChar = apChar.begin(); + SQLRETURN rc = 0; + val.clear(); + + do + { + memset(pChar, 0, CHUNK_SIZE); + len = 0; + rc = SQLGetData(_rStmt, + (SQLUSMALLINT) pos + 1, + cType, //C data type + pChar, //returned value + CHUNK_SIZE, //buffer length + &len); //length indicator + + if (SQL_NO_DATA != rc && Utility::isError(rc)) + throw StatementException(_rStmt, "SQLGetData()"); + + if (SQL_NO_TOTAL == len)//unknown length, throw + throw UnknownDataLengthException("Could not determine returned data length."); + + if (SQL_NO_DATA == rc || SQL_NULL_DATA == len || !len) + break; + + fetchedSize = len > CHUNK_SIZE ? CHUNK_SIZE : len; + totalSize += fetchedSize; + if (totalSize <= maxSize) val.append(pChar, fetchedSize); + else throw DataException(format(FLD_SIZE_EXCEEDED_FMT, + fetchedSize, + maxSize)); + + }while (true); + + return true; +} + + +template<> +bool Extractor::extractManualImpl(std::size_t pos, + Poco::Data::BLOB& val, + SQLSMALLINT cType) +{ + std::size_t maxSize = _rPreparation.getMaxFieldSize(); + std::size_t fetchedSize = 0; + std::size_t totalSize = 0; + + SQLLEN len; + Poco::Buffer apChar(CHUNK_SIZE); + char* pChar = apChar.begin(); + SQLRETURN rc = 0; + val.clear(); + + do + { + memset(pChar, 0, CHUNK_SIZE); + len = 0; + rc = SQLGetData(_rStmt, + (SQLUSMALLINT) pos + 1, + cType, //C data type + pChar, //returned value + CHUNK_SIZE, //buffer length + &len); //length indicator + + if (SQL_NO_DATA != rc && Utility::isError(rc)) + throw StatementException(_rStmt, "SQLGetData()"); + + if (SQL_NO_TOTAL == len)//unknown length, throw + throw UnknownDataLengthException("Could not determine returned data length."); + + if (SQL_NO_DATA == rc || SQL_NULL_DATA == len || !len) + break; + + fetchedSize = len > CHUNK_SIZE ? CHUNK_SIZE : len; + totalSize += fetchedSize; + if (totalSize <= maxSize) val.appendRaw(pChar, fetchedSize); + else throw DataException(format(FLD_SIZE_EXCEEDED_FMT, + fetchedSize, + maxSize)); + + }while (true); + + return true; +} + + +bool Extractor::extract(std::size_t pos, Poco::Int32& val) +{ + if (Preparation::DE_MANUAL == _dataExtraction) + return extractManualImpl(pos, val, SQL_C_SLONG); + else + return extractBoundImpl(pos, val); + +} + + +bool Extractor::extract(std::size_t pos, Poco::Int64& val) +{ + if (Preparation::DE_MANUAL == _dataExtraction) + return extractManualImpl(pos, val, SQL_C_SBIGINT); + else + return extractBoundImpl(pos, val); +} + + +bool Extractor::extract(std::size_t pos, double& val) +{ + if (Preparation::DE_MANUAL == _dataExtraction) + return extractManualImpl(pos, val, SQL_C_DOUBLE); + else + return extractBoundImpl(pos, val); +} + + +bool Extractor::extract(std::size_t pos, std::string& val) +{ + if (Preparation::DE_MANUAL == _dataExtraction) + return extractManualImpl(pos, val, SQL_C_CHAR); + else + return extractBoundImpl(pos, val); +} + + +bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val) +{ + if (Preparation::DE_MANUAL == _dataExtraction) + return extractManualImpl(pos, val, SQL_C_BINARY); + else + return extractBoundImpl(pos, val); +} + + +bool Extractor::extract(std::size_t pos, Poco::Int8& val) +{ + if (Preparation::DE_MANUAL == _dataExtraction) + return extractManualImpl(pos, val, SQL_C_STINYINT); + else + return extractBoundImpl(pos, val); +} + + +bool Extractor::extract(std::size_t pos, Poco::UInt8& val) +{ + if (Preparation::DE_MANUAL == _dataExtraction) + return extractManualImpl(pos, val, SQL_C_UTINYINT); + else + return extractBoundImpl(pos, val); +} + + +bool Extractor::extract(std::size_t pos, Poco::Int16& val) +{ + if (Preparation::DE_MANUAL == _dataExtraction) + return extractManualImpl(pos, val, SQL_C_SSHORT); + else + return extractBoundImpl(pos, val); +} + + +bool Extractor::extract(std::size_t pos, Poco::UInt16& val) +{ + if (Preparation::DE_MANUAL == _dataExtraction) + return extractManualImpl(pos, val, SQL_C_USHORT); + else + return extractBoundImpl(pos, val); +} + + +bool Extractor::extract(std::size_t pos, Poco::UInt32& val) +{ + if (Preparation::DE_MANUAL == _dataExtraction) + return extractManualImpl(pos, val, SQL_C_ULONG); + else + return extractBoundImpl(pos, val); +} + + +bool Extractor::extract(std::size_t pos, Poco::UInt64& val) +{ + if (Preparation::DE_MANUAL == _dataExtraction) + return extractManualImpl(pos, val, SQL_C_SBIGINT); + else + return extractBoundImpl(pos, val); +} + + +bool Extractor::extract(std::size_t pos, bool& val) +{ + if (Preparation::DE_MANUAL == _dataExtraction) + return extractManualImpl(pos, val, Utility::boolDataType); + else + return extractBoundImpl(pos, val); +} + + +bool Extractor::extract(std::size_t pos, float& val) +{ + if (Preparation::DE_MANUAL == _dataExtraction) + return extractManualImpl(pos, val, SQL_C_FLOAT); + else + return extractBoundImpl(pos, val); +} + + +bool Extractor::extract(std::size_t pos, char& val) +{ + if (Preparation::DE_MANUAL == _dataExtraction) + return extractManualImpl(pos, val, SQL_C_STINYINT); + else + return extractBoundImpl(pos, val); +} + + +bool Extractor::extract(std::size_t pos, Poco::Any& val) +{ + ODBCColumn column(_rStmt, pos); + + switch (column.type()) + { + case MetaColumn::FDT_INT8: + { Poco::Int8 i = 0; extract(pos, i); val = i; return true; } + + case MetaColumn::FDT_UINT8: + { Poco::UInt8 i = 0; extract(pos, i); val = i; return true; } + + case MetaColumn::FDT_INT16: + { Poco::Int16 i = 0; extract(pos, i); val = i; return true; } + + case MetaColumn::FDT_UINT16: + { Poco::UInt16 i = 0; extract(pos, i); val = i; return true; } + + case MetaColumn::FDT_INT32: + { Poco::Int32 i = 0; extract(pos, i); val = i; return true; } + + case MetaColumn::FDT_UINT32: + { Poco::UInt32 i = 0; extract(pos, i); val = i; return true; } + + case MetaColumn::FDT_INT64: + { Poco::Int64 i = 0; extract(pos, i); val = i; return true; } + + case MetaColumn::FDT_UINT64: + { Poco::UInt64 i = 0; extract(pos, i); val = i; return true; } + + case MetaColumn::FDT_BOOL: + { bool b; extract(pos, b); val = b; return true; } + + case MetaColumn::FDT_FLOAT: + { float f; extract(pos, f); val = f; return true; } + + case MetaColumn::FDT_DOUBLE: + { double d; extract(pos, d); val = d; return true; } + + case MetaColumn::FDT_STRING: + { std::string s; extract(pos, s); val = s; return true; } + + case MetaColumn::FDT_BLOB: + { Poco::Data::BLOB b; extract(pos, b); val = b; return true; } + + default: + throw DataFormatException("Unsupported data type."); + } + + return false; +} + + +void Extractor::checkDataSize(std::size_t size) +{ + std::size_t maxSize = _rPreparation.getMaxFieldSize(); + if (size > maxSize) + { + throw DataException(format(FLD_SIZE_EXCEEDED_FMT, + size, + maxSize)); + } +} + + +} } } // namespace Poco::Data::ODBC diff --git a/Data/ODBC/src/ODBCColumn.cpp b/Data/ODBC/src/ODBCColumn.cpp index dac407883..f9d2ec3c4 100644 --- a/Data/ODBC/src/ODBCColumn.cpp +++ b/Data/ODBC/src/ODBCColumn.cpp @@ -1,145 +1,145 @@ -// -// ODBCColumn.cpp -// -// $Id: //poco/1.3/Data/ODBC/src/ODBCColumn.cpp#5 $ -// -// Library: ODBC -// Package: ODBC -// Module: ODBCColumn -// -// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/ODBC/ODBCColumn.h" -#include "Poco/Data/ODBC/Utility.h" - - -namespace Poco { -namespace Data { -namespace ODBC { - - -ODBCColumn::ODBCColumn(const StatementHandle& rStmt, std::size_t position) : - MetaColumn(position), - _rStmt(rStmt) -{ - init(); -} - - -ODBCColumn::~ODBCColumn() -{ -} - - -void ODBCColumn::getDescription() -{ - memset(_columnDesc.name, 0, NAME_BUFFER_LENGTH); - _columnDesc.nameBufferLength = 0; - _columnDesc.dataType = 0; - _columnDesc.size = 0; - _columnDesc.decimalDigits = 0; - _columnDesc.isNullable = 0; - - if (Utility::isError(SQLDescribeCol(_rStmt, - (SQLUSMALLINT) position() + 1, // ODBC columns are 1-based - _columnDesc.name, - NAME_BUFFER_LENGTH, - &_columnDesc.nameBufferLength, - &_columnDesc.dataType, - &_columnDesc.size, - &_columnDesc.decimalDigits, - &_columnDesc.isNullable))) - { - throw StatementException(_rStmt); - } -} - - -void ODBCColumn::init() -{ - getDescription(); - - if (Utility::isError(SQLColAttribute(_rStmt, - (SQLUSMALLINT) position() + 1, // ODBC columns are 1-based - SQL_DESC_LENGTH, - 0, - 0, - 0, - &_dataLength))) - { - throw StatementException(_rStmt); - } - - setName(std::string((char*) _columnDesc.name)); - setLength(_columnDesc.size); - setPrecision(_columnDesc.decimalDigits); - setNullable(SQL_NULLABLE == _columnDesc.isNullable); - switch(_columnDesc.dataType) - { - case SQL_CHAR: - case SQL_VARCHAR: - case SQL_LONGVARCHAR: - case -9:// SQL Server NVARCHAR - case -10:// PostgreSQL VARCHAR (without size specified) - setType(MetaColumn::FDT_STRING); break; - case SQL_TINYINT: - setType(MetaColumn::FDT_INT8); break; - case SQL_SMALLINT: - setType(MetaColumn::FDT_INT16); break; - case SQL_INTEGER: - setType(MetaColumn::FDT_INT32); break; - case SQL_BIGINT: - setType(MetaColumn::FDT_INT64); break; - - case SQL_DOUBLE: - case SQL_FLOAT: - setType(MetaColumn::FDT_DOUBLE); break; - - case SQL_NUMERIC: - case SQL_DECIMAL: - if (0 == _columnDesc.decimalDigits) - setType(MetaColumn::FDT_INT32); - else - setType(MetaColumn::FDT_DOUBLE); - - break; - - case SQL_REAL: - setType(MetaColumn::FDT_FLOAT); break; - case SQL_BINARY: - case SQL_VARBINARY: - case SQL_LONGVARBINARY: - case -98:// IBM DB2 non-standard type - setType(MetaColumn::FDT_BLOB); break; - default: - throw DataFormatException("Unsupported data type."); - } -} - - -} } } // namespace Poco::Data::ODBC +// +// ODBCColumn.cpp +// +// $Id: //poco/1.3/Data/ODBC/src/ODBCColumn.cpp#6 $ +// +// Library: ODBC +// Package: ODBC +// Module: ODBCColumn +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/ODBC/ODBCColumn.h" +#include "Poco/Data/ODBC/Utility.h" + + +namespace Poco { +namespace Data { +namespace ODBC { + + +ODBCColumn::ODBCColumn(const StatementHandle& rStmt, std::size_t position) : + MetaColumn(position), + _rStmt(rStmt) +{ + init(); +} + + +ODBCColumn::~ODBCColumn() +{ +} + + +void ODBCColumn::getDescription() +{ + memset(_columnDesc.name, 0, NAME_BUFFER_LENGTH); + _columnDesc.nameBufferLength = 0; + _columnDesc.dataType = 0; + _columnDesc.size = 0; + _columnDesc.decimalDigits = 0; + _columnDesc.isNullable = 0; + + if (Utility::isError(SQLDescribeCol(_rStmt, + (SQLUSMALLINT) position() + 1, // ODBC columns are 1-based + _columnDesc.name, + NAME_BUFFER_LENGTH, + &_columnDesc.nameBufferLength, + &_columnDesc.dataType, + &_columnDesc.size, + &_columnDesc.decimalDigits, + &_columnDesc.isNullable))) + { + throw StatementException(_rStmt); + } +} + + +void ODBCColumn::init() +{ + getDescription(); + + if (Utility::isError(SQLColAttribute(_rStmt, + (SQLUSMALLINT) position() + 1, // ODBC columns are 1-based + SQL_DESC_LENGTH, + 0, + 0, + 0, + &_dataLength))) + { + throw StatementException(_rStmt); + } + + setName(std::string((char*) _columnDesc.name)); + setLength(_columnDesc.size); + setPrecision(_columnDesc.decimalDigits); + setNullable(SQL_NULLABLE == _columnDesc.isNullable); + switch(_columnDesc.dataType) + { + case SQL_CHAR: + case SQL_VARCHAR: + case SQL_LONGVARCHAR: + case -9:// SQL Server NVARCHAR + case -10:// PostgreSQL VARCHAR (without size specified) + setType(MetaColumn::FDT_STRING); break; + case SQL_TINYINT: + setType(MetaColumn::FDT_INT8); break; + case SQL_SMALLINT: + setType(MetaColumn::FDT_INT16); break; + case SQL_INTEGER: + setType(MetaColumn::FDT_INT32); break; + case SQL_BIGINT: + setType(MetaColumn::FDT_INT64); break; + + case SQL_DOUBLE: + case SQL_FLOAT: + setType(MetaColumn::FDT_DOUBLE); break; + + case SQL_NUMERIC: + case SQL_DECIMAL: + if (0 == _columnDesc.decimalDigits) + setType(MetaColumn::FDT_INT32); + else + setType(MetaColumn::FDT_DOUBLE); + + break; + + case SQL_REAL: + setType(MetaColumn::FDT_FLOAT); break; + case SQL_BINARY: + case SQL_VARBINARY: + case SQL_LONGVARBINARY: + case -98:// IBM DB2 non-standard type + setType(MetaColumn::FDT_BLOB); break; + default: + throw DataFormatException("Unsupported data type."); + } +} + + +} } } // namespace Poco::Data::ODBC diff --git a/Data/ODBC/src/Parameter.cpp b/Data/ODBC/src/Parameter.cpp index fe2777088..616b0a28f 100644 --- a/Data/ODBC/src/Parameter.cpp +++ b/Data/ODBC/src/Parameter.cpp @@ -1,75 +1,75 @@ -// -// Parameter.cpp -// -// $Id: //poco/1.3/Data/ODBC/src/Parameter.cpp#3 $ -// -// Library: ODBC -// Package: ODBC -// Module: Parameter -// -// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/ODBC/Parameter.h" -#include "Poco/Data/ODBC/Utility.h" -#include "Poco/Data/ODBC/Error.h" -#include "Poco/Data/ODBC/ODBCException.h" - - -namespace Poco { -namespace Data { -namespace ODBC { - - -Parameter::Parameter(const StatementHandle& rStmt, std::size_t colNum) : - _rStmt(rStmt), - _number(colNum) -{ - init(); -} - - -Parameter::~Parameter() -{ -} - - -void Parameter::init() -{ - if (Utility::isError(SQLDescribeParam(_rStmt, - (SQLUSMALLINT) _number + 1, - &_dataType, - &_columnSize, - &_decimalDigits, - &_isNullable))) - { - throw StatementException(_rStmt); - } -} - - -} } } // namespace Poco::Data::ODBC +// +// Parameter.cpp +// +// $Id: //poco/1.3/Data/ODBC/src/Parameter.cpp#4 $ +// +// Library: ODBC +// Package: ODBC +// Module: Parameter +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/ODBC/Parameter.h" +#include "Poco/Data/ODBC/Utility.h" +#include "Poco/Data/ODBC/Error.h" +#include "Poco/Data/ODBC/ODBCException.h" + + +namespace Poco { +namespace Data { +namespace ODBC { + + +Parameter::Parameter(const StatementHandle& rStmt, std::size_t colNum) : + _rStmt(rStmt), + _number(colNum) +{ + init(); +} + + +Parameter::~Parameter() +{ +} + + +void Parameter::init() +{ + if (Utility::isError(SQLDescribeParam(_rStmt, + (SQLUSMALLINT) _number + 1, + &_dataType, + &_columnSize, + &_decimalDigits, + &_isNullable))) + { + throw StatementException(_rStmt); + } +} + + +} } } // namespace Poco::Data::ODBC diff --git a/Data/ODBC/testsuite/TestSuite_vs90.vcproj b/Data/ODBC/testsuite/TestSuite_vs90.vcproj new file mode 100644 index 000000000..8b6d3cde0 --- /dev/null +++ b/Data/ODBC/testsuite/TestSuite_vs90.vcproj @@ -0,0 +1,307 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Data/SQLite/SQLite_vs90.sln b/Data/SQLite/SQLite_vs90.sln new file mode 100644 index 000000000..676435de7 --- /dev/null +++ b/Data/SQLite/SQLite_vs90.sln @@ -0,0 +1,28 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite", "SQLite_vs90.vcproj", "{1B29820D-375F-11DB-837B-00123FC423B5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestSuite", "testsuite\TestSuite_vs90.vcproj", "{1B30A91B-375F-11DB-837B-00123FC423B5}" + ProjectSection(ProjectDependencies) = postProject + {1B29820D-375F-11DB-837B-00123FC423B5} = {1B29820D-375F-11DB-837B-00123FC423B5} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|Win32 = debug_shared|Win32 + release_shared|Win32 = release_shared|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1B29820D-375F-11DB-837B-00123FC423B5}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {1B29820D-375F-11DB-837B-00123FC423B5}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {1B29820D-375F-11DB-837B-00123FC423B5}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {1B29820D-375F-11DB-837B-00123FC423B5}.release_shared|Win32.Build.0 = release_shared|Win32 + {1B30A91B-375F-11DB-837B-00123FC423B5}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {1B30A91B-375F-11DB-837B-00123FC423B5}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {1B30A91B-375F-11DB-837B-00123FC423B5}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {1B30A91B-375F-11DB-837B-00123FC423B5}.release_shared|Win32.Build.0 = release_shared|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Data/SQLite/SQLite_vs90.vcproj b/Data/SQLite/SQLite_vs90.vcproj new file mode 100644 index 000000000..37c61678e --- /dev/null +++ b/Data/SQLite/SQLite_vs90.vcproj @@ -0,0 +1,301 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Data/SQLite/include/Poco/Data/SQLite/SQLiteException.h b/Data/SQLite/include/Poco/Data/SQLite/SQLiteException.h index 8604e8f56..c1be591a0 100644 --- a/Data/SQLite/include/Poco/Data/SQLite/SQLiteException.h +++ b/Data/SQLite/include/Poco/Data/SQLite/SQLiteException.h @@ -1,82 +1,82 @@ -// -// SQLiteException.h -// -// $Id: //poco/1.3/Data/SQLite/include/Poco/Data/SQLite/SQLiteException.h#3 $ -// -// Library: SQLite -// Package: SQLite -// Module: SQLiteException -// -// Definition of SQLiteException. -// -// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef SQLite_SQLiteException_INCLUDED -#define SQLite_SQLiteException_INCLUDED - - -#include "Poco/Data/SQLite/SQLite.h" -#include "Poco/Data/DataException.h" - - -namespace Poco { -namespace Data { -namespace SQLite { - - -POCO_DECLARE_EXCEPTION(SQLite_API, SQLiteException, Poco::Data::DataException) -POCO_DECLARE_EXCEPTION(SQLite_API, InvalidSQLStatementException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, InternalDBErrorException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, DBAccessDeniedException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, ExecutionAbortedException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, DBLockedException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, TableLockedException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, NoMemoryException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, ReadOnlyException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, InterruptException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, IOErrorException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, CorruptImageException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, TableNotFoundException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, DatabaseFullException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, CantOpenDBFileException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, LockProtocolException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, SchemaDiffersException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, RowTooBigException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, ConstraintViolationException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, DataTypeMismatchException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, ParameterCountMismatchException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, InvalidLibraryUseException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, OSFeaturesMissingException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, AuthorizationDeniedException, SQLiteException) -POCO_DECLARE_EXCEPTION(SQLite_API, TransactionException, SQLiteException) - - -} } } // namespace Poco::Data::SQLite - - -#endif +// +// SQLiteException.h +// +// $Id: //poco/1.3/Data/SQLite/include/Poco/Data/SQLite/SQLiteException.h#4 $ +// +// Library: SQLite +// Package: SQLite +// Module: SQLiteException +// +// Definition of SQLiteException. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef SQLite_SQLiteException_INCLUDED +#define SQLite_SQLiteException_INCLUDED + + +#include "Poco/Data/SQLite/SQLite.h" +#include "Poco/Data/DataException.h" + + +namespace Poco { +namespace Data { +namespace SQLite { + + +POCO_DECLARE_EXCEPTION(SQLite_API, SQLiteException, Poco::Data::DataException) +POCO_DECLARE_EXCEPTION(SQLite_API, InvalidSQLStatementException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, InternalDBErrorException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, DBAccessDeniedException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, ExecutionAbortedException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, DBLockedException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, TableLockedException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, NoMemoryException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, ReadOnlyException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, InterruptException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, IOErrorException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, CorruptImageException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, TableNotFoundException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, DatabaseFullException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, CantOpenDBFileException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, LockProtocolException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, SchemaDiffersException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, RowTooBigException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, ConstraintViolationException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, DataTypeMismatchException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, ParameterCountMismatchException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, InvalidLibraryUseException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, OSFeaturesMissingException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, AuthorizationDeniedException, SQLiteException) +POCO_DECLARE_EXCEPTION(SQLite_API, TransactionException, SQLiteException) + + +} } } // namespace Poco::Data::SQLite + + +#endif diff --git a/Data/SQLite/src/SQLiteException.cpp b/Data/SQLite/src/SQLiteException.cpp index 195d871bb..f207e5b45 100644 --- a/Data/SQLite/src/SQLiteException.cpp +++ b/Data/SQLite/src/SQLiteException.cpp @@ -1,73 +1,73 @@ -// -// SQLiteException.cpp -// -// $Id: //poco/1.3/Data/SQLite/src/SQLiteException.cpp#3 $ -// -// Library: SQLite -// Package: SQLite -// Module: SQLiteException -// -// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/SQLite/SQLiteException.h" -#include - - -namespace Poco { -namespace Data { -namespace SQLite { - - -POCO_IMPLEMENT_EXCEPTION(SQLiteException, Poco::Data::DataException, "Generic SQLite error") -POCO_IMPLEMENT_EXCEPTION(InvalidSQLStatementException, SQLiteException, "SQL Statement invalid") -POCO_IMPLEMENT_EXCEPTION(InternalDBErrorException, SQLiteException, "Internal error") -POCO_IMPLEMENT_EXCEPTION(DBAccessDeniedException, SQLiteException, "Access permission denied") -POCO_IMPLEMENT_EXCEPTION(ExecutionAbortedException, SQLiteException, "Execution of SQL statement aborted") -POCO_IMPLEMENT_EXCEPTION(DBLockedException, SQLiteException, "The database is locked") -POCO_IMPLEMENT_EXCEPTION(TableLockedException, SQLiteException, "A table in the database is locked") -POCO_IMPLEMENT_EXCEPTION(NoMemoryException, SQLiteException, "Out of Memory") -POCO_IMPLEMENT_EXCEPTION(ReadOnlyException, SQLiteException, "Attempt to write a readonly database") -POCO_IMPLEMENT_EXCEPTION(InterruptException, SQLiteException, "Operation terminated by an interrupt") -POCO_IMPLEMENT_EXCEPTION(IOErrorException, SQLiteException, "Some kind of disk I/O error occurred") -POCO_IMPLEMENT_EXCEPTION(CorruptImageException, SQLiteException, "The database disk image is malformed") -POCO_IMPLEMENT_EXCEPTION(TableNotFoundException, SQLiteException, "Table not found") -POCO_IMPLEMENT_EXCEPTION(DatabaseFullException, SQLiteException, "Insertion failed because database is full") -POCO_IMPLEMENT_EXCEPTION(CantOpenDBFileException, SQLiteException, "Unable to open the database file") -POCO_IMPLEMENT_EXCEPTION(LockProtocolException, SQLiteException, "Database lock protocol error") -POCO_IMPLEMENT_EXCEPTION(SchemaDiffersException, SQLiteException, "The database schema changed") -POCO_IMPLEMENT_EXCEPTION(RowTooBigException, SQLiteException, "Too much data for one row of a table") -POCO_IMPLEMENT_EXCEPTION(ConstraintViolationException, SQLiteException, "Abort due to constraint violation") -POCO_IMPLEMENT_EXCEPTION(DataTypeMismatchException, SQLiteException, "Data type mismatch") -POCO_IMPLEMENT_EXCEPTION(ParameterCountMismatchException, SQLiteException, "Parameter count mismatch") -POCO_IMPLEMENT_EXCEPTION(InvalidLibraryUseException, SQLiteException, "Library used incorrectly") -POCO_IMPLEMENT_EXCEPTION(OSFeaturesMissingException, SQLiteException, "Uses OS features not supported on host") -POCO_IMPLEMENT_EXCEPTION(AuthorizationDeniedException, SQLiteException, "Authorization denied") -POCO_IMPLEMENT_EXCEPTION(TransactionException, SQLiteException, "Transaction exception") - - -} } } // namespace Poco::Data::SQLite +// +// SQLiteException.cpp +// +// $Id: //poco/1.3/Data/SQLite/src/SQLiteException.cpp#4 $ +// +// Library: SQLite +// Package: SQLite +// Module: SQLiteException +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/SQLite/SQLiteException.h" +#include + + +namespace Poco { +namespace Data { +namespace SQLite { + + +POCO_IMPLEMENT_EXCEPTION(SQLiteException, Poco::Data::DataException, "Generic SQLite error") +POCO_IMPLEMENT_EXCEPTION(InvalidSQLStatementException, SQLiteException, "SQL Statement invalid") +POCO_IMPLEMENT_EXCEPTION(InternalDBErrorException, SQLiteException, "Internal error") +POCO_IMPLEMENT_EXCEPTION(DBAccessDeniedException, SQLiteException, "Access permission denied") +POCO_IMPLEMENT_EXCEPTION(ExecutionAbortedException, SQLiteException, "Execution of SQL statement aborted") +POCO_IMPLEMENT_EXCEPTION(DBLockedException, SQLiteException, "The database is locked") +POCO_IMPLEMENT_EXCEPTION(TableLockedException, SQLiteException, "A table in the database is locked") +POCO_IMPLEMENT_EXCEPTION(NoMemoryException, SQLiteException, "Out of Memory") +POCO_IMPLEMENT_EXCEPTION(ReadOnlyException, SQLiteException, "Attempt to write a readonly database") +POCO_IMPLEMENT_EXCEPTION(InterruptException, SQLiteException, "Operation terminated by an interrupt") +POCO_IMPLEMENT_EXCEPTION(IOErrorException, SQLiteException, "Some kind of disk I/O error occurred") +POCO_IMPLEMENT_EXCEPTION(CorruptImageException, SQLiteException, "The database disk image is malformed") +POCO_IMPLEMENT_EXCEPTION(TableNotFoundException, SQLiteException, "Table not found") +POCO_IMPLEMENT_EXCEPTION(DatabaseFullException, SQLiteException, "Insertion failed because database is full") +POCO_IMPLEMENT_EXCEPTION(CantOpenDBFileException, SQLiteException, "Unable to open the database file") +POCO_IMPLEMENT_EXCEPTION(LockProtocolException, SQLiteException, "Database lock protocol error") +POCO_IMPLEMENT_EXCEPTION(SchemaDiffersException, SQLiteException, "The database schema changed") +POCO_IMPLEMENT_EXCEPTION(RowTooBigException, SQLiteException, "Too much data for one row of a table") +POCO_IMPLEMENT_EXCEPTION(ConstraintViolationException, SQLiteException, "Abort due to constraint violation") +POCO_IMPLEMENT_EXCEPTION(DataTypeMismatchException, SQLiteException, "Data type mismatch") +POCO_IMPLEMENT_EXCEPTION(ParameterCountMismatchException, SQLiteException, "Parameter count mismatch") +POCO_IMPLEMENT_EXCEPTION(InvalidLibraryUseException, SQLiteException, "Library used incorrectly") +POCO_IMPLEMENT_EXCEPTION(OSFeaturesMissingException, SQLiteException, "Uses OS features not supported on host") +POCO_IMPLEMENT_EXCEPTION(AuthorizationDeniedException, SQLiteException, "Authorization denied") +POCO_IMPLEMENT_EXCEPTION(TransactionException, SQLiteException, "Transaction exception") + + +} } } // namespace Poco::Data::SQLite diff --git a/Data/SQLite/src/SQLiteStatementImpl.cpp b/Data/SQLite/src/SQLiteStatementImpl.cpp index 6af26333f..d12c29b38 100644 --- a/Data/SQLite/src/SQLiteStatementImpl.cpp +++ b/Data/SQLite/src/SQLiteStatementImpl.cpp @@ -1,244 +1,244 @@ -// -// SQLiteStatementImpl.cpp -// -// $Id: //poco/1.3/Data/SQLite/src/SQLiteStatementImpl.cpp#4 $ -// -// Library: SQLite -// Package: SQLite -// Module: SQLiteStatementImpl -// -// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/SQLite/SQLiteStatementImpl.h" -#include "Poco/Data/SQLite/Utility.h" -#include "Poco/Data/SQLite/SQLiteException.h" -#include "Poco/String.h" -#include -#include -#include "sqlite3.h" - - -namespace Poco { -namespace Data { -namespace SQLite { - - -SQLiteStatementImpl::SQLiteStatementImpl(sqlite3* pDB): - _pDB(pDB), - _pStmt(0), - _stepCalled(false), - _nextResponse(0) -{ -} - - -SQLiteStatementImpl::~SQLiteStatementImpl() -{ - clear(); -} - - -void SQLiteStatementImpl::compileImpl() -{ - if (_pStmt) return; - - std::string statement(toString()); - if (statement.empty()) - throw InvalidSQLStatementException("Empty statements are illegal"); - - sqlite3_stmt* pStmt = 0; - const char* pSql = statement.c_str(); // The SQL to be executed - int rc = SQLITE_OK; - const char* pLeftover = 0; - bool queryFound = false; - - while (rc == SQLITE_OK && !pStmt && !queryFound) - { - rc = sqlite3_prepare_v2(_pDB, pSql, -1, &pStmt, &pLeftover); - if (rc != SQLITE_OK) - { - if (pStmt) - { - sqlite3_finalize(pStmt); - } - pStmt = 0; - std::string errMsg = sqlite3_errmsg(_pDB); - Utility::throwException(rc, errMsg); - } - else if (rc == SQLITE_OK && pStmt) - { - queryFound = true; - } - else if(rc == SQLITE_OK && !pStmt) // comment/whitespace ignore - { - pSql = pLeftover; - if (std::strlen(pSql) == 0) - { - // empty statement or an conditional statement! like CREATE IF NOT EXISTS - // this is valid - queryFound = true; - } - } - } - - clear(); - _pStmt = pStmt; - - // prepare binding - _pBinder = new Binder(_pStmt); - _pExtractor = new Extractor(_pStmt); - - int colCount = sqlite3_column_count(_pStmt); - - for (int i = 0; i < colCount; ++i) - { - MetaColumn mc(i, sqlite3_column_name(_pStmt, i), Utility::getColumnType(_pStmt, i)); - _columns.push_back(mc); - } -} - - -bool SQLiteStatementImpl::canBind() const -{ - bool ret = false; - if (!bindings().empty() && _pStmt) - ret = (*bindings().begin())->canBind(); - - return ret; -} - - -void SQLiteStatementImpl::bindImpl() -{ - _stepCalled = false; - _nextResponse = 0; - if (_pStmt == 0) return; - - sqlite3_reset(_pStmt); - - // bind - Bindings& binds = bindings(); - int pc = sqlite3_bind_parameter_count(_pStmt); - if (binds.empty() && 0 == pc) return; - else if (binds.empty() && pc > 0) - throw ParameterCountMismatchException(); - else if (!binds.empty() && binds.size() * (*binds.begin())->numOfColumnsHandled() != pc) - throw ParameterCountMismatchException(); - - std::size_t pos = 1; // sqlite starts with 1 not 0! - - Bindings::iterator it = binds.begin(); - Bindings::iterator itEnd = binds.end(); - for (; it != itEnd && (*it)->canBind(); ++it) - { - (*it)->bind(pos); - pos += (*it)->numOfColumnsHandled(); - } -} - - -void SQLiteStatementImpl::clear() -{ - _columns.clear(); - - if (_pStmt) - { - sqlite3_finalize(_pStmt); - _pStmt=0; - } -} - - -bool SQLiteStatementImpl::hasNext() -{ - if (_stepCalled) - return (_nextResponse == SQLITE_ROW); - - // _pStmt is allowed to be null for conditional SQL statements - if (_pStmt == 0) - { - _stepCalled = true; - _nextResponse = SQLITE_DONE; - return false; - } - - _stepCalled = true; - _nextResponse = sqlite3_step(_pStmt); - - if (_nextResponse != SQLITE_ROW && _nextResponse != SQLITE_OK && _nextResponse != SQLITE_DONE) - { - Utility::throwException(_nextResponse); - } - - return (_nextResponse == SQLITE_ROW); -} - - -void SQLiteStatementImpl::next() -{ - if (SQLITE_ROW == _nextResponse) - { - poco_assert (columnsReturned() == sqlite3_column_count(_pStmt)); - - Extractions& extracts = extractions(); - Extractions::iterator it = extracts.begin(); - Extractions::iterator itEnd = extracts.end(); - std::size_t pos = 0; // sqlite starts with pos 0 for results! - for (; it != itEnd; ++it) - { - (*it)->extract(pos); - pos += (*it)->numOfColumnsHandled(); - } - _stepCalled = false; - } - else if (SQLITE_DONE == _nextResponse) - { - throw Poco::Data::DataException("No data received"); - } - else - { - int rc = _nextResponse; - Utility::throwException(rc, std::string("Iterator Error: trying to access the next value")); - } -} - - -Poco::UInt32 SQLiteStatementImpl::columnsReturned() const -{ - return (Poco::UInt32) _columns.size(); -} - - -const MetaColumn& SQLiteStatementImpl::metaColumn(Poco::UInt32 pos) const -{ - poco_assert (pos >= 0 && pos <= _columns.size()); - return _columns[pos]; -} - - -} } } // namespace Poco::Data::SQLite +// +// SQLiteStatementImpl.cpp +// +// $Id: //poco/1.3/Data/SQLite/src/SQLiteStatementImpl.cpp#5 $ +// +// Library: SQLite +// Package: SQLite +// Module: SQLiteStatementImpl +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/SQLite/SQLiteStatementImpl.h" +#include "Poco/Data/SQLite/Utility.h" +#include "Poco/Data/SQLite/SQLiteException.h" +#include "Poco/String.h" +#include +#include +#include "sqlite3.h" + + +namespace Poco { +namespace Data { +namespace SQLite { + + +SQLiteStatementImpl::SQLiteStatementImpl(sqlite3* pDB): + _pDB(pDB), + _pStmt(0), + _stepCalled(false), + _nextResponse(0) +{ +} + + +SQLiteStatementImpl::~SQLiteStatementImpl() +{ + clear(); +} + + +void SQLiteStatementImpl::compileImpl() +{ + if (_pStmt) return; + + std::string statement(toString()); + if (statement.empty()) + throw InvalidSQLStatementException("Empty statements are illegal"); + + sqlite3_stmt* pStmt = 0; + const char* pSql = statement.c_str(); // The SQL to be executed + int rc = SQLITE_OK; + const char* pLeftover = 0; + bool queryFound = false; + + while (rc == SQLITE_OK && !pStmt && !queryFound) + { + rc = sqlite3_prepare_v2(_pDB, pSql, -1, &pStmt, &pLeftover); + if (rc != SQLITE_OK) + { + if (pStmt) + { + sqlite3_finalize(pStmt); + } + pStmt = 0; + std::string errMsg = sqlite3_errmsg(_pDB); + Utility::throwException(rc, errMsg); + } + else if (rc == SQLITE_OK && pStmt) + { + queryFound = true; + } + else if(rc == SQLITE_OK && !pStmt) // comment/whitespace ignore + { + pSql = pLeftover; + if (std::strlen(pSql) == 0) + { + // empty statement or an conditional statement! like CREATE IF NOT EXISTS + // this is valid + queryFound = true; + } + } + } + + clear(); + _pStmt = pStmt; + + // prepare binding + _pBinder = new Binder(_pStmt); + _pExtractor = new Extractor(_pStmt); + + int colCount = sqlite3_column_count(_pStmt); + + for (int i = 0; i < colCount; ++i) + { + MetaColumn mc(i, sqlite3_column_name(_pStmt, i), Utility::getColumnType(_pStmt, i)); + _columns.push_back(mc); + } +} + + +bool SQLiteStatementImpl::canBind() const +{ + bool ret = false; + if (!bindings().empty() && _pStmt) + ret = (*bindings().begin())->canBind(); + + return ret; +} + + +void SQLiteStatementImpl::bindImpl() +{ + _stepCalled = false; + _nextResponse = 0; + if (_pStmt == 0) return; + + sqlite3_reset(_pStmt); + + // bind + Bindings& binds = bindings(); + int pc = sqlite3_bind_parameter_count(_pStmt); + if (binds.empty() && 0 == pc) return; + else if (binds.empty() && pc > 0) + throw ParameterCountMismatchException(); + else if (!binds.empty() && binds.size() * (*binds.begin())->numOfColumnsHandled() != pc) + throw ParameterCountMismatchException(); + + std::size_t pos = 1; // sqlite starts with 1 not 0! + + Bindings::iterator it = binds.begin(); + Bindings::iterator itEnd = binds.end(); + for (; it != itEnd && (*it)->canBind(); ++it) + { + (*it)->bind(pos); + pos += (*it)->numOfColumnsHandled(); + } +} + + +void SQLiteStatementImpl::clear() +{ + _columns.clear(); + + if (_pStmt) + { + sqlite3_finalize(_pStmt); + _pStmt=0; + } +} + + +bool SQLiteStatementImpl::hasNext() +{ + if (_stepCalled) + return (_nextResponse == SQLITE_ROW); + + // _pStmt is allowed to be null for conditional SQL statements + if (_pStmt == 0) + { + _stepCalled = true; + _nextResponse = SQLITE_DONE; + return false; + } + + _stepCalled = true; + _nextResponse = sqlite3_step(_pStmt); + + if (_nextResponse != SQLITE_ROW && _nextResponse != SQLITE_OK && _nextResponse != SQLITE_DONE) + { + Utility::throwException(_nextResponse); + } + + return (_nextResponse == SQLITE_ROW); +} + + +void SQLiteStatementImpl::next() +{ + if (SQLITE_ROW == _nextResponse) + { + poco_assert (columnsReturned() == sqlite3_column_count(_pStmt)); + + Extractions& extracts = extractions(); + Extractions::iterator it = extracts.begin(); + Extractions::iterator itEnd = extracts.end(); + std::size_t pos = 0; // sqlite starts with pos 0 for results! + for (; it != itEnd; ++it) + { + (*it)->extract(pos); + pos += (*it)->numOfColumnsHandled(); + } + _stepCalled = false; + } + else if (SQLITE_DONE == _nextResponse) + { + throw Poco::Data::DataException("No data received"); + } + else + { + int rc = _nextResponse; + Utility::throwException(rc, std::string("Iterator Error: trying to access the next value")); + } +} + + +Poco::UInt32 SQLiteStatementImpl::columnsReturned() const +{ + return (Poco::UInt32) _columns.size(); +} + + +const MetaColumn& SQLiteStatementImpl::metaColumn(Poco::UInt32 pos) const +{ + poco_assert (pos >= 0 && pos <= _columns.size()); + return _columns[pos]; +} + + +} } } // namespace Poco::Data::SQLite diff --git a/Data/SQLite/testsuite/TestSuite_vs90.vcproj b/Data/SQLite/testsuite/TestSuite_vs90.vcproj new file mode 100644 index 000000000..40fd09ea4 --- /dev/null +++ b/Data/SQLite/testsuite/TestSuite_vs90.vcproj @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Data/SQLite/testsuite/src/SQLiteTest.cpp b/Data/SQLite/testsuite/src/SQLiteTest.cpp index baf873493..c7e0864f4 100644 --- a/Data/SQLite/testsuite/src/SQLiteTest.cpp +++ b/Data/SQLite/testsuite/src/SQLiteTest.cpp @@ -1,1625 +1,1625 @@ -// -// SQLiteTest.cpp -// -// $Id: //poco/1.3/Data/SQLite/testsuite/src/SQLiteTest.cpp#4 $ -// -// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "SQLiteTest.h" -#include "CppUnit/TestCaller.h" -#include "CppUnit/TestSuite.h" -#include "Poco/Data/Common.h" -#include "Poco/Data/BLOB.h" -#include "Poco/Data/Statement.h" -#include "Poco/Data/RecordSet.h" -#include "Poco/Data/SQLite/Connector.h" -#include "Poco/Tuple.h" -#include "Poco/Any.h" -#include "Poco/Exception.h" -#include -#include "Poco/File.h" -#include "Poco/Stopwatch.h" -#include "Poco/Data/SQLite/SQLiteException.h" - - -using namespace Poco::Data; -using Poco::Tuple; -using Poco::Any; -using Poco::AnyCast; -using Poco::InvalidAccessException; -using Poco::RangeException; -using Poco::BadCastException; -using Poco::Data::SQLite::ParameterCountMismatchException; - - -struct Person -{ - std::string lastName; - std::string firstName; - std::string address; - int age; - Person(){age = 0;} - Person(const std::string& ln, const std::string& fn, const std::string& adr, int a):lastName(ln), firstName(fn), address(adr), age(a) - { - } - bool operator==(const Person& other) const - { - return lastName == other.lastName && firstName == other.firstName && address == other.address && age == other.age; - } - - bool operator < (const Person& p) const - { - if (age < p.age) - return true; - if (lastName < p.lastName) - return true; - if (firstName < p.firstName) - return true; - return (address < p.address); - } - - const std::string& operator () () const - /// This method is required so we can extract data to a map! - { - // we choose the lastName as examplary key - return lastName; - } -}; - - -namespace Poco { -namespace Data { - - -template <> -class TypeHandler -{ -public: - static void bind(std::size_t pos, const Person& obj, AbstractBinder* pBinder) - { - // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3)) - poco_assert_dbg (pBinder != 0); - pBinder->bind(pos++, obj.lastName); - pBinder->bind(pos++, obj.firstName); - pBinder->bind(pos++, obj.address); - pBinder->bind(pos++, obj.age); - } - - static void prepare(std::size_t pos, const Person& obj, AbstractPreparation* pPrepare) - { - // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3)) - poco_assert_dbg (pPrepare != 0); - pPrepare->prepare(pos++, obj.lastName); - pPrepare->prepare(pos++, obj.firstName); - pPrepare->prepare(pos++, obj.address); - pPrepare->prepare(pos++, obj.age); - } - - static std::size_t size() - { - return 4; - } - - static void extract(std::size_t pos, Person& obj, const Person& defVal, AbstractExtractor* pExt) - { - poco_assert_dbg (pExt != 0); - std::string lastName; - std::string firstName; - std::string address; - if (!pExt->extract(pos++, obj.lastName)) - obj.lastName = defVal.lastName; - if (!pExt->extract(pos++, obj.firstName)) - obj.firstName = defVal.firstName; - if (!pExt->extract(pos++, obj.address)) - obj.address = defVal.address; - if (!pExt->extract(pos++, obj.age)) - obj.age = defVal.age; - } - -private: - TypeHandler(); - ~TypeHandler(); - TypeHandler(const TypeHandler&); - TypeHandler& operator=(const TypeHandler&); -}; - - -} } // namespace Poco::Data - - -SQLiteTest::SQLiteTest(const std::string& name): CppUnit::TestCase(name) -{ - SQLite::Connector::registerConnector(); -} - - -SQLiteTest::~SQLiteTest() -{ - SQLite::Connector::unregisterConnector(); -} - - -void SQLiteTest::testSimpleAccess() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - assert (tmp.isConnected()); - std::string tableName("Person"); - std::string lastName("lastname"); - std::string firstName("firstname"); - std::string address("Address"); - int age = 133132; - int count = 0; - std::string result; - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "SELECT name FROM sqlite_master WHERE tbl_name=?", use(tableName), into(result), now; - assert (result == tableName); - - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastName), use(firstName), use(address), use(age), now; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 1); - tmp << "SELECT LastName FROM PERSON", into(result), now; - assert (lastName == result); - tmp << "SELECT Age FROM PERSON", into(count), now; - assert (count == age); - tmp.close(); - assert (!tmp.isConnected()); -} - - -void SQLiteTest::testComplexType() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(p1), now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(p2), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - - Person c1; - Person c2; - tmp << "SELECT * FROM PERSON WHERE LASTNAME = :ln", into(c1), use(p1.lastName), now; - assert (c1 == p1); -} - - - -void SQLiteTest::testSimpleAccessVector() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::vector lastNames; - std::vector firstNames; - std::vector addresses; - std::vector ages; - std::string tableName("Person"); - lastNames.push_back("LN1"); - lastNames.push_back("LN2"); - firstNames.push_back("FN1"); - firstNames.push_back("FN2"); - addresses.push_back("ADDR1"); - addresses.push_back("ADDR2"); - ages.push_back(1); - ages.push_back(2); - int count = 0; - std::string result; - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastNames), use(firstNames), use(addresses), use(ages), now; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - - std::vector lastNamesR; - std::vector firstNamesR; - std::vector addressesR; - std::vector agesR; - tmp << "SELECT * FROM PERSON", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; - assert (ages == agesR); - assert (lastNames == lastNamesR); - assert (firstNames == firstNamesR); - assert (addresses == addressesR); -} - - -void SQLiteTest::testComplexTypeVector() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::vector people; - people.push_back(Person("LN1", "FN1", "ADDR1", 1)); - people.push_back(Person("LN2", "FN2", "ADDR2", 2)); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - - std::vector result; - tmp << "SELECT * FROM PERSON", into(result), now; - assert (result == people); -} - - -void SQLiteTest::testInsertVector() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::vector str; - str.push_back("s1"); - str.push_back("s2"); - str.push_back("s3"); - str.push_back("s3"); - int count = 100; - tmp << "DROP TABLE IF EXISTS Strings", now; - tmp << "CREATE TABLE IF NOT EXISTS Strings (str VARCHAR(30))", now; - { - Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(str))); - tmp << "SELECT COUNT(*) FROM Strings", into(count), now; - assert (count == 0); - stmt.execute(); - tmp << "SELECT COUNT(*) FROM Strings", into(count), now; - assert (count == 4); - } - count = 0; - tmp << "SELECT COUNT(*) FROM Strings", into(count), now; - assert (count == 4); -} - - -void SQLiteTest::testInsertEmptyVector() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::vector str; - - tmp << "DROP TABLE IF EXISTS Strings", now; - tmp << "CREATE TABLE IF NOT EXISTS Strings (str VARCHAR(30))", now; - try - { - tmp << "INSERT INTO Strings VALUES(:str)", use(str), now; - fail("empty collectons should not work"); - } - catch (Poco::Exception&) - { - } -} - - -void SQLiteTest::testInsertSingleBulk() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Strings", now; - tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; - int x = 0; - Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(x))); - - for (x = 0; x < 100; ++x) - { - int i = stmt.execute(); - assert (i == 0); - } - int count = 0; - tmp << "SELECT COUNT(*) FROM Strings", into(count), now; - assert (count == 100); - tmp << "SELECT SUM(str) FROM Strings", into(count), now; - assert (count == ((0+99)*100/2)); -} - - -void SQLiteTest::testInsertSingleBulkVec() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Strings", now; - tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; - std::vector data; - data.push_back(0); - data.push_back(1); - - Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(data))); - - for (int x = 0; x < 100; x += 2) - { - data[0] = x; - data[1] = x+1; - stmt.execute(); - } - int count = 0; - tmp << "SELECT COUNT(*) FROM Strings", into(count), now; - assert (count == 100); - tmp << "SELECT SUM(str) FROM Strings", into(count), now; - assert (count == ((0+99)*100/2)); -} - - -void SQLiteTest::testLimit() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Strings", now; - tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; - std::vector data; - for (int x = 0; x < 100; ++x) - { - data.push_back(x); - } - - tmp << "INSERT INTO Strings VALUES(:str)", use(data), now; - - std::vector retData; - tmp << "SELECT * FROM Strings", into(retData), limit(50), now; - assert (retData.size() == 50); - for (int x = 0; x < 50; ++x) - { - assert(data[x] == retData[x]); - } -} - - -void SQLiteTest::testLimitZero() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Strings", now; - tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; - std::vector data; - for (int x = 0; x < 100; ++x) - { - data.push_back(x); - } - - tmp << "INSERT INTO Strings VALUES(:str)", use(data), now; - - std::vector retData; - tmp << "SELECT * FROM Strings", into(retData), limit(0), now; // stupid test, but at least we shouldn't crash - assert (retData.size() == 0); -} - - -void SQLiteTest::testLimitOnce() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Strings", now; - tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; - std::vector data; - for (int x = 0; x < 101; ++x) - { - data.push_back(x); - } - - tmp << "INSERT INTO Strings VALUES(:str)", use(data), now; - - std::vector retData; - Statement stmt = (tmp << "SELECT * FROM Strings", into(retData), limit(50), now); - assert (!stmt.done()); - assert (retData.size() == 50); - stmt.execute(); - assert (!stmt.done()); - assert (retData.size() == 100); - stmt.execute(); - assert (stmt.done()); - assert (retData.size() == 101); - - for (int x = 0; x < 101; ++x) - { - assert(data[x] == retData[x]); - } -} - - -void SQLiteTest::testLimitPrepare() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Strings", now; - tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; - std::vector data; - for (int x = 0; x < 100; ++x) - { - data.push_back(x); - } - - tmp << "INSERT INTO Strings VALUES(:str)", use(data), now; - - std::vector retData; - Statement stmt = (tmp << "SELECT * FROM Strings", into(retData), limit(50)); - assert (retData.size() == 0); - assert (!stmt.done()); - stmt.execute(); - assert (!stmt.done()); - assert (retData.size() == 50); - stmt.execute(); - assert (stmt.done()); - assert (retData.size() == 100); - stmt.execute(); // will restart execution! - assert (!stmt.done()); - assert (retData.size() == 150); - for (int x = 0; x < 150; ++x) - { - assert(data[x%100] == retData[x]); - } -} - - - -void SQLiteTest::testPrepare() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Strings", now; - tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; - std::vector data; - for (int x = 0; x < 100; x += 2) - { - data.push_back(x); - } - - { - Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(data))); - } - // stmt should not have been executed when destroyed - int count = 100; - tmp << "SELECT COUNT(*) FROM Strings", into(count), now; - assert (count == 0); -} - - -void SQLiteTest::testSetSimple() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::set lastNames; - std::set firstNames; - std::set addresses; - std::set ages; - std::string tableName("Person"); - lastNames.insert("LN1"); - lastNames.insert("LN2"); - firstNames.insert("FN1"); - firstNames.insert("FN2"); - addresses.insert("ADDR1"); - addresses.insert("ADDR2"); - ages.insert(1); - ages.insert(2); - int count = 0; - std::string result; - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastNames), use(firstNames), use(addresses), use(ages), now; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - - std::set lastNamesR; - std::set firstNamesR; - std::set addressesR; - std::set agesR; - tmp << "SELECT * FROM PERSON", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; - assert (ages == agesR); - assert (lastNames == lastNamesR); - assert (firstNames == firstNamesR); - assert (addresses == addressesR); -} - - -void SQLiteTest::testSetComplex() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::set people; - people.insert(Person("LN1", "FN1", "ADDR1", 1)); - people.insert(Person("LN2", "FN2", "ADDR2", 2)); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - - std::set result; - tmp << "SELECT * FROM PERSON", into(result), now; - assert (result == people); -} - - -void SQLiteTest::testSetComplexUnique() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::vector people; - Person p1("LN1", "FN1", "ADDR1", 1); - people.push_back(p1); - people.push_back(p1); - people.push_back(p1); - people.push_back(p1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.push_back(p2); - - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 5); - - std::set result; - tmp << "SELECT * FROM PERSON", into(result), now; - assert (result.size() == 2); - assert (*result.begin() == p1); - assert (*++result.begin() == p2); -} - -void SQLiteTest::testMultiSetSimple() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::multiset lastNames; - std::multiset firstNames; - std::multiset addresses; - std::multiset ages; - std::string tableName("Person"); - lastNames.insert("LN1"); - lastNames.insert("LN2"); - firstNames.insert("FN1"); - firstNames.insert("FN2"); - addresses.insert("ADDR1"); - addresses.insert("ADDR2"); - ages.insert(1); - ages.insert(2); - int count = 0; - std::string result; - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastNames), use(firstNames), use(addresses), use(ages), now; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - - std::multiset lastNamesR; - std::multiset firstNamesR; - std::multiset addressesR; - std::multiset agesR; - tmp << "SELECT * FROM PERSON", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; - assert (ages.size() == agesR.size()); - assert (lastNames.size() == lastNamesR.size()); - assert (firstNames.size() == firstNamesR.size()); - assert (addresses.size() == addressesR.size()); -} - - -void SQLiteTest::testMultiSetComplex() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::multiset people; - Person p1("LN1", "FN1", "ADDR1", 1); - people.insert(p1); - people.insert(p1); - people.insert(p1); - people.insert(p1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(p2); - - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 5); - - std::multiset result; - tmp << "SELECT * FROM PERSON", into(result), now; - assert (result.size() == people.size()); -} - - -void SQLiteTest::testMapComplex() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::map people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN2", p2)); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - - std::map result; - tmp << "SELECT * FROM PERSON", into(result), now; - assert (result == people); -} - - -void SQLiteTest::testMapComplexUnique() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN2", p2)); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 5); - - std::map result; - tmp << "SELECT * FROM PERSON", into(result), now; - assert (result.size() == 2); -} - - -void SQLiteTest::testMultiMapComplex() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN2", p2)); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 5); - - std::multimap result; - tmp << "SELECT * FROM PERSON", into(result), now; - assert (result.size() == people.size()); -} - - -void SQLiteTest::testSelectIntoSingle() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - Person result; - tmp << "SELECT * FROM PERSON", into(result), limit(1), now; // will return 1 object into one single result - assert (result == p1); -} - - -void SQLiteTest::testSelectIntoSingleStep() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - Person result; - Statement stmt = (tmp << "SELECT * FROM PERSON", into(result), limit(1)); - stmt.execute(); - assert (result == p1); - assert (!stmt.done()); - stmt.execute(); - assert (result == p2); - assert (stmt.done()); -} - - -void SQLiteTest::testSelectIntoSingleFail() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), limit(2, true), now; - assert (count == 2); - Person result; - try - { - tmp << "SELECT * FROM PERSON", into(result), limit(1, true), now; // will fail now - fail("hardLimit is set: must fail"); - } - catch(Poco::Data::LimitException&) - { - } -} - - -void SQLiteTest::testLowerLimitOk() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - Person result; - try - { - tmp << "SELECT * FROM PERSON", into(result), lowerLimit(2), now; // will return 2 objects into one single result but only room for one! - fail("Not enough space for results"); - } - catch(Poco::Exception&) - { - } -} - - -void SQLiteTest::testSingleSelect() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - Person result; - Statement stmt = (tmp << "SELECT * FROM PERSON", into(result), limit(1)); - stmt.execute(); - assert (result == p1); - assert (!stmt.done()); - stmt.execute(); - assert (result == p2); - assert (stmt.done()); -} - - -void SQLiteTest::testLowerLimitFail() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - Person result; - try - { - tmp << "SELECT * FROM PERSON", into(result), lowerLimit(3), now; // will fail - fail("should fail. not enough data"); - } - catch(Poco::Exception&) - { - } -} - - -void SQLiteTest::testCombinedLimits() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - std::vector result; - tmp << "SELECT * FROM PERSON", into(result), lowerLimit(2), upperLimit(2), now; // will return 2 objects - assert (result.size() == 2); - assert (result[0] == p1); - assert (result[1] == p2); -} - - - -void SQLiteTest::testRange() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - std::vector result; - tmp << "SELECT * FROM PERSON", into(result), range(2, 2), now; // will return 2 objects - assert (result.size() == 2); - assert (result[0] == p1); - assert (result[1] == p2); -} - - -void SQLiteTest::testCombinedIllegalLimits() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - Person result; - try - { - tmp << "SELECT * FROM PERSON", into(result), lowerLimit(3), upperLimit(2), now; - fail("lower > upper is not allowed"); - } - catch(LimitException&) - { - } -} - - - -void SQLiteTest::testIllegalRange() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - std::multimap people; - Person p1("LN1", "FN1", "ADDR1", 1); - Person p2("LN2", "FN2", "ADDR2", 2); - people.insert(std::make_pair("LN1", p1)); - people.insert(std::make_pair("LN1", p2)); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 2); - Person result; - try - { - tmp << "SELECT * FROM PERSON", into(result), range(3, 2), now; - fail("lower > upper is not allowed"); - } - catch(LimitException&) - { - } -} - - -void SQLiteTest::testEmptyDB() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; - int count = 0; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 0); - Person result; - Statement stmt = (tmp << "SELECT * FROM PERSON", into(result), limit(1)); - stmt.execute(); - assert (result.firstName.empty()); - assert (stmt.done()); -} - - -void SQLiteTest::testBLOB() -{ - std::string lastName("lastname"); - std::string firstName("firstname"); - std::string address("Address"); - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Image BLOB)", now; - BLOB img("0123456789", 10); - int count = 0; - tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :img)", use(lastName), use(firstName), use(address), use(img), now; - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 1); - BLOB res; - poco_assert (res.size() == 0); - tmp << "SELECT Image FROM Person WHERE LastName == :ln", use("lastname"), into(res), now; - poco_assert (res == img); -} - - -void SQLiteTest::testBLOBStmt() -{ - // the following test will fail becuase we use a temporary object as parameter to use - /* - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Person", now; - tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Image BLOB)", now; - BLOB img("0123456789", 10); - int count = 0; - Statement ins = (tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :img)", use("lastname"), use("firstname"), use("Address"), use(BLOB("0123456789", 10))); - ins.execute(); - tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; - assert (count == 1); - BLOB res; - poco_assert (res.size() == 0); - Statement stmt = (tmp << "SELECT Image FROM Person WHERE LastName == :ln", use("lastname"), into(res)); - stmt.execute(); - poco_assert (res == img); - */ -} - - -void SQLiteTest::testTuple10() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " - "int7 INTEGER, int8 INTEGER, int9 INTEGER)", now; - - Tuple t(0,1,2,3,4,5,6,7,8,9); - - tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?)", use(t), now; - - Tuple ret(-10,-11,-12,-13,-14,-15,-16,-17,-18,-19); - assert (ret != t); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == t); -} - - -void SQLiteTest::testTupleVector10() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " - "int7 INTEGER, int8 INTEGER, int9 INTEGER)", now; - - Tuple t(0,1,2,3,4,5,6,7,8,9); - Tuple t10(10,11,12,13,14,15,16,17,18,19); - Tuple t100(100,101,102,103,104,105,106,107,108,109); - std::vector > v; - v.push_back(t); - v.push_back(t10); - v.push_back(t100); - - tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?)", use(v), now; - - int count = 0; - tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; - assert (v.size() == count); - - std::vector > ret; - assert (ret != v); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == v); -} - - -void SQLiteTest::testTuple9() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " - "int7 INTEGER, int8 INTEGER)", now; - - Tuple t(0,1,2,3,4,5,6,7,8); - - tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?)", use(t), now; - - Tuple ret(-10,-11,-12,-13,-14,-15,-16,-17,-18); - assert (ret != t); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == t); -} - - -void SQLiteTest::testTupleVector9() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " - "int7 INTEGER, int8 INTEGER)", now; - - Tuple t(0,1,2,3,4,5,6,7,8); - Tuple t10(10,11,12,13,14,15,16,17,18); - Tuple t100(100,101,102,103,104,105,106,107,108); - std::vector > v; - v.push_back(t); - v.push_back(t10); - v.push_back(t100); - - tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?)", use(v), now; - - int count = 0; - tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; - assert (v.size() == count); - - std::vector > ret; - assert (ret != v); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == v); -} - - -void SQLiteTest::testTuple8() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " - "int7 INTEGER)", now; - - Tuple t(0,1,2,3,4,5,6,7); - - tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?)", use(t), now; - - Tuple ret(-10,-11,-12,-13,-14,-15,-16,-17); - assert (ret != t); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == t); -} - - -void SQLiteTest::testTupleVector8() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " - "int7 INTEGER)", now; - - Tuple t(0,1,2,3,4,5,6,7); - Tuple t10(10,11,12,13,14,15,16,17); - Tuple t100(100,101,102,103,104,105,106,107); - std::vector > v; - v.push_back(t); - v.push_back(t10); - v.push_back(t100); - - tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?)", use(v), now; - - int count = 0; - tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; - assert (v.size() == count); - - std::vector > ret; - assert (ret != v); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == v); -} - - -void SQLiteTest::testTuple7() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER)", now; - - Tuple t(0,1,2,3,4,5,6); - - tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?)", use(t), now; - - Tuple ret(-10,-11,-12,-13,-14,-15,-16); - assert (ret != t); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == t); -} - - -void SQLiteTest::testTupleVector7() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER)", now; - - Tuple t(0,1,2,3,4,5,6); - Tuple t10(10,11,12,13,14,15,16); - Tuple t100(100,101,102,103,104,105,106); - std::vector > v; - v.push_back(t); - v.push_back(t10); - v.push_back(t100); - - tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?)", use(v), now; - - int count = 0; - tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; - assert (v.size() == count); - - std::vector > ret; - assert (ret != v); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == v); -} - - -void SQLiteTest::testTuple6() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER)", now; - - Tuple t(0,1,2,3,4,5); - - tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?)", use(t), now; - - Tuple ret(-10,-11,-12,-13,-14,-15); - assert (ret != t); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == t); -} - - -void SQLiteTest::testTupleVector6() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER)", now; - - Tuple t(0,1,2,3,4,5); - Tuple t10(10,11,12,13,14,15); - Tuple t100(100,101,102,103,104,105); - std::vector > v; - v.push_back(t); - v.push_back(t10); - v.push_back(t100); - - tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?)", use(v), now; - - int count = 0; - tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; - assert (v.size() == count); - - std::vector > ret; - assert (ret != v); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == v); -} - - -void SQLiteTest::testTuple5() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER)", now; - - Tuple t(0,1,2,3,4); - - tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?)", use(t), now; - - Tuple ret(-10,-11,-12,-13,-14); - assert (ret != t); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == t); -} - - -void SQLiteTest::testTupleVector5() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER)", now; - - Tuple t(0,1,2,3,4); - Tuple t10(10,11,12,13,14); - Tuple t100(100,101,102,103,104); - std::vector > v; - v.push_back(t); - v.push_back(t10); - v.push_back(t100); - - tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?)", use(v), now; - - int count = 0; - tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; - assert (v.size() == count); - - std::vector > ret; - assert (ret != v); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == v); -} - - -void SQLiteTest::testTuple4() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER)", now; - - Tuple t(0,1,2,3); - - tmp << "INSERT INTO Tuples VALUES (?,?,?,?)", use(t), now; - - Tuple ret(-10,-11,-12,-13); - assert (ret != t); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == t); -} - - -void SQLiteTest::testTupleVector4() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER)", now; - - Tuple t(0,1,2,3); - Tuple t10(10,11,12,13); - Tuple t100(100,101,102,103); - std::vector > v; - v.push_back(t); - v.push_back(t10); - v.push_back(t100); - - tmp << "INSERT INTO Tuples VALUES (?,?,?,?)", use(v), now; - - int count = 0; - tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; - assert (v.size() == count); - - std::vector > ret; - assert (ret != v); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == v); -} - - -void SQLiteTest::testTuple3() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER)", now; - - Tuple t(0,1,2); - - tmp << "INSERT INTO Tuples VALUES (?,?,?)", use(t), now; - - Tuple ret(-10,-11,-12); - assert (ret != t); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == t); -} - - -void SQLiteTest::testTupleVector3() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples " - "(int0 INTEGER, int1 INTEGER, int2 INTEGER)", now; - - Tuple t(0,1,2); - Tuple t10(10,11,12); - Tuple t100(100,101,102); - std::vector > v; - v.push_back(t); - v.push_back(t10); - v.push_back(t100); - - tmp << "INSERT INTO Tuples VALUES (?,?,?)", use(v), now; - - int count = 0; - tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; - assert (v.size() == count); - - std::vector > ret; - assert (ret != v); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == v); -} - - -void SQLiteTest::testTuple2() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples (int0 INTEGER, int1 INTEGER)", now; - - Tuple t(0,1); - - tmp << "INSERT INTO Tuples VALUES (?,?)", use(t), now; - - Tuple ret(-10,-11); - assert (ret != t); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == t); -} - - -void SQLiteTest::testTupleVector2() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples (int0 INTEGER, int1 INTEGER)", now; - - Tuple t(0,1); - Tuple t10(10,11); - Tuple t100(100,101); - std::vector > v; - v.push_back(t); - v.push_back(t10); - v.push_back(t100); - - tmp << "INSERT INTO Tuples VALUES (?,?)", use(v), now; - - int count = 0; - tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; - assert (v.size() == count); - - std::vector > ret; - assert (ret != v); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == v); -} - - -void SQLiteTest::testTuple1() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples (int0 INTEGER)", now; - - Tuple t(0); - - tmp << "INSERT INTO Tuples VALUES (?)", use(t), now; - - Tuple ret(-10); - assert (ret != t); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == t); -} - - -void SQLiteTest::testTupleVector1() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Tuples", now; - tmp << "CREATE TABLE Tuples (int0 INTEGER)", now; - - Tuple t(0); - Tuple t10(10); - Tuple t100(100); - std::vector > v; - v.push_back(t); - v.push_back(t10); - v.push_back(t100); - - tmp << "INSERT INTO Tuples VALUES (?)", use(v), now; - - int count = 0; - tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; - assert (v.size() == count); - - std::vector > ret; - assert (ret != v); - tmp << "SELECT * FROM Tuples", into(ret), now; - assert (ret == v); -} - - -void SQLiteTest::testInternalExtraction() -{ - Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); - tmp << "DROP TABLE IF EXISTS Vectors", now; - tmp << "CREATE TABLE Vectors (int0 INTEGER, flt0 REAL, str0 VARCHAR)", now; - - std::vector > v; - v.push_back(Tuple(1, 1.5, "3")); - v.push_back(Tuple(2, 2.5, "4")); - v.push_back(Tuple(3, 3.5, "5")); - v.push_back(Tuple(4, 4.5, "6")); - - tmp << "INSERT INTO Vectors VALUES (?,?,?)", use(v), now; - - Statement stmt = (tmp << "SELECT * FROM Vectors", now); - RecordSet rset(stmt); - assert (3 == rset.columnCount()); - assert (4 == rset.rowCount()); - - RecordSet rset2(rset); - assert (3 == rset2.columnCount()); - assert (4 == rset2.rowCount()); - - int a = rset.value(0,2); - assert (3 == a); - - int b = rset2.value("InT0",2); - assert (3 == b); - - double d = rset.value(1,0); - assert (1.5 == d); - - std::string s = rset.value(2,1); - assert ("4" == s); - - const Column& col = rset.column(0); - assert (col[0] == 1); - - try { const Column& col1 = rset.column(100); fail ("must fail"); } - catch (RangeException&) { } - - const Column& col1 = rset.column(0); - assert ("int0" == col1.name()); - Column::Iterator it = col1.begin(); - Column::Iterator itEnd = col1.end(); - int counter = 1; - for (; it != itEnd; ++it, ++counter) - assert (counter == *it); - - rset = (tmp << "SELECT COUNT(*) FROM Vectors", now); - s = rset.value(0,0); - assert ("4" == s); - - stmt = (tmp << "DELETE FROM Vectors", now); - rset = stmt; - - try { const Column& col1 = rset.column(0); fail ("must fail"); } - catch (RangeException&) { } -} - - -void SQLiteTest::testBindingCount() -{ - Session tmp (SQLite::Connector::KEY, "dummy.db"); - - tmp << "DROP TABLE IF EXISTS Ints", now; - tmp << "CREATE TABLE Ints (int0 INTEGER)", now; - - int i = 42; - try { tmp << "INSERT INTO Ints VALUES (?)", now; } - catch (ParameterCountMismatchException&) { } - - try { tmp << "INSERT INTO Ints VALUES (?)", use(i), use(i), now; } - catch (ParameterCountMismatchException&) { } - tmp << "INSERT INTO Ints VALUES (?)", use(i), now; - - int j = 0; - try { tmp << "SELECT int0 from Ints where int0 = ?", into(i), now; } - catch (ParameterCountMismatchException&) { } - tmp << "SELECT int0 from Ints where int0 = ?", use(i), into(j), now; - assert (42 == j); -} - - -void SQLiteTest::setUp() -{ -} - - -void SQLiteTest::tearDown() -{ -} - - -CppUnit::Test* SQLiteTest::suite() -{ - CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("SQLiteTest"); - - CppUnit_addTest(pSuite, SQLiteTest, testSimpleAccess); - CppUnit_addTest(pSuite, SQLiteTest, testComplexType); - CppUnit_addTest(pSuite, SQLiteTest, testSimpleAccessVector); - CppUnit_addTest(pSuite, SQLiteTest, testComplexTypeVector); - CppUnit_addTest(pSuite, SQLiteTest, testInsertVector); - CppUnit_addTest(pSuite, SQLiteTest, testInsertEmptyVector); - CppUnit_addTest(pSuite, SQLiteTest, testInsertSingleBulk); - CppUnit_addTest(pSuite, SQLiteTest, testInsertSingleBulkVec); - CppUnit_addTest(pSuite, SQLiteTest, testLimit); - CppUnit_addTest(pSuite, SQLiteTest, testLimitOnce); - CppUnit_addTest(pSuite, SQLiteTest, testLimitPrepare); - CppUnit_addTest(pSuite, SQLiteTest, testLimitZero); - CppUnit_addTest(pSuite, SQLiteTest, testPrepare); - CppUnit_addTest(pSuite, SQLiteTest, testSetSimple); - CppUnit_addTest(pSuite, SQLiteTest, testSetComplex); - CppUnit_addTest(pSuite, SQLiteTest, testSetComplexUnique); - CppUnit_addTest(pSuite, SQLiteTest, testMultiSetSimple); - CppUnit_addTest(pSuite, SQLiteTest, testMultiSetComplex); - CppUnit_addTest(pSuite, SQLiteTest, testMapComplex); - CppUnit_addTest(pSuite, SQLiteTest, testMapComplexUnique); - CppUnit_addTest(pSuite, SQLiteTest, testMultiMapComplex); - CppUnit_addTest(pSuite, SQLiteTest, testSelectIntoSingle); - CppUnit_addTest(pSuite, SQLiteTest, testSelectIntoSingleStep); - CppUnit_addTest(pSuite, SQLiteTest, testSelectIntoSingleFail); - CppUnit_addTest(pSuite, SQLiteTest, testLowerLimitOk); - CppUnit_addTest(pSuite, SQLiteTest, testLowerLimitFail); - CppUnit_addTest(pSuite, SQLiteTest, testCombinedLimits); - CppUnit_addTest(pSuite, SQLiteTest, testCombinedIllegalLimits); - CppUnit_addTest(pSuite, SQLiteTest, testRange); - CppUnit_addTest(pSuite, SQLiteTest, testIllegalRange); - CppUnit_addTest(pSuite, SQLiteTest, testSingleSelect); - CppUnit_addTest(pSuite, SQLiteTest, testEmptyDB); - CppUnit_addTest(pSuite, SQLiteTest, testBLOB); - CppUnit_addTest(pSuite, SQLiteTest, testBLOBStmt); - CppUnit_addTest(pSuite, SQLiteTest, testTuple10); - CppUnit_addTest(pSuite, SQLiteTest, testTupleVector10); - CppUnit_addTest(pSuite, SQLiteTest, testTuple9); - CppUnit_addTest(pSuite, SQLiteTest, testTupleVector9); - CppUnit_addTest(pSuite, SQLiteTest, testTuple8); - CppUnit_addTest(pSuite, SQLiteTest, testTupleVector8); - CppUnit_addTest(pSuite, SQLiteTest, testTuple7); - CppUnit_addTest(pSuite, SQLiteTest, testTupleVector7); - CppUnit_addTest(pSuite, SQLiteTest, testTuple6); - CppUnit_addTest(pSuite, SQLiteTest, testTupleVector6); - CppUnit_addTest(pSuite, SQLiteTest, testTuple5); - CppUnit_addTest(pSuite, SQLiteTest, testTupleVector5); - CppUnit_addTest(pSuite, SQLiteTest, testTuple4); - CppUnit_addTest(pSuite, SQLiteTest, testTupleVector4); - CppUnit_addTest(pSuite, SQLiteTest, testTuple3); - CppUnit_addTest(pSuite, SQLiteTest, testTupleVector3); - CppUnit_addTest(pSuite, SQLiteTest, testTuple2); - CppUnit_addTest(pSuite, SQLiteTest, testTupleVector2); - CppUnit_addTest(pSuite, SQLiteTest, testTuple1); - CppUnit_addTest(pSuite, SQLiteTest, testTupleVector1); - CppUnit_addTest(pSuite, SQLiteTest, testInternalExtraction); - CppUnit_addTest(pSuite, SQLiteTest, testBindingCount); - - return pSuite; -} +// +// SQLiteTest.cpp +// +// $Id: //poco/1.3/Data/SQLite/testsuite/src/SQLiteTest.cpp#5 $ +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "SQLiteTest.h" +#include "CppUnit/TestCaller.h" +#include "CppUnit/TestSuite.h" +#include "Poco/Data/Common.h" +#include "Poco/Data/BLOB.h" +#include "Poco/Data/Statement.h" +#include "Poco/Data/RecordSet.h" +#include "Poco/Data/SQLite/Connector.h" +#include "Poco/Tuple.h" +#include "Poco/Any.h" +#include "Poco/Exception.h" +#include +#include "Poco/File.h" +#include "Poco/Stopwatch.h" +#include "Poco/Data/SQLite/SQLiteException.h" + + +using namespace Poco::Data; +using Poco::Tuple; +using Poco::Any; +using Poco::AnyCast; +using Poco::InvalidAccessException; +using Poco::RangeException; +using Poco::BadCastException; +using Poco::Data::SQLite::ParameterCountMismatchException; + + +struct Person +{ + std::string lastName; + std::string firstName; + std::string address; + int age; + Person(){age = 0;} + Person(const std::string& ln, const std::string& fn, const std::string& adr, int a):lastName(ln), firstName(fn), address(adr), age(a) + { + } + bool operator==(const Person& other) const + { + return lastName == other.lastName && firstName == other.firstName && address == other.address && age == other.age; + } + + bool operator < (const Person& p) const + { + if (age < p.age) + return true; + if (lastName < p.lastName) + return true; + if (firstName < p.firstName) + return true; + return (address < p.address); + } + + const std::string& operator () () const + /// This method is required so we can extract data to a map! + { + // we choose the lastName as examplary key + return lastName; + } +}; + + +namespace Poco { +namespace Data { + + +template <> +class TypeHandler +{ +public: + static void bind(std::size_t pos, const Person& obj, AbstractBinder* pBinder) + { + // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3)) + poco_assert_dbg (pBinder != 0); + pBinder->bind(pos++, obj.lastName); + pBinder->bind(pos++, obj.firstName); + pBinder->bind(pos++, obj.address); + pBinder->bind(pos++, obj.age); + } + + static void prepare(std::size_t pos, const Person& obj, AbstractPreparation* pPrepare) + { + // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3)) + poco_assert_dbg (pPrepare != 0); + pPrepare->prepare(pos++, obj.lastName); + pPrepare->prepare(pos++, obj.firstName); + pPrepare->prepare(pos++, obj.address); + pPrepare->prepare(pos++, obj.age); + } + + static std::size_t size() + { + return 4; + } + + static void extract(std::size_t pos, Person& obj, const Person& defVal, AbstractExtractor* pExt) + { + poco_assert_dbg (pExt != 0); + std::string lastName; + std::string firstName; + std::string address; + if (!pExt->extract(pos++, obj.lastName)) + obj.lastName = defVal.lastName; + if (!pExt->extract(pos++, obj.firstName)) + obj.firstName = defVal.firstName; + if (!pExt->extract(pos++, obj.address)) + obj.address = defVal.address; + if (!pExt->extract(pos++, obj.age)) + obj.age = defVal.age; + } + +private: + TypeHandler(); + ~TypeHandler(); + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + + +} } // namespace Poco::Data + + +SQLiteTest::SQLiteTest(const std::string& name): CppUnit::TestCase(name) +{ + SQLite::Connector::registerConnector(); +} + + +SQLiteTest::~SQLiteTest() +{ + SQLite::Connector::unregisterConnector(); +} + + +void SQLiteTest::testSimpleAccess() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + assert (tmp.isConnected()); + std::string tableName("Person"); + std::string lastName("lastname"); + std::string firstName("firstname"); + std::string address("Address"); + int age = 133132; + int count = 0; + std::string result; + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "SELECT name FROM sqlite_master WHERE tbl_name=?", use(tableName), into(result), now; + assert (result == tableName); + + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastName), use(firstName), use(address), use(age), now; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 1); + tmp << "SELECT LastName FROM PERSON", into(result), now; + assert (lastName == result); + tmp << "SELECT Age FROM PERSON", into(count), now; + assert (count == age); + tmp.close(); + assert (!tmp.isConnected()); +} + + +void SQLiteTest::testComplexType() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(p1), now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(p2), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + + Person c1; + Person c2; + tmp << "SELECT * FROM PERSON WHERE LASTNAME = :ln", into(c1), use(p1.lastName), now; + assert (c1 == p1); +} + + + +void SQLiteTest::testSimpleAccessVector() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::vector lastNames; + std::vector firstNames; + std::vector addresses; + std::vector ages; + std::string tableName("Person"); + lastNames.push_back("LN1"); + lastNames.push_back("LN2"); + firstNames.push_back("FN1"); + firstNames.push_back("FN2"); + addresses.push_back("ADDR1"); + addresses.push_back("ADDR2"); + ages.push_back(1); + ages.push_back(2); + int count = 0; + std::string result; + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastNames), use(firstNames), use(addresses), use(ages), now; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + + std::vector lastNamesR; + std::vector firstNamesR; + std::vector addressesR; + std::vector agesR; + tmp << "SELECT * FROM PERSON", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; + assert (ages == agesR); + assert (lastNames == lastNamesR); + assert (firstNames == firstNamesR); + assert (addresses == addressesR); +} + + +void SQLiteTest::testComplexTypeVector() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::vector people; + people.push_back(Person("LN1", "FN1", "ADDR1", 1)); + people.push_back(Person("LN2", "FN2", "ADDR2", 2)); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + + std::vector result; + tmp << "SELECT * FROM PERSON", into(result), now; + assert (result == people); +} + + +void SQLiteTest::testInsertVector() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::vector str; + str.push_back("s1"); + str.push_back("s2"); + str.push_back("s3"); + str.push_back("s3"); + int count = 100; + tmp << "DROP TABLE IF EXISTS Strings", now; + tmp << "CREATE TABLE IF NOT EXISTS Strings (str VARCHAR(30))", now; + { + Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(str))); + tmp << "SELECT COUNT(*) FROM Strings", into(count), now; + assert (count == 0); + stmt.execute(); + tmp << "SELECT COUNT(*) FROM Strings", into(count), now; + assert (count == 4); + } + count = 0; + tmp << "SELECT COUNT(*) FROM Strings", into(count), now; + assert (count == 4); +} + + +void SQLiteTest::testInsertEmptyVector() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::vector str; + + tmp << "DROP TABLE IF EXISTS Strings", now; + tmp << "CREATE TABLE IF NOT EXISTS Strings (str VARCHAR(30))", now; + try + { + tmp << "INSERT INTO Strings VALUES(:str)", use(str), now; + fail("empty collectons should not work"); + } + catch (Poco::Exception&) + { + } +} + + +void SQLiteTest::testInsertSingleBulk() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Strings", now; + tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; + int x = 0; + Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(x))); + + for (x = 0; x < 100; ++x) + { + int i = stmt.execute(); + assert (i == 0); + } + int count = 0; + tmp << "SELECT COUNT(*) FROM Strings", into(count), now; + assert (count == 100); + tmp << "SELECT SUM(str) FROM Strings", into(count), now; + assert (count == ((0+99)*100/2)); +} + + +void SQLiteTest::testInsertSingleBulkVec() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Strings", now; + tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; + std::vector data; + data.push_back(0); + data.push_back(1); + + Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(data))); + + for (int x = 0; x < 100; x += 2) + { + data[0] = x; + data[1] = x+1; + stmt.execute(); + } + int count = 0; + tmp << "SELECT COUNT(*) FROM Strings", into(count), now; + assert (count == 100); + tmp << "SELECT SUM(str) FROM Strings", into(count), now; + assert (count == ((0+99)*100/2)); +} + + +void SQLiteTest::testLimit() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Strings", now; + tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; + std::vector data; + for (int x = 0; x < 100; ++x) + { + data.push_back(x); + } + + tmp << "INSERT INTO Strings VALUES(:str)", use(data), now; + + std::vector retData; + tmp << "SELECT * FROM Strings", into(retData), limit(50), now; + assert (retData.size() == 50); + for (int x = 0; x < 50; ++x) + { + assert(data[x] == retData[x]); + } +} + + +void SQLiteTest::testLimitZero() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Strings", now; + tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; + std::vector data; + for (int x = 0; x < 100; ++x) + { + data.push_back(x); + } + + tmp << "INSERT INTO Strings VALUES(:str)", use(data), now; + + std::vector retData; + tmp << "SELECT * FROM Strings", into(retData), limit(0), now; // stupid test, but at least we shouldn't crash + assert (retData.size() == 0); +} + + +void SQLiteTest::testLimitOnce() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Strings", now; + tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; + std::vector data; + for (int x = 0; x < 101; ++x) + { + data.push_back(x); + } + + tmp << "INSERT INTO Strings VALUES(:str)", use(data), now; + + std::vector retData; + Statement stmt = (tmp << "SELECT * FROM Strings", into(retData), limit(50), now); + assert (!stmt.done()); + assert (retData.size() == 50); + stmt.execute(); + assert (!stmt.done()); + assert (retData.size() == 100); + stmt.execute(); + assert (stmt.done()); + assert (retData.size() == 101); + + for (int x = 0; x < 101; ++x) + { + assert(data[x] == retData[x]); + } +} + + +void SQLiteTest::testLimitPrepare() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Strings", now; + tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; + std::vector data; + for (int x = 0; x < 100; ++x) + { + data.push_back(x); + } + + tmp << "INSERT INTO Strings VALUES(:str)", use(data), now; + + std::vector retData; + Statement stmt = (tmp << "SELECT * FROM Strings", into(retData), limit(50)); + assert (retData.size() == 0); + assert (!stmt.done()); + stmt.execute(); + assert (!stmt.done()); + assert (retData.size() == 50); + stmt.execute(); + assert (stmt.done()); + assert (retData.size() == 100); + stmt.execute(); // will restart execution! + assert (!stmt.done()); + assert (retData.size() == 150); + for (int x = 0; x < 150; ++x) + { + assert(data[x%100] == retData[x]); + } +} + + + +void SQLiteTest::testPrepare() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Strings", now; + tmp << "CREATE TABLE IF NOT EXISTS Strings (str INTEGER(10))", now; + std::vector data; + for (int x = 0; x < 100; x += 2) + { + data.push_back(x); + } + + { + Statement stmt((tmp << "INSERT INTO Strings VALUES(:str)", use(data))); + } + // stmt should not have been executed when destroyed + int count = 100; + tmp << "SELECT COUNT(*) FROM Strings", into(count), now; + assert (count == 0); +} + + +void SQLiteTest::testSetSimple() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::set lastNames; + std::set firstNames; + std::set addresses; + std::set ages; + std::string tableName("Person"); + lastNames.insert("LN1"); + lastNames.insert("LN2"); + firstNames.insert("FN1"); + firstNames.insert("FN2"); + addresses.insert("ADDR1"); + addresses.insert("ADDR2"); + ages.insert(1); + ages.insert(2); + int count = 0; + std::string result; + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastNames), use(firstNames), use(addresses), use(ages), now; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + + std::set lastNamesR; + std::set firstNamesR; + std::set addressesR; + std::set agesR; + tmp << "SELECT * FROM PERSON", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; + assert (ages == agesR); + assert (lastNames == lastNamesR); + assert (firstNames == firstNamesR); + assert (addresses == addressesR); +} + + +void SQLiteTest::testSetComplex() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::set people; + people.insert(Person("LN1", "FN1", "ADDR1", 1)); + people.insert(Person("LN2", "FN2", "ADDR2", 2)); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + + std::set result; + tmp << "SELECT * FROM PERSON", into(result), now; + assert (result == people); +} + + +void SQLiteTest::testSetComplexUnique() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::vector people; + Person p1("LN1", "FN1", "ADDR1", 1); + people.push_back(p1); + people.push_back(p1); + people.push_back(p1); + people.push_back(p1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.push_back(p2); + + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 5); + + std::set result; + tmp << "SELECT * FROM PERSON", into(result), now; + assert (result.size() == 2); + assert (*result.begin() == p1); + assert (*++result.begin() == p2); +} + +void SQLiteTest::testMultiSetSimple() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::multiset lastNames; + std::multiset firstNames; + std::multiset addresses; + std::multiset ages; + std::string tableName("Person"); + lastNames.insert("LN1"); + lastNames.insert("LN2"); + firstNames.insert("FN1"); + firstNames.insert("FN2"); + addresses.insert("ADDR1"); + addresses.insert("ADDR2"); + ages.insert(1); + ages.insert(2); + int count = 0; + std::string result; + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(lastNames), use(firstNames), use(addresses), use(ages), now; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + + std::multiset lastNamesR; + std::multiset firstNamesR; + std::multiset addressesR; + std::multiset agesR; + tmp << "SELECT * FROM PERSON", into(lastNamesR), into(firstNamesR), into(addressesR), into(agesR), now; + assert (ages.size() == agesR.size()); + assert (lastNames.size() == lastNamesR.size()); + assert (firstNames.size() == firstNamesR.size()); + assert (addresses.size() == addressesR.size()); +} + + +void SQLiteTest::testMultiSetComplex() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::multiset people; + Person p1("LN1", "FN1", "ADDR1", 1); + people.insert(p1); + people.insert(p1); + people.insert(p1); + people.insert(p1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(p2); + + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 5); + + std::multiset result; + tmp << "SELECT * FROM PERSON", into(result), now; + assert (result.size() == people.size()); +} + + +void SQLiteTest::testMapComplex() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::map people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN2", p2)); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + + std::map result; + tmp << "SELECT * FROM PERSON", into(result), now; + assert (result == people); +} + + +void SQLiteTest::testMapComplexUnique() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN2", p2)); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 5); + + std::map result; + tmp << "SELECT * FROM PERSON", into(result), now; + assert (result.size() == 2); +} + + +void SQLiteTest::testMultiMapComplex() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN2", p2)); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 5); + + std::multimap result; + tmp << "SELECT * FROM PERSON", into(result), now; + assert (result.size() == people.size()); +} + + +void SQLiteTest::testSelectIntoSingle() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + Person result; + tmp << "SELECT * FROM PERSON", into(result), limit(1), now; // will return 1 object into one single result + assert (result == p1); +} + + +void SQLiteTest::testSelectIntoSingleStep() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + Person result; + Statement stmt = (tmp << "SELECT * FROM PERSON", into(result), limit(1)); + stmt.execute(); + assert (result == p1); + assert (!stmt.done()); + stmt.execute(); + assert (result == p2); + assert (stmt.done()); +} + + +void SQLiteTest::testSelectIntoSingleFail() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), limit(2, true), now; + assert (count == 2); + Person result; + try + { + tmp << "SELECT * FROM PERSON", into(result), limit(1, true), now; // will fail now + fail("hardLimit is set: must fail"); + } + catch(Poco::Data::LimitException&) + { + } +} + + +void SQLiteTest::testLowerLimitOk() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + Person result; + try + { + tmp << "SELECT * FROM PERSON", into(result), lowerLimit(2), now; // will return 2 objects into one single result but only room for one! + fail("Not enough space for results"); + } + catch(Poco::Exception&) + { + } +} + + +void SQLiteTest::testSingleSelect() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + Person result; + Statement stmt = (tmp << "SELECT * FROM PERSON", into(result), limit(1)); + stmt.execute(); + assert (result == p1); + assert (!stmt.done()); + stmt.execute(); + assert (result == p2); + assert (stmt.done()); +} + + +void SQLiteTest::testLowerLimitFail() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + Person result; + try + { + tmp << "SELECT * FROM PERSON", into(result), lowerLimit(3), now; // will fail + fail("should fail. not enough data"); + } + catch(Poco::Exception&) + { + } +} + + +void SQLiteTest::testCombinedLimits() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + std::vector result; + tmp << "SELECT * FROM PERSON", into(result), lowerLimit(2), upperLimit(2), now; // will return 2 objects + assert (result.size() == 2); + assert (result[0] == p1); + assert (result[1] == p2); +} + + + +void SQLiteTest::testRange() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + std::vector result; + tmp << "SELECT * FROM PERSON", into(result), range(2, 2), now; // will return 2 objects + assert (result.size() == 2); + assert (result[0] == p1); + assert (result[1] == p2); +} + + +void SQLiteTest::testCombinedIllegalLimits() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + Person result; + try + { + tmp << "SELECT * FROM PERSON", into(result), lowerLimit(3), upperLimit(2), now; + fail("lower > upper is not allowed"); + } + catch(LimitException&) + { + } +} + + + +void SQLiteTest::testIllegalRange() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + std::multimap people; + Person p1("LN1", "FN1", "ADDR1", 1); + Person p2("LN2", "FN2", "ADDR2", 2); + people.insert(std::make_pair("LN1", p1)); + people.insert(std::make_pair("LN1", p2)); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", use(people), now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 2); + Person result; + try + { + tmp << "SELECT * FROM PERSON", into(result), range(3, 2), now; + fail("lower > upper is not allowed"); + } + catch(LimitException&) + { + } +} + + +void SQLiteTest::testEmptyDB() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))", now; + int count = 0; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 0); + Person result; + Statement stmt = (tmp << "SELECT * FROM PERSON", into(result), limit(1)); + stmt.execute(); + assert (result.firstName.empty()); + assert (stmt.done()); +} + + +void SQLiteTest::testBLOB() +{ + std::string lastName("lastname"); + std::string firstName("firstname"); + std::string address("Address"); + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Image BLOB)", now; + BLOB img("0123456789", 10); + int count = 0; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :img)", use(lastName), use(firstName), use(address), use(img), now; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 1); + BLOB res; + poco_assert (res.size() == 0); + tmp << "SELECT Image FROM Person WHERE LastName == :ln", use("lastname"), into(res), now; + poco_assert (res == img); +} + + +void SQLiteTest::testBLOBStmt() +{ + // the following test will fail becuase we use a temporary object as parameter to use + /* + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Image BLOB)", now; + BLOB img("0123456789", 10); + int count = 0; + Statement ins = (tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :img)", use("lastname"), use("firstname"), use("Address"), use(BLOB("0123456789", 10))); + ins.execute(); + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assert (count == 1); + BLOB res; + poco_assert (res.size() == 0); + Statement stmt = (tmp << "SELECT Image FROM Person WHERE LastName == :ln", use("lastname"), into(res)); + stmt.execute(); + poco_assert (res == img); + */ +} + + +void SQLiteTest::testTuple10() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " + "int7 INTEGER, int8 INTEGER, int9 INTEGER)", now; + + Tuple t(0,1,2,3,4,5,6,7,8,9); + + tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?)", use(t), now; + + Tuple ret(-10,-11,-12,-13,-14,-15,-16,-17,-18,-19); + assert (ret != t); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == t); +} + + +void SQLiteTest::testTupleVector10() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " + "int7 INTEGER, int8 INTEGER, int9 INTEGER)", now; + + Tuple t(0,1,2,3,4,5,6,7,8,9); + Tuple t10(10,11,12,13,14,15,16,17,18,19); + Tuple t100(100,101,102,103,104,105,106,107,108,109); + std::vector > v; + v.push_back(t); + v.push_back(t10); + v.push_back(t100); + + tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?,?)", use(v), now; + + int count = 0; + tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; + assert (v.size() == count); + + std::vector > ret; + assert (ret != v); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == v); +} + + +void SQLiteTest::testTuple9() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " + "int7 INTEGER, int8 INTEGER)", now; + + Tuple t(0,1,2,3,4,5,6,7,8); + + tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?)", use(t), now; + + Tuple ret(-10,-11,-12,-13,-14,-15,-16,-17,-18); + assert (ret != t); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == t); +} + + +void SQLiteTest::testTupleVector9() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " + "int7 INTEGER, int8 INTEGER)", now; + + Tuple t(0,1,2,3,4,5,6,7,8); + Tuple t10(10,11,12,13,14,15,16,17,18); + Tuple t100(100,101,102,103,104,105,106,107,108); + std::vector > v; + v.push_back(t); + v.push_back(t10); + v.push_back(t100); + + tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?,?)", use(v), now; + + int count = 0; + tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; + assert (v.size() == count); + + std::vector > ret; + assert (ret != v); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == v); +} + + +void SQLiteTest::testTuple8() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " + "int7 INTEGER)", now; + + Tuple t(0,1,2,3,4,5,6,7); + + tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?)", use(t), now; + + Tuple ret(-10,-11,-12,-13,-14,-15,-16,-17); + assert (ret != t); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == t); +} + + +void SQLiteTest::testTupleVector8() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, " + "int7 INTEGER)", now; + + Tuple t(0,1,2,3,4,5,6,7); + Tuple t10(10,11,12,13,14,15,16,17); + Tuple t100(100,101,102,103,104,105,106,107); + std::vector > v; + v.push_back(t); + v.push_back(t10); + v.push_back(t100); + + tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?,?)", use(v), now; + + int count = 0; + tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; + assert (v.size() == count); + + std::vector > ret; + assert (ret != v); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == v); +} + + +void SQLiteTest::testTuple7() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER)", now; + + Tuple t(0,1,2,3,4,5,6); + + tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?)", use(t), now; + + Tuple ret(-10,-11,-12,-13,-14,-15,-16); + assert (ret != t); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == t); +} + + +void SQLiteTest::testTupleVector7() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER)", now; + + Tuple t(0,1,2,3,4,5,6); + Tuple t10(10,11,12,13,14,15,16); + Tuple t100(100,101,102,103,104,105,106); + std::vector > v; + v.push_back(t); + v.push_back(t10); + v.push_back(t100); + + tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?,?)", use(v), now; + + int count = 0; + tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; + assert (v.size() == count); + + std::vector > ret; + assert (ret != v); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == v); +} + + +void SQLiteTest::testTuple6() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER)", now; + + Tuple t(0,1,2,3,4,5); + + tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?)", use(t), now; + + Tuple ret(-10,-11,-12,-13,-14,-15); + assert (ret != t); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == t); +} + + +void SQLiteTest::testTupleVector6() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER)", now; + + Tuple t(0,1,2,3,4,5); + Tuple t10(10,11,12,13,14,15); + Tuple t100(100,101,102,103,104,105); + std::vector > v; + v.push_back(t); + v.push_back(t10); + v.push_back(t100); + + tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?,?)", use(v), now; + + int count = 0; + tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; + assert (v.size() == count); + + std::vector > ret; + assert (ret != v); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == v); +} + + +void SQLiteTest::testTuple5() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER)", now; + + Tuple t(0,1,2,3,4); + + tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?)", use(t), now; + + Tuple ret(-10,-11,-12,-13,-14); + assert (ret != t); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == t); +} + + +void SQLiteTest::testTupleVector5() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER)", now; + + Tuple t(0,1,2,3,4); + Tuple t10(10,11,12,13,14); + Tuple t100(100,101,102,103,104); + std::vector > v; + v.push_back(t); + v.push_back(t10); + v.push_back(t100); + + tmp << "INSERT INTO Tuples VALUES (?,?,?,?,?)", use(v), now; + + int count = 0; + tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; + assert (v.size() == count); + + std::vector > ret; + assert (ret != v); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == v); +} + + +void SQLiteTest::testTuple4() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER)", now; + + Tuple t(0,1,2,3); + + tmp << "INSERT INTO Tuples VALUES (?,?,?,?)", use(t), now; + + Tuple ret(-10,-11,-12,-13); + assert (ret != t); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == t); +} + + +void SQLiteTest::testTupleVector4() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER)", now; + + Tuple t(0,1,2,3); + Tuple t10(10,11,12,13); + Tuple t100(100,101,102,103); + std::vector > v; + v.push_back(t); + v.push_back(t10); + v.push_back(t100); + + tmp << "INSERT INTO Tuples VALUES (?,?,?,?)", use(v), now; + + int count = 0; + tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; + assert (v.size() == count); + + std::vector > ret; + assert (ret != v); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == v); +} + + +void SQLiteTest::testTuple3() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER)", now; + + Tuple t(0,1,2); + + tmp << "INSERT INTO Tuples VALUES (?,?,?)", use(t), now; + + Tuple ret(-10,-11,-12); + assert (ret != t); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == t); +} + + +void SQLiteTest::testTupleVector3() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples " + "(int0 INTEGER, int1 INTEGER, int2 INTEGER)", now; + + Tuple t(0,1,2); + Tuple t10(10,11,12); + Tuple t100(100,101,102); + std::vector > v; + v.push_back(t); + v.push_back(t10); + v.push_back(t100); + + tmp << "INSERT INTO Tuples VALUES (?,?,?)", use(v), now; + + int count = 0; + tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; + assert (v.size() == count); + + std::vector > ret; + assert (ret != v); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == v); +} + + +void SQLiteTest::testTuple2() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples (int0 INTEGER, int1 INTEGER)", now; + + Tuple t(0,1); + + tmp << "INSERT INTO Tuples VALUES (?,?)", use(t), now; + + Tuple ret(-10,-11); + assert (ret != t); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == t); +} + + +void SQLiteTest::testTupleVector2() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples (int0 INTEGER, int1 INTEGER)", now; + + Tuple t(0,1); + Tuple t10(10,11); + Tuple t100(100,101); + std::vector > v; + v.push_back(t); + v.push_back(t10); + v.push_back(t100); + + tmp << "INSERT INTO Tuples VALUES (?,?)", use(v), now; + + int count = 0; + tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; + assert (v.size() == count); + + std::vector > ret; + assert (ret != v); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == v); +} + + +void SQLiteTest::testTuple1() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples (int0 INTEGER)", now; + + Tuple t(0); + + tmp << "INSERT INTO Tuples VALUES (?)", use(t), now; + + Tuple ret(-10); + assert (ret != t); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == t); +} + + +void SQLiteTest::testTupleVector1() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Tuples", now; + tmp << "CREATE TABLE Tuples (int0 INTEGER)", now; + + Tuple t(0); + Tuple t10(10); + Tuple t100(100); + std::vector > v; + v.push_back(t); + v.push_back(t10); + v.push_back(t100); + + tmp << "INSERT INTO Tuples VALUES (?)", use(v), now; + + int count = 0; + tmp << "SELECT COUNT(*) FROM Tuples", into(count), now; + assert (v.size() == count); + + std::vector > ret; + assert (ret != v); + tmp << "SELECT * FROM Tuples", into(ret), now; + assert (ret == v); +} + + +void SQLiteTest::testInternalExtraction() +{ + Session tmp (SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); + tmp << "DROP TABLE IF EXISTS Vectors", now; + tmp << "CREATE TABLE Vectors (int0 INTEGER, flt0 REAL, str0 VARCHAR)", now; + + std::vector > v; + v.push_back(Tuple(1, 1.5, "3")); + v.push_back(Tuple(2, 2.5, "4")); + v.push_back(Tuple(3, 3.5, "5")); + v.push_back(Tuple(4, 4.5, "6")); + + tmp << "INSERT INTO Vectors VALUES (?,?,?)", use(v), now; + + Statement stmt = (tmp << "SELECT * FROM Vectors", now); + RecordSet rset(stmt); + assert (3 == rset.columnCount()); + assert (4 == rset.rowCount()); + + RecordSet rset2(rset); + assert (3 == rset2.columnCount()); + assert (4 == rset2.rowCount()); + + int a = rset.value(0,2); + assert (3 == a); + + int b = rset2.value("InT0",2); + assert (3 == b); + + double d = rset.value(1,0); + assert (1.5 == d); + + std::string s = rset.value(2,1); + assert ("4" == s); + + const Column& col = rset.column(0); + assert (col[0] == 1); + + try { const Column& col1 = rset.column(100); fail ("must fail"); } + catch (RangeException&) { } + + const Column& col1 = rset.column(0); + assert ("int0" == col1.name()); + Column::Iterator it = col1.begin(); + Column::Iterator itEnd = col1.end(); + int counter = 1; + for (; it != itEnd; ++it, ++counter) + assert (counter == *it); + + rset = (tmp << "SELECT COUNT(*) FROM Vectors", now); + s = rset.value(0,0); + assert ("4" == s); + + stmt = (tmp << "DELETE FROM Vectors", now); + rset = stmt; + + try { const Column& col1 = rset.column(0); fail ("must fail"); } + catch (RangeException&) { } +} + + +void SQLiteTest::testBindingCount() +{ + Session tmp (SQLite::Connector::KEY, "dummy.db"); + + tmp << "DROP TABLE IF EXISTS Ints", now; + tmp << "CREATE TABLE Ints (int0 INTEGER)", now; + + int i = 42; + try { tmp << "INSERT INTO Ints VALUES (?)", now; } + catch (ParameterCountMismatchException&) { } + + try { tmp << "INSERT INTO Ints VALUES (?)", use(i), use(i), now; } + catch (ParameterCountMismatchException&) { } + tmp << "INSERT INTO Ints VALUES (?)", use(i), now; + + int j = 0; + try { tmp << "SELECT int0 from Ints where int0 = ?", into(i), now; } + catch (ParameterCountMismatchException&) { } + tmp << "SELECT int0 from Ints where int0 = ?", use(i), into(j), now; + assert (42 == j); +} + + +void SQLiteTest::setUp() +{ +} + + +void SQLiteTest::tearDown() +{ +} + + +CppUnit::Test* SQLiteTest::suite() +{ + CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("SQLiteTest"); + + CppUnit_addTest(pSuite, SQLiteTest, testSimpleAccess); + CppUnit_addTest(pSuite, SQLiteTest, testComplexType); + CppUnit_addTest(pSuite, SQLiteTest, testSimpleAccessVector); + CppUnit_addTest(pSuite, SQLiteTest, testComplexTypeVector); + CppUnit_addTest(pSuite, SQLiteTest, testInsertVector); + CppUnit_addTest(pSuite, SQLiteTest, testInsertEmptyVector); + CppUnit_addTest(pSuite, SQLiteTest, testInsertSingleBulk); + CppUnit_addTest(pSuite, SQLiteTest, testInsertSingleBulkVec); + CppUnit_addTest(pSuite, SQLiteTest, testLimit); + CppUnit_addTest(pSuite, SQLiteTest, testLimitOnce); + CppUnit_addTest(pSuite, SQLiteTest, testLimitPrepare); + CppUnit_addTest(pSuite, SQLiteTest, testLimitZero); + CppUnit_addTest(pSuite, SQLiteTest, testPrepare); + CppUnit_addTest(pSuite, SQLiteTest, testSetSimple); + CppUnit_addTest(pSuite, SQLiteTest, testSetComplex); + CppUnit_addTest(pSuite, SQLiteTest, testSetComplexUnique); + CppUnit_addTest(pSuite, SQLiteTest, testMultiSetSimple); + CppUnit_addTest(pSuite, SQLiteTest, testMultiSetComplex); + CppUnit_addTest(pSuite, SQLiteTest, testMapComplex); + CppUnit_addTest(pSuite, SQLiteTest, testMapComplexUnique); + CppUnit_addTest(pSuite, SQLiteTest, testMultiMapComplex); + CppUnit_addTest(pSuite, SQLiteTest, testSelectIntoSingle); + CppUnit_addTest(pSuite, SQLiteTest, testSelectIntoSingleStep); + CppUnit_addTest(pSuite, SQLiteTest, testSelectIntoSingleFail); + CppUnit_addTest(pSuite, SQLiteTest, testLowerLimitOk); + CppUnit_addTest(pSuite, SQLiteTest, testLowerLimitFail); + CppUnit_addTest(pSuite, SQLiteTest, testCombinedLimits); + CppUnit_addTest(pSuite, SQLiteTest, testCombinedIllegalLimits); + CppUnit_addTest(pSuite, SQLiteTest, testRange); + CppUnit_addTest(pSuite, SQLiteTest, testIllegalRange); + CppUnit_addTest(pSuite, SQLiteTest, testSingleSelect); + CppUnit_addTest(pSuite, SQLiteTest, testEmptyDB); + CppUnit_addTest(pSuite, SQLiteTest, testBLOB); + CppUnit_addTest(pSuite, SQLiteTest, testBLOBStmt); + CppUnit_addTest(pSuite, SQLiteTest, testTuple10); + CppUnit_addTest(pSuite, SQLiteTest, testTupleVector10); + CppUnit_addTest(pSuite, SQLiteTest, testTuple9); + CppUnit_addTest(pSuite, SQLiteTest, testTupleVector9); + CppUnit_addTest(pSuite, SQLiteTest, testTuple8); + CppUnit_addTest(pSuite, SQLiteTest, testTupleVector8); + CppUnit_addTest(pSuite, SQLiteTest, testTuple7); + CppUnit_addTest(pSuite, SQLiteTest, testTupleVector7); + CppUnit_addTest(pSuite, SQLiteTest, testTuple6); + CppUnit_addTest(pSuite, SQLiteTest, testTupleVector6); + CppUnit_addTest(pSuite, SQLiteTest, testTuple5); + CppUnit_addTest(pSuite, SQLiteTest, testTupleVector5); + CppUnit_addTest(pSuite, SQLiteTest, testTuple4); + CppUnit_addTest(pSuite, SQLiteTest, testTupleVector4); + CppUnit_addTest(pSuite, SQLiteTest, testTuple3); + CppUnit_addTest(pSuite, SQLiteTest, testTupleVector3); + CppUnit_addTest(pSuite, SQLiteTest, testTuple2); + CppUnit_addTest(pSuite, SQLiteTest, testTupleVector2); + CppUnit_addTest(pSuite, SQLiteTest, testTuple1); + CppUnit_addTest(pSuite, SQLiteTest, testTupleVector1); + CppUnit_addTest(pSuite, SQLiteTest, testInternalExtraction); + CppUnit_addTest(pSuite, SQLiteTest, testBindingCount); + + return pSuite; +} diff --git a/Data/SQLite/testsuite/src/SQLiteTest.h b/Data/SQLite/testsuite/src/SQLiteTest.h index a42dbf97d..17feb4b45 100644 --- a/Data/SQLite/testsuite/src/SQLiteTest.h +++ b/Data/SQLite/testsuite/src/SQLiteTest.h @@ -1,121 +1,121 @@ -// -// SQLiteTest.h -// -// $Id: //poco/1.3/Data/SQLite/testsuite/src/SQLiteTest.h#4 $ -// -// Definition of the SQLiteTest class. -// -// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef SQLiteTest_INCLUDED -#define SQLiteTest_INCLUDED - - -#include "Poco/Data/SQLite/SQLite.h" -#include "CppUnit/TestCase.h" - - -class SQLiteTest: public CppUnit::TestCase -{ -public: - SQLiteTest(const std::string& name); - ~SQLiteTest(); - - void testSimpleAccess(); - void testComplexType(); - void testSimpleAccessVector(); - void testComplexTypeVector(); - void testInsertVector(); - void testInsertEmptyVector(); - - void testInsertSingleBulk(); - void testInsertSingleBulkVec(); - - void testLimit(); - void testLimitOnce(); - void testLimitPrepare(); - void testLimitZero(); - void testPrepare(); - - void testSetSimple(); - void testSetComplex(); - void testSetComplexUnique(); - void testMultiSetSimple(); - void testMultiSetComplex(); - void testMapComplex(); - void testMapComplexUnique(); - void testMultiMapComplex(); - void testSelectIntoSingle(); - void testSelectIntoSingleStep(); - void testSelectIntoSingleFail(); - void testLowerLimitOk(); - void testLowerLimitFail(); - void testCombinedLimits(); - void testCombinedIllegalLimits(); - void testRange(); - void testIllegalRange(); - void testSingleSelect(); - void testEmptyDB(); - - void testBLOB(); - void testBLOBStmt(); - - void testTuple1(); - void testTupleVector1(); - void testTuple2(); - void testTupleVector2(); - void testTuple3(); - void testTupleVector3(); - void testTuple4(); - void testTupleVector4(); - void testTuple5(); - void testTupleVector5(); - void testTuple6(); - void testTupleVector6(); - void testTuple7(); - void testTupleVector7(); - void testTuple8(); - void testTupleVector8(); - void testTuple9(); - void testTupleVector9(); - void testTuple10(); - void testTupleVector10(); - - void testInternalExtraction(); - void testBindingCount(); - - void setUp(); - void tearDown(); - - static CppUnit::Test* suite(); - -private: -}; - - -#endif // SQLiteTest_INCLUDED +// +// SQLiteTest.h +// +// $Id: //poco/1.3/Data/SQLite/testsuite/src/SQLiteTest.h#5 $ +// +// Definition of the SQLiteTest class. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef SQLiteTest_INCLUDED +#define SQLiteTest_INCLUDED + + +#include "Poco/Data/SQLite/SQLite.h" +#include "CppUnit/TestCase.h" + + +class SQLiteTest: public CppUnit::TestCase +{ +public: + SQLiteTest(const std::string& name); + ~SQLiteTest(); + + void testSimpleAccess(); + void testComplexType(); + void testSimpleAccessVector(); + void testComplexTypeVector(); + void testInsertVector(); + void testInsertEmptyVector(); + + void testInsertSingleBulk(); + void testInsertSingleBulkVec(); + + void testLimit(); + void testLimitOnce(); + void testLimitPrepare(); + void testLimitZero(); + void testPrepare(); + + void testSetSimple(); + void testSetComplex(); + void testSetComplexUnique(); + void testMultiSetSimple(); + void testMultiSetComplex(); + void testMapComplex(); + void testMapComplexUnique(); + void testMultiMapComplex(); + void testSelectIntoSingle(); + void testSelectIntoSingleStep(); + void testSelectIntoSingleFail(); + void testLowerLimitOk(); + void testLowerLimitFail(); + void testCombinedLimits(); + void testCombinedIllegalLimits(); + void testRange(); + void testIllegalRange(); + void testSingleSelect(); + void testEmptyDB(); + + void testBLOB(); + void testBLOBStmt(); + + void testTuple1(); + void testTupleVector1(); + void testTuple2(); + void testTupleVector2(); + void testTuple3(); + void testTupleVector3(); + void testTuple4(); + void testTupleVector4(); + void testTuple5(); + void testTupleVector5(); + void testTuple6(); + void testTupleVector6(); + void testTuple7(); + void testTupleVector7(); + void testTuple8(); + void testTupleVector8(); + void testTuple9(); + void testTupleVector9(); + void testTuple10(); + void testTupleVector10(); + + void testInternalExtraction(); + void testBindingCount(); + + void setUp(); + void tearDown(); + + static CppUnit::Test* suite(); + +private: +}; + + +#endif // SQLiteTest_INCLUDED diff --git a/Data/include/Poco/Data/BLOB.h b/Data/include/Poco/Data/BLOB.h index 6da45e343..498767d27 100644 --- a/Data/include/Poco/Data/BLOB.h +++ b/Data/include/Poco/Data/BLOB.h @@ -1,314 +1,314 @@ -// -// BLOB.h -// -// $Id: //poco/1.3/Data/include/Poco/Data/BLOB.h#5 $ -// -// Library: Data -// Package: DataCore -// Module: BLOB -// -// Definition of the BLOB class. -// -// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef Data_BLOB_INCLUDED -#define Data_BLOB_INCLUDED - - -#include "Poco/Data/Data.h" -#include "Poco/SharedPtr.h" -#include "Poco/DynamicAnyHolder.h" -#include "Poco/Exception.h" -#include - - -namespace Poco { -namespace Data { - - -class Data_API BLOB - /// Representation of a Binary Large OBject. - /// - /// A BLOB can hold arbitrary binary data. - /// The maximum size depends on the underlying database. - /// - /// The BLOBInputStream and BLOBOutputStream classes provide - /// a convenient way to access the data in a BLOB. -{ -public: - typedef std::vector::const_iterator Iterator; - - BLOB(); - /// Creates an empty BLOB. - - BLOB(const std::vector& content); - /// Creates the BLOB, content is deep-copied. - - BLOB(const char* const pContent, std::size_t size); - /// Creates the BLOB by deep-copying pContent. - - BLOB(const std::string& content); - /// Creates a BLOB from a string. - - BLOB(const BLOB& other); - /// Creates a BLOB by copying another one. - - ~BLOB(); - /// Destroys the BLOB. - - BLOB& operator = (const BLOB& other); - /// Assignment operator. - - bool operator == (const BLOB& other) const; - /// Compares for equality BLOB by value. - - bool operator != (const BLOB& other) const; - /// Compares for inequality BLOB by value. - - void swap(BLOB& other); - /// Swaps the BLOB with another one. - - const std::vector& content() const; - /// Returns the content. - - const char* rawContent() const; - /// Returns the raw content. - - void assignRaw(const char* pChar, std::size_t count); - /// Assigns raw content to internal storage. - - void appendRaw(const char* pChar, std::size_t count); - /// Assigns raw content to internal storage. - - void clear(bool doCompact = false); - /// Clears the content of the blob. - /// If doCompact is true, trims the excess capacity. - - void compact(); - /// Trims the internal storage excess capacity. - - Iterator begin() const; - Iterator end() const; - - std::size_t size() const; - /// Returns the size of the BLOB in bytes. - -private: - Poco::SharedPtr > _pContent; - - friend class BLOBStreamBuf; -}; - - -// -// inlines -// -inline const std::vector& BLOB::content() const -{ - return *_pContent; -} - - -inline const char* BLOB::rawContent() const -{ - return &(*_pContent)[0]; -} - - -inline std::size_t BLOB::size() const -{ - return _pContent->size(); -} - - -inline bool BLOB::operator == (const BLOB& other) const -{ - return *_pContent == *other._pContent; -} - - -inline bool BLOB::operator != (const BLOB& other) const -{ - return *_pContent != *other._pContent; -} - - -inline BLOB::Iterator BLOB::begin() const -{ - return _pContent->begin(); -} - - -inline BLOB::Iterator BLOB::end() const -{ - return _pContent->end(); -} - - -inline void BLOB::assignRaw(const char* pChar, std::size_t count) -{ - poco_assert_dbg (pChar); - BLOB tmp(pChar, count); - swap(tmp); -} - - -inline void BLOB::appendRaw(const char* pChar, std::size_t count) -{ - poco_assert_dbg (pChar); - _pContent->insert(_pContent->end(), pChar, pChar+count); -} - - -inline void BLOB::swap(BLOB& other) -{ - using std::swap; - swap(_pContent, other._pContent); -} - - -inline void BLOB::clear(bool doCompact) -{ - _pContent->clear(); - if (doCompact) compact(); -} - - -inline void BLOB::compact() -{ - std::vector(*_pContent).swap(*_pContent); -} - - -} } // namespace Poco::Data - - -// -// DynamicAnyHolderImpl -// - - -namespace Poco { - - -template <> -class DynamicAnyHolderImpl: public DynamicAnyHolder -{ -public: - DynamicAnyHolderImpl(const Data::BLOB& val): _val(val) - { - } - - ~DynamicAnyHolderImpl() - { - } - - const std::type_info& type() const - { - return typeid(Data::BLOB); - } - - void convert(Int8& val) const - { - throw Poco::BadCastException(); - } - - void convert(Int16& val) const - { - throw Poco::BadCastException(); - } - - void convert(Int32& val) const - { - throw Poco::BadCastException(); - } - - void convert(Int64& val) const - { - throw Poco::BadCastException(); - } - - void convert(UInt8& val) const - { - throw Poco::BadCastException(); - } - - void convert(UInt16& val) const - { - throw Poco::BadCastException(); - } - - void convert(UInt32& val) const - { - throw Poco::BadCastException(); - } - - void convert(UInt64& val) const - { - throw Poco::BadCastException(); - } - - void convert(bool& val) const - { - throw Poco::BadCastException(); - } - - void convert(float& val) const - { - throw Poco::BadCastException(); - } - - void convert(double& val) const - { - throw Poco::BadCastException(); - } - - void convert(char& val) const - { - throw Poco::BadCastException(); - } - - void convert(std::string& val) const - { - val.assign(_val.begin(), _val.end()); - } - - DynamicAnyHolder* clone() const - { - return new DynamicAnyHolderImpl(_val); - } - -private: - Data::BLOB _val; -}; - - -} // namespace Poco - - -#endif // Data_BLOB_INCLUDED +// +// BLOB.h +// +// $Id: //poco/1.3/Data/include/Poco/Data/BLOB.h#6 $ +// +// Library: Data +// Package: DataCore +// Module: BLOB +// +// Definition of the BLOB class. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Data_BLOB_INCLUDED +#define Data_BLOB_INCLUDED + + +#include "Poco/Data/Data.h" +#include "Poco/SharedPtr.h" +#include "Poco/DynamicAnyHolder.h" +#include "Poco/Exception.h" +#include + + +namespace Poco { +namespace Data { + + +class Data_API BLOB + /// Representation of a Binary Large OBject. + /// + /// A BLOB can hold arbitrary binary data. + /// The maximum size depends on the underlying database. + /// + /// The BLOBInputStream and BLOBOutputStream classes provide + /// a convenient way to access the data in a BLOB. +{ +public: + typedef std::vector::const_iterator Iterator; + + BLOB(); + /// Creates an empty BLOB. + + BLOB(const std::vector& content); + /// Creates the BLOB, content is deep-copied. + + BLOB(const char* const pContent, std::size_t size); + /// Creates the BLOB by deep-copying pContent. + + BLOB(const std::string& content); + /// Creates a BLOB from a string. + + BLOB(const BLOB& other); + /// Creates a BLOB by copying another one. + + ~BLOB(); + /// Destroys the BLOB. + + BLOB& operator = (const BLOB& other); + /// Assignment operator. + + bool operator == (const BLOB& other) const; + /// Compares for equality BLOB by value. + + bool operator != (const BLOB& other) const; + /// Compares for inequality BLOB by value. + + void swap(BLOB& other); + /// Swaps the BLOB with another one. + + const std::vector& content() const; + /// Returns the content. + + const char* rawContent() const; + /// Returns the raw content. + + void assignRaw(const char* pChar, std::size_t count); + /// Assigns raw content to internal storage. + + void appendRaw(const char* pChar, std::size_t count); + /// Assigns raw content to internal storage. + + void clear(bool doCompact = false); + /// Clears the content of the blob. + /// If doCompact is true, trims the excess capacity. + + void compact(); + /// Trims the internal storage excess capacity. + + Iterator begin() const; + Iterator end() const; + + std::size_t size() const; + /// Returns the size of the BLOB in bytes. + +private: + Poco::SharedPtr > _pContent; + + friend class BLOBStreamBuf; +}; + + +// +// inlines +// +inline const std::vector& BLOB::content() const +{ + return *_pContent; +} + + +inline const char* BLOB::rawContent() const +{ + return &(*_pContent)[0]; +} + + +inline std::size_t BLOB::size() const +{ + return _pContent->size(); +} + + +inline bool BLOB::operator == (const BLOB& other) const +{ + return *_pContent == *other._pContent; +} + + +inline bool BLOB::operator != (const BLOB& other) const +{ + return *_pContent != *other._pContent; +} + + +inline BLOB::Iterator BLOB::begin() const +{ + return _pContent->begin(); +} + + +inline BLOB::Iterator BLOB::end() const +{ + return _pContent->end(); +} + + +inline void BLOB::assignRaw(const char* pChar, std::size_t count) +{ + poco_assert_dbg (pChar); + BLOB tmp(pChar, count); + swap(tmp); +} + + +inline void BLOB::appendRaw(const char* pChar, std::size_t count) +{ + poco_assert_dbg (pChar); + _pContent->insert(_pContent->end(), pChar, pChar+count); +} + + +inline void BLOB::swap(BLOB& other) +{ + using std::swap; + swap(_pContent, other._pContent); +} + + +inline void BLOB::clear(bool doCompact) +{ + _pContent->clear(); + if (doCompact) compact(); +} + + +inline void BLOB::compact() +{ + std::vector(*_pContent).swap(*_pContent); +} + + +} } // namespace Poco::Data + + +// +// DynamicAnyHolderImpl +// + + +namespace Poco { + + +template <> +class DynamicAnyHolderImpl: public DynamicAnyHolder +{ +public: + DynamicAnyHolderImpl(const Data::BLOB& val): _val(val) + { + } + + ~DynamicAnyHolderImpl() + { + } + + const std::type_info& type() const + { + return typeid(Data::BLOB); + } + + void convert(Int8& val) const + { + throw Poco::BadCastException(); + } + + void convert(Int16& val) const + { + throw Poco::BadCastException(); + } + + void convert(Int32& val) const + { + throw Poco::BadCastException(); + } + + void convert(Int64& val) const + { + throw Poco::BadCastException(); + } + + void convert(UInt8& val) const + { + throw Poco::BadCastException(); + } + + void convert(UInt16& val) const + { + throw Poco::BadCastException(); + } + + void convert(UInt32& val) const + { + throw Poco::BadCastException(); + } + + void convert(UInt64& val) const + { + throw Poco::BadCastException(); + } + + void convert(bool& val) const + { + throw Poco::BadCastException(); + } + + void convert(float& val) const + { + throw Poco::BadCastException(); + } + + void convert(double& val) const + { + throw Poco::BadCastException(); + } + + void convert(char& val) const + { + throw Poco::BadCastException(); + } + + void convert(std::string& val) const + { + val.assign(_val.begin(), _val.end()); + } + + DynamicAnyHolder* clone() const + { + return new DynamicAnyHolderImpl(_val); + } + +private: + Data::BLOB _val; +}; + + +} // namespace Poco + + +#endif // Data_BLOB_INCLUDED diff --git a/Data/samples/Binding/Binding_vs90.vcproj b/Data/samples/Binding/Binding_vs90.vcproj new file mode 100644 index 000000000..cce29f5fa --- /dev/null +++ b/Data/samples/Binding/Binding_vs90.vcproj @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Data/samples/Binding/src/Binding.cpp b/Data/samples/Binding/src/Binding.cpp index e836ae88d..9e940ff89 100644 --- a/Data/samples/Binding/src/Binding.cpp +++ b/Data/samples/Binding/src/Binding.cpp @@ -1,115 +1,115 @@ -// -// Binding.cpp -// -// $Id: //poco/1.3/Data/samples/Binding/src/Binding.cpp#3 $ -// -// This sample demonstrates the Data library. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - - -#include "Poco/SharedPtr.h" -#include "Poco/Data/SessionFactory.h" -#include "Poco/Data/Session.h" -#include "Poco/Data/SQLite/Connector.h" -#include -#include - - -using namespace Poco::Data; - - -struct Person -{ - std::string name; - std::string address; - int age; -}; - - -int main(int argc, char** argv) -{ - // register SQLite connector - Poco::Data::SQLite::Connector::registerConnector(); - - // create a session - Session session("SQLite", "sample.db"); - - // drop sample table, if it exists - session << "DROP TABLE IF EXISTS Person", now; - - // (re)create table - session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now; - - // insert some rows - Person person = - { - "Bart Simpson", - "Springfield", - 12 - }; - - Statement insert(session); - insert << "INSERT INTO Person VALUES(?, ?, ?)", - use(person.name), - use(person.address), - use(person.age); - - insert.execute(); - - person.name = "Lisa Simpson"; - person.address = "Springfield"; - person.age = 10; - - insert.execute(); - - // a simple query - Statement select(session); - select << "SELECT Name, Address, Age FROM Person", - into(person.name), - into(person.address), - into(person.age), - range(0, 1); // iterate over result set one row at a time - - while (!select.done()) - { - select.execute(); - std::cout << person.name << " " << person.address << " " << person.age << std::endl; - } - - // another query - store the result in a container - std::vector names; - session << "SELECT Name FROM Person", - into(names), - now; - - for (std::vector::const_iterator it = names.begin(); it != names.end(); ++it) - { - std::cout << *it << std::endl; - } - - return 0; -} +// +// Binding.cpp +// +// $Id: //poco/1.3/Data/samples/Binding/src/Binding.cpp#4 $ +// +// This sample demonstrates the Data library. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + + +#include "Poco/SharedPtr.h" +#include "Poco/Data/SessionFactory.h" +#include "Poco/Data/Session.h" +#include "Poco/Data/SQLite/Connector.h" +#include +#include + + +using namespace Poco::Data; + + +struct Person +{ + std::string name; + std::string address; + int age; +}; + + +int main(int argc, char** argv) +{ + // register SQLite connector + Poco::Data::SQLite::Connector::registerConnector(); + + // create a session + Session session("SQLite", "sample.db"); + + // drop sample table, if it exists + session << "DROP TABLE IF EXISTS Person", now; + + // (re)create table + session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now; + + // insert some rows + Person person = + { + "Bart Simpson", + "Springfield", + 12 + }; + + Statement insert(session); + insert << "INSERT INTO Person VALUES(?, ?, ?)", + use(person.name), + use(person.address), + use(person.age); + + insert.execute(); + + person.name = "Lisa Simpson"; + person.address = "Springfield"; + person.age = 10; + + insert.execute(); + + // a simple query + Statement select(session); + select << "SELECT Name, Address, Age FROM Person", + into(person.name), + into(person.address), + into(person.age), + range(0, 1); // iterate over result set one row at a time + + while (!select.done()) + { + select.execute(); + std::cout << person.name << " " << person.address << " " << person.age << std::endl; + } + + // another query - store the result in a container + std::vector names; + session << "SELECT Name FROM Person", + into(names), + now; + + for (std::vector::const_iterator it = names.begin(); it != names.end(); ++it) + { + std::cout << *it << std::endl; + } + + return 0; +} diff --git a/Data/samples/RecordSet/RecordSet_vs90.vcproj b/Data/samples/RecordSet/RecordSet_vs90.vcproj new file mode 100644 index 000000000..166f92e01 --- /dev/null +++ b/Data/samples/RecordSet/RecordSet_vs90.vcproj @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Data/samples/RecordSet/src/RecordSet.cpp b/Data/samples/RecordSet/src/RecordSet.cpp index ccf4e1068..9549905da 100644 --- a/Data/samples/RecordSet/src/RecordSet.cpp +++ b/Data/samples/RecordSet/src/RecordSet.cpp @@ -1,98 +1,98 @@ -// -// RecordSet.cpp -// -// $Id: //poco/1.3/Data/samples/RecordSet/src/RecordSet.cpp#2 $ -// -// This sample demonstrates the Data library. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - - -#include "Poco/SharedPtr.h" -#include "Poco/Data/SessionFactory.h" -#include "Poco/Data/Session.h" -#include "Poco/Data/RecordSet.h" -#include "Poco/Data/Column.h" -#include "Poco/Data/SQLite/Connector.h" -#include - - -using namespace Poco::Data; - - -struct Person -{ - std::string name; - std::string address; - int age; -}; - - -int main(int argc, char** argv) -{ - // register SQLite connector - Poco::Data::SQLite::Connector::registerConnector(); - - // create a session - Session session("SQLite", "sample.db"); - - // drop sample table, if it exists - session << "DROP TABLE IF EXISTS Person", now; - - // (re)create table - session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now; - - // insert some rows - session << "INSERT INTO Person VALUES('Bart Simpson', 'Springfield', 12)", now; - session << "INSERT INTO Person VALUES('Lisa Simpson', 'Springfield', 10)", now; - - // a simple query - Statement select(session); - select << "SELECT * FROM Person"; - select.execute(); - - // create a RecordSet - RecordSet rs(select); - std::size_t cols = rs.columnCount(); - // print all column names - for (std::size_t col = 0; col < cols; ++col) - { - std::cout << rs.columnName(col) << std::endl; - } - // iterate over all rows and columns - bool more = rs.moveFirst(); - while (more) - { - for (std::size_t col = 0; col < cols; ++col) - { - std::cout << rs[col].convert() << " "; - } - std::cout << std::endl; - more = rs.moveNext(); - } - - return 0; -} +// +// RecordSet.cpp +// +// $Id: //poco/1.3/Data/samples/RecordSet/src/RecordSet.cpp#3 $ +// +// This sample demonstrates the Data library. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + + +#include "Poco/SharedPtr.h" +#include "Poco/Data/SessionFactory.h" +#include "Poco/Data/Session.h" +#include "Poco/Data/RecordSet.h" +#include "Poco/Data/Column.h" +#include "Poco/Data/SQLite/Connector.h" +#include + + +using namespace Poco::Data; + + +struct Person +{ + std::string name; + std::string address; + int age; +}; + + +int main(int argc, char** argv) +{ + // register SQLite connector + Poco::Data::SQLite::Connector::registerConnector(); + + // create a session + Session session("SQLite", "sample.db"); + + // drop sample table, if it exists + session << "DROP TABLE IF EXISTS Person", now; + + // (re)create table + session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now; + + // insert some rows + session << "INSERT INTO Person VALUES('Bart Simpson', 'Springfield', 12)", now; + session << "INSERT INTO Person VALUES('Lisa Simpson', 'Springfield', 10)", now; + + // a simple query + Statement select(session); + select << "SELECT * FROM Person"; + select.execute(); + + // create a RecordSet + RecordSet rs(select); + std::size_t cols = rs.columnCount(); + // print all column names + for (std::size_t col = 0; col < cols; ++col) + { + std::cout << rs.columnName(col) << std::endl; + } + // iterate over all rows and columns + bool more = rs.moveFirst(); + while (more) + { + for (std::size_t col = 0; col < cols; ++col) + { + std::cout << rs[col].convert() << " "; + } + std::cout << std::endl; + more = rs.moveNext(); + } + + return 0; +} diff --git a/Data/samples/Tuple/Tuple_vs90.vcproj b/Data/samples/Tuple/Tuple_vs90.vcproj new file mode 100644 index 000000000..7ed2f9e24 --- /dev/null +++ b/Data/samples/Tuple/Tuple_vs90.vcproj @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Data/samples/Tuple/src/Tuple.cpp b/Data/samples/Tuple/src/Tuple.cpp index 6e38fbc7c..a70e62d21 100644 --- a/Data/samples/Tuple/src/Tuple.cpp +++ b/Data/samples/Tuple/src/Tuple.cpp @@ -1,88 +1,88 @@ -// -// Tuple.cpp -// -// $Id: //poco/1.3/Data/samples/Tuple/src/Tuple.cpp#3 $ -// -// This sample demonstrates the Data library. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - - -#include "Poco/SharedPtr.h" -#include "Poco/Tuple.h" -#include "Poco/Data/SessionFactory.h" -#include "Poco/Data/Session.h" -#include "Poco/Data/SQLite/Connector.h" -#include -#include - - -using namespace Poco::Data; - - -int main(int argc, char** argv) -{ - typedef Poco::Tuple Person; - typedef std::vector People; - - // register SQLite connector - Poco::Data::SQLite::Connector::registerConnector(); - - // create a session - Session session("SQLite", "sample.db"); - - // drop sample table, if it exists - session << "DROP TABLE IF EXISTS Person", now; - - // (re)create table - session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now; - - // insert some rows - People people; - people.push_back(Person("Bart Simpson", "Springfield", 12)); - people.push_back(Person("Lisa Simpson", "Springfield", 10)); - - Statement insert(session); - insert << "INSERT INTO Person VALUES(?, ?, ?)", - use(people), now; - - people.clear(); - - // a simple query - Statement select(session); - select << "SELECT Name, Address, Age FROM Person", - into(people), - now; - - for (People::const_iterator it = people.begin(); it != people.end(); ++it) - { - std::cout << "Name: " << it->get<0>() << - ", Address: " << it->get<1>() << - ", Age: " << it->get<2>() < +#include + + +using namespace Poco::Data; + + +int main(int argc, char** argv) +{ + typedef Poco::Tuple Person; + typedef std::vector People; + + // register SQLite connector + Poco::Data::SQLite::Connector::registerConnector(); + + // create a session + Session session("SQLite", "sample.db"); + + // drop sample table, if it exists + session << "DROP TABLE IF EXISTS Person", now; + + // (re)create table + session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now; + + // insert some rows + People people; + people.push_back(Person("Bart Simpson", "Springfield", 12)); + people.push_back(Person("Lisa Simpson", "Springfield", 10)); + + Statement insert(session); + insert << "INSERT INTO Person VALUES(?, ?, ?)", + use(people), now; + + people.clear(); + + // a simple query + Statement select(session); + select << "SELECT Name, Address, Age FROM Person", + into(people), + now; + + for (People::const_iterator it = people.begin(); it != people.end(); ++it) + { + std::cout << "Name: " << it->get<0>() << + ", Address: " << it->get<1>() << + ", Age: " << it->get<2>() < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Data/samples/TypeHandler/src/TypeHandler.cpp b/Data/samples/TypeHandler/src/TypeHandler.cpp index efdcb0ac8..44ee7804a 100644 --- a/Data/samples/TypeHandler/src/TypeHandler.cpp +++ b/Data/samples/TypeHandler/src/TypeHandler.cpp @@ -1,153 +1,153 @@ -// -// Binding.cpp -// -// $Id: //poco/1.3/Data/samples/TypeHandler/src/TypeHandler.cpp#3 $ -// -// This sample demonstrates the Data library. -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - - -#include "Poco/SharedPtr.h" -#include "Poco/Data/SessionFactory.h" -#include "Poco/Data/Session.h" -#include "Poco/Data/TypeHandler.h" -#include "Poco/Data/SQLite/Connector.h" -#include -#include - - -using namespace Poco::Data; - - -struct Person -{ - std::string name; - std::string address; - int age; -}; - - -namespace Poco { -namespace Data { - - -template <> -class TypeHandler - /// Defining a specialization of TypeHandler for Person allows us - /// to use the Person struct in use and into clauses. -{ -public: - static std::size_t size() - { - return 3; - } - - static void bind(std::size_t pos, const Person& person, AbstractBinder* pBinder) - { - TypeHandler::bind(pos++, person.name, pBinder); - TypeHandler::bind(pos++, person.address, pBinder); - TypeHandler::bind(pos++, person.age, pBinder); - } - - static void extract(std::size_t pos, Person& person, const Person& deflt, AbstractExtractor* pExtr) - { - TypeHandler::extract(pos++, person.name, deflt.name, pExtr); - TypeHandler::extract(pos++, person.address, deflt.address, pExtr); - TypeHandler::extract(pos++, person.age, deflt.age, pExtr); - } - - static void prepare(std::size_t pos, const Person& person, AbstractPreparation* pPrep) - { - TypeHandler::prepare(pos++, person.name, pPrep); - TypeHandler::prepare(pos++, person.address, pPrep); - TypeHandler::prepare(pos++, person.age, pPrep); - } -}; - - -} } // namespace Poco::Data - - -int main(int argc, char** argv) -{ - // register SQLite connector - Poco::Data::SQLite::Connector::registerConnector(); - - // create a session - Session session("SQLite", "sample.db"); - - // drop sample table, if it exists - session << "DROP TABLE IF EXISTS Person", now; - - // (re)create table - session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now; - - // insert some rows - Person person = - { - "Bart Simpson", - "Springfield", - 12 - }; - - Statement insert(session); - insert << "INSERT INTO Person VALUES(?, ?, ?)", - use(person); - - insert.execute(); - - person.name = "Lisa Simpson"; - person.address = "Springfield"; - person.age = 10; - - insert.execute(); - - // a simple query - Statement select(session); - select << "SELECT Name, Address, Age FROM Person", - into(person), - range(0, 1); // iterate over result set one row at a time - - while (!select.done()) - { - select.execute(); - std::cout << person.name << " " << person.address << " " << person.age << std::endl; - } - - // another query - store the result in a container - std::vector persons; - session << "SELECT Name, Address, Age FROM Person", - into(persons), - now; - - for (std::vector::const_iterator it = persons.begin(); it != persons.end(); ++it) - { - std::cout << it->name << " " << it->address << " " << it->age << std::endl; - } - - return 0; -} +// +// Binding.cpp +// +// $Id: //poco/1.3/Data/samples/TypeHandler/src/TypeHandler.cpp#4 $ +// +// This sample demonstrates the Data library. +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + + +#include "Poco/SharedPtr.h" +#include "Poco/Data/SessionFactory.h" +#include "Poco/Data/Session.h" +#include "Poco/Data/TypeHandler.h" +#include "Poco/Data/SQLite/Connector.h" +#include +#include + + +using namespace Poco::Data; + + +struct Person +{ + std::string name; + std::string address; + int age; +}; + + +namespace Poco { +namespace Data { + + +template <> +class TypeHandler + /// Defining a specialization of TypeHandler for Person allows us + /// to use the Person struct in use and into clauses. +{ +public: + static std::size_t size() + { + return 3; + } + + static void bind(std::size_t pos, const Person& person, AbstractBinder* pBinder) + { + TypeHandler::bind(pos++, person.name, pBinder); + TypeHandler::bind(pos++, person.address, pBinder); + TypeHandler::bind(pos++, person.age, pBinder); + } + + static void extract(std::size_t pos, Person& person, const Person& deflt, AbstractExtractor* pExtr) + { + TypeHandler::extract(pos++, person.name, deflt.name, pExtr); + TypeHandler::extract(pos++, person.address, deflt.address, pExtr); + TypeHandler::extract(pos++, person.age, deflt.age, pExtr); + } + + static void prepare(std::size_t pos, const Person& person, AbstractPreparation* pPrep) + { + TypeHandler::prepare(pos++, person.name, pPrep); + TypeHandler::prepare(pos++, person.address, pPrep); + TypeHandler::prepare(pos++, person.age, pPrep); + } +}; + + +} } // namespace Poco::Data + + +int main(int argc, char** argv) +{ + // register SQLite connector + Poco::Data::SQLite::Connector::registerConnector(); + + // create a session + Session session("SQLite", "sample.db"); + + // drop sample table, if it exists + session << "DROP TABLE IF EXISTS Person", now; + + // (re)create table + session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now; + + // insert some rows + Person person = + { + "Bart Simpson", + "Springfield", + 12 + }; + + Statement insert(session); + insert << "INSERT INTO Person VALUES(?, ?, ?)", + use(person); + + insert.execute(); + + person.name = "Lisa Simpson"; + person.address = "Springfield"; + person.age = 10; + + insert.execute(); + + // a simple query + Statement select(session); + select << "SELECT Name, Address, Age FROM Person", + into(person), + range(0, 1); // iterate over result set one row at a time + + while (!select.done()) + { + select.execute(); + std::cout << person.name << " " << person.address << " " << person.age << std::endl; + } + + // another query - store the result in a container + std::vector persons; + session << "SELECT Name, Address, Age FROM Person", + into(persons), + now; + + for (std::vector::const_iterator it = persons.begin(); it != persons.end(); ++it) + { + std::cout << it->name << " " << it->address << " " << it->age << std::endl; + } + + return 0; +} diff --git a/Data/samples/samples_vs90.sln b/Data/samples/samples_vs90.sln new file mode 100644 index 000000000..4f0b0caa0 --- /dev/null +++ b/Data/samples/samples_vs90.sln @@ -0,0 +1,38 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Binding", "Binding\Binding_vs90.vcproj", "{F2972327-DCA7-49BB-B55D-66C554CF1205}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TypeHandler", "TypeHandler\TypeHandler_vs90.vcproj", "{822AEE4A-48B6-4B45-AB04-5C3C21C365C5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RecordSet", "RecordSet\RecordSet_vs90.vcproj", "{56F66D36-F11E-4AA1-AD37-4518A253059D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tuple", "Tuple\Tuple_vs90.vcproj", "{08C81227-3322-4DBD-A83F-55CCC933A5F7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|Win32 = debug_shared|Win32 + release_shared|Win32 = release_shared|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F2972327-DCA7-49BB-B55D-66C554CF1205}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {F2972327-DCA7-49BB-B55D-66C554CF1205}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {F2972327-DCA7-49BB-B55D-66C554CF1205}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {F2972327-DCA7-49BB-B55D-66C554CF1205}.release_shared|Win32.Build.0 = release_shared|Win32 + {822AEE4A-48B6-4B45-AB04-5C3C21C365C5}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {822AEE4A-48B6-4B45-AB04-5C3C21C365C5}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {822AEE4A-48B6-4B45-AB04-5C3C21C365C5}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {822AEE4A-48B6-4B45-AB04-5C3C21C365C5}.release_shared|Win32.Build.0 = release_shared|Win32 + {56F66D36-F11E-4AA1-AD37-4518A253059D}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {56F66D36-F11E-4AA1-AD37-4518A253059D}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {56F66D36-F11E-4AA1-AD37-4518A253059D}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {56F66D36-F11E-4AA1-AD37-4518A253059D}.release_shared|Win32.Build.0 = release_shared|Win32 + {08C81227-3322-4DBD-A83F-55CCC933A5F7}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {08C81227-3322-4DBD-A83F-55CCC933A5F7}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {08C81227-3322-4DBD-A83F-55CCC933A5F7}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {08C81227-3322-4DBD-A83F-55CCC933A5F7}.release_shared|Win32.Build.0 = release_shared|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Data/src/SessionPool.cpp b/Data/src/SessionPool.cpp index db61a4d57..1336344c1 100644 --- a/Data/src/SessionPool.cpp +++ b/Data/src/SessionPool.cpp @@ -1,208 +1,208 @@ -// -// SessionPool.cpp -// -// $Id: //poco/1.3/Data/src/SessionPool.cpp#3 $ -// -// Library: Data -// Package: SessionPooling -// Module: SessionPool -// -// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/SessionPool.h" -#include "Poco/Data/SessionFactory.h" -#include "Poco/Data/DataException.h" -#include - - -namespace Poco { -namespace Data { - - -SessionPool::SessionPool(const std::string& sessionKey, const std::string& connectionString, int minSessions, int maxSessions, int idleTime): - _sessionKey(sessionKey), - _connectionString(connectionString), - _minSessions(minSessions), - _maxSessions(maxSessions), - _idleTime(idleTime), - _nSessions(0), - _janitorTimer(1000*idleTime, 1000*idleTime/4) -{ - Poco::TimerCallback callback(*this, &SessionPool::onJanitorTimer); - _janitorTimer.start(callback); -} - - -SessionPool::~SessionPool() -{ - _janitorTimer.stop(); -} - - -Session SessionPool::get() -{ - Poco::FastMutex::ScopedLock lock(_mutex); - - purgeDeadSessions(); - - if (_idleSessions.empty()) - { - if (_nSessions < _maxSessions) - { - Session newSession(SessionFactory::instance().create(_sessionKey, _connectionString)); - PooledSessionHolderPtr pHolder(new PooledSessionHolder(*this, newSession.impl())); - _idleSessions.push_front(pHolder); - ++_nSessions; - } - else throw SessionPoolExhaustedException(_sessionKey, _connectionString); - } - PooledSessionHolderPtr pHolder(_idleSessions.front()); - PooledSessionImplPtr pPSI(new PooledSessionImpl(pHolder)); - _activeSessions.push_front(pHolder); - _idleSessions.pop_front(); - return Session(pPSI); -} - - -void SessionPool::purgeDeadSessions() -{ - SessionList::iterator it = _idleSessions.begin(); - for (; it != _idleSessions.end(); ) - { - if (!(*it)->session()->isConnected()) - { - it = _idleSessions.erase(it); - --_nSessions; - } - else ++it; - } -} - - -int SessionPool::capacity() const -{ - return _maxSessions; -} - - -int SessionPool::used() const -{ - Poco::FastMutex::ScopedLock lock(_mutex); - - return (int) _activeSessions.size(); -} - - -int SessionPool::idle() const -{ - Poco::FastMutex::ScopedLock lock(_mutex); - - return (int) _idleSessions.size(); -} - - -int SessionPool::dead() -{ - Poco::FastMutex::ScopedLock lock(_mutex); - - int count = 0; - - SessionList::iterator it = _activeSessions.begin(); - SessionList::iterator itEnd = _activeSessions.end(); - for (; it != itEnd; ++it) - { - if (!(*it)->session()->isConnected()) - ++count; - } - - return count; -} - - -int SessionPool::allocated() const -{ - Poco::FastMutex::ScopedLock lock(_mutex); - - return _nSessions; -} - - -int SessionPool::available() const -{ - return _maxSessions - used(); -} - - -void SessionPool::putBack(PooledSessionHolderPtr pHolder) -{ - Poco::FastMutex::ScopedLock lock(_mutex); - - SessionList::iterator it = std::find(_activeSessions.begin(), _activeSessions.end(), pHolder); - if (it != _activeSessions.end()) - { - if (pHolder->session()->isConnected()) - { - pHolder->access(); - _idleSessions.push_front(pHolder); - } - else --_nSessions; - - _activeSessions.erase(it); - } - else - { - poco_bugcheck_msg("Unknown session passed to SessionPool::putBack()"); - } -} - - -void SessionPool::onJanitorTimer(Poco::Timer&) -{ - Poco::FastMutex::ScopedLock lock(_mutex); - - SessionList::iterator it = _idleSessions.begin(); - while (_nSessions > _minSessions && it != _idleSessions.end()) - { - if ((*it)->idle() > _idleTime || !(*it)->session()->isConnected()) - { - try - { - (*it)->session()->close(); - } - catch (...) - { - } - it = _idleSessions.erase(it); - --_nSessions; - } - else ++it; - } -} - - -} } // namespace Poco::Data +// +// SessionPool.cpp +// +// $Id: //poco/1.3/Data/src/SessionPool.cpp#4 $ +// +// Library: Data +// Package: SessionPooling +// Module: SessionPool +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/SessionPool.h" +#include "Poco/Data/SessionFactory.h" +#include "Poco/Data/DataException.h" +#include + + +namespace Poco { +namespace Data { + + +SessionPool::SessionPool(const std::string& sessionKey, const std::string& connectionString, int minSessions, int maxSessions, int idleTime): + _sessionKey(sessionKey), + _connectionString(connectionString), + _minSessions(minSessions), + _maxSessions(maxSessions), + _idleTime(idleTime), + _nSessions(0), + _janitorTimer(1000*idleTime, 1000*idleTime/4) +{ + Poco::TimerCallback callback(*this, &SessionPool::onJanitorTimer); + _janitorTimer.start(callback); +} + + +SessionPool::~SessionPool() +{ + _janitorTimer.stop(); +} + + +Session SessionPool::get() +{ + Poco::FastMutex::ScopedLock lock(_mutex); + + purgeDeadSessions(); + + if (_idleSessions.empty()) + { + if (_nSessions < _maxSessions) + { + Session newSession(SessionFactory::instance().create(_sessionKey, _connectionString)); + PooledSessionHolderPtr pHolder(new PooledSessionHolder(*this, newSession.impl())); + _idleSessions.push_front(pHolder); + ++_nSessions; + } + else throw SessionPoolExhaustedException(_sessionKey, _connectionString); + } + PooledSessionHolderPtr pHolder(_idleSessions.front()); + PooledSessionImplPtr pPSI(new PooledSessionImpl(pHolder)); + _activeSessions.push_front(pHolder); + _idleSessions.pop_front(); + return Session(pPSI); +} + + +void SessionPool::purgeDeadSessions() +{ + SessionList::iterator it = _idleSessions.begin(); + for (; it != _idleSessions.end(); ) + { + if (!(*it)->session()->isConnected()) + { + it = _idleSessions.erase(it); + --_nSessions; + } + else ++it; + } +} + + +int SessionPool::capacity() const +{ + return _maxSessions; +} + + +int SessionPool::used() const +{ + Poco::FastMutex::ScopedLock lock(_mutex); + + return (int) _activeSessions.size(); +} + + +int SessionPool::idle() const +{ + Poco::FastMutex::ScopedLock lock(_mutex); + + return (int) _idleSessions.size(); +} + + +int SessionPool::dead() +{ + Poco::FastMutex::ScopedLock lock(_mutex); + + int count = 0; + + SessionList::iterator it = _activeSessions.begin(); + SessionList::iterator itEnd = _activeSessions.end(); + for (; it != itEnd; ++it) + { + if (!(*it)->session()->isConnected()) + ++count; + } + + return count; +} + + +int SessionPool::allocated() const +{ + Poco::FastMutex::ScopedLock lock(_mutex); + + return _nSessions; +} + + +int SessionPool::available() const +{ + return _maxSessions - used(); +} + + +void SessionPool::putBack(PooledSessionHolderPtr pHolder) +{ + Poco::FastMutex::ScopedLock lock(_mutex); + + SessionList::iterator it = std::find(_activeSessions.begin(), _activeSessions.end(), pHolder); + if (it != _activeSessions.end()) + { + if (pHolder->session()->isConnected()) + { + pHolder->access(); + _idleSessions.push_front(pHolder); + } + else --_nSessions; + + _activeSessions.erase(it); + } + else + { + poco_bugcheck_msg("Unknown session passed to SessionPool::putBack()"); + } +} + + +void SessionPool::onJanitorTimer(Poco::Timer&) +{ + Poco::FastMutex::ScopedLock lock(_mutex); + + SessionList::iterator it = _idleSessions.begin(); + while (_nSessions > _minSessions && it != _idleSessions.end()) + { + if ((*it)->idle() > _idleTime || !(*it)->session()->isConnected()) + { + try + { + (*it)->session()->close(); + } + catch (...) + { + } + it = _idleSessions.erase(it); + --_nSessions; + } + else ++it; + } +} + + +} } // namespace Poco::Data diff --git a/Data/src/StatementImpl.cpp b/Data/src/StatementImpl.cpp index e4222fe73..433e3775b 100644 --- a/Data/src/StatementImpl.cpp +++ b/Data/src/StatementImpl.cpp @@ -1,322 +1,322 @@ -// -// StatementImpl.cpp -// -// $Id: //poco/1.3/Data/src/StatementImpl.cpp#4 $ -// -// Library: Data -// Package: DataCore -// Module: StatementImpl -// -// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Data/StatementImpl.h" -#include "Poco/Data/DataException.h" -#include "Poco/Data/AbstractBinder.h" -#include "Poco/Data/Extraction.h" -#include "Poco/Data/BLOB.h" -#include "Poco/SharedPtr.h" -#include "Poco/String.h" -#include "Poco/Exception.h" - - -namespace Poco { -namespace Data { - - -StatementImpl::StatementImpl(): - _state(ST_INITIALIZED), - _extrLimit(upperLimit((Poco::UInt32) Limit::LIMIT_UNLIMITED, false)), - _lowerLimit(0), - _columnsExtracted(0), - _ostr(), - _bindings() -{ -} - - -StatementImpl::~StatementImpl() -{ -} - - -Poco::UInt32 StatementImpl::execute() -{ - resetExtraction(); - Poco::UInt32 lim = 0; - if (_lowerLimit > _extrLimit.value()) - throw LimitException("Illegal Statement state. Upper limit must not be smaller than the lower limit."); - - if (_extrLimit.value() == Limit::LIMIT_UNLIMITED) - lim = executeWithoutLimit(); - else - lim = executeWithLimit(); - - if (lim < _lowerLimit) - { - throw LimitException("Did not receive enough data."); - } - return lim; -} - - -Poco::UInt32 StatementImpl::executeWithLimit() -{ - poco_assert (_state != ST_DONE); - - compile(); - - Poco::UInt32 count = 0; - Poco::UInt32 limit = _extrLimit.value(); - do - { - bind(); - while (hasNext() && count < limit) - { - next(); - ++count; - } - } - while (canBind() && count < limit); - - if (!canBind() && (!hasNext() || 0 == limit)) - _state = ST_DONE; - else if (hasNext() && limit == count && _extrLimit.isHardLimit()) - throw LimitException("HardLimit reached. We got more data than we asked for"); - - return count; -} - - -Poco::UInt32 StatementImpl::executeWithoutLimit() -{ - poco_assert (_state != ST_DONE); - - compile(); - - Poco::UInt32 count = 0; - do - { - bind(); - while (hasNext()) - { - next(); - ++count; - } - } - while (canBind()); - - _state = ST_DONE; - return count; -} - - -void StatementImpl::compile() -{ - if (_state == ST_INITIALIZED) - { - compileImpl(); - _state = ST_COMPILED; - - if (!extractions().size()) - { - Poco::UInt32 cols = columnsReturned(); - if (cols) makeExtractors(cols); - } - - fixupExtraction(); - fixupBinding(); - } - else if (_state == ST_RESET) - { - resetBinding(); - resetExtraction(); - _state = ST_COMPILED; - } -} - - -void StatementImpl::bind() -{ - if (_state == ST_COMPILED) - { - bindImpl(); - _state = ST_BOUND; - } - else if (_state == ST_BOUND) - { - if (!hasNext()) - { - if (canBind()) - { - bindImpl(); - } - else - _state = ST_DONE; - } - } -} - - -void StatementImpl::reset() -{ - _state = ST_RESET; - compile(); -} - - -void StatementImpl::setExtractionLimit(const Limit& extrLimit) -{ - if (!extrLimit.isLowerLimit()) - _extrLimit = extrLimit; - else - _lowerLimit = extrLimit.value(); -} - - -void StatementImpl::fixupExtraction() -{ - Poco::Data::AbstractExtractionVec::iterator it = extractions().begin(); - Poco::Data::AbstractExtractionVec::iterator itEnd = extractions().end(); - AbstractExtractor& ex = extractor(); - _columnsExtracted = 0; - for (; it != itEnd; ++it) - { - (*it)->setExtractor(&ex); - (*it)->setLimit(_extrLimit.value()), - _columnsExtracted += (int)(*it)->numOfColumnsHandled(); - } -} - - -void StatementImpl::fixupBinding() -{ - // no need to call binder().reset(); here will be called before each bind anyway - AbstractBindingVec::iterator it = bindings().begin(); - AbstractBindingVec::iterator itEnd = bindings().end(); - AbstractBinder& bin = binder(); - std::size_t numRows = 0; - if (it != itEnd) - numRows = (*it)->numOfRowsHandled(); - for (; it != itEnd; ++it) - { - if (numRows != (*it)->numOfRowsHandled()) - { - throw BindingException("Size mismatch in Bindings. All Bindings MUST have the same size"); - } - (*it)->setBinder(&bin); - } -} - - -void StatementImpl::resetBinding() -{ - AbstractBindingVec::iterator it = bindings().begin(); - AbstractBindingVec::iterator itEnd = bindings().end(); - for (; it != itEnd; ++it) - { - (*it)->reset(); - } -} - - -void StatementImpl::resetExtraction() -{ - Poco::Data::AbstractExtractionVec::iterator it = extractions().begin(); - Poco::Data::AbstractExtractionVec::iterator itEnd = extractions().end(); - for (; it != itEnd; ++it) - { - (*it)->reset(); - } -} - - -void StatementImpl::makeExtractors(Poco::UInt32 count) -{ - for (int i = 0; i < count; ++i) - { - const MetaColumn& mc = metaColumn(i); - switch (mc.type()) - { - case MetaColumn::FDT_BOOL: - case MetaColumn::FDT_INT8: - addInternalExtract >(mc); - break; - case MetaColumn::FDT_UINT8: - addInternalExtract >(mc); - break; - case MetaColumn::FDT_INT16: - addInternalExtract >(mc); - break; - case MetaColumn::FDT_UINT16: - addInternalExtract >(mc); - break; - case MetaColumn::FDT_INT32: - addInternalExtract >(mc); - break; - case MetaColumn::FDT_UINT32: - addInternalExtract >(mc); - break; - case MetaColumn::FDT_INT64: - addInternalExtract >(mc); - break; - case MetaColumn::FDT_UINT64: - addInternalExtract >(mc); - break; - case MetaColumn::FDT_FLOAT: - addInternalExtract >(mc); - break; - case MetaColumn::FDT_DOUBLE: - addInternalExtract >(mc); - break; - case MetaColumn::FDT_STRING: - addInternalExtract >(mc); - break; - case MetaColumn::FDT_BLOB: - addInternalExtract >(mc); - break; - default: - throw Poco::InvalidArgumentException("Data type not supported."); - } - } -} - - -const MetaColumn& StatementImpl::metaColumn(const std::string& name) const -{ - Poco::UInt32 cols = columnsReturned(); - for (Poco::UInt32 i = 0; i < cols; ++i) - { - const MetaColumn& column = metaColumn(i); - if (0 == icompare(column.name(), name)) return column; - } - - throw NotFoundException(format("Invalid column name: %s", name)); -} - - -} } // namespace Poco::Data +// +// StatementImpl.cpp +// +// $Id: //poco/1.3/Data/src/StatementImpl.cpp#5 $ +// +// Library: Data +// Package: DataCore +// Module: StatementImpl +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Data/StatementImpl.h" +#include "Poco/Data/DataException.h" +#include "Poco/Data/AbstractBinder.h" +#include "Poco/Data/Extraction.h" +#include "Poco/Data/BLOB.h" +#include "Poco/SharedPtr.h" +#include "Poco/String.h" +#include "Poco/Exception.h" + + +namespace Poco { +namespace Data { + + +StatementImpl::StatementImpl(): + _state(ST_INITIALIZED), + _extrLimit(upperLimit((Poco::UInt32) Limit::LIMIT_UNLIMITED, false)), + _lowerLimit(0), + _columnsExtracted(0), + _ostr(), + _bindings() +{ +} + + +StatementImpl::~StatementImpl() +{ +} + + +Poco::UInt32 StatementImpl::execute() +{ + resetExtraction(); + Poco::UInt32 lim = 0; + if (_lowerLimit > _extrLimit.value()) + throw LimitException("Illegal Statement state. Upper limit must not be smaller than the lower limit."); + + if (_extrLimit.value() == Limit::LIMIT_UNLIMITED) + lim = executeWithoutLimit(); + else + lim = executeWithLimit(); + + if (lim < _lowerLimit) + { + throw LimitException("Did not receive enough data."); + } + return lim; +} + + +Poco::UInt32 StatementImpl::executeWithLimit() +{ + poco_assert (_state != ST_DONE); + + compile(); + + Poco::UInt32 count = 0; + Poco::UInt32 limit = _extrLimit.value(); + do + { + bind(); + while (hasNext() && count < limit) + { + next(); + ++count; + } + } + while (canBind() && count < limit); + + if (!canBind() && (!hasNext() || 0 == limit)) + _state = ST_DONE; + else if (hasNext() && limit == count && _extrLimit.isHardLimit()) + throw LimitException("HardLimit reached. We got more data than we asked for"); + + return count; +} + + +Poco::UInt32 StatementImpl::executeWithoutLimit() +{ + poco_assert (_state != ST_DONE); + + compile(); + + Poco::UInt32 count = 0; + do + { + bind(); + while (hasNext()) + { + next(); + ++count; + } + } + while (canBind()); + + _state = ST_DONE; + return count; +} + + +void StatementImpl::compile() +{ + if (_state == ST_INITIALIZED) + { + compileImpl(); + _state = ST_COMPILED; + + if (!extractions().size()) + { + Poco::UInt32 cols = columnsReturned(); + if (cols) makeExtractors(cols); + } + + fixupExtraction(); + fixupBinding(); + } + else if (_state == ST_RESET) + { + resetBinding(); + resetExtraction(); + _state = ST_COMPILED; + } +} + + +void StatementImpl::bind() +{ + if (_state == ST_COMPILED) + { + bindImpl(); + _state = ST_BOUND; + } + else if (_state == ST_BOUND) + { + if (!hasNext()) + { + if (canBind()) + { + bindImpl(); + } + else + _state = ST_DONE; + } + } +} + + +void StatementImpl::reset() +{ + _state = ST_RESET; + compile(); +} + + +void StatementImpl::setExtractionLimit(const Limit& extrLimit) +{ + if (!extrLimit.isLowerLimit()) + _extrLimit = extrLimit; + else + _lowerLimit = extrLimit.value(); +} + + +void StatementImpl::fixupExtraction() +{ + Poco::Data::AbstractExtractionVec::iterator it = extractions().begin(); + Poco::Data::AbstractExtractionVec::iterator itEnd = extractions().end(); + AbstractExtractor& ex = extractor(); + _columnsExtracted = 0; + for (; it != itEnd; ++it) + { + (*it)->setExtractor(&ex); + (*it)->setLimit(_extrLimit.value()), + _columnsExtracted += (int)(*it)->numOfColumnsHandled(); + } +} + + +void StatementImpl::fixupBinding() +{ + // no need to call binder().reset(); here will be called before each bind anyway + AbstractBindingVec::iterator it = bindings().begin(); + AbstractBindingVec::iterator itEnd = bindings().end(); + AbstractBinder& bin = binder(); + std::size_t numRows = 0; + if (it != itEnd) + numRows = (*it)->numOfRowsHandled(); + for (; it != itEnd; ++it) + { + if (numRows != (*it)->numOfRowsHandled()) + { + throw BindingException("Size mismatch in Bindings. All Bindings MUST have the same size"); + } + (*it)->setBinder(&bin); + } +} + + +void StatementImpl::resetBinding() +{ + AbstractBindingVec::iterator it = bindings().begin(); + AbstractBindingVec::iterator itEnd = bindings().end(); + for (; it != itEnd; ++it) + { + (*it)->reset(); + } +} + + +void StatementImpl::resetExtraction() +{ + Poco::Data::AbstractExtractionVec::iterator it = extractions().begin(); + Poco::Data::AbstractExtractionVec::iterator itEnd = extractions().end(); + for (; it != itEnd; ++it) + { + (*it)->reset(); + } +} + + +void StatementImpl::makeExtractors(Poco::UInt32 count) +{ + for (int i = 0; i < count; ++i) + { + const MetaColumn& mc = metaColumn(i); + switch (mc.type()) + { + case MetaColumn::FDT_BOOL: + case MetaColumn::FDT_INT8: + addInternalExtract >(mc); + break; + case MetaColumn::FDT_UINT8: + addInternalExtract >(mc); + break; + case MetaColumn::FDT_INT16: + addInternalExtract >(mc); + break; + case MetaColumn::FDT_UINT16: + addInternalExtract >(mc); + break; + case MetaColumn::FDT_INT32: + addInternalExtract >(mc); + break; + case MetaColumn::FDT_UINT32: + addInternalExtract >(mc); + break; + case MetaColumn::FDT_INT64: + addInternalExtract >(mc); + break; + case MetaColumn::FDT_UINT64: + addInternalExtract >(mc); + break; + case MetaColumn::FDT_FLOAT: + addInternalExtract >(mc); + break; + case MetaColumn::FDT_DOUBLE: + addInternalExtract >(mc); + break; + case MetaColumn::FDT_STRING: + addInternalExtract >(mc); + break; + case MetaColumn::FDT_BLOB: + addInternalExtract >(mc); + break; + default: + throw Poco::InvalidArgumentException("Data type not supported."); + } + } +} + + +const MetaColumn& StatementImpl::metaColumn(const std::string& name) const +{ + Poco::UInt32 cols = columnsReturned(); + for (Poco::UInt32 i = 0; i < cols; ++i) + { + const MetaColumn& column = metaColumn(i); + if (0 == icompare(column.name(), name)) return column; + } + + throw NotFoundException(format("Invalid column name: %s", name)); +} + + +} } // namespace Poco::Data diff --git a/Data/testsuite/TestSuite_vs90.vcproj b/Data/testsuite/TestSuite_vs90.vcproj new file mode 100644 index 000000000..6542f5456 --- /dev/null +++ b/Data/testsuite/TestSuite_vs90.vcproj @@ -0,0 +1,331 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Foundation/include/Poco/Stopwatch.h b/Foundation/include/Poco/Stopwatch.h index fe332662b..579e0a56d 100644 --- a/Foundation/include/Poco/Stopwatch.h +++ b/Foundation/include/Poco/Stopwatch.h @@ -1,124 +1,130 @@ -// -// Stopwatch.h -// -// $Id: //poco/1.3/Foundation/include/Poco/Stopwatch.h#1 $ -// -// Library: Foundation -// Package: DateTime -// Module: Stopwatch -// -// Definition of the Stopwatch class. -// -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef Foundation_Stopwatch_INCLUDED -#define Foundation_Stopwatch_INCLUDED - - -#include "Poco/Foundation.h" -#include "Poco/Timestamp.h" - - -namespace Poco { - - -class Foundation_API Stopwatch - /// A simple facility to measure time intervals - /// with microsecond resolution. -{ -public: - Stopwatch(); - ~Stopwatch(); - - void start(); - /// Starts (or restarts) the stopwatch. - - void stop(); - /// Stops or pauses the stopwatch. - - void reset(); - /// Resets the stopwatch. - - void restart(); - /// Resets and starts the stopwatch. - - Timestamp::TimeDiff elapsed() const; - /// Returns the elapsed time in microseconds - /// since the stopwatch started. - - int elapsedSeconds() const; - /// Returns the number of seconds elapsed - /// since the stopwatch started. - - static Timestamp::TimeVal resolution(); - /// Returns the resolution of the stopwatch. - -private: - Stopwatch(const Stopwatch&); - Stopwatch& operator = (const Stopwatch&); - - Timestamp _start; - Timestamp::TimeDiff _elapsed; - bool _running; -}; - - -// -// inlines -// -inline void Stopwatch::start() -{ - _start.update(); - _running = true; -} - - -inline void Stopwatch::stop() -{ - Timestamp current; - _elapsed += current - _start; - _running = false; -} - - -inline int Stopwatch::elapsedSeconds() const -{ - return int(elapsed()/resolution()); -} - - -inline Timestamp::TimeVal Stopwatch::resolution() -{ - return Timestamp::resolution(); -} - - -} // namespace Poco - - -#endif // Foundation_Stopwatch_INCLUDED +// +// Stopwatch.h +// +// $Id: //poco/1.3/Foundation/include/Poco/Stopwatch.h#2 $ +// +// Library: Foundation +// Package: DateTime +// Module: Stopwatch +// +// Definition of the Stopwatch class. +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Foundation_Stopwatch_INCLUDED +#define Foundation_Stopwatch_INCLUDED + + +#include "Poco/Foundation.h" +#include "Poco/Timestamp.h" + + +namespace Poco { + + +class Foundation_API Stopwatch + /// A simple facility to measure time intervals + /// with microsecond resolution. +{ +public: + Stopwatch(); + ~Stopwatch(); + + void start(); + /// Starts (or restarts) the stopwatch. + + void stop(); + /// Stops or pauses the stopwatch. + + void reset(); + /// Resets the stopwatch. + + void restart(); + /// Resets and starts the stopwatch. + + Timestamp::TimeDiff elapsed() const; + /// Returns the elapsed time in microseconds + /// since the stopwatch started. + + int elapsedSeconds() const; + /// Returns the number of seconds elapsed + /// since the stopwatch started. + + static Timestamp::TimeVal resolution(); + /// Returns the resolution of the stopwatch. + +private: + Stopwatch(const Stopwatch&); + Stopwatch& operator = (const Stopwatch&); + + Timestamp _start; + Timestamp::TimeDiff _elapsed; + bool _running; +}; + + +// +// inlines +// +inline void Stopwatch::start() +{ + if (!_running) + { + _start.update(); + _running = true; + } +} + + +inline void Stopwatch::stop() +{ + if (_running) + { + Timestamp current; + _elapsed += current - _start; + _running = false; + } +} + + +inline int Stopwatch::elapsedSeconds() const +{ + return int(elapsed()/resolution()); +} + + +inline Timestamp::TimeVal Stopwatch::resolution() +{ + return Timestamp::resolution(); +} + + +} // namespace Poco + + +#endif // Foundation_Stopwatch_INCLUDED diff --git a/Foundation/src/EventLogChannel.cpp b/Foundation/src/EventLogChannel.cpp index 09b476e9c..b5c85b75c 100644 --- a/Foundation/src/EventLogChannel.cpp +++ b/Foundation/src/EventLogChannel.cpp @@ -1,315 +1,315 @@ -// -// EventLogChannel.cpp -// -// $Id: //poco/1.3/Foundation/src/EventLogChannel.cpp#2 $ -// -// Library: Foundation -// Package: Logging -// Module: EventLogChannel -// -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/EventLogChannel.h" -#include "Poco/Message.h" -#include "Poco/String.h" -#include "pocomsg.h" -#if defined(POCO_WIN32_UTF8) -#include "Poco/UnicodeConverter.h" -#endif - - -namespace Poco { - - -const std::string EventLogChannel::PROP_NAME = "name"; -const std::string EventLogChannel::PROP_HOST = "host"; -const std::string EventLogChannel::PROP_LOGHOST = "loghost"; -const std::string EventLogChannel::PROP_LOGFILE = "logfile"; - - -EventLogChannel::EventLogChannel(): - _logFile("Application"), - _h(0) -{ -#if defined(POCO_WIN32_UTF8) - wchar_t name[256]; - int n = GetModuleFileNameW(NULL, name, sizeof(name)); - if (n > 0) - { - wchar_t* end = name + n - 1; - while (end > name && *end != '\\') --end; - if (*end == '\\') ++end; - std::wstring uname(end); - UnicodeConverter::toUTF8(uname, _name); - } -#else - char name[256]; - int n = GetModuleFileNameA(NULL, name, sizeof(name)); - if (n > 0) - { - char* end = name + n - 1; - while (end > name && *end != '\\') --end; - if (*end == '\\') ++end; - _name = end; - } -#endif -} - - -EventLogChannel::EventLogChannel(const std::string& name): - _name(name), - _logFile("Application"), - _h(0) -{ -} - - -EventLogChannel::EventLogChannel(const std::string& name, const std::string& host): - _name(name), - _host(host), - _logFile("Application"), - _h(0) -{ -} - - -EventLogChannel::~EventLogChannel() -{ - close(); -} - - -void EventLogChannel::open() -{ - setUpRegistry(); -#if defined(POCO_WIN32_UTF8) - std::wstring uhost; - UnicodeConverter::toUTF16(_host, uhost); - std::wstring uname; - UnicodeConverter::toUTF16(_name, uname); - _h = RegisterEventSourceW(uhost.empty() ? NULL : uhost.c_str(), uname.c_str()); -#else - _h = RegisterEventSource(_host.empty() ? NULL : _host.c_str(), _name.c_str()); -#endif - if (!_h) throw SystemException("cannot register event source"); -} - - -void EventLogChannel::close() -{ - if (_h) DeregisterEventSource(_h); - _h = 0; -} - - -void EventLogChannel::log(const Message& msg) -{ - if (!_h) open(); -#if defined(POCO_WIN32_UTF8) - std::wstring utext; - UnicodeConverter::toUTF16(msg.getText(), utext); - const wchar_t* pMsg = utext.c_str(); - ReportEventW(_h, getType(msg), getCategory(msg), POCO_MSG_LOG, NULL, 1, 0, &pMsg, NULL); -#else - const char* pMsg = msg.getText().c_str(); - ReportEvent(_h, getType(msg), getCategory(msg), POCO_MSG_LOG, NULL, 1, 0, &pMsg, NULL); -#endif -} - - -void EventLogChannel::setProperty(const std::string& name, const std::string& value) -{ - if (icompare(name, PROP_NAME) == 0) - _name = value; - else if (icompare(name, PROP_HOST) == 0) - _host = value; - else if (icompare(name, PROP_LOGHOST) == 0) - _host = value; - else if (icompare(name, PROP_LOGFILE) == 0) - _logFile = value; - else - Channel::setProperty(name, value); -} - - -std::string EventLogChannel::getProperty(const std::string& name) const -{ - if (icompare(name, PROP_NAME) == 0) - return _name; - else if (icompare(name, PROP_HOST) == 0) - return _host; - else if (icompare(name, PROP_LOGHOST) == 0) - return _host; - else if (icompare(name, PROP_LOGFILE) == 0) - return _logFile; - else - return Channel::getProperty(name); -} - - -int EventLogChannel::getType(const Message& msg) -{ - switch (msg.getPriority()) - { - case Message::PRIO_TRACE: - case Message::PRIO_DEBUG: - case Message::PRIO_INFORMATION: - return EVENTLOG_INFORMATION_TYPE; - case Message::PRIO_NOTICE: - case Message::PRIO_WARNING: - return EVENTLOG_WARNING_TYPE; - default: - return EVENTLOG_ERROR_TYPE; - } -} - - -int EventLogChannel::getCategory(const Message& msg) -{ - switch (msg.getPriority()) - { - case Message::PRIO_TRACE: - return POCO_CTG_TRACE; - case Message::PRIO_DEBUG: - return POCO_CTG_DEBUG; - case Message::PRIO_INFORMATION: - return POCO_CTG_INFORMATION; - case Message::PRIO_NOTICE: - return POCO_CTG_NOTICE; - case Message::PRIO_WARNING: - return POCO_CTG_WARNING; - case Message::PRIO_ERROR: - return POCO_CTG_ERROR; - case Message::PRIO_CRITICAL: - return POCO_CTG_CRITICAL; - case Message::PRIO_FATAL: - return POCO_CTG_FATAL; - default: - return 0; - } -} - - -void EventLogChannel::setUpRegistry() const -{ - std::string key = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\"; - key.append(_logFile); - key.append("\\"); - key.append(_name); - HKEY hKey; - DWORD disp; -#if defined(POCO_WIN32_UTF8) - std::wstring ukey; - UnicodeConverter::toUTF16(key, ukey); - DWORD rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, ukey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &disp); -#else - DWORD rc = RegCreateKeyEx(HKEY_LOCAL_MACHINE, key.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &disp); -#endif - if (rc != ERROR_SUCCESS) return; - - if (disp == REG_CREATED_NEW_KEY) - { -#if defined(POCO_WIN32_UTF8) - std::wstring path; - #if defined(POCO_DLL) - #if defined(_DEBUG) - path = findLibrary(L"PocoFoundationd.dll"); - #else - path = findLibrary(L"PocoFoundation.dll"); - #endif - #endif - - if (path.empty()) - path = findLibrary(L"PocoMsg.dll"); -#else - std::string path; - #if defined(POCO_DLL) - #if defined(_DEBUG) - path = findLibrary("PocoFoundationd.dll"); - #else - path = findLibrary("PocoFoundation.dll"); - #endif - #endif - - if (path.empty()) - path = findLibrary("PocoMsg.dll"); -#endif - - if (!path.empty()) - { - DWORD count = 8; - DWORD types = 7; -#if defined(POCO_WIN32_UTF8) - RegSetValueExW(hKey, L"CategoryMessageFile", 0, REG_SZ, (const BYTE*) path.c_str(), (DWORD) path.size() + 1); - RegSetValueExW(hKey, L"EventMessageFile", 0, REG_SZ, (const BYTE*) path.c_str(), (DWORD) path.size() + 1); - RegSetValueExW(hKey, L"CategoryCount", 0, REG_DWORD, (const BYTE*) &count, (DWORD) sizeof(count)); - RegSetValueExW(hKey, L"TypesSupported", 0, REG_DWORD, (const BYTE*) &types, (DWORD) sizeof(types)); -#else - RegSetValueEx(hKey, "CategoryMessageFile", 0, REG_SZ, (const BYTE*) path.c_str(), (DWORD) path.size() + 1); - RegSetValueEx(hKey, "EventMessageFile", 0, REG_SZ, (const BYTE*) path.c_str(), (DWORD) path.size() + 1); - RegSetValueEx(hKey, "CategoryCount", 0, REG_DWORD, (const BYTE*) &count, (DWORD) sizeof(count)); - RegSetValueEx(hKey, "TypesSupported", 0, REG_DWORD, (const BYTE*) &types, (DWORD) sizeof(types)); -#endif - } - } - RegCloseKey(hKey); -} - - -#if defined(POCO_WIN32_UTF8) -std::wstring EventLogChannel::findLibrary(const wchar_t* name) -{ - std::wstring path; - HMODULE dll = LoadLibraryW(name); - if (dll) - { - wchar_t name[MAX_PATH + 1]; - int n = GetModuleFileNameW(dll, name, sizeof(name)); - if (n > 0) path = name; - FreeLibrary(dll); - } - return path; -} -#else -std::string EventLogChannel::findLibrary(const char* name) -{ - std::string path; - HMODULE dll = LoadLibraryA(name); - if (dll) - { - char name[MAX_PATH + 1]; - int n = GetModuleFileNameA(dll, name, sizeof(name)); - if (n > 0) path = name; - FreeLibrary(dll); - } - return path; -} -#endif - - -} // namespace Poco +// +// EventLogChannel.cpp +// +// $Id: //poco/1.3/Foundation/src/EventLogChannel.cpp#3 $ +// +// Library: Foundation +// Package: Logging +// Module: EventLogChannel +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/EventLogChannel.h" +#include "Poco/Message.h" +#include "Poco/String.h" +#include "pocomsg.h" +#if defined(POCO_WIN32_UTF8) +#include "Poco/UnicodeConverter.h" +#endif + + +namespace Poco { + + +const std::string EventLogChannel::PROP_NAME = "name"; +const std::string EventLogChannel::PROP_HOST = "host"; +const std::string EventLogChannel::PROP_LOGHOST = "loghost"; +const std::string EventLogChannel::PROP_LOGFILE = "logfile"; + + +EventLogChannel::EventLogChannel(): + _logFile("Application"), + _h(0) +{ +#if defined(POCO_WIN32_UTF8) + wchar_t name[256]; + int n = GetModuleFileNameW(NULL, name, sizeof(name)); + if (n > 0) + { + wchar_t* end = name + n - 1; + while (end > name && *end != '\\') --end; + if (*end == '\\') ++end; + std::wstring uname(end); + UnicodeConverter::toUTF8(uname, _name); + } +#else + char name[256]; + int n = GetModuleFileNameA(NULL, name, sizeof(name)); + if (n > 0) + { + char* end = name + n - 1; + while (end > name && *end != '\\') --end; + if (*end == '\\') ++end; + _name = end; + } +#endif +} + + +EventLogChannel::EventLogChannel(const std::string& name): + _name(name), + _logFile("Application"), + _h(0) +{ +} + + +EventLogChannel::EventLogChannel(const std::string& name, const std::string& host): + _name(name), + _host(host), + _logFile("Application"), + _h(0) +{ +} + + +EventLogChannel::~EventLogChannel() +{ + close(); +} + + +void EventLogChannel::open() +{ + setUpRegistry(); +#if defined(POCO_WIN32_UTF8) + std::wstring uhost; + UnicodeConverter::toUTF16(_host, uhost); + std::wstring uname; + UnicodeConverter::toUTF16(_name, uname); + _h = RegisterEventSourceW(uhost.empty() ? NULL : uhost.c_str(), uname.c_str()); +#else + _h = RegisterEventSource(_host.empty() ? NULL : _host.c_str(), _name.c_str()); +#endif + if (!_h) throw SystemException("cannot register event source"); +} + + +void EventLogChannel::close() +{ + if (_h) DeregisterEventSource(_h); + _h = 0; +} + + +void EventLogChannel::log(const Message& msg) +{ + if (!_h) open(); +#if defined(POCO_WIN32_UTF8) + std::wstring utext; + UnicodeConverter::toUTF16(msg.getText(), utext); + const wchar_t* pMsg = utext.c_str(); + ReportEventW(_h, getType(msg), getCategory(msg), POCO_MSG_LOG, NULL, 1, 0, &pMsg, NULL); +#else + const char* pMsg = msg.getText().c_str(); + ReportEvent(_h, getType(msg), getCategory(msg), POCO_MSG_LOG, NULL, 1, 0, &pMsg, NULL); +#endif +} + + +void EventLogChannel::setProperty(const std::string& name, const std::string& value) +{ + if (icompare(name, PROP_NAME) == 0) + _name = value; + else if (icompare(name, PROP_HOST) == 0) + _host = value; + else if (icompare(name, PROP_LOGHOST) == 0) + _host = value; + else if (icompare(name, PROP_LOGFILE) == 0) + _logFile = value; + else + Channel::setProperty(name, value); +} + + +std::string EventLogChannel::getProperty(const std::string& name) const +{ + if (icompare(name, PROP_NAME) == 0) + return _name; + else if (icompare(name, PROP_HOST) == 0) + return _host; + else if (icompare(name, PROP_LOGHOST) == 0) + return _host; + else if (icompare(name, PROP_LOGFILE) == 0) + return _logFile; + else + return Channel::getProperty(name); +} + + +int EventLogChannel::getType(const Message& msg) +{ + switch (msg.getPriority()) + { + case Message::PRIO_TRACE: + case Message::PRIO_DEBUG: + case Message::PRIO_INFORMATION: + return EVENTLOG_INFORMATION_TYPE; + case Message::PRIO_NOTICE: + case Message::PRIO_WARNING: + return EVENTLOG_WARNING_TYPE; + default: + return EVENTLOG_ERROR_TYPE; + } +} + + +int EventLogChannel::getCategory(const Message& msg) +{ + switch (msg.getPriority()) + { + case Message::PRIO_TRACE: + return POCO_CTG_TRACE; + case Message::PRIO_DEBUG: + return POCO_CTG_DEBUG; + case Message::PRIO_INFORMATION: + return POCO_CTG_INFORMATION; + case Message::PRIO_NOTICE: + return POCO_CTG_NOTICE; + case Message::PRIO_WARNING: + return POCO_CTG_WARNING; + case Message::PRIO_ERROR: + return POCO_CTG_ERROR; + case Message::PRIO_CRITICAL: + return POCO_CTG_CRITICAL; + case Message::PRIO_FATAL: + return POCO_CTG_FATAL; + default: + return 0; + } +} + + +void EventLogChannel::setUpRegistry() const +{ + std::string key = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\"; + key.append(_logFile); + key.append("\\"); + key.append(_name); + HKEY hKey; + DWORD disp; +#if defined(POCO_WIN32_UTF8) + std::wstring ukey; + UnicodeConverter::toUTF16(key, ukey); + DWORD rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, ukey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &disp); +#else + DWORD rc = RegCreateKeyEx(HKEY_LOCAL_MACHINE, key.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &disp); +#endif + if (rc != ERROR_SUCCESS) return; + + if (disp == REG_CREATED_NEW_KEY) + { +#if defined(POCO_WIN32_UTF8) + std::wstring path; + #if defined(POCO_DLL) + #if defined(_DEBUG) + path = findLibrary(L"PocoFoundationd.dll"); + #else + path = findLibrary(L"PocoFoundation.dll"); + #endif + #endif + + if (path.empty()) + path = findLibrary(L"PocoMsg.dll"); +#else + std::string path; + #if defined(POCO_DLL) + #if defined(_DEBUG) + path = findLibrary("PocoFoundationd.dll"); + #else + path = findLibrary("PocoFoundation.dll"); + #endif + #endif + + if (path.empty()) + path = findLibrary("PocoMsg.dll"); +#endif + + if (!path.empty()) + { + DWORD count = 8; + DWORD types = 7; +#if defined(POCO_WIN32_UTF8) + RegSetValueExW(hKey, L"CategoryMessageFile", 0, REG_SZ, (const BYTE*) path.c_str(), (DWORD) sizeof(wchar_t)*(path.size() + 1)); + RegSetValueExW(hKey, L"EventMessageFile", 0, REG_SZ, (const BYTE*) path.c_str(), (DWORD) sizeof(wchar_t)*(path.size() + 1)); + RegSetValueExW(hKey, L"CategoryCount", 0, REG_DWORD, (const BYTE*) &count, (DWORD) sizeof(count)); + RegSetValueExW(hKey, L"TypesSupported", 0, REG_DWORD, (const BYTE*) &types, (DWORD) sizeof(types)); +#else + RegSetValueEx(hKey, "CategoryMessageFile", 0, REG_SZ, (const BYTE*) path.c_str(), (DWORD) path.size() + 1); + RegSetValueEx(hKey, "EventMessageFile", 0, REG_SZ, (const BYTE*) path.c_str(), (DWORD) path.size() + 1); + RegSetValueEx(hKey, "CategoryCount", 0, REG_DWORD, (const BYTE*) &count, (DWORD) sizeof(count)); + RegSetValueEx(hKey, "TypesSupported", 0, REG_DWORD, (const BYTE*) &types, (DWORD) sizeof(types)); +#endif + } + } + RegCloseKey(hKey); +} + + +#if defined(POCO_WIN32_UTF8) +std::wstring EventLogChannel::findLibrary(const wchar_t* name) +{ + std::wstring path; + HMODULE dll = LoadLibraryW(name); + if (dll) + { + wchar_t name[MAX_PATH + 1]; + int n = GetModuleFileNameW(dll, name, sizeof(name)); + if (n > 0) path = name; + FreeLibrary(dll); + } + return path; +} +#else +std::string EventLogChannel::findLibrary(const char* name) +{ + std::string path; + HMODULE dll = LoadLibraryA(name); + if (dll) + { + char name[MAX_PATH + 1]; + int n = GetModuleFileNameA(dll, name, sizeof(name)); + if (n > 0) path = name; + FreeLibrary(dll); + } + return path; +} +#endif + + +} // namespace Poco diff --git a/Foundation/testsuite/src/PathTest.cpp b/Foundation/testsuite/src/PathTest.cpp index 726aacf0a..17e24518c 100644 --- a/Foundation/testsuite/src/PathTest.cpp +++ b/Foundation/testsuite/src/PathTest.cpp @@ -1,1652 +1,1652 @@ -// -// PathTest.cpp -// -// $Id: //poco/1.3/Foundation/testsuite/src/PathTest.cpp#1 $ -// -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "PathTest.h" -#include "CppUnit/TestCaller.h" -#include "CppUnit/TestSuite.h" -#include "Poco/Path.h" -#include "Poco/Exception.h" -#include "Poco/Random.h" -#include "Poco/Environment.h" -#include - - -using Poco::Path; -using Poco::PathSyntaxException; -using Poco::Random; -using Poco::Environment; - - -PathTest::PathTest(const std::string& name): CppUnit::TestCase(name) -{ -} - - -PathTest::~PathTest() -{ -} - - -void PathTest::testParseUnix1() -{ - Path p; - p.parse("", Path::PATH_UNIX); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 0); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == ""); - - p.parse("/", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 0); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/"); - - p.parse("/usr", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 0); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr"); - - p.parse("/usr/", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "usr"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr/"); - - p.parse("usr/", Path::PATH_UNIX); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "usr"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "usr/"); - - p.parse("usr", Path::PATH_UNIX); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 0); - assert (p[0] == "usr"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "usr"); - - p.parse("/usr/local", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr/local"); -} - - -void PathTest::testParseUnix2() -{ - Path p; - p.parse("/usr/local/", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr/local/"); - - p.parse("usr/local/", Path::PATH_UNIX); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "usr/local/"); - - p.parse("usr/local", Path::PATH_UNIX); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "usr/local"); - - p.parse("/usr/local/bin", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin"); - - p.parse("/usr/local/bin/", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); -} - - -void PathTest::testParseUnix3() -{ - Path p; - p.parse("//usr/local/bin/", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); - - p.parse("/usr//local/bin/", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); - - p.parse("/usr/local//bin/", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); - - p.parse("/usr/local/bin//", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); - - p.parse("/usr/local/./bin/", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); - - p.parse("./usr/local/bin/", Path::PATH_UNIX); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "usr/local/bin/"); - - p.parse("./usr/local/bin/./", Path::PATH_UNIX); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "usr/local/bin/"); - - p.parse("./usr/local/bin/.", Path::PATH_UNIX); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "usr/local/bin/."); -} - - -void PathTest::testParseUnix4() -{ - Path p; - p.parse("/usr/local/lib/../bin/", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); - - p.parse("/usr/local/lib/../bin/", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); - - p.parse("/usr/local/lib/../../", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "usr"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr/"); - - p.parse("/usr/local/lib/..", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "lib"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr/local/lib/.."); - - p.parse("../usr/local/lib/", Path::PATH_UNIX); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 4); - assert (p[0] == ".."); - assert (p[1] == "usr"); - assert (p[2] == "local"); - assert (p[3] == "lib"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "../usr/local/lib/"); - - p.parse("/usr/../lib/", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "lib"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/lib/"); - - p.parse("/usr/../../lib/", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "lib"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/lib/"); - - p.parse("local/../../lib/", Path::PATH_UNIX); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == ".."); - assert (p[1] == "lib"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "../lib/"); - - p.parse("a/b/c/d", Path::PATH_UNIX); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "a"); - assert (p[1] == "b"); - assert (p[2] == "c"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "a/b/c/d"); -} - - -void PathTest::testParseUnix5() -{ - Path p; - p.parse("/c:/windows/system32/", Path::PATH_UNIX); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.getDevice() == "c"); - assert (p.depth() == 2); - assert (p[0] == "windows"); - assert (p[1] == "system32"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/c:/windows/system32/"); -} - - -void PathTest::testParseWindows1() -{ - Path p; - p.parse("", Path::PATH_WINDOWS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 0); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == ""); - - p.parse("/", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 0); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\"); - - p.parse("\\", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 0); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\"); - - p.parse("/usr", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 0); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr"); - - p.parse("\\usr", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 0); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr"); - - p.parse("/usr/", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "usr"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\"); - - p.parse("\\usr\\", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "usr"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\"); -} - - -void PathTest::testParseWindows2() -{ - Path p; - p.parse("usr/", Path::PATH_WINDOWS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "usr"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "usr\\"); - - p.parse("usr", Path::PATH_WINDOWS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 0); - assert (p[0] == "usr"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "usr"); - - p.parse("usr\\", Path::PATH_WINDOWS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "usr"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "usr\\"); - - p.parse("/usr/local", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local"); - - p.parse("\\usr\\local", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local"); - - p.parse("/usr/local/", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\"); - - p.parse("usr/local/", Path::PATH_WINDOWS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "usr\\local\\"); - - p.parse("usr/local", Path::PATH_WINDOWS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "usr\\local"); - - p.parse("/usr/local/bin", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin"); - - p.parse("/usr/local/bin/", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); - - p.parse("/usr//local/bin/", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); - - p.parse("/usr/local//bin/", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); - - p.parse("/usr/local/bin//", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); -} - - -void PathTest::testParseWindows3() -{ - Path p; - p.parse("/usr/local/./bin/", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); - - p.parse("./usr/local/bin/", Path::PATH_WINDOWS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "usr\\local\\bin\\"); - - p.parse("./usr/local/bin/./", Path::PATH_WINDOWS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "usr\\local\\bin\\"); - - p.parse("./usr/local/bin/.", Path::PATH_WINDOWS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "usr\\local\\bin\\."); - - p.parse("/usr/local/lib/../bin/", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); - - p.parse("/usr/local/lib/../bin/", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); - - p.parse("\\usr\\local\\lib\\..\\bin\\", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); - - p.parse("/usr/local/lib/../../", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "usr"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\"); - - p.parse("/usr/local/lib/..", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "lib"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\lib\\.."); - - p.parse("../usr/local/lib/", Path::PATH_WINDOWS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 4); - assert (p[0] == ".."); - assert (p[1] == "usr"); - assert (p[2] == "local"); - assert (p[3] == "lib"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "..\\usr\\local\\lib\\"); - - p.parse("/usr/../lib/", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "lib"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\lib\\"); - - p.parse("/usr/../../lib/", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "lib"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\lib\\"); - - p.parse("local/../../lib/", Path::PATH_WINDOWS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == ".."); - assert (p[1] == "lib"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "..\\lib\\"); -} - - -void PathTest::testParseWindows4() -{ - Path p; - p.parse("\\\\server\\files", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "files"); - assert (p.getNode() == "server"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\\\server\\files\\"); - - p.parse("\\\\server\\files\\", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "files"); - assert (p.getNode() == "server"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\\\server\\files\\"); - - p.parse("\\\\server\\files\\file", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "files"); - assert (p.getNode() == "server"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\\\server\\files\\file"); - - p.parse("\\\\server\\files\\dir\\file", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == "files"); - assert (p[1] == "dir"); - assert (p.getNode() == "server"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\\\server\\files\\dir\\file"); - - p.parse("\\\\server\\files\\dir\\file", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == "files"); - assert (p[1] == "dir"); - assert (p.getNode() == "server"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\\\server\\files\\dir\\file"); - - p.parse("\\\\server", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 0); - assert (p.getNode() == "server"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\\\server\\"); - - p.parse("c:\\", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 0); - assert (p.getDevice() == "c"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "c:\\"); - - p.parse("c:\\WinNT", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 0); - assert (p.getDevice() == "c"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "c:\\WinNT"); - - p.parse("c:\\WinNT\\", Path::PATH_WINDOWS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "WinNT"); - assert (p.getDevice() == "c"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "c:\\WinNT\\"); - - try - { - p.parse("ü:\\", Path::PATH_WINDOWS); - fail("bad path - must throw exception"); - } - catch (PathSyntaxException&) - { - } - - try - { - p.parse("c:file.txt", Path::PATH_WINDOWS); - fail("bad path - must throw exception"); - } - catch (PathSyntaxException&) - { - } - - p.parse("a\\b\\c\\d", Path::PATH_WINDOWS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "a"); - assert (p[1] == "b"); - assert (p[2] == "c"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "a\\b\\c\\d"); -} - - -void PathTest::testParseVMS1() -{ - Path p; - p.parse("", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 0); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == ""); - - p.parse("[]", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 0); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == ""); - - p.parse("[foo]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo]"); - - p.parse("[.foo]", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[.foo]"); - - p.parse("[foo.bar]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == "foo"); - assert (p[1] == "bar"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo.bar]"); - - p.parse("[.foo.bar]", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == "foo"); - assert (p[1] == "bar"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[.foo.bar]"); - - p.parse("[foo.bar.foobar]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "foo"); - assert (p[1] == "bar"); - assert (p[2] == "foobar"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo.bar.foobar]"); - - p.parse("[.foo.bar.foobar]", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "foo"); - assert (p[1] == "bar"); - assert (p[2] == "foobar"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[.foo.bar.foobar]"); -} - - -void PathTest::testParseVMS2() -{ - Path p; - p.parse("[foo][bar]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == "foo"); - assert (p[1] == "bar"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo.bar]"); - - p.parse("[foo.][bar]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == "foo"); - assert (p[1] == "bar"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo.bar]"); - - p.parse("[foo.bar][foo]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "foo"); - assert (p[1] == "bar"); - assert (p[2] == "foo"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo.bar.foo]"); - - try - { - p.parse("[foo.bar][.foo]", Path::PATH_VMS); - failmsg("bad path - must throw exception"); - } - catch (PathSyntaxException&) - { - } - - try - { - p.parse("[.foo.bar][foo]", Path::PATH_VMS); - failmsg("bad path - must throw exception"); - } - catch (PathSyntaxException&) - { - } - - p.parse("[-]", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == ".."); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[-]"); - - p.parse("[--]", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == ".."); - assert (p[1] == ".."); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[--]"); - - p.parse("[---]", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == ".."); - assert (p[1] == ".."); - assert (p[2] == ".."); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[---]"); - - p.parse("[-.-]", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == ".."); - assert (p[1] == ".."); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[--]"); - - p.parse("[.-.-]", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == ".."); - assert (p[1] == ".."); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[--]"); - - p.parse("[-.-.-]", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == ".."); - assert (p[1] == ".."); - assert (p[2] == ".."); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[---]"); - - p.parse("[.-.-.-]", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == ".."); - assert (p[1] == ".."); - assert (p[2] == ".."); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[---]"); - - p.parse("[.--.-]", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == ".."); - assert (p[1] == ".."); - assert (p[2] == ".."); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[---]"); - - p.parse("[--.-]", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == ".."); - assert (p[1] == ".."); - assert (p[2] == ".."); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[---]"); -} - - -void PathTest::testParseVMS3() -{ - Path p; - p.parse("[foo][-]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo]"); - - p.parse("[foo][--]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo]"); - - p.parse("[foo][-.-]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo]"); - - p.parse("[foo][bar.-]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo]"); - - p.parse("[foo][bar.foo.-]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == "foo"); - assert (p[1] == "bar"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo.bar]"); - - p.parse("[foo][bar.foo.--]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo]"); - - p.parse("[foo][bar.foo.---]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo]"); - - p.parse("[foo][bar.foo.-.-.-]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo]"); -} - - -void PathTest::testParseVMS4() -{ - Path p; - p.parse("device:[foo]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (p.getDevice() == "device"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "device:[foo]"); - - p.parse("device:[.foo]", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (p.getDevice() == "device"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "device:[.foo]"); - - p.parse("node::device:[foo]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (p.getNode() == "node"); - assert (p.getDevice() == "device"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "node::device:[foo]"); - - p.parse("node::device:[foo.bar]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == "foo"); - assert (p[1] == "bar"); - assert (p.getNode() == "node"); - assert (p.getDevice() == "device"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "node::device:[foo.bar]"); - - p.parse("node::device:[foo.bar.][goo]", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 3); - assert (p[0] == "foo"); - assert (p[1] == "bar"); - assert (p[2] == "goo"); - assert (p.getNode() == "node"); - assert (p.getDevice() == "device"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "node::device:[foo.bar.goo]"); - - p.parse("[]foo.txt", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 0); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_VMS) == "foo.txt"); - - p.parse("[foo]bar.txt", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo]bar.txt"); - - p.parse("[foo]bar.txt;", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo]bar.txt"); - - p.parse("[foo]bar.txt;5", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo]bar.txt;5"); - assert (p.version() == "5"); - - p.parse("foo:bar.txt", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 0); - assert (p.getDevice() == "foo"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_VMS) == "foo:bar.txt"); - - p.parse("foo:bar.txt;5", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 0); - assert (p.getDevice() == "foo"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_VMS) == "foo:bar.txt;5"); - assert (p.version() == "5"); - - p.parse("foo:", Path::PATH_VMS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 0); - assert (p.getDevice() == "foo"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_VMS) == "foo:"); - - p.parse("bar.txt", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 0); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_VMS) == "bar.txt"); - - p.parse("bar.txt;5", Path::PATH_VMS); - assert (p.isRelative()); - assert (!p.isAbsolute()); - assert (p.depth() == 0); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_VMS) == "bar.txt;5"); - assert (p.version() == "5"); -} - - -void PathTest::testParseGuess() -{ - Path p; - - p.parse("foo:bar.txt;5", Path::PATH_GUESS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 0); - assert (p.getDevice() == "foo"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_VMS) == "foo:bar.txt;5"); - assert (p.version() == "5"); - - p.parse("/usr/local/bin", Path::PATH_GUESS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 2); - assert (p[0] == "usr"); - assert (p[1] == "local"); - assert (p[2] == "bin"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin"); - - p.parse("\\\\server\\files", Path::PATH_GUESS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "files"); - assert (p.getNode() == "server"); - assert (p.isDirectory()); - assert (!p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "\\\\server\\files\\"); - - p.parse("c:\\WinNT", Path::PATH_GUESS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 0); - assert (p.getDevice() == "c"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_WINDOWS) == "c:\\WinNT"); - - p.parse("foo:bar.txt;5", Path::PATH_GUESS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 0); - assert (p.getDevice() == "foo"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_VMS) == "foo:bar.txt;5"); - assert (p.version() == "5"); - - p.parse("[foo]bar.txt", Path::PATH_GUESS); - assert (!p.isRelative()); - assert (p.isAbsolute()); - assert (p.depth() == 1); - assert (p[0] == "foo"); - assert (!p.isDirectory()); - assert (p.isFile()); - assert (p.toString(Path::PATH_VMS) == "[foo]bar.txt"); -} - - -void PathTest::testTryParse() -{ - Path p; -#if defined(POCO_OS_FAMILY_UNIX) - assert (p.tryParse("/etc/passwd")); - assert (p.toString() == "/etc/passwd"); -#elif defined(POCO_OS_FAMILY_WINDOWS) - assert (p.tryParse("c:\\windows\\system32")); - assert (p.toString() == "c:\\windows\\system32"); - assert (!p.tryParse("c:foo.bar")); - assert (p.toString() == "c:\\windows\\system32"); -#endif - - assert (p.tryParse("c:\\windows\\system", Path::PATH_WINDOWS)); - assert (p.toString(Path::PATH_WINDOWS) == "c:\\windows\\system"); - assert (!p.tryParse("c:foo.bar", Path::PATH_WINDOWS)); - assert (p.toString(Path::PATH_WINDOWS) == "c:\\windows\\system"); -} - - -void PathTest::testStatics() -{ - std::string s = Path::current(); - assert (!s.empty()); - Path p(s); - assert (p.isDirectory() && p.isAbsolute()); - - s = Path::home(); - assert (!s.empty()); - p = s; - assert (p.isDirectory() && p.isAbsolute()); - - s = Path::temp(); - assert (!s.empty()); - p = s; - assert (p.isDirectory() && p.isAbsolute()); - - s = Path::null(); - assert (!s.empty()); - p = s; -} - - -void PathTest::testBaseNameExt() -{ - Path p("foo.bar"); - assert (p.getFileName() == "foo.bar"); - assert (p.getBaseName() == "foo"); - assert (p.getExtension() == "bar"); - - p.setBaseName("readme"); - assert (p.getFileName() == "readme.bar"); - assert (p.getBaseName() == "readme"); - assert (p.getExtension() == "bar"); - - p.setExtension("txt"); - assert (p.getFileName() == "readme.txt"); - assert (p.getBaseName() == "readme"); - assert (p.getExtension() == "txt"); - - p.setExtension("html"); - assert (p.getFileName() == "readme.html"); - assert (p.getBaseName() == "readme"); - assert (p.getExtension() == "html"); - - p.setBaseName("index"); - assert (p.getFileName() == "index.html"); - assert (p.getBaseName() == "index"); - assert (p.getExtension() == "html"); -} - - -void PathTest::testAbsolute() -{ - Path base("C:\\Program Files\\", Path::PATH_WINDOWS); - Path rel("Poco"); - Path abs = rel.absolute(base); - assert (abs.toString(Path::PATH_WINDOWS) == "C:\\Program Files\\Poco"); - - base.parse("/usr/local", Path::PATH_UNIX); - rel.parse("Poco/include", Path::PATH_UNIX); - abs = rel.absolute(base); - assert (abs.toString(Path::PATH_UNIX) == "/usr/local/Poco/include"); - - base.parse("/usr/local/bin", Path::PATH_UNIX); - rel.parse("../Poco/include", Path::PATH_UNIX); - abs = rel.absolute(base); - assert (abs.toString(Path::PATH_UNIX) == "/usr/local/Poco/include"); -} - - -void PathTest::testRobustness() -{ - Random r; - for (int i = 0; i < 256; ++i) - { - int len = r.next(1024); - std::string s; - for (int i = 0; i < len; ++i) s += r.nextChar(); - try - { - Path p(s, Path::PATH_WINDOWS); - } - catch (PathSyntaxException&) - { - } - try - { - Path p(s, Path::PATH_UNIX); - } - catch (PathSyntaxException&) - { - } - try - { - Path p(s, Path::PATH_VMS); - } - catch (PathSyntaxException&) - { - } - try - { - Path p(s, Path::PATH_GUESS); - } - catch (PathSyntaxException&) - { - } - } -} - - -void PathTest::testParent() -{ - Path p("/usr/local/include", Path::PATH_UNIX); - p.makeParent(); - assert (p.toString(Path::PATH_UNIX) == "/usr/local/"); - p.makeParent(); - assert (p.toString(Path::PATH_UNIX) == "/usr/"); - p.makeParent(); - assert (p.toString(Path::PATH_UNIX) == "/"); - p.makeParent(); - assert (p.toString(Path::PATH_UNIX) == "/"); -} - - -void PathTest::testForDirectory() -{ - Path p = Path::forDirectory("/usr/local/include", Path::PATH_UNIX); - assert (p.toString(Path::PATH_UNIX) == "/usr/local/include/"); - - p = Path::forDirectory("/usr/local/include/", Path::PATH_UNIX); - assert (p.toString(Path::PATH_UNIX) == "/usr/local/include/"); -} - - -void PathTest::testExpand() -{ -#if defined(POCO_OS_FAMILY_UNIX) - std::string s = Path::expand("~/.bashrc"); - assert (s == Path::expand("$HOME/.bashrc")); - assert (s == Environment::get("HOME") + "/.bashrc" || - s == Environment::get("HOME") + "//.bashrc"); - Path p(s); - s = Path::expand("$HOME/.bashrc"); - assert (s == Path::expand("~/.bashrc")); - s = Path::expand("${HOME}/.bashrc"); - assert (s == Path::expand("~/.bashrc")); -#elif defined(POCO_OS_FAMILY_WINDOWS) - std::string s = Path::expand("%TMP%\\foo"); - assert (s == Environment::get("TMP") + "\\foo"); - Path p(s); -#else - std::string s = Path::expand("SYS$LOGIN:[projects]"); - assert (s.find(":[projects]") != std::string::npos); - Path p(s); -#endif -} - - -void PathTest::testListRoots() -{ - std::vector devs; - Path::listRoots(devs); - assert (devs.size() > 0); - for (std::vector::iterator it = devs.begin(); it != devs.end(); ++it) - { - std::cout << *it << std::endl; - } -} - - -void PathTest::testFind() -{ - Path p; -#if defined(POCO_OS_FAMILY_UNIX) - bool found = Path::find(Environment::get("PATH"), "ls", p); - bool notfound = Path::find(Environment::get("PATH"), "xxxyyy123", p); -#elif defined(POCO_OS_FAMILY_WINDOWS) - bool found = Path::find(Environment::get("PATH"), "cmd.exe", p); - bool notfound = Path::find(Environment::get("PATH"), "xxxyyy123.zzz", p); -#else - bool found = true; - bool notfound = false; -#endif - assert (found); - assert (!notfound); - - std::string fn = p.toString(); - assert (fn.size() > 0); -} - - -void PathTest::testSwap() -{ - Path p1("c:\\temp\\foo.bar"); - Path p2("\\\\server\\files\\foo.bar"); - p1.swap(p2); - assert (p1.toString() == "\\\\server\\files\\foo.bar"); - assert (p2.toString() == "c:\\temp\\foo.bar"); -} - - -void PathTest::testResolve() -{ - Path p("c:\\foo\\", Path::PATH_WINDOWS); - p.resolve("test.dat"); - assert (p.toString(Path::PATH_WINDOWS) == "c:\\foo\\test.dat"); - - p.assign("c:\\foo\\", Path::PATH_WINDOWS); - p.resolve(Path("d:\\bar.txt", Path::PATH_WINDOWS)); - assert (p.toString(Path::PATH_WINDOWS) == "d:\\bar.txt"); - - p.assign("c:\\foo\\bar.txt", Path::PATH_WINDOWS); - p.resolve("foo.txt"); - assert (p.toString(Path::PATH_WINDOWS) == "c:\\foo\\foo.txt"); - - p.assign("c:\\foo\\bar\\", Path::PATH_WINDOWS); - p.resolve(Path("..\\baz\\test.dat", Path::PATH_WINDOWS)); - assert (p.toString(Path::PATH_WINDOWS) == "c:\\foo\\baz\\test.dat"); -} - - -void PathTest::setUp() -{ -} - - -void PathTest::tearDown() -{ -} - - -CppUnit::Test* PathTest::suite() -{ - CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("PathTest"); - - CppUnit_addTest(pSuite, PathTest, testParseUnix1); - CppUnit_addTest(pSuite, PathTest, testParseUnix2); - CppUnit_addTest(pSuite, PathTest, testParseUnix3); - CppUnit_addTest(pSuite, PathTest, testParseUnix4); - CppUnit_addTest(pSuite, PathTest, testParseUnix5); - CppUnit_addTest(pSuite, PathTest, testParseWindows1); - CppUnit_addTest(pSuite, PathTest, testParseWindows2); - CppUnit_addTest(pSuite, PathTest, testParseWindows3); - CppUnit_addTest(pSuite, PathTest, testParseWindows4); - CppUnit_addTest(pSuite, PathTest, testParseVMS1); - CppUnit_addTest(pSuite, PathTest, testParseVMS2); - CppUnit_addTest(pSuite, PathTest, testParseVMS3); - CppUnit_addTest(pSuite, PathTest, testParseVMS4); - CppUnit_addTest(pSuite, PathTest, testParseGuess); - CppUnit_addTest(pSuite, PathTest, testTryParse); - CppUnit_addTest(pSuite, PathTest, testStatics); - CppUnit_addTest(pSuite, PathTest, testBaseNameExt); - CppUnit_addTest(pSuite, PathTest, testAbsolute); - CppUnit_addTest(pSuite, PathTest, testRobustness); - CppUnit_addTest(pSuite, PathTest, testParent); - CppUnit_addTest(pSuite, PathTest, testForDirectory); - CppUnit_addTest(pSuite, PathTest, testExpand); - CppUnit_addTest(pSuite, PathTest, testListRoots); - CppUnit_addTest(pSuite, PathTest, testFind); - CppUnit_addTest(pSuite, PathTest, testSwap); - CppUnit_addTest(pSuite, PathTest, testResolve); - - return pSuite; -} +// +// PathTest.cpp +// +// $Id: //poco/1.3/Foundation/testsuite/src/PathTest.cpp#2 $ +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "PathTest.h" +#include "CppUnit/TestCaller.h" +#include "CppUnit/TestSuite.h" +#include "Poco/Path.h" +#include "Poco/Exception.h" +#include "Poco/Random.h" +#include "Poco/Environment.h" +#include + + +using Poco::Path; +using Poco::PathSyntaxException; +using Poco::Random; +using Poco::Environment; + + +PathTest::PathTest(const std::string& name): CppUnit::TestCase(name) +{ +} + + +PathTest::~PathTest() +{ +} + + +void PathTest::testParseUnix1() +{ + Path p; + p.parse("", Path::PATH_UNIX); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 0); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == ""); + + p.parse("/", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 0); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/"); + + p.parse("/usr", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 0); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr"); + + p.parse("/usr/", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "usr"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr/"); + + p.parse("usr/", Path::PATH_UNIX); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "usr"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "usr/"); + + p.parse("usr", Path::PATH_UNIX); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 0); + assert (p[0] == "usr"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "usr"); + + p.parse("/usr/local", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr/local"); +} + + +void PathTest::testParseUnix2() +{ + Path p; + p.parse("/usr/local/", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr/local/"); + + p.parse("usr/local/", Path::PATH_UNIX); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "usr/local/"); + + p.parse("usr/local", Path::PATH_UNIX); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "usr/local"); + + p.parse("/usr/local/bin", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin"); + + p.parse("/usr/local/bin/", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); +} + + +void PathTest::testParseUnix3() +{ + Path p; + p.parse("//usr/local/bin/", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); + + p.parse("/usr//local/bin/", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); + + p.parse("/usr/local//bin/", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); + + p.parse("/usr/local/bin//", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); + + p.parse("/usr/local/./bin/", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); + + p.parse("./usr/local/bin/", Path::PATH_UNIX); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "usr/local/bin/"); + + p.parse("./usr/local/bin/./", Path::PATH_UNIX); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "usr/local/bin/"); + + p.parse("./usr/local/bin/.", Path::PATH_UNIX); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "usr/local/bin/."); +} + + +void PathTest::testParseUnix4() +{ + Path p; + p.parse("/usr/local/lib/../bin/", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); + + p.parse("/usr/local/lib/../bin/", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin/"); + + p.parse("/usr/local/lib/../../", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "usr"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr/"); + + p.parse("/usr/local/lib/..", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "lib"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr/local/lib/.."); + + p.parse("../usr/local/lib/", Path::PATH_UNIX); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 4); + assert (p[0] == ".."); + assert (p[1] == "usr"); + assert (p[2] == "local"); + assert (p[3] == "lib"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "../usr/local/lib/"); + + p.parse("/usr/../lib/", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "lib"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/lib/"); + + p.parse("/usr/../../lib/", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "lib"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/lib/"); + + p.parse("local/../../lib/", Path::PATH_UNIX); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == ".."); + assert (p[1] == "lib"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "../lib/"); + + p.parse("a/b/c/d", Path::PATH_UNIX); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "a"); + assert (p[1] == "b"); + assert (p[2] == "c"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "a/b/c/d"); +} + + +void PathTest::testParseUnix5() +{ + Path p; + p.parse("/c:/windows/system32/", Path::PATH_UNIX); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.getDevice() == "c"); + assert (p.depth() == 2); + assert (p[0] == "windows"); + assert (p[1] == "system32"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/c:/windows/system32/"); +} + + +void PathTest::testParseWindows1() +{ + Path p; + p.parse("", Path::PATH_WINDOWS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 0); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == ""); + + p.parse("/", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 0); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\"); + + p.parse("\\", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 0); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\"); + + p.parse("/usr", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 0); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr"); + + p.parse("\\usr", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 0); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr"); + + p.parse("/usr/", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "usr"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\"); + + p.parse("\\usr\\", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "usr"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\"); +} + + +void PathTest::testParseWindows2() +{ + Path p; + p.parse("usr/", Path::PATH_WINDOWS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "usr"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "usr\\"); + + p.parse("usr", Path::PATH_WINDOWS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 0); + assert (p[0] == "usr"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "usr"); + + p.parse("usr\\", Path::PATH_WINDOWS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "usr"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "usr\\"); + + p.parse("/usr/local", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local"); + + p.parse("\\usr\\local", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local"); + + p.parse("/usr/local/", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\"); + + p.parse("usr/local/", Path::PATH_WINDOWS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "usr\\local\\"); + + p.parse("usr/local", Path::PATH_WINDOWS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "usr\\local"); + + p.parse("/usr/local/bin", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin"); + + p.parse("/usr/local/bin/", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); + + p.parse("/usr//local/bin/", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); + + p.parse("/usr/local//bin/", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); + + p.parse("/usr/local/bin//", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); +} + + +void PathTest::testParseWindows3() +{ + Path p; + p.parse("/usr/local/./bin/", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); + + p.parse("./usr/local/bin/", Path::PATH_WINDOWS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "usr\\local\\bin\\"); + + p.parse("./usr/local/bin/./", Path::PATH_WINDOWS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "usr\\local\\bin\\"); + + p.parse("./usr/local/bin/.", Path::PATH_WINDOWS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "usr\\local\\bin\\."); + + p.parse("/usr/local/lib/../bin/", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); + + p.parse("/usr/local/lib/../bin/", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); + + p.parse("\\usr\\local\\lib\\..\\bin\\", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\bin\\"); + + p.parse("/usr/local/lib/../../", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "usr"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\"); + + p.parse("/usr/local/lib/..", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "lib"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\usr\\local\\lib\\.."); + + p.parse("../usr/local/lib/", Path::PATH_WINDOWS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 4); + assert (p[0] == ".."); + assert (p[1] == "usr"); + assert (p[2] == "local"); + assert (p[3] == "lib"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "..\\usr\\local\\lib\\"); + + p.parse("/usr/../lib/", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "lib"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\lib\\"); + + p.parse("/usr/../../lib/", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "lib"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\lib\\"); + + p.parse("local/../../lib/", Path::PATH_WINDOWS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == ".."); + assert (p[1] == "lib"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "..\\lib\\"); +} + + +void PathTest::testParseWindows4() +{ + Path p; + p.parse("\\\\server\\files", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "files"); + assert (p.getNode() == "server"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\\\server\\files\\"); + + p.parse("\\\\server\\files\\", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "files"); + assert (p.getNode() == "server"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\\\server\\files\\"); + + p.parse("\\\\server\\files\\file", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "files"); + assert (p.getNode() == "server"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\\\server\\files\\file"); + + p.parse("\\\\server\\files\\dir\\file", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == "files"); + assert (p[1] == "dir"); + assert (p.getNode() == "server"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\\\server\\files\\dir\\file"); + + p.parse("\\\\server\\files\\dir\\file", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == "files"); + assert (p[1] == "dir"); + assert (p.getNode() == "server"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\\\server\\files\\dir\\file"); + + p.parse("\\\\server", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 0); + assert (p.getNode() == "server"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\\\server\\"); + + p.parse("c:\\", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 0); + assert (p.getDevice() == "c"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "c:\\"); + + p.parse("c:\\WinNT", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 0); + assert (p.getDevice() == "c"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "c:\\WinNT"); + + p.parse("c:\\WinNT\\", Path::PATH_WINDOWS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "WinNT"); + assert (p.getDevice() == "c"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "c:\\WinNT\\"); + + try + { + p.parse("~:\\", Path::PATH_WINDOWS); + fail("bad path - must throw exception"); + } + catch (PathSyntaxException&) + { + } + + try + { + p.parse("c:file.txt", Path::PATH_WINDOWS); + fail("bad path - must throw exception"); + } + catch (PathSyntaxException&) + { + } + + p.parse("a\\b\\c\\d", Path::PATH_WINDOWS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "a"); + assert (p[1] == "b"); + assert (p[2] == "c"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "a\\b\\c\\d"); +} + + +void PathTest::testParseVMS1() +{ + Path p; + p.parse("", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 0); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == ""); + + p.parse("[]", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 0); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == ""); + + p.parse("[foo]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo]"); + + p.parse("[.foo]", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[.foo]"); + + p.parse("[foo.bar]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == "foo"); + assert (p[1] == "bar"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo.bar]"); + + p.parse("[.foo.bar]", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == "foo"); + assert (p[1] == "bar"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[.foo.bar]"); + + p.parse("[foo.bar.foobar]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "foo"); + assert (p[1] == "bar"); + assert (p[2] == "foobar"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo.bar.foobar]"); + + p.parse("[.foo.bar.foobar]", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "foo"); + assert (p[1] == "bar"); + assert (p[2] == "foobar"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[.foo.bar.foobar]"); +} + + +void PathTest::testParseVMS2() +{ + Path p; + p.parse("[foo][bar]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == "foo"); + assert (p[1] == "bar"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo.bar]"); + + p.parse("[foo.][bar]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == "foo"); + assert (p[1] == "bar"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo.bar]"); + + p.parse("[foo.bar][foo]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "foo"); + assert (p[1] == "bar"); + assert (p[2] == "foo"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo.bar.foo]"); + + try + { + p.parse("[foo.bar][.foo]", Path::PATH_VMS); + failmsg("bad path - must throw exception"); + } + catch (PathSyntaxException&) + { + } + + try + { + p.parse("[.foo.bar][foo]", Path::PATH_VMS); + failmsg("bad path - must throw exception"); + } + catch (PathSyntaxException&) + { + } + + p.parse("[-]", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == ".."); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[-]"); + + p.parse("[--]", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == ".."); + assert (p[1] == ".."); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[--]"); + + p.parse("[---]", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == ".."); + assert (p[1] == ".."); + assert (p[2] == ".."); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[---]"); + + p.parse("[-.-]", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == ".."); + assert (p[1] == ".."); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[--]"); + + p.parse("[.-.-]", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == ".."); + assert (p[1] == ".."); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[--]"); + + p.parse("[-.-.-]", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == ".."); + assert (p[1] == ".."); + assert (p[2] == ".."); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[---]"); + + p.parse("[.-.-.-]", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == ".."); + assert (p[1] == ".."); + assert (p[2] == ".."); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[---]"); + + p.parse("[.--.-]", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == ".."); + assert (p[1] == ".."); + assert (p[2] == ".."); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[---]"); + + p.parse("[--.-]", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == ".."); + assert (p[1] == ".."); + assert (p[2] == ".."); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[---]"); +} + + +void PathTest::testParseVMS3() +{ + Path p; + p.parse("[foo][-]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo]"); + + p.parse("[foo][--]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo]"); + + p.parse("[foo][-.-]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo]"); + + p.parse("[foo][bar.-]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo]"); + + p.parse("[foo][bar.foo.-]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == "foo"); + assert (p[1] == "bar"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo.bar]"); + + p.parse("[foo][bar.foo.--]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo]"); + + p.parse("[foo][bar.foo.---]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo]"); + + p.parse("[foo][bar.foo.-.-.-]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo]"); +} + + +void PathTest::testParseVMS4() +{ + Path p; + p.parse("device:[foo]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (p.getDevice() == "device"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "device:[foo]"); + + p.parse("device:[.foo]", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (p.getDevice() == "device"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "device:[.foo]"); + + p.parse("node::device:[foo]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (p.getNode() == "node"); + assert (p.getDevice() == "device"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "node::device:[foo]"); + + p.parse("node::device:[foo.bar]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == "foo"); + assert (p[1] == "bar"); + assert (p.getNode() == "node"); + assert (p.getDevice() == "device"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "node::device:[foo.bar]"); + + p.parse("node::device:[foo.bar.][goo]", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 3); + assert (p[0] == "foo"); + assert (p[1] == "bar"); + assert (p[2] == "goo"); + assert (p.getNode() == "node"); + assert (p.getDevice() == "device"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "node::device:[foo.bar.goo]"); + + p.parse("[]foo.txt", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 0); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_VMS) == "foo.txt"); + + p.parse("[foo]bar.txt", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo]bar.txt"); + + p.parse("[foo]bar.txt;", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo]bar.txt"); + + p.parse("[foo]bar.txt;5", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo]bar.txt;5"); + assert (p.version() == "5"); + + p.parse("foo:bar.txt", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 0); + assert (p.getDevice() == "foo"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_VMS) == "foo:bar.txt"); + + p.parse("foo:bar.txt;5", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 0); + assert (p.getDevice() == "foo"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_VMS) == "foo:bar.txt;5"); + assert (p.version() == "5"); + + p.parse("foo:", Path::PATH_VMS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 0); + assert (p.getDevice() == "foo"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_VMS) == "foo:"); + + p.parse("bar.txt", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 0); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_VMS) == "bar.txt"); + + p.parse("bar.txt;5", Path::PATH_VMS); + assert (p.isRelative()); + assert (!p.isAbsolute()); + assert (p.depth() == 0); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_VMS) == "bar.txt;5"); + assert (p.version() == "5"); +} + + +void PathTest::testParseGuess() +{ + Path p; + + p.parse("foo:bar.txt;5", Path::PATH_GUESS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 0); + assert (p.getDevice() == "foo"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_VMS) == "foo:bar.txt;5"); + assert (p.version() == "5"); + + p.parse("/usr/local/bin", Path::PATH_GUESS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 2); + assert (p[0] == "usr"); + assert (p[1] == "local"); + assert (p[2] == "bin"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_UNIX) == "/usr/local/bin"); + + p.parse("\\\\server\\files", Path::PATH_GUESS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "files"); + assert (p.getNode() == "server"); + assert (p.isDirectory()); + assert (!p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "\\\\server\\files\\"); + + p.parse("c:\\WinNT", Path::PATH_GUESS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 0); + assert (p.getDevice() == "c"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_WINDOWS) == "c:\\WinNT"); + + p.parse("foo:bar.txt;5", Path::PATH_GUESS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 0); + assert (p.getDevice() == "foo"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_VMS) == "foo:bar.txt;5"); + assert (p.version() == "5"); + + p.parse("[foo]bar.txt", Path::PATH_GUESS); + assert (!p.isRelative()); + assert (p.isAbsolute()); + assert (p.depth() == 1); + assert (p[0] == "foo"); + assert (!p.isDirectory()); + assert (p.isFile()); + assert (p.toString(Path::PATH_VMS) == "[foo]bar.txt"); +} + + +void PathTest::testTryParse() +{ + Path p; +#if defined(POCO_OS_FAMILY_UNIX) + assert (p.tryParse("/etc/passwd")); + assert (p.toString() == "/etc/passwd"); +#elif defined(POCO_OS_FAMILY_WINDOWS) + assert (p.tryParse("c:\\windows\\system32")); + assert (p.toString() == "c:\\windows\\system32"); + assert (!p.tryParse("c:foo.bar")); + assert (p.toString() == "c:\\windows\\system32"); +#endif + + assert (p.tryParse("c:\\windows\\system", Path::PATH_WINDOWS)); + assert (p.toString(Path::PATH_WINDOWS) == "c:\\windows\\system"); + assert (!p.tryParse("c:foo.bar", Path::PATH_WINDOWS)); + assert (p.toString(Path::PATH_WINDOWS) == "c:\\windows\\system"); +} + + +void PathTest::testStatics() +{ + std::string s = Path::current(); + assert (!s.empty()); + Path p(s); + assert (p.isDirectory() && p.isAbsolute()); + + s = Path::home(); + assert (!s.empty()); + p = s; + assert (p.isDirectory() && p.isAbsolute()); + + s = Path::temp(); + assert (!s.empty()); + p = s; + assert (p.isDirectory() && p.isAbsolute()); + + s = Path::null(); + assert (!s.empty()); + p = s; +} + + +void PathTest::testBaseNameExt() +{ + Path p("foo.bar"); + assert (p.getFileName() == "foo.bar"); + assert (p.getBaseName() == "foo"); + assert (p.getExtension() == "bar"); + + p.setBaseName("readme"); + assert (p.getFileName() == "readme.bar"); + assert (p.getBaseName() == "readme"); + assert (p.getExtension() == "bar"); + + p.setExtension("txt"); + assert (p.getFileName() == "readme.txt"); + assert (p.getBaseName() == "readme"); + assert (p.getExtension() == "txt"); + + p.setExtension("html"); + assert (p.getFileName() == "readme.html"); + assert (p.getBaseName() == "readme"); + assert (p.getExtension() == "html"); + + p.setBaseName("index"); + assert (p.getFileName() == "index.html"); + assert (p.getBaseName() == "index"); + assert (p.getExtension() == "html"); +} + + +void PathTest::testAbsolute() +{ + Path base("C:\\Program Files\\", Path::PATH_WINDOWS); + Path rel("Poco"); + Path abs = rel.absolute(base); + assert (abs.toString(Path::PATH_WINDOWS) == "C:\\Program Files\\Poco"); + + base.parse("/usr/local", Path::PATH_UNIX); + rel.parse("Poco/include", Path::PATH_UNIX); + abs = rel.absolute(base); + assert (abs.toString(Path::PATH_UNIX) == "/usr/local/Poco/include"); + + base.parse("/usr/local/bin", Path::PATH_UNIX); + rel.parse("../Poco/include", Path::PATH_UNIX); + abs = rel.absolute(base); + assert (abs.toString(Path::PATH_UNIX) == "/usr/local/Poco/include"); +} + + +void PathTest::testRobustness() +{ + Random r; + for (int i = 0; i < 256; ++i) + { + int len = r.next(1024); + std::string s; + for (int i = 0; i < len; ++i) s += r.nextChar(); + try + { + Path p(s, Path::PATH_WINDOWS); + } + catch (PathSyntaxException&) + { + } + try + { + Path p(s, Path::PATH_UNIX); + } + catch (PathSyntaxException&) + { + } + try + { + Path p(s, Path::PATH_VMS); + } + catch (PathSyntaxException&) + { + } + try + { + Path p(s, Path::PATH_GUESS); + } + catch (PathSyntaxException&) + { + } + } +} + + +void PathTest::testParent() +{ + Path p("/usr/local/include", Path::PATH_UNIX); + p.makeParent(); + assert (p.toString(Path::PATH_UNIX) == "/usr/local/"); + p.makeParent(); + assert (p.toString(Path::PATH_UNIX) == "/usr/"); + p.makeParent(); + assert (p.toString(Path::PATH_UNIX) == "/"); + p.makeParent(); + assert (p.toString(Path::PATH_UNIX) == "/"); +} + + +void PathTest::testForDirectory() +{ + Path p = Path::forDirectory("/usr/local/include", Path::PATH_UNIX); + assert (p.toString(Path::PATH_UNIX) == "/usr/local/include/"); + + p = Path::forDirectory("/usr/local/include/", Path::PATH_UNIX); + assert (p.toString(Path::PATH_UNIX) == "/usr/local/include/"); +} + + +void PathTest::testExpand() +{ +#if defined(POCO_OS_FAMILY_UNIX) + std::string s = Path::expand("~/.bashrc"); + assert (s == Path::expand("$HOME/.bashrc")); + assert (s == Environment::get("HOME") + "/.bashrc" || + s == Environment::get("HOME") + "//.bashrc"); + Path p(s); + s = Path::expand("$HOME/.bashrc"); + assert (s == Path::expand("~/.bashrc")); + s = Path::expand("${HOME}/.bashrc"); + assert (s == Path::expand("~/.bashrc")); +#elif defined(POCO_OS_FAMILY_WINDOWS) + std::string s = Path::expand("%TMP%\\foo"); + assert (s == Environment::get("TMP") + "\\foo"); + Path p(s); +#else + std::string s = Path::expand("SYS$LOGIN:[projects]"); + assert (s.find(":[projects]") != std::string::npos); + Path p(s); +#endif +} + + +void PathTest::testListRoots() +{ + std::vector devs; + Path::listRoots(devs); + assert (devs.size() > 0); + for (std::vector::iterator it = devs.begin(); it != devs.end(); ++it) + { + std::cout << *it << std::endl; + } +} + + +void PathTest::testFind() +{ + Path p; +#if defined(POCO_OS_FAMILY_UNIX) + bool found = Path::find(Environment::get("PATH"), "ls", p); + bool notfound = Path::find(Environment::get("PATH"), "xxxyyy123", p); +#elif defined(POCO_OS_FAMILY_WINDOWS) + bool found = Path::find(Environment::get("PATH"), "cmd.exe", p); + bool notfound = Path::find(Environment::get("PATH"), "xxxyyy123.zzz", p); +#else + bool found = true; + bool notfound = false; +#endif + assert (found); + assert (!notfound); + + std::string fn = p.toString(); + assert (fn.size() > 0); +} + + +void PathTest::testSwap() +{ + Path p1("c:\\temp\\foo.bar"); + Path p2("\\\\server\\files\\foo.bar"); + p1.swap(p2); + assert (p1.toString() == "\\\\server\\files\\foo.bar"); + assert (p2.toString() == "c:\\temp\\foo.bar"); +} + + +void PathTest::testResolve() +{ + Path p("c:\\foo\\", Path::PATH_WINDOWS); + p.resolve("test.dat"); + assert (p.toString(Path::PATH_WINDOWS) == "c:\\foo\\test.dat"); + + p.assign("c:\\foo\\", Path::PATH_WINDOWS); + p.resolve(Path("d:\\bar.txt", Path::PATH_WINDOWS)); + assert (p.toString(Path::PATH_WINDOWS) == "d:\\bar.txt"); + + p.assign("c:\\foo\\bar.txt", Path::PATH_WINDOWS); + p.resolve("foo.txt"); + assert (p.toString(Path::PATH_WINDOWS) == "c:\\foo\\foo.txt"); + + p.assign("c:\\foo\\bar\\", Path::PATH_WINDOWS); + p.resolve(Path("..\\baz\\test.dat", Path::PATH_WINDOWS)); + assert (p.toString(Path::PATH_WINDOWS) == "c:\\foo\\baz\\test.dat"); +} + + +void PathTest::setUp() +{ +} + + +void PathTest::tearDown() +{ +} + + +CppUnit::Test* PathTest::suite() +{ + CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("PathTest"); + + CppUnit_addTest(pSuite, PathTest, testParseUnix1); + CppUnit_addTest(pSuite, PathTest, testParseUnix2); + CppUnit_addTest(pSuite, PathTest, testParseUnix3); + CppUnit_addTest(pSuite, PathTest, testParseUnix4); + CppUnit_addTest(pSuite, PathTest, testParseUnix5); + CppUnit_addTest(pSuite, PathTest, testParseWindows1); + CppUnit_addTest(pSuite, PathTest, testParseWindows2); + CppUnit_addTest(pSuite, PathTest, testParseWindows3); + CppUnit_addTest(pSuite, PathTest, testParseWindows4); + CppUnit_addTest(pSuite, PathTest, testParseVMS1); + CppUnit_addTest(pSuite, PathTest, testParseVMS2); + CppUnit_addTest(pSuite, PathTest, testParseVMS3); + CppUnit_addTest(pSuite, PathTest, testParseVMS4); + CppUnit_addTest(pSuite, PathTest, testParseGuess); + CppUnit_addTest(pSuite, PathTest, testTryParse); + CppUnit_addTest(pSuite, PathTest, testStatics); + CppUnit_addTest(pSuite, PathTest, testBaseNameExt); + CppUnit_addTest(pSuite, PathTest, testAbsolute); + CppUnit_addTest(pSuite, PathTest, testRobustness); + CppUnit_addTest(pSuite, PathTest, testParent); + CppUnit_addTest(pSuite, PathTest, testForDirectory); + CppUnit_addTest(pSuite, PathTest, testExpand); + CppUnit_addTest(pSuite, PathTest, testListRoots); + CppUnit_addTest(pSuite, PathTest, testFind); + CppUnit_addTest(pSuite, PathTest, testSwap); + CppUnit_addTest(pSuite, PathTest, testResolve); + + return pSuite; +} diff --git a/Net/include/Poco/Net/NetworkInterface.h b/Net/include/Poco/Net/NetworkInterface.h index 5b61a5b18..d56d8615a 100644 --- a/Net/include/Poco/Net/NetworkInterface.h +++ b/Net/include/Poco/Net/NetworkInterface.h @@ -1,165 +1,172 @@ -// -// NetworkInterface.h -// -// $Id: //poco/1.3/Net/include/Poco/Net/NetworkInterface.h#2 $ -// -// Library: Net -// Package: Sockets -// Module: NetworkInterface -// -// Definition of the NetworkInterface class. -// -// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef Net_NetworkInterface_INCLUDED -#define Net_NetworkInterface_INCLUDED - - -#include "Poco/Net/Net.h" -#include "Poco/Net/IPAddress.h" -#include "Poco/Mutex.h" -#include - - -namespace Poco { -namespace Net { - - -class NetworkInterfaceImpl; - - -class Net_API NetworkInterface - /// This class represents a network interface. - /// - /// NetworkInterface is used with MulticastSocket to specify - /// multicast interfaces for sending and receiving multicast - /// messages. -{ -public: - typedef std::vector NetworkInterfaceList; - - NetworkInterface(); - /// Creates a NetworkInterface representing the - /// default interface. - /// - /// The name is empty, the IP address is the wildcard - /// address and the index is zero. - - NetworkInterface(const NetworkInterface& interface); - /// Creates the NetworkInterface by copying another one. - - ~NetworkInterface(); - /// Destroys the NetworkInterface. - - NetworkInterface& operator = (const NetworkInterface& interface); - /// Assigns another NetworkInterface. - - void swap(NetworkInterface& other); - /// Swaps the NetworkInterface with another one. - - int index() const; - /// Returns the interface index. - /// - /// Only supported if IPv6 is available. - /// Returns -1 if IPv6 is not available. - - const std::string& name() const; - /// Returns the interface name. - - const IPAddress& address() const; - /// Returns the IP address bound to the interface. - - const IPAddress& subnetMask() const; - /// Returns the IPv4 subnet mask for this network interface. - - const IPAddress& broadcastAddress() const; - /// Returns the IPv4 broadcast address for this network interface. - - bool supportsIPv4() const; - /// Returns true if the interface supports IPv4. - - bool supportsIPv6() const; - /// Returns true if the interface supports IPv6. - - static NetworkInterface forName(const std::string& name, bool requireIPv6 = false); - /// Returns the NetworkInterface for the given name. - /// - /// If requireIPv6 is false, an IPv4 interface is returned. - /// Otherwise, an IPv6 interface is returned. - /// - /// Throws an InterfaceNotFoundException if an interface - /// with the give name does not exist. - - static NetworkInterface forAddress(const IPAddress& address); - /// Returns the NetworkInterface for the given IP address. - /// - /// Throws an InterfaceNotFoundException if an interface - /// with the give address does not exist. - - static NetworkInterface forIndex(int index); - /// Returns the NetworkInterface for the given interface index. - /// If an index of 0 is specified, a NetworkInterface instance - /// representing the default interface (empty name and - /// wildcard address) is returned. - /// - /// Throws an InterfaceNotFoundException if an interface - /// with the given index does not exist (or IPv6 is not - /// available). - - static NetworkInterfaceList list(); - /// Returns a list with all network interfaces - /// on the system. - /// - /// If there are multiple addresses bound to one interface, - /// multiple NetworkInterface instances are created for - /// the same interface. - -protected: - NetworkInterface(const std::string& name, const IPAddress& address, int index = -1); - /// Creates the NetworkInterface. - - NetworkInterface(const std::string& name, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, int index = -1); - /// Creates the NetworkInterface. - - IPAddress interfaceNameToAddress(const std::string& interfaceName) const; - /// Determines the IPAddress bound to the interface with the given name. - - int interfaceNameToIndex(const std::string& interfaceName) const; - /// Determines the interface index of the interface with the given name. - -private: - NetworkInterfaceImpl* _pImpl; - - static Poco::FastMutex _mutex; -}; - - -} } // namespace Poco::Net - - -#endif // Net_NetworkInterface_INCLUDED +// +// NetworkInterface.h +// +// $Id: //poco/1.3/Net/include/Poco/Net/NetworkInterface.h#4 $ +// +// Library: Net +// Package: Sockets +// Module: NetworkInterface +// +// Definition of the NetworkInterface class. +// +// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Net_NetworkInterface_INCLUDED +#define Net_NetworkInterface_INCLUDED + + +#include "Poco/Net/Net.h" +#include "Poco/Net/IPAddress.h" +#include "Poco/Mutex.h" +#include + + +namespace Poco { +namespace Net { + + +class NetworkInterfaceImpl; + + +class Net_API NetworkInterface + /// This class represents a network interface. + /// + /// NetworkInterface is used with MulticastSocket to specify + /// multicast interfaces for sending and receiving multicast + /// messages. +{ +public: + typedef std::vector NetworkInterfaceList; + + NetworkInterface(); + /// Creates a NetworkInterface representing the + /// default interface. + /// + /// The name is empty, the IP address is the wildcard + /// address and the index is zero. + + NetworkInterface(const NetworkInterface& interface); + /// Creates the NetworkInterface by copying another one. + + ~NetworkInterface(); + /// Destroys the NetworkInterface. + + NetworkInterface& operator = (const NetworkInterface& interface); + /// Assigns another NetworkInterface. + + void swap(NetworkInterface& other); + /// Swaps the NetworkInterface with another one. + + int index() const; + /// Returns the interface index. + /// + /// Only supported if IPv6 is available. + /// Returns -1 if IPv6 is not available. + + const std::string& name() const; + /// Returns the interface name. + + const std::string& displayName() const; + /// Returns the interface display name. + /// + /// On Windows platforms, this is the user-friendly interface + /// name (e.g., "Local Area Connection"). On other platforms, + /// this is the same as name(). + + const IPAddress& address() const; + /// Returns the IP address bound to the interface. + + const IPAddress& subnetMask() const; + /// Returns the IPv4 subnet mask for this network interface. + + const IPAddress& broadcastAddress() const; + /// Returns the IPv4 broadcast address for this network interface. + + bool supportsIPv4() const; + /// Returns true if the interface supports IPv4. + + bool supportsIPv6() const; + /// Returns true if the interface supports IPv6. + + static NetworkInterface forName(const std::string& name, bool requireIPv6 = false); + /// Returns the NetworkInterface for the given name. + /// + /// If requireIPv6 is false, an IPv4 interface is returned. + /// Otherwise, an IPv6 interface is returned. + /// + /// Throws an InterfaceNotFoundException if an interface + /// with the give name does not exist. + + static NetworkInterface forAddress(const IPAddress& address); + /// Returns the NetworkInterface for the given IP address. + /// + /// Throws an InterfaceNotFoundException if an interface + /// with the give address does not exist. + + static NetworkInterface forIndex(int index); + /// Returns the NetworkInterface for the given interface index. + /// If an index of 0 is specified, a NetworkInterface instance + /// representing the default interface (empty name and + /// wildcard address) is returned. + /// + /// Throws an InterfaceNotFoundException if an interface + /// with the given index does not exist (or IPv6 is not + /// available). + + static NetworkInterfaceList list(); + /// Returns a list with all network interfaces + /// on the system. + /// + /// If there are multiple addresses bound to one interface, + /// multiple NetworkInterface instances are created for + /// the same interface. + +protected: + NetworkInterface(const std::string& name, const std::string& displayName, const IPAddress& address, int index = -1); + /// Creates the NetworkInterface. + + NetworkInterface(const std::string& name, const std::string& displayName, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, int index = -1); + /// Creates the NetworkInterface. + + IPAddress interfaceNameToAddress(const std::string& interfaceName) const; + /// Determines the IPAddress bound to the interface with the given name. + + int interfaceNameToIndex(const std::string& interfaceName) const; + /// Determines the interface index of the interface with the given name. + +private: + NetworkInterfaceImpl* _pImpl; + + static Poco::FastMutex _mutex; +}; + + +} } // namespace Poco::Net + + +#endif // Net_NetworkInterface_INCLUDED diff --git a/Net/src/NetworkInterface.cpp b/Net/src/NetworkInterface.cpp index ad1675356..45e5363ac 100644 --- a/Net/src/NetworkInterface.cpp +++ b/Net/src/NetworkInterface.cpp @@ -1,681 +1,726 @@ -// -// NetworkInterface.cpp -// -// $Id: //poco/1.3/Net/src/NetworkInterface.cpp#4 $ -// -// Library: Net -// Package: Sockets -// Module: NetworkInterface -// -// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "Poco/Net/NetworkInterface.h" -#include "Poco/Net/DatagramSocket.h" -#include "Poco/Net/NetException.h" -#include "Poco/NumberFormatter.h" -#include "Poco/RefCountedObject.h" -#include - - -using Poco::NumberFormatter; -using Poco::FastMutex; - - -namespace Poco { -namespace Net { - - -// -// NetworkInterfaceImpl -// - - -class NetworkInterfaceImpl: public Poco::RefCountedObject -{ -public: - NetworkInterfaceImpl(); - NetworkInterfaceImpl(const std::string& name, const IPAddress& address, int index = -1); - NetworkInterfaceImpl(const std::string& name, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, int index = -1); - - int index() const; - const std::string& name() const; - const IPAddress& address() const; - const IPAddress& subnetMask() const; - const IPAddress& broadcastAddress() const; - -protected: - ~NetworkInterfaceImpl(); - -private: - std::string _name; - IPAddress _address; - IPAddress _subnetMask; - IPAddress _broadcastAddress; - int _index; -}; - - -NetworkInterfaceImpl::NetworkInterfaceImpl(): - _index(-1) -{ -} - - -NetworkInterfaceImpl::NetworkInterfaceImpl(const std::string& name, const IPAddress& address, int index): - _name(name), - _address(address), - _index(index) -{ -#ifndef _WIN32 - if (index == -1) // IPv4 - { - struct ifreq ifr; - std::strncpy(ifr.ifr_name, name.c_str(), IFNAMSIZ); - DatagramSocket ds(IPAddress::IPv4); - ds.impl()->ioctl(SIOCGIFNETMASK, &ifr); - if (ifr.ifr_addr.sa_family == AF_INET) - _subnetMask = IPAddress(&reinterpret_cast(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr)); - if (!address.isLoopback()) - { - try - { - // Not every interface (e.g. loopback) has a broadcast address - ds.impl()->ioctl(SIOCGIFBRDADDR, &ifr); - if (ifr.ifr_addr.sa_family == AF_INET) - _broadcastAddress = IPAddress(&reinterpret_cast(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr)); - } - catch (...) - { - } - } - } -#endif -} - - -NetworkInterfaceImpl::NetworkInterfaceImpl(const std::string& name, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, int index): - _name(name), - _address(address), - _subnetMask(subnetMask), - _broadcastAddress(broadcastAddress), - _index(index) -{ -} - - -NetworkInterfaceImpl::~NetworkInterfaceImpl() -{ -} - - -inline int NetworkInterfaceImpl::index() const -{ - return _index; -} - - -inline const std::string& NetworkInterfaceImpl::name() const -{ - return _name; -} - - -inline const IPAddress& NetworkInterfaceImpl::address() const -{ - return _address; -} - - -inline const IPAddress& NetworkInterfaceImpl::subnetMask() const -{ - return _subnetMask; -} - - -inline const IPAddress& NetworkInterfaceImpl::broadcastAddress() const -{ - return _broadcastAddress; -} - - -// -// NetworkInterface -// - - -FastMutex NetworkInterface::_mutex; - - -NetworkInterface::NetworkInterface(): - _pImpl(new NetworkInterfaceImpl) -{ -} - - -NetworkInterface::NetworkInterface(const NetworkInterface& interface): - _pImpl(interface._pImpl) -{ - _pImpl->duplicate(); -} - - -NetworkInterface::NetworkInterface(const std::string& name, const IPAddress& address, int index): - _pImpl(new NetworkInterfaceImpl(name, address, index)) -{ -} - - -NetworkInterface::NetworkInterface(const std::string& name, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, int index): - _pImpl(new NetworkInterfaceImpl(name, address, subnetMask, broadcastAddress, index)) -{ -} - - -NetworkInterface::~NetworkInterface() -{ - _pImpl->release(); -} - - -NetworkInterface& NetworkInterface::operator = (const NetworkInterface& interface) -{ - NetworkInterface tmp(interface); - swap(tmp); - return *this; -} - - -void NetworkInterface::swap(NetworkInterface& other) -{ - using std::swap; - swap(_pImpl, other._pImpl); -} - - -int NetworkInterface::index() const -{ - return _pImpl->index(); -} - - -const std::string& NetworkInterface::name() const -{ - return _pImpl->name(); -} - - -const IPAddress& NetworkInterface::address() const -{ - return _pImpl->address(); -} - - -const IPAddress& NetworkInterface::subnetMask() const -{ - return _pImpl->subnetMask(); -} - - -const IPAddress& NetworkInterface::broadcastAddress() const -{ - return _pImpl->broadcastAddress(); -} - - -bool NetworkInterface::supportsIPv4() const -{ - return _pImpl->index() == -1; -} - - -bool NetworkInterface::supportsIPv6() const -{ - return _pImpl->index() != -1; -} - - -NetworkInterface NetworkInterface::forName(const std::string& name, bool requireIPv6) -{ -#if defined(_WIN32) - NetworkInterfaceList ifs = list(); - for (NetworkInterfaceList::const_iterator it = ifs.begin(); it != ifs.end(); ++it) - { - if (it->name() == name && it->supportsIPv6() == requireIPv6) - return *it; - } - throw InterfaceNotFoundException(name); -#else - FastMutex::ScopedLock lock(_mutex); - - struct ifreq ifr; - std::strncpy(ifr.ifr_name, name.c_str(), IFNAMSIZ); - DatagramSocket ds(requireIPv6 ? IPAddress::IPv6 : IPAddress::IPv4); - ds.impl()->ioctl(SIOCGIFADDR, &ifr); - IPAddress addr; -#if defined(POCO_HAVE_IPv6) - if (ifr.ifr_addr.sa_family == AF_INET) - addr = IPAddress(&reinterpret_cast(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr)); - else if (ifr.ifr_addr.sa_family == AF_INET6) - addr = IPAddress(&reinterpret_cast(&ifr.ifr_addr)->sin6_addr, sizeof(struct in6_addr)); - else - throw InterfaceNotFoundException(addr.toString(), "interface has no IP address"); - int index = if_nametoindex(name.c_str()); -#else - if (ifr.ifr_addr.sa_family == AF_INET) - addr = IPAddress(&reinterpret_cast(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr)); - else - throw InterfaceNotFoundException(addr.toString(), "interface has no IP address"); - int index = 0; -#endif - return NetworkInterface(name, addr, index); -#endif -} - - -NetworkInterface NetworkInterface::forAddress(const IPAddress& addr) -{ - NetworkInterfaceList ifs = list(); - for (NetworkInterfaceList::const_iterator it = ifs.begin(); it != ifs.end(); ++it) - { - if (it->address() == addr) - return *it; - } - throw InterfaceNotFoundException(addr.toString()); -} - - -NetworkInterface NetworkInterface::forIndex(int i) -{ - if (i != 0) - { - NetworkInterfaceList ifs = list(); - for (NetworkInterfaceList::const_iterator it = ifs.begin(); it != ifs.end(); ++it) - { - if (it->index() == i) - return *it; - } - throw InterfaceNotFoundException("#" + NumberFormatter::format(i)); - } - else return NetworkInterface(); -} - - -} } // namespace Poco::Net - - -// -// platform-specific code below -// - - -#if defined(POCO_OS_FAMILY_WINDOWS) -// -// Windows -// -#include - - -namespace Poco { -namespace Net { - - -NetworkInterface::NetworkInterfaceList NetworkInterface::list() -{ - FastMutex::ScopedLock lock(_mutex); - NetworkInterfaceList result; - DWORD rc; - -#if defined(POCO_HAVE_IPv6) - // On Windows XP/Server 2003 and later we use GetAdaptersAddresses. - PIP_ADAPTER_ADDRESSES pAdapterAddresses; - PIP_ADAPTER_ADDRESSES pAddress = 0; - ULONG addrLen = sizeof(IP_ADAPTER_ADDRESSES); - pAdapterAddresses = reinterpret_cast(new char[addrLen]); - // Make an initial call to GetAdaptersAddresses to get - // the necessary size into addrLen - rc = GetAdaptersAddresses(AF_INET6, 0, 0, pAdapterAddresses, &addrLen); - if (rc == ERROR_BUFFER_OVERFLOW) - { - delete [] reinterpret_cast(pAdapterAddresses); - pAdapterAddresses = reinterpret_cast(new char[addrLen]); - } - else if (rc != ERROR_SUCCESS) - { - throw NetException("cannot get network adapter list"); - } - try - { - if (GetAdaptersAddresses(AF_INET6, 0, 0, pAdapterAddresses, &addrLen) == NO_ERROR) - { - pAddress = pAdapterAddresses; - while (pAddress) - { - if (pAddress->FirstUnicastAddress) - { - IPAddress addr(pAddress->FirstUnicastAddress->Address.lpSockaddr, pAddress->FirstUnicastAddress->Address.iSockaddrLength); - result.push_back(NetworkInterface(std::string(pAddress->AdapterName), addr, pAddress->Ipv6IfIndex)); - pAddress = pAddress->Next; - } - } - } - else throw NetException("cannot get network adapter list"); - } - catch (Poco::Exception&) - { - delete [] reinterpret_cast(pAdapterAddresses); - throw; - } - delete [] reinterpret_cast(pAdapterAddresses); -#endif - - // Add IPv4 loopback interface (not returned by GetAdaptersInfo) - result.push_back(NetworkInterface("Loopback", IPAddress("127.0.0.1"), IPAddress("255.0.0.0"), IPAddress(), -1)); - // On Windows 2000 we use GetAdaptersInfo. - PIP_ADAPTER_INFO pAdapterInfo; - PIP_ADAPTER_INFO pInfo = 0; - ULONG infoLen = sizeof(IP_ADAPTER_INFO); - pAdapterInfo = reinterpret_cast(new char[infoLen]); - // Make an initial call to GetAdaptersInfo to get - // the necessary size into infoLen - rc = GetAdaptersInfo(pAdapterInfo, &infoLen); - if (rc == ERROR_BUFFER_OVERFLOW) - { - delete [] reinterpret_cast(pAdapterInfo); - pAdapterInfo = reinterpret_cast(new char[infoLen]); - } - else if (rc != ERROR_SUCCESS) - { - throw NetException("cannot get network adapter list"); - } - try - { - if (GetAdaptersInfo(pAdapterInfo, &infoLen) == NO_ERROR) - { - pInfo = pAdapterInfo; - while (pInfo) - { - IPAddress address(std::string(pInfo->IpAddressList.IpAddress.String)); - if (!address.isWildcard()) // only return interfaces that have an address assigned. - { - IPAddress subnetMask(std::string(pInfo->IpAddressList.IpMask.String)); - IPAddress broadcastAddress(address); - broadcastAddress.mask(subnetMask, IPAddress("255.255.255.255")); - result.push_back(NetworkInterface(std::string(pInfo->AdapterName), address, subnetMask, broadcastAddress)); - } - pInfo = pInfo->Next; - } - } - else throw NetException("cannot get network adapter list"); - } - catch (Poco::Exception&) - { - delete [] reinterpret_cast(pAdapterInfo); - throw; - } - delete [] reinterpret_cast(pAdapterInfo); - - return result; -} - - -} } // namespace Poco::Net - - -#elif defined(POCO_OS_FAMILY_BSD) || POCO_OS == POCO_OS_QNX -// -// BSD variants -// -#include -#include -#include -#include - - -namespace Poco { -namespace Net { - - -NetworkInterface::NetworkInterfaceList NetworkInterface::list() -{ - FastMutex::ScopedLock lock(_mutex); - NetworkInterfaceList result; - - struct ifaddrs* ifaphead; - int rc = getifaddrs(&ifaphead); - if (rc) throw NetException("cannot get network adapter list"); - - for (struct ifaddrs* ifap = ifaphead; ifap; ifap = ifap->ifa_next) - { - if (ifap->ifa_addr) - { - if (ifap->ifa_addr->sa_family == AF_INET) - { - IPAddress addr(&reinterpret_cast(ifap->ifa_addr)->sin_addr, sizeof(struct in_addr)); - result.push_back(NetworkInterface(std::string(ifap->ifa_name), addr)); - } -#if defined(POCO_HAVE_IPv6) - else if (ifap->ifa_addr->sa_family == AF_INET6) - { - IPAddress addr(&reinterpret_cast(ifap->ifa_addr)->sin6_addr, sizeof(struct in6_addr)); - result.push_back(NetworkInterface(std::string(ifap->ifa_name), addr, if_nametoindex(ifap->ifa_name))); - } -#endif - } - } - freeifaddrs(ifaphead); - return result; -} - - -} } // namespace Poco::Net - - -#elif POCO_OS == POCO_OS_LINUX -// -// Linux -// - - -namespace Poco { -namespace Net { - - -NetworkInterface::NetworkInterfaceList NetworkInterface::list() -{ - FastMutex::ScopedLock lock(_mutex); - NetworkInterfaceList result; - DatagramSocket socket; - // the following code is loosely based - // on W. Richard Stevens, UNIX Network Programming, pp 434ff. - int lastlen = 0; - int len = 100*sizeof(struct ifreq); - char* buf = 0; - try - { - struct ifconf ifc; - for (;;) - { - buf = new char[len]; - ifc.ifc_len = len; - ifc.ifc_buf = buf; - if (::ioctl(socket.impl()->sockfd(), SIOCGIFCONF, &ifc) < 0) - { - if (errno != EINVAL || lastlen != 0) - throw NetException("cannot get network adapter list"); - } - else - { - if (ifc.ifc_len == lastlen) - break; - lastlen = ifc.ifc_len; - } - len += 10*sizeof(struct ifreq); - delete [] buf; - } - for (const char* ptr = buf; ptr < buf + ifc.ifc_len;) - { - const struct ifreq* ifr = reinterpret_cast(ptr); - IPAddress addr; - bool haveAddr = false; - switch (ifr->ifr_addr.sa_family) - { -#if defined(POCO_HAVE_IPv6) - case AF_INET6: - addr = IPAddress(&reinterpret_cast(&ifr->ifr_addr)->sin6_addr, sizeof(struct in6_addr)); - haveAddr = true; - break; -#endif - case AF_INET: - addr = IPAddress(&reinterpret_cast(&ifr->ifr_addr)->sin_addr, sizeof(struct in_addr)); - haveAddr = true; - break; - default: - break; - } - if (haveAddr) - { -#if defined(POCO_HAVE_IPv6) - int index = if_nametoindex(ifr->ifr_name); -#else - int index = -1; -#endif - result.push_back(NetworkInterface(std::string(ifr->ifr_name), addr, index)); - } - ptr += sizeof(struct ifreq); - } - } - catch (...) - { - delete [] buf; - throw; - } - delete [] buf; - return result; -} - - -} } // namespace Poco::Net - - -#else -// -// Non-BSD Unix variants -// - - -namespace Poco { -namespace Net { - - -NetworkInterface::NetworkInterfaceList NetworkInterface::list() -{ - FastMutex::ScopedLock lock(_mutex); - NetworkInterfaceList result; - DatagramSocket socket; - // the following code is loosely based - // on W. Richard Stevens, UNIX Network Programming, pp 434ff. - int lastlen = 0; - int len = 100*sizeof(struct ifreq); - char* buf = 0; - try - { - struct ifconf ifc; - for (;;) - { - buf = new char[len]; - ifc.ifc_len = len; - ifc.ifc_buf = buf; - if (::ioctl(socket.impl()->sockfd(), SIOCGIFCONF, &ifc) < 0) - { - if (errno != EINVAL || lastlen != 0) - throw NetException("cannot get network adapter list"); - } - else - { - if (ifc.ifc_len == lastlen) - break; - lastlen = ifc.ifc_len; - } - len += 10*sizeof(struct ifreq); - delete [] buf; - } - for (const char* ptr = buf; ptr < buf + ifc.ifc_len;) - { - const struct ifreq* ifr = reinterpret_cast(ptr); -#if defined(POCO_HAVE_SALEN) - len = ifr->ifr_addr.sa_len; - if (sizeof(struct sockaddr) > len) len = sizeof(struct sockaddr); -#else - len = sizeof(struct sockaddr); -#endif - IPAddress addr; - bool haveAddr = false; - switch (ifr->ifr_addr.sa_family) - { -#if defined(POCO_HAVE_IPv6) - case AF_INET6: - if (len < sizeof(struct sockaddr_in6)) len = sizeof(struct sockaddr_in6); - addr = IPAddress(&reinterpret_cast(&ifr->ifr_addr)->sin6_addr, sizeof(struct in6_addr)); - haveAddr = true; - break; -#endif - case AF_INET: - if (len < sizeof(struct sockaddr_in)) len = sizeof(struct sockaddr_in); - addr = IPAddress(&reinterpret_cast(&ifr->ifr_addr)->sin_addr, sizeof(struct in_addr)); - haveAddr = true; - break; - default: - break; - } - if (haveAddr) - { -#if defined(POCO_HAVE_IPv6) - int index = if_nametoindex(ifr->ifr_name); -#else - int index = -1; -#endif - result.push_back(NetworkInterface(std::string(ifr->ifr_name), addr, index)); - } - len += sizeof(ifr->ifr_name); - ptr += len; - } - } - catch (...) - { - delete [] buf; - throw; - } - delete [] buf; - return result; -} - - -} } // namespace Poco::Net - - -#endif +// +// NetworkInterface.cpp +// +// $Id: //poco/1.3/Net/src/NetworkInterface.cpp#6 $ +// +// Library: Net +// Package: Sockets +// Module: NetworkInterface +// +// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Net/NetworkInterface.h" +#include "Poco/Net/DatagramSocket.h" +#include "Poco/Net/NetException.h" +#include "Poco/NumberFormatter.h" +#include "Poco/RefCountedObject.h" +#if defined(_WIN32) && defined(POCO_WIN32_UTF8) +#include "Poco/UnicodeConverter.h" +#endif +#include + + +using Poco::NumberFormatter; +using Poco::FastMutex; + + +namespace Poco { +namespace Net { + + +// +// NetworkInterfaceImpl +// + + +class NetworkInterfaceImpl: public Poco::RefCountedObject +{ +public: + NetworkInterfaceImpl(); + NetworkInterfaceImpl(const std::string& name, const std::string& displayName, const IPAddress& address, int index = -1); + NetworkInterfaceImpl(const std::string& name, const std::string& displayName, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, int index = -1); + + int index() const; + const std::string& name() const; + const std::string& displayName() const; + const IPAddress& address() const; + const IPAddress& subnetMask() const; + const IPAddress& broadcastAddress() const; + +protected: + ~NetworkInterfaceImpl(); + +private: + std::string _name; + std::string _displayName; + IPAddress _address; + IPAddress _subnetMask; + IPAddress _broadcastAddress; + int _index; +}; + + +NetworkInterfaceImpl::NetworkInterfaceImpl(): + _index(-1) +{ +} + + +NetworkInterfaceImpl::NetworkInterfaceImpl(const std::string& name, const std::string& displayName, const IPAddress& address, int index): + _name(name), + _displayName(name), + _address(address), + _index(index) +{ +#ifndef _WIN32 + if (index == -1) // IPv4 + { + struct ifreq ifr; + std::strncpy(ifr.ifr_name, name.c_str(), IFNAMSIZ); + DatagramSocket ds(IPAddress::IPv4); + ds.impl()->ioctl(SIOCGIFNETMASK, &ifr); + if (ifr.ifr_addr.sa_family == AF_INET) + _subnetMask = IPAddress(&reinterpret_cast(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr)); + if (!address.isLoopback()) + { + try + { + // Not every interface (e.g. loopback) has a broadcast address + ds.impl()->ioctl(SIOCGIFBRDADDR, &ifr); + if (ifr.ifr_addr.sa_family == AF_INET) + _broadcastAddress = IPAddress(&reinterpret_cast(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr)); + } + catch (...) + { + } + } + } +#endif +} + + +NetworkInterfaceImpl::NetworkInterfaceImpl(const std::string& name, const std::string& displayName, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, int index): + _name(name), + _displayName(name), + _address(address), + _subnetMask(subnetMask), + _broadcastAddress(broadcastAddress), + _index(index) +{ +} + + +NetworkInterfaceImpl::~NetworkInterfaceImpl() +{ +} + + +inline int NetworkInterfaceImpl::index() const +{ + return _index; +} + + +inline const std::string& NetworkInterfaceImpl::name() const +{ + return _name; +} + + +inline const std::string& NetworkInterfaceImpl::displayName() const +{ + return _displayName; +} + + +inline const IPAddress& NetworkInterfaceImpl::address() const +{ + return _address; +} + + +inline const IPAddress& NetworkInterfaceImpl::subnetMask() const +{ + return _subnetMask; +} + + +inline const IPAddress& NetworkInterfaceImpl::broadcastAddress() const +{ + return _broadcastAddress; +} + + +// +// NetworkInterface +// + + +FastMutex NetworkInterface::_mutex; + + +NetworkInterface::NetworkInterface(): + _pImpl(new NetworkInterfaceImpl) +{ +} + + +NetworkInterface::NetworkInterface(const NetworkInterface& interface): + _pImpl(interface._pImpl) +{ + _pImpl->duplicate(); +} + + +NetworkInterface::NetworkInterface(const std::string& name, const std::string& displayName, const IPAddress& address, int index): + _pImpl(new NetworkInterfaceImpl(name, displayName, address, index)) +{ +} + + +NetworkInterface::NetworkInterface(const std::string& name, const std::string& displayName, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, int index): + _pImpl(new NetworkInterfaceImpl(name, displayName, address, subnetMask, broadcastAddress, index)) +{ +} + + +NetworkInterface::~NetworkInterface() +{ + _pImpl->release(); +} + + +NetworkInterface& NetworkInterface::operator = (const NetworkInterface& interface) +{ + NetworkInterface tmp(interface); + swap(tmp); + return *this; +} + + +void NetworkInterface::swap(NetworkInterface& other) +{ + using std::swap; + swap(_pImpl, other._pImpl); +} + + +int NetworkInterface::index() const +{ + return _pImpl->index(); +} + + +const std::string& NetworkInterface::name() const +{ + return _pImpl->name(); +} + + +const std::string& NetworkInterface::displayName() const +{ + return _pImpl->displayName(); +} + + +const IPAddress& NetworkInterface::address() const +{ + return _pImpl->address(); +} + + +const IPAddress& NetworkInterface::subnetMask() const +{ + return _pImpl->subnetMask(); +} + + +const IPAddress& NetworkInterface::broadcastAddress() const +{ + return _pImpl->broadcastAddress(); +} + + +bool NetworkInterface::supportsIPv4() const +{ + return _pImpl->index() == -1; +} + + +bool NetworkInterface::supportsIPv6() const +{ + return _pImpl->index() != -1; +} + + +NetworkInterface NetworkInterface::forName(const std::string& name, bool requireIPv6) +{ +#if defined(_WIN32) + NetworkInterfaceList ifs = list(); + for (NetworkInterfaceList::const_iterator it = ifs.begin(); it != ifs.end(); ++it) + { + if (it->name() == name && it->supportsIPv6() == requireIPv6) + return *it; + } + throw InterfaceNotFoundException(name); +#else + FastMutex::ScopedLock lock(_mutex); + + struct ifreq ifr; + std::strncpy(ifr.ifr_name, name.c_str(), IFNAMSIZ); + DatagramSocket ds(requireIPv6 ? IPAddress::IPv6 : IPAddress::IPv4); + ds.impl()->ioctl(SIOCGIFADDR, &ifr); + IPAddress addr; +#if defined(POCO_HAVE_IPv6) + if (ifr.ifr_addr.sa_family == AF_INET) + addr = IPAddress(&reinterpret_cast(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr)); + else if (ifr.ifr_addr.sa_family == AF_INET6) + addr = IPAddress(&reinterpret_cast(&ifr.ifr_addr)->sin6_addr, sizeof(struct in6_addr)); + else + throw InterfaceNotFoundException(addr.toString(), "interface has no IP address"); + int index = if_nametoindex(name.c_str()); +#else + if (ifr.ifr_addr.sa_family == AF_INET) + addr = IPAddress(&reinterpret_cast(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr)); + else + throw InterfaceNotFoundException(addr.toString(), "interface has no IP address"); + int index = 0; +#endif + return NetworkInterface(name, name, addr, index); +#endif +} + + +NetworkInterface NetworkInterface::forAddress(const IPAddress& addr) +{ + NetworkInterfaceList ifs = list(); + for (NetworkInterfaceList::const_iterator it = ifs.begin(); it != ifs.end(); ++it) + { + if (it->address() == addr) + return *it; + } + throw InterfaceNotFoundException(addr.toString()); +} + + +NetworkInterface NetworkInterface::forIndex(int i) +{ + if (i != 0) + { + NetworkInterfaceList ifs = list(); + for (NetworkInterfaceList::const_iterator it = ifs.begin(); it != ifs.end(); ++it) + { + if (it->index() == i) + return *it; + } + throw InterfaceNotFoundException("#" + NumberFormatter::format(i)); + } + else return NetworkInterface(); +} + + +} } // namespace Poco::Net + + +// +// platform-specific code below +// + + +#if defined(POCO_OS_FAMILY_WINDOWS) +// +// Windows +// +#include + + +namespace Poco { +namespace Net { + + +NetworkInterface::NetworkInterfaceList NetworkInterface::list() +{ + FastMutex::ScopedLock lock(_mutex); + NetworkInterfaceList result; + DWORD rc; + +#if defined(POCO_HAVE_IPv6) + // On Windows XP/Server 2003 and later we use GetAdaptersAddresses. + PIP_ADAPTER_ADDRESSES pAdapterAddresses; + PIP_ADAPTER_ADDRESSES pAddress = 0; + ULONG addrLen = sizeof(IP_ADAPTER_ADDRESSES); + pAdapterAddresses = reinterpret_cast(new char[addrLen]); + // Make an initial call to GetAdaptersAddresses to get + // the necessary size into addrLen + rc = GetAdaptersAddresses(AF_INET6, 0, 0, pAdapterAddresses, &addrLen); + if (rc == ERROR_BUFFER_OVERFLOW) + { + delete [] reinterpret_cast(pAdapterAddresses); + pAdapterAddresses = reinterpret_cast(new char[addrLen]); + } + else if (rc != ERROR_SUCCESS) + { + throw NetException("cannot get network adapter list"); + } + try + { + if (GetAdaptersAddresses(AF_INET6, 0, 0, pAdapterAddresses, &addrLen) == NO_ERROR) + { + pAddress = pAdapterAddresses; + while (pAddress) + { + if (pAddress->FirstUnicastAddress) + { + IPAddress addr(pAddress->FirstUnicastAddress->Address.lpSockaddr, pAddress->FirstUnicastAddress->Address.iSockaddrLength); + std::string name(pAddress->AdapterName); + std::string displayName; +#if POCO_WIN32_UTF8 + Poco::UnicodeConverter::toUTF8(pAddress->FriendlyName, displayName); +#else + char displayNameBuffer[1024]; + int rc = WideCharToMultiByte(CP_ACP, WC_DEFAULTCHAR, pAddress->FriendlyName, -1, displayNameBuffer, sizeof(displayNameBuffer), NULL, NULL); + if (rc) displayName = displayNameBuffer; +#endif + result.push_back(NetworkInterface(std::string(name, displayName, addr, pAddress->Ipv6IfIndex)); + pAddress = pAddress->Next; + } + } + } + else throw NetException("cannot get network adapter list"); + } + catch (Poco::Exception&) + { + delete [] reinterpret_cast(pAdapterAddresses); + throw; + } + delete [] reinterpret_cast(pAdapterAddresses); +#endif + + // Add IPv4 loopback interface (not returned by GetAdaptersInfo) + result.push_back(NetworkInterface("Loopback", IPAddress("127.0.0.1"), IPAddress("255.0.0.0"), IPAddress(), -1)); + // On Windows 2000 we use GetAdaptersInfo. + PIP_ADAPTER_INFO pAdapterInfo; + PIP_ADAPTER_INFO pInfo = 0; + ULONG infoLen = sizeof(IP_ADAPTER_INFO); + pAdapterInfo = reinterpret_cast(new char[infoLen]); + // Make an initial call to GetAdaptersInfo to get + // the necessary size into infoLen + rc = GetAdaptersInfo(pAdapterInfo, &infoLen); + if (rc == ERROR_BUFFER_OVERFLOW) + { + delete [] reinterpret_cast(pAdapterInfo); + pAdapterInfo = reinterpret_cast(new char[infoLen]); + } + else if (rc != ERROR_SUCCESS) + { + throw NetException("cannot get network adapter list"); + } + try + { + if (GetAdaptersInfo(pAdapterInfo, &infoLen) == NO_ERROR) + { + pInfo = pAdapterInfo; + while (pInfo) + { + IPAddress address(std::string(pInfo->IpAddressList.IpAddress.String)); + if (!address.isWildcard()) // only return interfaces that have an address assigned. + { + IPAddress subnetMask(std::string(pInfo->IpAddressList.IpMask.String)); + IPAddress broadcastAddress(address); + broadcastAddress.mask(subnetMask, IPAddress("255.255.255.255")); + std::string name(pInfo->AdapterName); + std::string displayName; +#if POCO_WIN32_UTF8 + Poco::UnicodeConverter::toUTF8(pAddress->FriendlyName, displayName); +#else + char displayNameBuffer[1024]; + int rc = WideCharToMultiByte(CP_ACP, WC_DEFAULTCHAR, pAddress->FriendlyName, -1, displayNameBuffer, sizeof(displayNameBuffer), NULL, NULL); + if (rc) displayName = displayNameBuffer; +#endif + result.push_back(NetworkInterface(name, displayName, address, subnetMask, broadcastAddress)); + } + pInfo = pInfo->Next; + } + } + else throw NetException("cannot get network adapter list"); + } + catch (Poco::Exception&) + { + delete [] reinterpret_cast(pAdapterInfo); + throw; + } + delete [] reinterpret_cast(pAdapterInfo); + + return result; +} + + +} } // namespace Poco::Net + + +#elif defined(POCO_OS_FAMILY_BSD) || POCO_OS == POCO_OS_QNX +// +// BSD variants +// +#include +#include +#include +#include + + +namespace Poco { +namespace Net { + + +NetworkInterface::NetworkInterfaceList NetworkInterface::list() +{ + FastMutex::ScopedLock lock(_mutex); + NetworkInterfaceList result; + + struct ifaddrs* ifaphead; + int rc = getifaddrs(&ifaphead); + if (rc) throw NetException("cannot get network adapter list"); + + for (struct ifaddrs* ifap = ifaphead; ifap; ifap = ifap->ifa_next) + { + if (ifap->ifa_addr) + { + if (ifap->ifa_addr->sa_family == AF_INET) + { + std::string name(ifap->ifa_name); + IPAddress addr(&reinterpret_cast(ifap->ifa_addr)->sin_addr, sizeof(struct in_addr)); + IPAddress subnetMask(&reinterpret_cast(ifap->ifa_netmask)->sin_addr, sizeof(struct in_addr)); + IPAddress broadcastAddr; + if (ifap->ifa_flags & IFF_BROADCAST) + broadcastAddr = IPAddress(&reinterpret_cast(ifap->ifa_dstaddr)->sin_addr, sizeof(struct in_addr)); + result.push_back(NetworkInterface(name, name, addr, subnetMask, broadcastAddr)); + } +#if defined(POCO_HAVE_IPv6) + else if (ifap->ifa_addr->sa_family == AF_INET6) + { + IPAddress addr(&reinterpret_cast(ifap->ifa_addr)->sin6_addr, sizeof(struct in6_addr)); + std::string name(ifap->ifa_name); + result.push_back(NetworkInterface(name, name, addr, if_nametoindex(ifap->ifa_name))); + } +#endif + } + } + freeifaddrs(ifaphead); + return result; +} + + +} } // namespace Poco::Net + + +#elif POCO_OS == POCO_OS_LINUX +// +// Linux +// + + +namespace Poco { +namespace Net { + + +NetworkInterface::NetworkInterfaceList NetworkInterface::list() +{ + FastMutex::ScopedLock lock(_mutex); + NetworkInterfaceList result; + DatagramSocket socket; + // the following code is loosely based + // on W. Richard Stevens, UNIX Network Programming, pp 434ff. + int lastlen = 0; + int len = 100*sizeof(struct ifreq); + char* buf = 0; + try + { + struct ifconf ifc; + for (;;) + { + buf = new char[len]; + ifc.ifc_len = len; + ifc.ifc_buf = buf; + if (::ioctl(socket.impl()->sockfd(), SIOCGIFCONF, &ifc) < 0) + { + if (errno != EINVAL || lastlen != 0) + throw NetException("cannot get network adapter list"); + } + else + { + if (ifc.ifc_len == lastlen) + break; + lastlen = ifc.ifc_len; + } + len += 10*sizeof(struct ifreq); + delete [] buf; + } + for (const char* ptr = buf; ptr < buf + ifc.ifc_len;) + { + const struct ifreq* ifr = reinterpret_cast(ptr); + IPAddress addr; + bool haveAddr = false; + switch (ifr->ifr_addr.sa_family) + { +#if defined(POCO_HAVE_IPv6) + case AF_INET6: + addr = IPAddress(&reinterpret_cast(&ifr->ifr_addr)->sin6_addr, sizeof(struct in6_addr)); + haveAddr = true; + break; +#endif + case AF_INET: + addr = IPAddress(&reinterpret_cast(&ifr->ifr_addr)->sin_addr, sizeof(struct in_addr)); + haveAddr = true; + break; + default: + break; + } + if (haveAddr) + { +#if defined(POCO_HAVE_IPv6) + int index = if_nametoindex(ifr->ifr_name); +#else + int index = -1; +#endif + std::string name(ifr->ifr_name); + result.push_back(NetworkInterface(name, name, addr, index)); + } + ptr += sizeof(struct ifreq); + } + } + catch (...) + { + delete [] buf; + throw; + } + delete [] buf; + return result; +} + + +} } // namespace Poco::Net + + +#else +// +// Non-BSD Unix variants +// + + +namespace Poco { +namespace Net { + + +NetworkInterface::NetworkInterfaceList NetworkInterface::list() +{ + FastMutex::ScopedLock lock(_mutex); + NetworkInterfaceList result; + DatagramSocket socket; + // the following code is loosely based + // on W. Richard Stevens, UNIX Network Programming, pp 434ff. + int lastlen = 0; + int len = 100*sizeof(struct ifreq); + char* buf = 0; + try + { + struct ifconf ifc; + for (;;) + { + buf = new char[len]; + ifc.ifc_len = len; + ifc.ifc_buf = buf; + if (::ioctl(socket.impl()->sockfd(), SIOCGIFCONF, &ifc) < 0) + { + if (errno != EINVAL || lastlen != 0) + throw NetException("cannot get network adapter list"); + } + else + { + if (ifc.ifc_len == lastlen) + break; + lastlen = ifc.ifc_len; + } + len += 10*sizeof(struct ifreq); + delete [] buf; + } + for (const char* ptr = buf; ptr < buf + ifc.ifc_len;) + { + const struct ifreq* ifr = reinterpret_cast(ptr); +#if defined(POCO_HAVE_SALEN) + len = ifr->ifr_addr.sa_len; + if (sizeof(struct sockaddr) > len) len = sizeof(struct sockaddr); +#else + len = sizeof(struct sockaddr); +#endif + IPAddress addr; + bool haveAddr = false; + switch (ifr->ifr_addr.sa_family) + { +#if defined(POCO_HAVE_IPv6) + case AF_INET6: + if (len < sizeof(struct sockaddr_in6)) len = sizeof(struct sockaddr_in6); + addr = IPAddress(&reinterpret_cast(&ifr->ifr_addr)->sin6_addr, sizeof(struct in6_addr)); + haveAddr = true; + break; +#endif + case AF_INET: + if (len < sizeof(struct sockaddr_in)) len = sizeof(struct sockaddr_in); + addr = IPAddress(&reinterpret_cast(&ifr->ifr_addr)->sin_addr, sizeof(struct in_addr)); + haveAddr = true; + break; + default: + break; + } + if (haveAddr) + { +#if defined(POCO_HAVE_IPv6) + int index = if_nametoindex(ifr->ifr_name); +#else + int index = -1; +#endif + std::string name(ifr->ifr_name); + result.push_back(NetworkInterface(name, name, addr, index)); + } + len += sizeof(ifr->ifr_name); + ptr += len; + } + } + catch (...) + { + delete [] buf; + throw; + } + delete [] buf; + return result; +} + + +} } // namespace Poco::Net + + +#endif diff --git a/Net/testsuite/src/NetworkInterfaceTest.cpp b/Net/testsuite/src/NetworkInterfaceTest.cpp index 9cbeb3f25..879a7e9bd 100644 --- a/Net/testsuite/src/NetworkInterfaceTest.cpp +++ b/Net/testsuite/src/NetworkInterfaceTest.cpp @@ -1,123 +1,124 @@ -// -// NetworkInterfaceTest.cpp -// -// $Id: //poco/1.3/Net/testsuite/src/NetworkInterfaceTest.cpp#2 $ -// -// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "NetworkInterfaceTest.h" -#include "CppUnit/TestCaller.h" -#include "CppUnit/TestSuite.h" -#include "Poco/Net/NetworkInterface.h" -#include - - -using Poco::Net::NetworkInterface; - - -NetworkInterfaceTest::NetworkInterfaceTest(const std::string& name): CppUnit::TestCase(name) -{ -} - - -NetworkInterfaceTest::~NetworkInterfaceTest() -{ -} - - -void NetworkInterfaceTest::testList() -{ - NetworkInterface::NetworkInterfaceList list = NetworkInterface::list(); - assert (!list.empty()); - for (NetworkInterface::NetworkInterfaceList::const_iterator it = list.begin(); it != list.end(); ++it) - { - std::cout << "Name: " << it->name() << std::endl; - std::cout << "Address: " << it->address().toString() << std::endl; - std::cout << "Subnet: " << it->subnetMask().toString() << std::endl; - std::cout << "Broadcast: " << it->broadcastAddress().toString() << std::endl; - std::cout << "Index: " << it->index() << std::endl; - } -} - - -void NetworkInterfaceTest::testForName() -{ - NetworkInterface::NetworkInterfaceList list = NetworkInterface::list(); - for (NetworkInterface::NetworkInterfaceList::const_iterator it = list.begin(); it != list.end(); ++it) - { - NetworkInterface ifc = NetworkInterface::forName(it->name()); - assert (ifc.name() == it->name()); - } -} - - -void NetworkInterfaceTest::testForAddress() -{ - NetworkInterface::NetworkInterfaceList list = NetworkInterface::list(); - for (NetworkInterface::NetworkInterfaceList::const_iterator it = list.begin(); it != list.end(); ++it) - { - NetworkInterface ifc = NetworkInterface::forAddress(it->address()); - assert (ifc.address() == it->address()); - } -} - - -void NetworkInterfaceTest::testForIndex() -{ -#if defined(POCO_HAVE_IPv6) - NetworkInterface::NetworkInterfaceList list = NetworkInterface::list(); - for (NetworkInterface::NetworkInterfaceList::const_iterator it = list.begin(); it != list.end(); ++it) - { - NetworkInterface ifc = NetworkInterface::forIndex(it->index()); - assert (ifc.index() == it->index()); - } -#endif -} - - -void NetworkInterfaceTest::setUp() -{ -} - - -void NetworkInterfaceTest::tearDown() -{ -} - - -CppUnit::Test* NetworkInterfaceTest::suite() -{ - CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("NetworkInterfaceTest"); - - CppUnit_addTest(pSuite, NetworkInterfaceTest, testList); - CppUnit_addTest(pSuite, NetworkInterfaceTest, testForName); - CppUnit_addTest(pSuite, NetworkInterfaceTest, testForAddress); - CppUnit_addTest(pSuite, NetworkInterfaceTest, testForIndex); - - return pSuite; -} +// +// NetworkInterfaceTest.cpp +// +// $Id: //poco/1.3/Net/testsuite/src/NetworkInterfaceTest.cpp#3 $ +// +// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "NetworkInterfaceTest.h" +#include "CppUnit/TestCaller.h" +#include "CppUnit/TestSuite.h" +#include "Poco/Net/NetworkInterface.h" +#include + + +using Poco::Net::NetworkInterface; + + +NetworkInterfaceTest::NetworkInterfaceTest(const std::string& name): CppUnit::TestCase(name) +{ +} + + +NetworkInterfaceTest::~NetworkInterfaceTest() +{ +} + + +void NetworkInterfaceTest::testList() +{ + NetworkInterface::NetworkInterfaceList list = NetworkInterface::list(); + assert (!list.empty()); + for (NetworkInterface::NetworkInterfaceList::const_iterator it = list.begin(); it != list.end(); ++it) + { + std::cout << "Name: " << it->name() << std::endl; + std::cout << "DisplayName: " << it->displayName() << std::endl; + std::cout << "Address: " << it->address().toString() << std::endl; + std::cout << "Subnet: " << it->subnetMask().toString() << std::endl; + std::cout << "Broadcast: " << it->broadcastAddress().toString() << std::endl; + std::cout << "Index: " << it->index() << std::endl; + } +} + + +void NetworkInterfaceTest::testForName() +{ + NetworkInterface::NetworkInterfaceList list = NetworkInterface::list(); + for (NetworkInterface::NetworkInterfaceList::const_iterator it = list.begin(); it != list.end(); ++it) + { + NetworkInterface ifc = NetworkInterface::forName(it->name()); + assert (ifc.name() == it->name()); + } +} + + +void NetworkInterfaceTest::testForAddress() +{ + NetworkInterface::NetworkInterfaceList list = NetworkInterface::list(); + for (NetworkInterface::NetworkInterfaceList::const_iterator it = list.begin(); it != list.end(); ++it) + { + NetworkInterface ifc = NetworkInterface::forAddress(it->address()); + assert (ifc.address() == it->address()); + } +} + + +void NetworkInterfaceTest::testForIndex() +{ +#if defined(POCO_HAVE_IPv6) + NetworkInterface::NetworkInterfaceList list = NetworkInterface::list(); + for (NetworkInterface::NetworkInterfaceList::const_iterator it = list.begin(); it != list.end(); ++it) + { + NetworkInterface ifc = NetworkInterface::forIndex(it->index()); + assert (ifc.index() == it->index()); + } +#endif +} + + +void NetworkInterfaceTest::setUp() +{ +} + + +void NetworkInterfaceTest::tearDown() +{ +} + + +CppUnit::Test* NetworkInterfaceTest::suite() +{ + CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("NetworkInterfaceTest"); + + CppUnit_addTest(pSuite, NetworkInterfaceTest, testList); + CppUnit_addTest(pSuite, NetworkInterfaceTest, testForName); + CppUnit_addTest(pSuite, NetworkInterfaceTest, testForAddress); + CppUnit_addTest(pSuite, NetworkInterfaceTest, testForIndex); + + return pSuite; +}