Added:
trunk/mysqlclient/NativeDriver.cs
trunk/mysqlclient/Resources.Designer.cs
trunk/mysqlclient/common/SocketStream.cs
Removed:
trunk/MySql.Data.2003.csproj
trunk/MySql.Data.2005.csproj
Modified:
trunk/Client.build
trunk/mysqlclient/CommandBuilder.cs
trunk/mysqlclient/CompressedStream.cs
trunk/mysqlclient/Connection.cs
trunk/mysqlclient/Crypt.cs
trunk/mysqlclient/Field.cs
trunk/mysqlclient/ISSchemaProvider.cs
trunk/mysqlclient/Logger.cs
trunk/mysqlclient/MySqlConnectionStringBuilder.cs
trunk/mysqlclient/ProcedureCache.cs
trunk/mysqlclient/Resources.resx
trunk/mysqlclient/Statement.cs
trunk/mysqlclient/StoredProcedure.cs
trunk/mysqlclient/Types/MySqlBinary.cs
trunk/mysqlclient/Types/MySqlByte.cs
trunk/mysqlclient/command.cs
trunk/mysqlclient/common/ContextString.cs
trunk/mysqlclient/common/StreamCreator.cs
trunk/mysqlclient/datareader.cs
trunk/mysqlclient/docs/MySqlConnectionStringBuilder.xml
Log:
General
---------------
Moved project files for core provider inside mysqlclient/command.cs
client.build
---------------
Adjusted ${outdir} to point inside mysqlclient.
command.cs
--------------------
Added internal method Close() that allows the command to cleanup after the reader is closed.
Changed the CommandText setter to look for the string "DEFAULT VALUES" and change it to "() VALUES ()" which is MySQL compatible.
ContextString.cs
---------------------
Exposed the context markers property so that calling code can change it without creating a new object.
Fixed a problem in Split() related to when the opening and closing context markers are the same.
Connection.cs
CommandBuilder.cs
Crypt.cs
CompressedStream.cs
MySqlConnectionStringBuilder.cs
ProcedureCache.cs
---------------------
Minor cleanups including using the new strongly typed resource class created by ResGen
datareader.cs
---------------------
Made values internal so that the stored procedure statement object can access them for updating parameters.
Added nextResultDone var to indicate if NextResult has already returned false. This is used in Close()
to keep us from having to call NextResult again.
Some cleanups related to DateTime
Field.cs
---------------------
Added SetTypeAndFlags method which is called from NativeDriver when creating metadata. It sets the imaginary
MySqlDbType values such as the unsigned ones based on flags.
ISSchemaProvider.cs
---------------------
Set the correct table names on many of the collections
Added a small optimization where when GetSchema is used for getting the meta data for a single sproc, we don't need
to retrieve the "procedures" collection more than once.
Fixed problem where parameter mode "IN" was not being set correctly.
Fixed several problems in type parsing.
Logger.cs
---------------------
Minor cleanups
nativedriver.cs
---------------------
Now calling Field.SetTypeAndFlags when building meta data
Resources.resx
---------------------
Added several new strings
Statement.cs
---------------------
Added virtual Close() method.
Fixed problem in TokenizeSql where @ or ? when they are not the place holder terminates parameter scanning
MySqlBinary.cs
---------------------
Small fixes related to setting the proper length in WriteValue
MySqlByte.cs
---------------------
Now using the InvariantCulture for parsing the Value
Modified: trunk/Client.build
===================================================================
--- trunk/Client.build 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/Client.build 2006-07-28 15:02:38 UTC (rev 277)
@@ -1,7 +1,7 @@
<project name="MySqlClient" default="allframeworks" xmlns="http://nant.sf.net/schemas/nant-0.84.win32.net-1.0.xsd">
<description>MySQLClient Managed Provider for MySQL</description>
- <property name="nunit" value="C:\Program Files\NUnit"/>
+ <property name="nunit" value="C:\Program Files (x86)\NUnit"/>
<property name="ncover.executable" value="c:\program files\ncover\ncover.console.exe"/>
<property name="fxcop.executable" value="c:\program files\fxcop\fxcopcmd.exe"/>
@@ -41,7 +41,7 @@
<!-- core managed driver target -->
<target name="client" description="Core client target">
<property name="nant.settings.currentframework" value="${framework}"/>
- <property name="outdir" value="bin/${framework}/${buildType}"/>
+ <property name="outdir" value="mysqlclient/bin/${framework}/${buildType}"/>
<mkdir dir="${outdir}" failonerror="false"/>
<resgen input="mysqlclient/Resources.resx" output="mysqlclient/Resources.resources"/>
@@ -49,8 +49,8 @@
define="${defines}" debug="${debug}" optimize="${opt}"
doc="${outdir}/MySql.Data.xml">
<arg value="/nowarn:0679,1591"/>
- <resources prefix="MySql.Data.MySqlClient" dynamicprefix="true">
- <include name="mysqlclient/Strings.resources"/>
+ <resources prefix="MySql.Data.MySqlClient" dynamicprefix="false">
+ <include name="mysqlclient/Resources.resources"/>
</resources>
<references>
<include name="ICSharpCode.SharpZipLib.dll"/>
@@ -69,6 +69,7 @@
<include name="System.Data.dll"/>
<include name="System.Configuration.dll"/>
<include name="System.Drawing.dll"/>
+ <include name="System.Windows.Forms.dll"/>
<include name="${nunit-lib}/nunit.framework.dll"/>
</references>
</csc>
@@ -98,7 +99,7 @@
<!-- core managed driver target mono 1.0 -->
<target name="mono-1.0" description="Mono 1.0 Target">
- <property name="nunit-lib" value="${framework::get-assembly-directory('mono-1.0')}"/>
+ <property name="nunit-lib" value="${framework::get-assembly-directory('mono-1.0')}"/>
<property name="framework" value="mono-1.0"/>
<call target="client"/>
</target>
@@ -124,7 +125,7 @@
</target>
<target name="test-mono-1.0" depends="mono-1.0">
- <property name="nunit" value="${nunit-mono}"/>
+ <property name="nunit" value="${nunit-mono}"/>
<property name="framework" value="mono-1.0"/>
<call target="testclient"/>
</target>
Deleted: trunk/MySql.Data.2003.csproj
===================================================================
--- trunk/MySql.Data.2003.csproj 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/MySql.Data.2003.csproj 2006-07-28 15:02:38 UTC (rev 277)
@@ -1,489 +0,0 @@
-<VisualStudioProject>
- <CSHARP
- ProjectType = "Local"
- ProductVersion = "7.10.3077"
- SchemaVersion = "2.0"
- ProjectGuid = "{5EAEFBC4-8389-4120-BAB3-9B27174F6F6F}"
- >
- <Build>
- <Settings
- ApplicationIcon = ""
- AssemblyKeyContainerName = ""
- AssemblyName = "MySQL.Data"
- AssemblyOriginatorKeyFile = ""
- DefaultClientScript = "JScript"
- DefaultHTMLPageLayout = "Grid"
- DefaultTargetSchema = "IE50"
- DelaySign = "false"
- OutputType = "Library"
- PreBuildEvent = ""
- PostBuildEvent = ""
- RootNamespace = "MySQL.Data.MySQLClient"
- RunPostBuildEvent = "OnBuildSuccess"
- StartupObject = ""
- >
- <Config
- Name = "Debug"
- AllowUnsafeBlocks = "false"
- BaseAddress = "285212672"
- CheckForOverflowUnderflow = "false"
- ConfigurationOverrideFile = ""
- DefineConstants = "DEBUG;TRACE;WINDOWS;FINAL"
- DocumentationFile = "doc.xml"
- DebugSymbols = "true"
- FileAlignment = "4096"
- IncrementalBuild = "true"
- NoStdLib = "false"
- NoWarn = ""
- Optimize = "false"
- OutputPath = "bin\net-1.1\Debug\"
- RegisterForComInterop = "false"
- RemoveIntegerChecks = "false"
- TreatWarningsAsErrors = "false"
- WarningLevel = "4"
- />
- <Config
- Name = "Release"
- AllowUnsafeBlocks = "false"
- BaseAddress = "285212672"
- CheckForOverflowUnderflow = "false"
- ConfigurationOverrideFile = ""
- DefineConstants = "TRACE;WINDOWS"
- DocumentationFile = "doc.xml"
- DebugSymbols = "false"
- FileAlignment = "4096"
- IncrementalBuild = "false"
- NoStdLib = "false"
- NoWarn = ""
- Optimize = "true"
- OutputPath = "bin\net-1.1\Release\"
- RegisterForComInterop = "false"
- RemoveIntegerChecks = "false"
- TreatWarningsAsErrors = "false"
- WarningLevel = "4"
- />
- </Settings>
- <References>
- <Reference
- Name = "System"
- AssemblyName = "System"
- HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.dll"
- />
- <Reference
- Name = "System.Data"
- AssemblyName = "System.Data"
- HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Data.dll"
- />
- <Reference
- Name = "System.XML"
- AssemblyName = "System.Xml"
- HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.XML.dll"
- />
- <Reference
- Name = "System.Design"
- AssemblyName = "System.Design"
- HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Design.dll"
- />
- <Reference
- Name = "System.Drawing"
- AssemblyName = "System.Drawing"
- HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Drawing.dll"
- />
- <Reference
- Name = "ICSharpCode.SharpZipLib"
- AssemblyName = "ICSharpCode.SharpZipLib"
- HintPath = "ICSharpCode.SharpZipLib.dll"
- Private = "True"
- />
- </References>
- </Build>
- <Files>
- <Include>
- <File
- RelPath = "CHANGES"
- BuildAction = "None"
- />
- <File
- RelPath = "README"
- BuildAction = "None"
- />
- <File
- RelPath = "MySqlClient\AssemblyInfo.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\CharSetMap.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\ClientAPI.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\ClientDriver.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\command.cs"
- SubType = "Component"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\CommandBuilder.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\CommandResult.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\CompressedStream.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Connection.cs"
- SubType = "Component"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\ConnectionString.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Crypt.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\dataadapter.cs"
- SubType = "Component"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\datareader.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Driver.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Exception.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Field.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Logger.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\MysqlDefs.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\MySqlError.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\MySqlHelper.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\MySqlPool.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\MySqlPoolManager.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\MySqlStream.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\MySqlStreamReader.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\MySqlStreamWriter.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\NativeDriver.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\parameter.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\parameter_collection.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\PreparedStatement.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\SharedMemoryStream.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Statement.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\StoredProcedure.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\transaction.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\UsageAdvisor.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\base\DbCommand.cs"
- SubType = "Component"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\base\DbCommandBuilder.cs"
- SubType = "Component"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\base\DbConnection.cs"
- SubType = "Component"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\base\DbConnection.resx"
- DependentUpon = "DbConnection.cs"
- BuildAction = "EmbeddedResource"
- />
- <File
- RelPath = "MySqlClient\base\DbDataReader.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\base\DbParameter.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\base\DbParameterCollection.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\base\DbTransaction.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\common\DBConnectionString.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\common\NamedPipeStream.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\common\Platform.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\common\SHA1.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\common\StreamCreator.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\common\Utility.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\common\Version.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\docs\MySqlCommand.xml"
- BuildAction = "Content"
- />
- <File
- RelPath = "MySqlClient\docs\MySqlCommandBuilder.xml"
- BuildAction = "Content"
- />
- <File
- RelPath = "MySqlClient\docs\MySqlConnection.xml"
- BuildAction = "Content"
- />
- <File
- RelPath = "MySqlClient\docs\MySqlDataAdapter.xml"
- BuildAction = "Content"
- />
- <File
- RelPath = "MySqlClient\docs\MySqlDataReader.xml"
- BuildAction = "Content"
- />
- <File
- RelPath = "MySqlClient\docs\MySqlException.xml"
- BuildAction = "Content"
- />
- <File
- RelPath = "MySqlClient\docs\MySqlHelper.xml"
- BuildAction = "Content"
- />
- <File
- RelPath = "MySqlClient\docs\MySqlParameter.xml"
- BuildAction = "Content"
- />
- <File
- RelPath = "MySqlClient\docs\MySqlParameterCollection.xml"
- BuildAction = "Content"
- />
- <File
- RelPath = "MySqlClient\docs\MySqlTransaction.xml"
- BuildAction = "Content"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlBinary.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlByte.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlConversionException.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlDateTime.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlDecimal.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlDouble.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlInt16.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlInt32.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlInt64.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlSingle.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlString.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlTime.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlUByte.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlUInt16.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlUInt32.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlUInt64.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\MySqlValue.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
- RelPath = "MySqlClient\Types\NumberFormat.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- </Include>
- </Files>
- </CSHARP>
-</VisualStudioProject>
-
Deleted: trunk/MySql.Data.2005.csproj
===================================================================
--- trunk/MySql.Data.2005.csproj 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/MySql.Data.2005.csproj 2006-07-28 15:02:38 UTC (rev 277)
@@ -1,206 +0,0 @@
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <ProjectType>Local</ProjectType>
- <ProductVersion>8.0.50727</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}</ProjectGuid>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ApplicationIcon>
- </ApplicationIcon>
- <AssemblyKeyContainerName>
- </AssemblyKeyContainerName>
- <AssemblyName>MySql.Data</AssemblyName>
- <AssemblyOriginatorKeyFile>
- </AssemblyOriginatorKeyFile>
- <DefaultClientScript>JScript</DefaultClientScript>
- <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
- <DefaultTargetSchema>IE50</DefaultTargetSchema>
- <DelaySign>false</DelaySign>
- <OutputType>Library</OutputType>
- <RootNamespace>MySql.Data.MySqlClient</RootNamespace>
- <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
- <StartupObject>
- </StartupObject>
- <FileUpgradeFlags>
- </FileUpgradeFlags>
- <UpgradeBackupLocation>
- </UpgradeBackupLocation>
- <SignAssembly>true</SignAssembly>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <OutputPath>bin\net-2.0\Debug\</OutputPath>
- <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
- <BaseAddress>285212672</BaseAddress>
- <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
- <ConfigurationOverrideFile>
- </ConfigurationOverrideFile>
- <DefineConstants>TRACE;DEBUG;WINDOWS NET20</DefineConstants>
- <DocumentationFile>doc.xml</DocumentationFile>
- <DebugSymbols>true</DebugSymbols>
- <FileAlignment>4096</FileAlignment>
- <NoStdLib>false</NoStdLib>
- <NoWarn>
- </NoWarn>
- <Optimize>false</Optimize>
- <RegisterForComInterop>false</RegisterForComInterop>
- <RemoveIntegerChecks>false</RemoveIntegerChecks>
- <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <OutputPath>bin\net-2.0\Release\</OutputPath>
- <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
- <BaseAddress>285212672</BaseAddress>
- <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
- <ConfigurationOverrideFile>
- </ConfigurationOverrideFile>
- <DefineConstants>TRACE;WINDOWS NET20</DefineConstants>
- <DocumentationFile>doc.xml</DocumentationFile>
- <DebugSymbols>false</DebugSymbols>
- <FileAlignment>4096</FileAlignment>
- <NoStdLib>false</NoStdLib>
- <NoWarn>
- </NoWarn>
- <Optimize>true</Optimize>
- <RegisterForComInterop>false</RegisterForComInterop>
- <RemoveIntegerChecks>false</RemoveIntegerChecks>
- <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="ICSharpCode.SharpZipLib, Version=0.81.0.1407, Culture=neutral, PublicKeyToken=1b03e6acf1164f73">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\ICSharpCode.SharpZipLib.dll</HintPath>
- </Reference>
- <Reference Include="System">
- <Name>System</Name>
- </Reference>
- <Reference Include="System.Data">
- <Name>System.Data</Name>
- </Reference>
- <Reference Include="System.Design">
- <Name>System.Design</Name>
- </Reference>
- <Reference Include="System.Drawing">
- <Name>System.Drawing</Name>
- </Reference>
- <Reference Include="System.Windows.Forms" />
- <Reference Include="System.Xml">
- <Name>System.XML</Name>
- </Reference>
- </ItemGroup>
- <ItemGroup>
- <None Include="..\CHANGES" />
- <None Include="..\README" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="AssemblyInfo.cs" />
- <Compile Include="CharSetMap.cs" />
- <Compile Include="command.cs">
- <SubType>Component</SubType>
- </Compile>
- <Compile Include="CommandBuilder.cs">
- <SubType>Component</SubType>
- </Compile>
- <Compile Include="common\ContextString.cs" />
- <Compile Include="common\NamedPipeStream.cs" />
- <Compile Include="common\NativeMethods.cs" />
- <Compile Include="common\Platform.cs" />
- <Compile Include="common\Resources.cs" />
- <Compile Include="common\SHA1.cs" />
- <Compile Include="common\SharedMemoryStream.cs" />
- <Compile Include="common\SocketStream.cs" />
- <Compile Include="common\StreamCreator.cs" />
- <Compile Include="common\Version.cs" />
- <Compile Include="common\WinCE.cs" />
- <Compile Include="CompressedStream.cs" />
- <Compile Include="Connection.cs">
- <SubType>Component</SubType>
- </Compile>
- <Compile Include="Crypt.cs" />
- <Compile Include="dataadapter.cs">
- <SubType>Component</SubType>
- </Compile>
- <Compile Include="datareader.cs" />
- <Compile Include="Driver.cs" />
- <Compile Include="Exception.cs" />
- <Compile Include="Field.cs" />
- <Compile Include="ISSchemaProvider.cs" />
- <Compile Include="Logger.cs" />
- <Compile Include="MySqlClientFactory.cs" />
- <Compile Include="MySqlConnectionStringBuilder.cs" />
- <Compile Include="MysqlDefs.cs" />
- <Compile Include="MySqlError.cs" />
- <Compile Include="MySqlHelper.cs" />
- <Compile Include="MySqlPool.cs" />
- <Compile Include="MySqlPoolManager.cs" />
- <Compile Include="MySqlStream.cs" />
- <Compile Include="MySqlStreamReader.cs" />
- <Compile Include="MySqlStreamWriter.cs" />
- <Compile Include="NativeDriver.cs" />
- <Compile Include="parameter.cs" />
- <Compile Include="parameter_collection.cs" />
- <Compile Include="PerformanceMonitor.cs" />
- <Compile Include="PreparedStatement.cs" />
- <Compile Include="ProcedureCache.cs" />
- <Compile Include="Resources.Designer.cs">
- <AutoGen>True</AutoGen>
- <DesignTime>True</DesignTime>
- <DependentUpon>Resources.resx</DependentUpon>
- </Compile>
- <Compile Include="SchemaProvider.cs" />
- <Compile Include="Statement.cs" />
- <Compile Include="StoredProcedure.cs" />
- <Compile Include="transaction.cs" />
- <Compile Include="Types\MetaData.cs" />
- <Compile Include="Types\MySqlBinary.cs" />
- <Compile Include="Types\MySqlBit.cs" />
- <Compile Include="Types\MySqlByte.cs" />
- <Compile Include="Types\MySqlConversionException.cs" />
- <Compile Include="Types\MySqlDateTime.cs" />
- <Compile Include="Types\MySqlDecimal.cs" />
- <Compile Include="Types\MySqlDouble.cs" />
- <Compile Include="Types\MySqlInt16.cs" />
- <Compile Include="Types\MySqlInt32.cs" />
- <Compile Include="Types\MySqlInt64.cs" />
- <Compile Include="Types\MySqlSingle.cs" />
- <Compile Include="Types\MySqlString.cs" />
- <Compile Include="Types\MySqlTime.cs" />
- <Compile Include="Types\MySqlUByte.cs" />
- <Compile Include="Types\MySqlUInt16.cs" />
- <Compile Include="Types\MySqlUInt32.cs" />
- <Compile Include="Types\MySqlUInt64.cs" />
- <Compile Include="Types\MySqlValue.cs" />
- <Compile Include="Types\NumberFormat.cs" />
- <Compile Include="UsageAdvisor.cs" />
- </ItemGroup>
- <ItemGroup>
- <Content Include="docs\MySqlCommand.xml" />
- <Content Include="docs\MySqlCommandBuilder.xml" />
- <Content Include="docs\MySqlConnection.xml" />
- <Content Include="docs\MySqlConnectionStringBuilder.xml" />
- <Content Include="docs\MySqlDataAdapter.xml" />
- <Content Include="docs\MySqlDataReader.xml" />
- <Content Include="docs\MySqlException.xml" />
- <Content Include="docs\MySqlHelper.xml" />
- <Content Include="docs\MySqlParameter.xml" />
- <Content Include="docs\MySqlParameterCollection.xml" />
- <Content Include="docs\MySqlTransaction.xml" />
- <Content Include="ReservedWords.txt" />
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="Resources.resx">
- <SubType>Designer</SubType>
- <Generator>ResXFileCodeGenerator</Generator>
- <LastGenOutput>Resources.Designer.cs</LastGenOutput>
- </EmbeddedResource>
- </ItemGroup>
- <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
- <PropertyGroup>
- <PreBuildEvent>
- </PreBuildEvent>
- <PostBuildEvent>
- </PostBuildEvent>
- </PropertyGroup>
-</Project>
\ No newline at end of file
Modified: trunk/mysqlclient/CommandBuilder.cs
===================================================================
--- trunk/mysqlclient/CommandBuilder.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/CommandBuilder.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -133,10 +133,7 @@
"prior to 5.0");
StoredProcedure sp = new StoredProcedure(command.Connection, "");
- string spType = "PROCEDURE";
string schema = command.Connection.Database;
- if (command.MySqlCommandType == MySqlCommandType.StoredFunction)
- spType = "FUNCTION";
string spName = command.CommandText;
int dotIndex = spName.IndexOf('.');
if (dotIndex != -1)
@@ -149,7 +146,6 @@
string[] restrictions = new string[5];
restrictions[1] = schema;
restrictions[2] = spName;
- restrictions[3] = spType;
DataTable parameters = command.Connection.GetSchema(
"procedure parameters", restrictions);
@@ -162,12 +158,12 @@
row["IS_RESULT"].ToString());
p.MySqlDbType = MetaData.NameToType(row["DATA_TYPE"].ToString(),
false, false, command.Connection);
- if (row["CHARACTER_MAXIMUM_LENGTH"] != null)
+ if (!row["CHARACTER_MAXIMUM_LENGTH"].Equals(DBNull.Value))
p.Size = (int)row["CHARACTER_MAXIMUM_LENGTH"];
- if (row["NUMERIC_PRECISION"] != null)
- p.Precision = (byte)(int)row["NUMERIC_PRECISION"];
- if (row["NUMERIC_SCALE"] != null)
- p.Scale = (byte)row["NUMERIC_SCALE"];
+ if (!row["NUMERIC_PRECISION"].Equals(DBNull.Value))
+ p.Precision = (byte)row["NUMERIC_PRECISION"];
+ if (!row["NUMERIC_SCALE"].Equals(DBNull.Value))
+ p.Scale = (byte)(int)row["NUMERIC_SCALE"];
command.Parameters.Add(p);
}
}
@@ -195,7 +191,7 @@
public new MySqlCommand GetInsertCommand()
{
- return (MySqlCommand)base.GetInsertCommand();
+ return (MySqlCommand)GetInsertCommand(false);
}
/* /// <include file='docs/MySqlCommandBuilder.xml' path='docs/GetDeleteCommand/*'/>
@@ -239,9 +235,9 @@
private void GenerateSchema()
{
if (DataAdapter == null)
- throw new MySqlException(Resources.GetString("AdapterIsNull"));
+ throw new MySqlException(Resources.AdapterIsNull);
if (DataAdapter.SelectCommand == null)
- throw new MySqlException(Resources.GetString("AdapterSelectIsNull"));
+ throw new MySqlException(Resources.AdapterSelectIsNull);
// set the parameter marker
MySqlConnection conn = (MySqlConnection)DataAdapter.SelectCommand.Connection;
@@ -268,12 +264,12 @@
tableName = rowTableName;
}
else if (tableName != rowTableName && rowTableName != null && rowTableName.Length > 0)
- throw new InvalidOperationException(Resources.GetString("CBMultiTableNotSupported"));
+ throw new InvalidOperationException(Resources.CBMultiTableNotSupported);
else if (schemaName != rowSchemaName && rowSchemaName != null && rowSchemaName.Length > 0)
- throw new InvalidOperationException(Resources.GetString("CBMultiTableNotSupported"));
+ throw new InvalidOperationException(Resources.CBMultiTableNotSupported);
}
if (! hasKeyOrUnique)
- throw new InvalidOperationException(Resources.GetString("CBNoKeyColumn"));
+ throw new InvalidOperationException(Resources.CBNoKeyColumn);
}
private string Quote(string table_or_column)
Modified: trunk/mysqlclient/CompressedStream.cs
===================================================================
--- trunk/mysqlclient/CompressedStream.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/CompressedStream.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -92,7 +92,7 @@
public override void SetLength(long value)
{
- throw new NotSupportedException(Resources.GetString("CSNoSetLength"));
+ throw new NotSupportedException(Resources.CSNoSetLength);
}
public override int ReadByte()
@@ -105,14 +105,11 @@
public override int Read(byte[] buffer, int offset, int count)
{
if (buffer == null)
- throw new ArgumentNullException("buffer",
- Resources.GetString("BufferCannotBeNull"));
+ throw new ArgumentNullException("buffer", Resources.BufferCannotBeNull);
if (offset < 0 || offset >= buffer.Length)
- throw new ArgumentOutOfRangeException("offset",
- Resources.GetString("OffsetMustBeValid"));
+ throw new ArgumentOutOfRangeException("offset", Resources.OffsetMustBeValid);
if ((offset + count) > buffer.Length)
- throw new ArgumentException(Resources.GetString("BufferNotLargeEnough"),
- "buffer");
+ throw new ArgumentException(Resources.BufferNotLargeEnough, "buffer");
EnsureData(count);
Modified: trunk/mysqlclient/Connection.cs
===================================================================
--- trunk/mysqlclient/Connection.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/Connection.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -247,7 +247,7 @@
{
//TODO: check note in help
if (State != ConnectionState.Open)
- throw new InvalidOperationException(Resources.GetString("ConnectionNotOpen"));
+ throw new InvalidOperationException(Resources.ConnectionNotOpen);
MySqlTransaction t = new MySqlTransaction(this, iso);
@@ -265,7 +265,7 @@
case IsolationLevel.Serializable:
cmd.CommandText += "SERIALIZABLE"; break;
case IsolationLevel.Chaos:
- throw new NotSupportedException(Resources.GetString("ChaosNotSupported"));
+ throw new NotSupportedException(Resources.ChaosNotSupported);
}
cmd.ExecuteNonQuery();
@@ -282,12 +282,10 @@
public override void ChangeDatabase(string database)
{
if (database == null || database.Trim().Length == 0)
- throw new ArgumentException(
- Resources.GetString("ParameterIsInvalid"), "database");
+ throw new ArgumentException(Resources.ParameterIsInvalid, "database");
if (State != ConnectionState.Open)
- throw new InvalidOperationException(
- Resources.GetString("ConnectionNotOpen"));
+ throw new InvalidOperationException(Resources.ConnectionNotOpen);
driver.SetDatabase( database );
settings.Database = database;
@@ -309,6 +307,8 @@
public bool Ping()
{
bool result = driver.Ping();
+ if (!result)
+ SetState(ConnectionState.Closed);
return result;
}
@@ -316,8 +316,7 @@
public override void Open()
{
if (State == ConnectionState.Open)
- throw new InvalidOperationException(
- Resources.GetString("ConnectionAlreadyOpen"));
+ throw new InvalidOperationException(Resources.ConnectionAlreadyOpen);
SetState(ConnectionState.Connecting);
Modified: trunk/mysqlclient/Crypt.cs
===================================================================
--- trunk/mysqlclient/Crypt.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/Crypt.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -75,21 +75,21 @@
{
// make sure we were called properly
if (fromIndex < 0 || fromIndex >= from.Length)
- throw new ArgumentException(Resources.GetString("IndexMustBeValid"), "fromIndex");
+ throw new ArgumentException(Resources.IndexMustBeValid, "fromIndex");
if ((fromIndex + length) > from.Length)
- throw new ArgumentException(Resources.GetString("FromAndLengthTooBig"), "fromIndex" );
+ throw new ArgumentException(Resources.FromAndLengthTooBig, "fromIndex" );
if (from == null)
- throw new ArgumentException(Resources.GetString("BufferCannotBeNull"), "from");
+ throw new ArgumentException(Resources.BufferCannotBeNull, "from");
if (to == null)
- throw new ArgumentException(Resources.GetString("BufferCannotBeNull"), "to");
+ throw new ArgumentException(Resources.BufferCannotBeNull, "to");
if (toIndex < 0 || toIndex >= to.Length)
- throw new ArgumentException(Resources.GetString("IndexMustBeValid"), "toIndex" );
+ throw new ArgumentException(Resources.IndexMustBeValid, "toIndex" );
if ((toIndex + length) > to.Length)
- throw new ArgumentException(Resources.GetString("IndexAndLengthTooBig"), "toIndex" );
+ throw new ArgumentException(Resources.IndexAndLengthTooBig, "toIndex" );
if (password == null || password.Length < length)
- throw new ArgumentException(Resources.GetString("PasswordMustHaveLegalChars"), "password");
+ throw new ArgumentException(Resources.PasswordMustHaveLegalChars, "password");
if (length < 0)
- throw new ArgumentException(Resources.GetString("ParameterCannotBeNegative"), "count");
+ throw new ArgumentException(Resources.ParameterCannotBeNegative, "count");
// now perform the work
for (int i=0; i < length; i++)
Modified: trunk/mysqlclient/Field.cs
===================================================================
--- trunk/mysqlclient/Field.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/Field.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -1,202 +1,219 @@
-// Copyright (C) 2004-2006 MySQL AB
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as published by
-// the Free Software Foundation
-//
-// There are special exceptions to the terms and conditions of the GPL
-// as it is applied to this software. View the full text of the
-// exception in file EXCEPTIONS in the directory of this software
-// distribution.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-using System;
-using System.Data;
-using System.Globalization;
-using System.Text;
-using MySql.Data.Common;
-using MySql.Data.Types;
-
-namespace MySql.Data.MySqlClient
-{
- internal enum ColumnFlags : int
- {
- NOT_NULL = 1,
- PRIMARY_KEY = 2,
- UNIQUE_KEY = 4,
- MULTIPLE_KEY = 8,
- BLOB = 16,
- UNSIGNED = 32,
- ZERO_FILL = 64,
- BINARY = 128,
- ENUM = 256,
- AUTO_INCREMENT = 512,
- TIMESTAMP = 1024,
- SET = 2048,
- NUMBER = 32768
- };
-
- /// <summary>
- /// Summary description for Field.
- /// </summary>
- internal class MySqlField
- {
- #region Fields
-
- // public fields
- public string CatalogName;
- public int ColumnLength;
- public string ColumnName;
- public string OriginalColumnName;
- public string TableName;
- public string RealTableName;
- public string DatabaseName;
- public Encoding Encoding;
-
- // protected fields
- protected ColumnFlags colFlags;
- protected int charSetIndex;
- protected byte precision;
- protected byte scale;
- protected MySqlDbType mySqlDbType;
- protected DBVersion connVersion;
-
- //protected IMySqlValue rowValue;
-
- #endregion
-
- public MySqlField( DBVersion connVersion )
- {
- this.connVersion = connVersion;
- }
-
- #region Properties
-
- public int CharactetSetIndex
- {
- get { return charSetIndex; }
- set { charSetIndex = value; }
- }
-
- public MySqlDbType Type
- {
- get { return mySqlDbType; }
- set { mySqlDbType = value; }
- }
-
- public byte Precision
- {
- get { return precision; }
- set { precision = value; }
- }
-
- public byte Scale
- {
- get { return scale; }
- set { scale = value; }
- }
-
- public ColumnFlags Flags
- {
- get { return colFlags; }
- set { colFlags = value; }
- }
-
- public bool IsAutoIncrement
- {
- get { return (colFlags & ColumnFlags.AUTO_INCREMENT) > 0; }
- }
-
- public bool IsNumeric
- {
- get { return (colFlags & ColumnFlags.NUMBER) > 0; }
- }
-
- public bool AllowsNull
- {
- get { return (colFlags & ColumnFlags.NOT_NULL) == 0; }
- }
-
- public bool IsUnique
- {
- get { return (colFlags & ColumnFlags.UNIQUE_KEY) > 0; }
- }
-
- public bool IsPrimaryKey
- {
- get { return (colFlags & ColumnFlags.PRIMARY_KEY) > 0; }
- }
-
- public bool IsBlob
- {
- get { return (colFlags & ColumnFlags.BLOB) > 0; }
- }
-
- public bool IsBinary
- {
- get { return (colFlags & ColumnFlags.BINARY) > 0; }
- }
-
- public bool IsUnsigned
- {
- get { return (colFlags & ColumnFlags.UNSIGNED) > 0; }
- }
-
-#endregion
-
- public IMySqlValue GetValueObject()
- {
- return GetIMySqlValue(Type, IsBinary);
- }
-
- public static IMySqlValue GetIMySqlValue(MySqlDbType type, bool binary)
- {
- switch (type)
- {
- case MySqlDbType.Byte:
- return new MySqlByte();
- case MySqlDbType.UByte: return new MySqlUByte();
- case MySqlDbType.Int16: return new MySqlInt16();
- case MySqlDbType.UInt16: return new MySqlUInt16();
- case MySqlDbType.Int24:
- case MySqlDbType.Int32:
- case MySqlDbType.Year: return new MySqlInt32(type, true);
- case MySqlDbType.UInt24:
- case MySqlDbType.UInt32: return new MySqlUInt32(type, true);
- case MySqlDbType.Bit: return new MySqlBit();
- case MySqlDbType.Int64:
- return new MySqlInt64();
- case MySqlDbType.UInt64: return new MySqlUInt64();
- case MySqlDbType.Time: return new MySqlTimeSpan();
- case MySqlDbType.Date:
- case MySqlDbType.Datetime:
- case MySqlDbType.Newdate:
- case MySqlDbType.Timestamp: return new MySqlDateTime(type, true);
- case MySqlDbType.Decimal:
- case MySqlDbType.NewDecimal:
- return new MySqlDecimal();
- case MySqlDbType.Float: return new MySqlSingle();
- case MySqlDbType.Double: return new MySqlDouble();
- case MySqlDbType.Set:
- case MySqlDbType.Enum:
- case MySqlDbType.String:
- case MySqlDbType.VarChar: return new MySqlString(type, true);
- case MySqlDbType.Blob:
- case MySqlDbType.MediumBlob:
- case MySqlDbType.LongBlob:
- default:
- if (binary) return new MySqlBinary(type, true);
- return new MySqlString(type, true);
- }
- }
- }
-
-}
+// Copyright (C) 2004-2006 MySQL AB
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation
+//
+// There are special exceptions to the terms and conditions of the GPL
+// as it is applied to this software. View the full text of the
+// exception in file EXCEPTIONS in the directory of this software
+// distribution.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+using System;
+using System.Data;
+using System.Globalization;
+using System.Text;
+using MySql.Data.Common;
+using MySql.Data.Types;
+
+namespace MySql.Data.MySqlClient
+{
+ internal enum ColumnFlags : int
+ {
+ NOT_NULL = 1,
+ PRIMARY_KEY = 2,
+ UNIQUE_KEY = 4,
+ MULTIPLE_KEY = 8,
+ BLOB = 16,
+ UNSIGNED = 32,
+ ZERO_FILL = 64,
+ BINARY = 128,
+ ENUM = 256,
+ AUTO_INCREMENT = 512,
+ TIMESTAMP = 1024,
+ SET = 2048,
+ NUMBER = 32768
+ };
+
+ /// <summary>
+ /// Summary description for Field.
+ /// </summary>
+ internal class MySqlField
+ {
+ #region Fields
+
+ // public fields
+ public string CatalogName;
+ public int ColumnLength;
+ public string ColumnName;
+ public string OriginalColumnName;
+ public string TableName;
+ public string RealTableName;
+ public string DatabaseName;
+ public Encoding Encoding;
+
+ // protected fields
+ protected ColumnFlags colFlags;
+ protected int charSetIndex;
+ protected byte precision;
+ protected byte scale;
+ protected MySqlDbType mySqlDbType;
+ protected DBVersion connVersion;
+
+ #endregion
+
+ public MySqlField( DBVersion connVersion )
+ {
+ this.connVersion = connVersion;
+ }
+
+ #region Properties
+
+ public int CharactetSetIndex
+ {
+ get { return charSetIndex; }
+ set { charSetIndex = value; }
+ }
+
+ public MySqlDbType Type
+ {
+ get { return mySqlDbType; }
+ }
+
+ public byte Precision
+ {
+ get { return precision; }
+ set { precision = value; }
+ }
+
+ public byte Scale
+ {
+ get { return scale; }
+ set { scale = value; }
+ }
+
+ public ColumnFlags Flags
+ {
+ get { return colFlags; }
+ }
+
+ public bool IsAutoIncrement
+ {
+ get { return (colFlags & ColumnFlags.AUTO_INCREMENT) > 0; }
+ }
+
+ public bool IsNumeric
+ {
+ get { return (colFlags & ColumnFlags.NUMBER) > 0; }
+ }
+
+ public bool AllowsNull
+ {
+ get { return (colFlags & ColumnFlags.NOT_NULL) == 0; }
+ }
+
+ public bool IsUnique
+ {
+ get { return (colFlags & ColumnFlags.UNIQUE_KEY) > 0; }
+ }
+
+ public bool IsPrimaryKey
+ {
+ get { return (colFlags & ColumnFlags.PRIMARY_KEY) > 0; }
+ }
+
+ public bool IsBlob
+ {
+ get { return (colFlags & ColumnFlags.BLOB) > 0; }
+ }
+
+ public bool IsBinary
+ {
+ get { return (colFlags & ColumnFlags.BINARY) > 0; }
+ }
+
+ public bool IsUnsigned
+ {
+ get { return (colFlags & ColumnFlags.UNSIGNED) > 0; }
+ }
+
+#endregion
+
+ public void SetTypeAndFlags(MySqlDbType type, ColumnFlags flags)
+ {
+ colFlags = flags;
+ mySqlDbType = type;
+ if (!IsUnsigned) return;
+
+ switch (type)
+ {
+ case MySqlDbType.Byte:
+ mySqlDbType = MySqlDbType.UByte; break;
+ case MySqlDbType.Int16:
+ mySqlDbType = MySqlDbType.UInt16; break;
+ case MySqlDbType.Int24:
+ mySqlDbType = MySqlDbType.UInt24; break;
+ case MySqlDbType.Int32:
+ mySqlDbType = MySqlDbType.UInt32; break;
+ case MySqlDbType.Int64:
+ mySqlDbType = MySqlDbType.UInt64; break;
+ }
+ }
+
+ public IMySqlValue GetValueObject()
+ {
+ return GetIMySqlValue(Type, IsBinary);
+ }
+
+ public static IMySqlValue GetIMySqlValue(MySqlDbType type, bool binary)
+ {
+ switch (type)
+ {
+ case MySqlDbType.Byte:
+ return new MySqlByte();
+ case MySqlDbType.UByte: return new MySqlUByte();
+ case MySqlDbType.Int16: return new MySqlInt16();
+ case MySqlDbType.UInt16: return new MySqlUInt16();
+ case MySqlDbType.Int24:
+ case MySqlDbType.Int32:
+ case MySqlDbType.Year: return new MySqlInt32(type, true);
+ case MySqlDbType.UInt24:
+ case MySqlDbType.UInt32: return new MySqlUInt32(type, true);
+ case MySqlDbType.Bit: return new MySqlBit();
+ case MySqlDbType.Int64:
+ return new MySqlInt64();
+ case MySqlDbType.UInt64: return new MySqlUInt64();
+ case MySqlDbType.Time: return new MySqlTimeSpan();
+ case MySqlDbType.Date:
+ case MySqlDbType.Datetime:
+ case MySqlDbType.Newdate:
+ case MySqlDbType.Timestamp: return new MySqlDateTime(type, true);
+ case MySqlDbType.Decimal:
+ case MySqlDbType.NewDecimal:
+ return new MySqlDecimal();
+ case MySqlDbType.Float: return new MySqlSingle();
+ case MySqlDbType.Double: return new MySqlDouble();
+ case MySqlDbType.Set:
+ case MySqlDbType.Enum:
+ case MySqlDbType.String:
+ case MySqlDbType.VarChar: return new MySqlString(type, true);
+ case MySqlDbType.Blob:
+ case MySqlDbType.MediumBlob:
+ case MySqlDbType.LongBlob:
+ default:
+ if (binary) return new MySqlBinary(type, true);
+ return new MySqlString(type, true);
+ }
+ }
+ }
+
+}
Modified: trunk/mysqlclient/ISSchemaProvider.cs
===================================================================
--- trunk/mysqlclient/ISSchemaProvider.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/ISSchemaProvider.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -87,6 +87,7 @@
keys[0] = "SCHEMA_NAME";
DataTable dt = Query("SCHEMATA", "", keys, restrictions);
dt.Columns[1].ColumnName = "database_name";
+ dt.TableName = "Databases";
return dt;
}
@@ -97,7 +98,9 @@
keys[1] = "TABLE_SCHEMA";
keys[2] = "TABLE_NAME";
keys[3] = "TABLE_TYPE";
- return Query("TABLES", "TABLE_TYPE != 'VIEW'", keys, restrictions);
+ DataTable dt = Query("TABLES", "TABLE_TYPE != 'VIEW'", keys, restrictions);
+ dt.TableName = "Tables";
+ return dt;
}
public override DataTable GetColumns(string[] restrictions)
@@ -109,6 +112,7 @@
keys[3] = "COLUMN_NAME";
DataTable dt = Query("COLUMNS", null, keys, restrictions);
dt.Columns.Remove("CHARACTER_OCTET_LENGTH");
+ dt.TableName = "Columns";
return dt;
}
@@ -118,7 +122,8 @@
keys[0] = "TABLE_CATALOG";
keys[1] = "TABLE_SCHEMA";
keys[2] = "TABLE_NAME";
- return Query("VIEWS", null, keys, restrictions);
+ DataTable dt = Query("VIEWS", null, keys, restrictions);
+ return dt;
}
private DataTable GetViewColumns(string[] restrictions)
@@ -156,7 +161,8 @@
keys[1] = "TRIGGER_SCHEMA";
keys[2] = "TRIGGER_NAME";
keys[3] = "EVENT_OBJECT_TABLE";
- return Query("TRIGGERS", null, keys, restrictions);
+ DataTable dt = Query("TRIGGERS", null, keys, restrictions);
+ return dt;
}
/// <summary>
@@ -173,7 +179,9 @@
keys[1] = "ROUTINE_SCHEMA";
keys[2] = "ROUTINE_NAME";
keys[3] = "ROUTINE_TYPE";
- return Query("ROUTINES", null, keys, restrictions);
+ DataTable dt = Query("ROUTINES", null, keys, restrictions);
+ dt.TableName = "Procedures";
+ return dt;
}
/// <summary>
@@ -181,9 +189,8 @@
/// Restrictions supported are:
/// schema, name, type, parameter name
/// </summary>
- /// <param name="restrictions"></param>
- /// <returns></returns>
- public virtual DataTable GetProcedureParameters(string[] restrictions)
+ public virtual DataTable GetProcedureParameters(string[] restrictions,
+ DataTable routines)
{
DataTable dt = new DataTable("Procedure Parameters");
dt.Columns.Add("ROUTINE_CATALOG", typeof(string));
@@ -194,22 +201,15 @@
dt.Columns.Add("PARAMETER_MODE", typeof(string));
dt.Columns.Add("IS_RESULT", typeof(string));
dt.Columns.Add("DATA_TYPE", typeof(string));
+ dt.Columns.Add("FLAGS", typeof(string));
dt.Columns.Add("CHARACTER_SET", typeof(string));
dt.Columns.Add("CHARACTER_MAXIMUM_LENGTH", typeof(Int32));
dt.Columns.Add("NUMERIC_PRECISION", typeof(byte));
dt.Columns.Add("NUMERIC_SCALE", typeof(Int32));
-
- // first try and get parameter information from mysql.proc
- // since that will be faster.
- // Fall back to show create since that requires lesser privs
try
{
-// GetParametersFromMySqlProc(dt, restrictions);
- // }
- // catch (MySqlException)
- // {
- GetParametersFromShowCreate(dt, restrictions);
+ GetParametersFromShowCreate(dt, restrictions, routines);
}
catch (Exception)
{
@@ -232,7 +232,7 @@
case "procedures":
return GetProcedures(restrictions);
case "procedure parameters":
- return GetProcedureParameters(restrictions);
+ return GetProcedureParameters(restrictions, null);
case "triggers":
return GetTriggers(restrictions);
case "viewcolumns":
@@ -248,13 +248,14 @@
StringBuilder query = new StringBuilder("SELECT * FROM INFORMATION_SCHEMA.");
query.Append(table_name);
- for (int i = 0; i < values.Length; i++)
- {
- if (values[i] == null || values[i] == String.Empty) continue;
- if (where.Length > 0)
- where.Append(" AND ");
- where.AppendFormat("{0}='{1}'", keys[i], values[i]);
- }
+ if (values != null)
+ for (int i = 0; i < values.Length; i++)
+ {
+ if (values[i] == null || values[i] == String.Empty) continue;
+ if (where.Length > 0)
+ where.Append(" AND ");
+ where.AppendFormat("{0}='{1}'", keys[i], values[i]);
+ }
if (where.Length > 0)
query.AppendFormat(" WHERE {0}", where.ToString());
@@ -325,10 +326,14 @@
}
}
*/
- private void GetParametersFromShowCreate(DataTable parametersTable,
- string[] restrictions)
+ internal void GetParametersFromShowCreate(DataTable parametersTable,
+ string[] restrictions, DataTable routines)
{
- DataTable routines = GetSchema("procedures", restrictions);
+ // this allows us to pass in a pre-populated routines table
+ // and avoid the querying for them again.
+ // we use this when calling a procedure or function
+ if (routines == null)
+ routines = GetSchema("procedures", restrictions);
MySqlCommand cmd = connection.CreateCommand();
MySqlDataReader reader = null;
@@ -415,19 +420,19 @@
string parms = body.Substring(0, rightParen).Trim();
quotePattern += "()";
+ cs.ContextMarkers = quotePattern;
string[] paramDefs = cs.Split(parms, ",");
ArrayList parmArray = new ArrayList(paramDefs);
body = body.Substring(rightParen + 1).Trim().ToLower(CultureInfo.InvariantCulture);
if (body.StartsWith("returns"))
parmArray.Add(body);
int pos = 1;
- foreach (string def in paramDefs)
+ foreach (string def in parmArray)
{
DataRow parmRow = parametersTable.NewRow();
parmRow["ROUTINE_CATALOG"] = null;
parmRow["ROUTINE_SCHEMA"] = row["ROUTINE_SCHEMA"];
parmRow["ROUTINE_NAME"] = row["ROUTINE_NAME"];
- parmRow["ORDINAL_POSITION"] = pos++;
ParseParameter(def, cs, sqlMode, parmRow);
if (parmRow["IS_RESULT"].Equals("YES"))
parmRow["ORDINAL_POSITION"] = 0;
@@ -447,16 +452,12 @@
string lowerDef = parmDef.ToLower(CultureInfo.InvariantCulture);
parmRow["IS_RESULT"] = "NO";
+ parmRow["PARAMETER_MODE"] = "IN";
if (lowerDef.StartsWith("inout "))
{
parmRow["PARAMETER_MODE"] = "INOUT";
parmDef = parmDef.Substring(6);
}
- else if (lowerDef.StartsWith("in "))
- {
- parmRow["PARAMETER_MODE"] = "IN";
- parmDef = parmDef.Substring(3);
- }
else if (lowerDef.StartsWith("out "))
{
parmRow["PARAMETER_MODE"] = "OUT";
@@ -468,6 +469,8 @@
parmRow["IS_RESULT"] = "YES";
parmDef = parmDef.Substring(8);
}
+ else if (lowerDef.StartsWith("in "))
+ parmDef = parmDef.Substring(3);
parmDef = parmDef.Trim();
string[] split = cs.Split(parmDef, " \t\r\n");
@@ -491,31 +494,36 @@
private void ParseType(string type, string sql_mode, DataRow parmRow)
{
string typeName, flags = String.Empty, size;
- int end;
+ int endExtra;
string rest = null;
type = type.ToLower(CultureInfo.InvariantCulture).Trim();
- int start = type.IndexOf("(");
- if (start != -1)
- end = type.IndexOf(')', start + 1);
+ int startExtra = type.IndexOf("(");
+ if (startExtra != -1)
+ endExtra = type.IndexOf(')', startExtra + 1);
else
- end = start = type.IndexOf(' ');
- if (start == -1)
- start = type.Length;
+ endExtra = startExtra = type.IndexOf(' ');
+ if (startExtra == -1)
+ startExtra = type.Length;
+ if (endExtra == -1)
+ endExtra = type.Length;
- typeName = type.Substring(0, start);
- rest = type.Substring(end).Trim();
+ typeName = type.Substring(0, startExtra);
+ rest = type.Substring(endExtra).Trim();
- if (end != -1)
- flags = type.Substring(end + 1);
- bool unsigned = flags.IndexOf("unsigned") != -1;
+ if (type.Length > endExtra)
+ {
+ flags = type.Substring(endExtra + 1);
+ if (flags.IndexOf("unsigned") != -1)
+ parmRow["FLAGS"] = "UNSIGNED";
+ }
bool real_as_float = sql_mode.IndexOf("REAL_AS_FLOAT") != -1;
parmRow["DATA_TYPE"] = typeName;
- if (end > start && typeName != "set")
+ if (endExtra > startExtra && typeName != "set")
{
- size = type.Substring(start + 1, end - (start + 1));
+ size = type.Substring(startExtra + 1, endExtra - (startExtra + 1));
string[] parts = size.Split(new char[] { ',' });
if (typeName == "varchar" || typeName == "char")
parmRow["CHARACTER_MAXIMUM_LENGTH"] = Int32.Parse(parts[0]);
@@ -529,8 +537,10 @@
if (rest.StartsWith("character set"))
{
rest = rest.Substring(14);
- start = rest.IndexOf(' ');
- parmRow["CHARACTER_SET"] = rest.Substring(0, start);
+ startExtra = rest.IndexOf(' ');
+ if (startExtra == -1)
+ startExtra = rest.Length;
+ parmRow["CHARACTER_SET"] = rest.Substring(0, startExtra);
}
}
Modified: trunk/mysqlclient/Logger.cs
===================================================================
--- trunk/mysqlclient/Logger.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/Logger.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -36,7 +36,7 @@
static public void LogCommand( DBCmd cmd, string text)
{
if (text.Length > 300)
- text = text.Substring( 0, 300 );
+ text = text.Substring(0, 300);
string msg = String.Format("Executing command {0} with text ='{1}'",
cmd.ToString(), text);
@@ -50,10 +50,10 @@
Trace.WriteLine(msg);
}
- static public void LogException( Exception ex )
+ static public void LogException(Exception ex)
{
string msg = String.Format("EXCEPTION: " + ex.Message);
- WriteLine( msg );
+ WriteLine(msg);
}
static public void LogWarning(string s)
Modified: trunk/mysqlclient/MySqlConnectionStringBuilder.cs
===================================================================
--- trunk/mysqlclient/MySqlConnectionStringBuilder.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/MySqlConnectionStringBuilder.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -395,8 +395,7 @@
private void CheckNullAndSet(string keyword, object value)
{
if (value == null)
- throw new ArgumentException(
- Resources.GetString("KeywordNoNull"), keyword);
+ throw new ArgumentException(Resources.KeywordNoNull, keyword);
base[keyword] = value;
}
@@ -409,8 +408,7 @@
}
catch (InvalidCastException)
{
- throw new ArgumentException(
- Resources.GetString("UnableToConvertValueToUInt"), value.ToString());
+ throw new ArgumentException(Resources.ImproperValueFormat, value.ToString());
}
}
@@ -421,8 +419,7 @@
string s = value.ToString().ToLower();
if (s == "yes" || s == "true") return true;
if (s == "no" || s == "false") return false;
- throw new ArgumentException(
- Resources.GetString("UnableToConvertValueToBool"), (string)value);
+ throw new ArgumentException(Resources.ImproperValueFormat, (string)value);
}
else
{
@@ -433,8 +430,7 @@
}
catch (InvalidCastException)
{
- throw new ArgumentException(
- Resources.GetString("UnableToConvertValueToBool"), value.ToString());
+ throw new ArgumentException(Resources.ImproperValueFormat, value.ToString());
}
}
}
@@ -462,8 +458,7 @@
return MySqlConnectionProtocol.SharedMemory;
}
}
- throw new ArgumentException(
- Resources.GetString("UnableToConvertToProtocol"), value.ToString());
+ throw new ArgumentException(Resources.ImproperValueFormat, value.ToString());
}
private MySqlDriverType ConvertToDriverType(object value)
@@ -471,8 +466,7 @@
if (value is string)
return (MySqlDriverType)Enum.Parse(
typeof(MySqlDriverType), (value as string), true);
- throw new ArgumentException(
- Resources.GetString("UnableToConvertToDriverType"), value.ToString());
+ throw new ArgumentException(Resources.ImproperValueFormat, value.ToString());
}
#endregion
@@ -597,8 +591,7 @@
case "connection reset":
return Keyword.ConnectionReset;
}
- throw new ArgumentException(Resources.GetString("KeywordNotSupported"),
- key);
+ throw new ArgumentException(Resources.KeywordNotSupported, key);
}
private object GetValue(Keyword kw)
Added: trunk/mysqlclient/NativeDriver.cs
===================================================================
--- trunk/mysqlclient/NativeDriver.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/NativeDriver.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -0,0 +1,770 @@
+// Copyright (C) 2004-2006 MySQL AB
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation
+//
+// There are special exceptions to the terms and conditions of the GPL
+// as it is applied to this software. View the full text of the
+// exception in file EXCEPTIONS in the directory of this software
+// distribution.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.IO;
+using ICSharpCode.SharpZipLib.Zip.Compression;
+using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
+using System.Security.Cryptography;
+using MySql.Data.Common;
+using System.Collections;
+using System.Text;
+using MySql.Data.Types;
+
+namespace MySql.Data.MySqlClient
+{
+ /// <summary>
+ /// Summary description for Driver.
+ /// </summary>
+ internal class NativeDriver : Driver
+ {
+ public int MaxSinglePacket = 255 * 255 * 255;
+ protected byte packetSeq;
+
+ protected int protocol;
+ protected String encryptionSeed;
+ protected ClientFlags connectionFlags;
+
+ protected MySqlStreamReader reader;
+ protected MySqlStreamWriter writer;
+ private BitArray nullMap;
+
+ private int warningCount;
+
+ public NativeDriver(MySqlConnectionStringBuilder settings) : base(settings)
+ {
+ packetSeq = 0;
+ isOpen = false;
+ maxPacketSize = 1047552;
+ }
+
+ public ClientFlags Flags
+ {
+ get { return connectionFlags; }
+ }
+
+ /// <summary>
+ /// Returns true if this connection can handle batch SQL natively
+ /// This means MySQL 4.1.1 or later.
+ /// </summary>
+ public override bool SupportsBatch
+ {
+ get
+ {
+ if ((Flags & ClientFlags.MULTI_STATEMENTS) != 0)
+ {
+ if (version.isAtLeast(4, 1, 0) && ! version.isAtLeast(4, 1, 10))
+ {
+ if (serverProps["query_cache_type"].Equals("ON") &&
+ !serverProps["query_cache_size"].Equals("0")) return false;
+ }
+ return true;
+ }
+ return false;
+ }
+ }
+
+
+ /// <summary>
+ /// ExecuteCommand does the work of writing the actual command bytes to the writer
+ /// We break it out into a function since it is used in several places besides query
+ /// </summary>
+ /// <param name="cmd">The cmd that we are sending</param>
+ /// <param name="bytes">The bytes of the command, can be null</param>
+ /// <param name="length">The number of bytes to send</param>
+ private void ExecuteCommand(DBCmd cmd, byte[] bytes, int length)
+ {
+ int len = 1;
+ if (bytes != null)
+ len += length;
+ writer.StartPacket(len, true);
+ writer.WriteByte((byte)cmd);
+ if (bytes != null)
+ writer.Write(bytes, 0, length);
+ writer.Flush();
+ }
+
+ private void ReadOk(bool read)
+ {
+ if (read)
+ reader.OpenPacket();
+ byte marker = reader.ReadByte();
+ if (marker != 0)
+ throw new MySqlException("Out of sync with server", true, null);
+
+ long affectedRows = reader.GetFieldLength();
+ long lastInsertId = reader.GetFieldLength();
+ if (reader.HasMoreData)
+ {
+ serverStatus = (ServerStatusFlags)reader.ReadInteger(2);
+ int warningCount = reader.ReadInteger(2);
+ if (reader.HasMoreData)
+ {
+ string msg = reader.ReadLenString();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Sets the current database for the this connection
+ /// </summary>
+ /// <param name="dbName"></param>
+ public override void SetDatabase(string dbName)
+ {
+ byte[] dbNameBytes = Encoding.GetBytes( dbName );
+ ExecuteCommand( DBCmd.INIT_DB, dbNameBytes, dbNameBytes.Length );
+ ReadOk(true);
+ }
+
+ public string GetString(byte[] stringBuffer)
+ {
+ if (stringBuffer == null) return String.Empty;
+ return encoding.GetString(stringBuffer, 0, stringBuffer.Length);
+ }
+
+ public byte[] GetBytes(string s)
+ {
+ return encoding.GetBytes(s);
+ }
+
+ public override void Open()
+ {
+ base.Open();
+
+ // connect to one of our specified hosts
+ Stream stream;
+ try
+ {
+#if !CF
+ if (Settings.ConnectionProtocol == MySqlConnectionProtocol.SharedMemory)
+ {
+ SharedMemoryStream str = new SharedMemoryStream(Settings.SharedMemoryName);
+ str.Open(Settings.ConnectionTimeout);
+ stream = str;
+ }
+ else
+ {
+#endif
+ string pipeName = Settings.PipeName;
+ if (Settings.ConnectionProtocol != MySqlConnectionProtocol.NamedPipe)
+ pipeName = null;
+ StreamCreator sc = new StreamCreator(Settings.Server, Settings.Port, pipeName);
+ stream = sc.GetStream(Settings.ConnectionTimeout);
+#if !CF
+ }
+#endif
+ }
+ catch (Exception ex)
+ {
+ throw new MySqlException("Unable to connect to any of the specified MySQL hosts", ex);
+ }
+
+
+ if (stream == null)
+ throw new MySqlException("Unable to connect to any of the specified MySQL hosts");
+ MySqlStream myStream = new MySqlStream(stream);
+
+ reader = new MySqlStreamReader(myStream, encoding);
+ writer = new MySqlStreamWriter(myStream, encoding);
+
+ // read off the welcome packet and parse out it's values
+ reader.OpenPacket();
+ protocol = reader.ReadByte();
+ string versionString = reader.ReadString();
+ version = DBVersion.Parse(versionString);
+ threadId = (int)reader.ReadInteger(4);
+ encryptionSeed = reader.ReadString();
+
+ // starting with 4.0.8, maxSinglePacket should be 0xffffff
+ if ( version.isAtLeast(4,0,8))
+ MaxSinglePacket = (256*256*256)-1;
+
+ // read in Server capabilities if they are provided
+ serverCaps = 0;
+ if (reader.HasMoreData)
+ serverCaps = (ClientFlags)reader.ReadInteger(2);
+
+ // based on our settings, set our connection flags
+ SetConnectionFlags();
+
+ writer.StartPacket(0, false);
+ writer.WriteInteger((int)connectionFlags,
+ version.isAtLeast(4,1,0) ? 4 : 2);
+ writer.WriteInteger(MaxSinglePacket,
+ version.isAtLeast(4,1,0) ? 4 : 3);
+
+ // 4.1.1 included some new server status info
+ if (reader.HasMoreData)
+ {
+ /* New protocol with 16 bytes to describe server characteristics */
+ serverCharSetIndex = reader.ReadInteger(1);
+
+ serverStatus = (ServerStatusFlags)reader.ReadInteger(2);
+ reader.SkipBytes(13);
+ }
+
+ if (version.isAtLeast(4,1,1))
+ {
+ string seedPart2 = reader.ReadString();
+ encryptionSeed += seedPart2;
+
+ writer.WriteByte(8);
+ writer.Write( new byte[23], 0, 23 );
+ }
+
+ Authenticate();
+
+ // if we are using compression, then we use our CompressedStream class
+ // to hide the ugliness of managing the compression
+ if ((connectionFlags & ClientFlags.COMPRESS) != 0)
+ {
+ MySqlStream compStream = new MySqlStream(new CompressedStream(stream));
+ reader = new MySqlStreamReader(compStream, encoding);
+ writer = new MySqlStreamWriter(compStream, encoding);
+ }
+
+ ((MySqlStream)reader.Stream).MaxSinglePacket = MaxSinglePacket;
+ ((MySqlStream)writer.Stream).MaxSinglePacket = MaxSinglePacket;
+
+ // give our reader the server version we are connected to. Our reader may have some fields
+ // that are read differently based on the version of the server we are connected to.
+ reader.Version = writer.Version = this.version;
+
+ isOpen = true;
+ }
+
+ /// <summary>
+ /// Return the appropriate set of connection flags for our
+ /// server capabilities and our user requested options.
+ /// </summary>
+ private void SetConnectionFlags()
+ {
+ ClientFlags flags = ClientFlags.FOUND_ROWS;
+
+ if (version.isAtLeast(4,1,1))
+ {
+ flags |= ClientFlags.PROTOCOL_41;
+ // Need this to get server status values
+ flags |= ClientFlags.TRANSACTIONS;
+
+ // user allows/disallows batch statements
+ if (connectionString.AllowBatch)
+ flags |= ClientFlags.MULTI_STATEMENTS;
+
+ // We always allow multiple result sets
+ flags |= ClientFlags.MULTI_RESULTS;
+ }
+ else if ( version.isAtLeast(4, 1, 0 ))
+ flags |= ClientFlags.RESERVED;
+
+ // if the server allows it, tell it that we want long column info
+ if ((serverCaps & ClientFlags.LONG_FLAG) != 0)
+ flags |= ClientFlags.LONG_FLAG;
+
+ // if the server supports it and it was requested, then turn on compression
+ if ((serverCaps & ClientFlags.COMPRESS) != 0 && connectionString.UseCompression)
+ flags |= ClientFlags.COMPRESS;
+
+ if (protocol > 9)
+ flags |= ClientFlags.LONG_PASSWORD; // for long passwords
+ else
+ flags &= ~ClientFlags.LONG_PASSWORD;
+
+ // allow load data local infile
+ flags |= ClientFlags.LOCAL_FILES;
+
+ // if the server allows it and a database was specified, then indicate
+ // that we will connect with a database name
+ if ((serverCaps & ClientFlags.CONNECT_WITH_DB) != 0 &&
+ connectionString.Database != null && connectionString.Database.Length > 0)
+ flags |= ClientFlags.CONNECT_WITH_DB;
+
+ // if the server is requesting a secure connection, then we oblige
+ if ((serverCaps & ClientFlags.SECURE_CONNECTION) != 0)
+ flags |= ClientFlags.SECURE_CONNECTION;
+
+ connectionFlags = flags;
+ }
+
+
+ /// <summary>Perform an authentication against a 4.1.1 server</summary>
+ private void Authenticate411()
+ {
+ if ( (connectionFlags & ClientFlags.SECURE_CONNECTION) == 0)
+ AuthenticateOld();
+
+ writer.Write( Crypt.Get411Password( connectionString.Password, this.encryptionSeed ));
+ if ( (connectionFlags & ClientFlags.CONNECT_WITH_DB) != 0 && connectionString.Database != null)
+ writer.WriteString( connectionString.Database );
+ writer.Flush();
+
+ // this result means the server wants us to send the password using
+ // old encryption
+ reader.OpenPacket();
+ if (reader.IsLastPacket)
+ {
+ writer.StartPacket(0, false);
+ writer.WriteString( Crypt.EncryptPassword(
+ connectionString.Password, this.encryptionSeed.Substring(0,8), true ) );
+ writer.Flush();
+ ReadOk(true);
+ }
+ else
+ ReadOk(false);
+ }
+
+ private void AuthenticateOld()
+ {
+ writer.WriteString( Crypt.EncryptPassword(
+ connectionString.Password, encryptionSeed, protocol > 9));
+ if ( (connectionFlags & ClientFlags.CONNECT_WITH_DB) != 0 && connectionString.Database != null)
+ writer.WriteString( connectionString.Database );
+ writer.Flush();
+ ReadOk(true);
+ }
+
+ public void Authenticate()
+ {
+ // write the user id to the auth packet
+ writer.WriteString( connectionString.UserID );
+
+ if ( version.isAtLeast(4,1,1) )
+ Authenticate411();
+ else
+ AuthenticateOld();
+ }
+
+ public override void Reset()
+ {
+ writer.StartPacket(0, true);
+ writer.WriteByte((byte)DBCmd.CHANGE_USER);
+ Authenticate();
+ }
+
+ /// <summary>
+ /// Query is the method that is called to send all queries to the server
+ /// </summary>
+ /// <param name="bytes">The query to send</param>
+ /// <param name="length">The length of the query to send</param>
+ /// <returns>
+ /// -1 for non select queries
+ /// >= 0 for select queries
+ /// </returns>
+ public override void Query(byte[] bytes, int length)
+ {
+ if (Settings.Logging)
+ Logger.LogCommand(DBCmd.QUERY, encoding.GetString(bytes, 0, length));
+
+ // send the command to the server
+ ExecuteCommand(DBCmd.QUERY, bytes, length);
+
+ // the server will respond in one of several ways with the first byte indicating
+ // the type of response.
+ // 0 == ok packet. This indicates non-select queries
+ // 0xff == error packet. This is handled in reader.OpenPacket
+ // > 0 = number of columns in select query
+ // We don't actually read the result here since a single query can generate
+ // multiple resultsets and we don't want to duplicate code. See ReadResult
+ // Instead we set our internal server status flag to indicate that we have a query waiting.
+ // This flag will be maintained by ReadResult
+ serverStatus |= ServerStatusFlags.AnotherQuery;
+ }
+
+ public override void Close()
+ {
+ if (isOpen)
+ ExecuteCommand( DBCmd.QUIT, null, 0 );
+
+ writer.Stream.Close();
+ reader.Close();
+
+ base.Close();
+ }
+
+
+ public override bool Ping()
+ {
+ try
+ {
+ ExecuteCommand(DBCmd.PING, null, 0);
+ ReadOk(true);
+ return true;
+ }
+ catch (Exception)
+ {
+ isOpen = false;
+ // exceptions here can be very common so we don't log
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// ReadResult will attempt to read a single result from the server. Note that it is not
+ /// reading all the rows of the result set but simple determining what type of result it is
+ /// and returning values appropriately.
+ /// </summary>
+ /// <param name="affectedRows">Set to the number of rows affected in this result, 0 for selects</param>
+ /// <param name="lastInsertId">Set to the id of the row inserted by this result, 0 for non-inserts</param>
+ /// <returns>Number of columns in the resultset, 0 for non-selects, -1 for no more resultsets</returns>
+ public override long ReadResult(ref ulong affectedRows, ref long lastInsertId)
+ {
+ // if there is not another query or resultset, then return -1
+ if ((serverStatus & (ServerStatusFlags.AnotherQuery | ServerStatusFlags.MoreResults)) == 0)
+ return -1;
+
+ lastInsertId = -1;
+ // the code to read last packet will set these server status vars
+ // again if necessary.
+ serverStatus &= ~(ServerStatusFlags.AnotherQuery |
+ ServerStatusFlags.MoreResults);
+ reader.OpenPacket();
+
+ long fieldCount = reader.GetFieldLength();
+ if (fieldCount > 0)
+ return fieldCount;
+
+ if (-1 == fieldCount)
+ {
+ string filename = reader.ReadString();
+ SendFileToServer(filename);
+
+ return ReadResult(ref affectedRows, ref lastInsertId);
+ }
+
+ affectedRows = (ulong)reader.GetFieldLength();
+ lastInsertId = (long)reader.GetFieldLength();
+ if ( version.isAtLeast(4,1,0) )
+ {
+ serverStatus = (ServerStatusFlags)reader.ReadInteger(2);
+ warningCount = reader.ReadInteger(2);
+ if (reader.HasMoreData)
+ {
+ reader.ReadLenString(); //TODO: server message
+ }
+ }
+ return fieldCount;
+ }
+
+ /// <summary>
+ /// Sends the specified file to the server.
+ /// This supports the LOAD DATA LOCAL INFILE
+ /// </summary>
+ /// <param name="filename"></param>
+ private void SendFileToServer( string filename )
+ {
+ byte[] buffer = new byte[4092];
+ FileStream fs = null;
+
+
+ try
+ {
+ fs = new FileStream(filename, FileMode.Open);
+ writer.StartPacket(fs.Length, true);
+
+ long len = fs.Length;
+ while (len > 0)
+ {
+ int count = fs.Read( buffer, 0, 4092 );
+ writer.Write( buffer, 0, count );
+ len -= count;
+ }
+ writer.Flush();
+
+ // write the terminating packet
+ //TODO: fix this
+// writer.WriteInteger(0, 3);
+// writer.WriteByte(this.SequenceByte ++);
+// writer.Flush();
+ }
+ catch (Exception ex)
+ {
+ throw new MySqlException("Error during LOAD DATA LOCAL INFILE", ex);
+ }
+ finally
+ {
+ fs.Close();
+ }
+ }
+
+ public override bool SkipDataRow()
+ {
+ bool result = true;
+ if (!reader.HasMoreData)
+ result = FetchDataRow(-1, 0, 0);
+ if (result)
+ reader.SkipPacket();
+ return result;
+ }
+
+ private void ReadNullMap( int fieldCount )
+ {
+ // if we are binary, then we need to load in our null bitmap
+ nullMap = null;
+ byte[] nullMapBytes = new byte[ (fieldCount+9)/8 ];
+ reader.ReadByte();
+ reader.Read(nullMapBytes, 0, nullMapBytes.Length);
+ nullMap = new BitArray( nullMapBytes );
+ }
+
+ public override IMySqlValue ReadColumnValue(int index, MySqlField field, IMySqlValue valObject)
+ {
+ long length = -1;
+ bool isNull = false;
+
+ if (nullMap != null)
+ isNull = nullMap [index+2];
+ else
+ {
+ length = reader.GetFieldLength();
+ isNull = length == -1;
+ }
+
+// if (valObject.IsNull) return valObject;
+
+ reader.Encoding = field.Encoding;
+ return valObject.ReadValue(reader, length, isNull);
+ }
+
+ public override void SkipColumnValue(IMySqlValue valObject)
+ {
+ long length = -1;
+ if (nullMap == null)
+ {
+ length = reader.GetFieldLength();
+ if (length == -1) return;
+ }
+ if (length > -1)
+ reader.SkipBytes( (int)length);
+ else
+ valObject.SkipValue(reader);
+ }
+
+ public override MySqlField[] ReadColumnMetadata(int count)
+ {
+ MySqlField[] fields = new MySqlField[count];
+
+ for (int i=0; i < count; i++)
+ fields[i] = GetFieldMetaData();
+
+ ReadEOF();
+ return fields;
+ }
+
+
+ private MySqlField GetFieldMetaData()
+ {
+ MySqlField field = null;
+
+ if ( version.isAtLeast(4,1,0) )
+ field = GetFieldMetaData41();
+ else
+ {
+ reader.OpenPacket();
+ field = new MySqlField( this.Version );
+
+ field.Encoding = encoding;
+ field.TableName = reader.ReadLenString();
+ field.ColumnName = reader.ReadLenString();
+ field.ColumnLength = reader.ReadNBytes();
+ MySqlDbType type = (MySqlDbType)reader.ReadNBytes();
+ reader.ReadByte();
+ ColumnFlags colFlags;
+ if ((Flags & ClientFlags.LONG_FLAG) != 0)
+ colFlags = (ColumnFlags)reader.ReadInteger(2);
+ else
+ colFlags = (ColumnFlags)reader.ReadByte();
+ field.SetTypeAndFlags(type, colFlags);
+
+ field.Scale = (byte)reader.ReadByte();
+ if ( !version.isAtLeast(3,23,15) && version.isAtLeast(3,23,0))
+ field.Scale++;
+ }
+
+ return field;
+ }
+
+ private MySqlField GetFieldMetaData41()
+ {
+ MySqlField field = new MySqlField( this.Version );
+
+ reader.OpenPacket();
+ field.Encoding = encoding;
+ field.CatalogName = reader.ReadLenString();
+ field.DatabaseName = reader.ReadLenString();
+ field.TableName = reader.ReadLenString();
+ field.RealTableName = reader.ReadLenString();
+ field.ColumnName = reader.ReadLenString();
+ field.OriginalColumnName = reader.ReadLenString();
+ reader.ReadByte();
+ field.CharactetSetIndex = reader.ReadInteger(2);
+ field.ColumnLength = reader.ReadInteger(4);
+ MySqlDbType type = (MySqlDbType)reader.ReadByte();
+ ColumnFlags colFlags;
+ if ((Flags & ClientFlags.LONG_FLAG) != 0)
+ colFlags = (ColumnFlags)reader.ReadInteger(2);
+ else
+ colFlags = (ColumnFlags)reader.ReadByte();
+ field.SetTypeAndFlags(type, colFlags);
+
+ field.Scale = (byte)reader.ReadByte();
+
+ if (reader.HasMoreData)
+ reader.ReadInteger(2); // reserved
+
+ if (charSets != null)
+ field.Encoding = CharSetMap.GetEncoding(this.version, (string)charSets[field.CharactetSetIndex]);
+
+ return field;
+ }
+
+
+ public override void ExecuteStatement(byte[] bytes)
+ {
+ ExecuteCommand(DBCmd.EXECUTE, bytes, bytes.Length);
+ serverStatus |= ServerStatusFlags.AnotherQuery;
+ }
+
+ private void CheckEOF()
+ {
+ if (!reader.IsLastPacket)
+ throw new MySqlException("Expected end of data packet");
+
+ reader.ReadByte(); // read off the 254
+
+ if (reader.HasMoreData && version.isAtLeast(4, 1, 0))
+ {
+ warningCount = reader.ReadInteger(2);
+ serverStatus = (ServerStatusFlags)reader.ReadInteger(2);
+
+ // if we are at the end of this cursor based resultset, then we remove
+ // the last row sent status flag so our next fetch doesn't abort early
+ // and we remove this command result from our list of active CommandResult objects.
+// if ((serverStatus & ServerStatusFlags.LastRowSent) != 0)
+ // {
+ // serverStatus &= ~ServerStatusFlags.LastRowSent;
+ // commandResults.Remove(lastCommandResult);
+ // }
+ }
+ }
+
+ private void ReadEOF()
+ {
+ reader.OpenPacket();
+ CheckEOF();
+ }
+
+ public override int PrepareStatement(string sql, ref MySqlField[] parameters)
+ {
+ //TODO: check this
+ //ClearFetchedRow();
+
+ byte[] bytes = encoding.GetBytes(sql);
+ ExecuteCommand(DBCmd.PREPARE, bytes, bytes.Length);
+
+ reader.OpenPacket();
+
+ int marker = reader.ReadByte();
+ if (marker != 0)
+ throw new MySqlException("Expected prepared statement marker");
+
+ int statementId = reader.ReadInteger(4);
+ int numCols = reader.ReadInteger(2);
+ int numParams = reader.ReadInteger(2);
+ //TODO: find out what this is needed for
+ reader.ReadInteger(3);
+ if (numParams > 0)
+ {
+ parameters = ReadColumnMetadata(numParams);
+
+ // we set the encoding for each parameter back to our connection encoding
+ // since we can't trust what is coming back from the server
+ for (int i=0; i < parameters.Length; i++)
+ parameters[i].Encoding = encoding;
+ }
+
+ if (numCols > 0)
+ {
+ while (numCols-- > 0)
+ {
+ reader.OpenPacket();
+ reader.SkipPacket();
+ }
+
+ ReadEOF();
+ }
+
+ return statementId;
+ }
+
+// private void ClearFetchedRow()
+// {
+// if (lastCommandResult == 0) return;
+
+ //TODO
+/* CommandResult result = (CommandResult)commandResults[lastCommandResult];
+ result.ReadRemainingColumns();
+
+ reader.OpenPacket();
+ if (! reader.IsLastPacket)
+ throw new MySqlException("Cursor reading out of sync");
+
+ ReadEOF(false);
+ lastCommandResult = 0;*/
+// }
+
+ /// <summary>
+ /// FetchDataRow is the method that the data reader calls to see if there is another
+ /// row to fetch. In the non-prepared mode, it will simply read the next data packet.
+ /// In the prepared mode (statementId > 0), it will
+ /// </summary>
+ public override bool FetchDataRow(int statementId, int pageSize, int columns)
+ {
+/* ClearFetchedRow();
+
+ if (!commandResults.ContainsKey(statementId)) return false;
+
+ if ( (serverStatus & ServerStatusFlags.LastRowSent) != 0)
+ return false;
+
+ writer.StartPacket(9, true);
+ writer.WriteByte((byte)DBCmd.FETCH);
+ writer.WriteInteger(statementId, 4);
+ writer.WriteInteger(1, 4);
+ writer.Flush();
+
+ lastCommandResult = statementId;
+ */
+ reader.OpenPacket();
+ if (reader.IsLastPacket)
+ {
+ CheckEOF();
+ return false;
+ }
+ nullMap = null;
+ if (statementId > 0)
+ ReadNullMap(columns);
+
+ return true;
+ }
+
+ }
+}
Modified: trunk/mysqlclient/ProcedureCache.cs
===================================================================
--- trunk/mysqlclient/ProcedureCache.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/ProcedureCache.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -60,9 +60,15 @@
{
ds = AddNew(conn, spName);
conn.PerfMonitor.AddHardProcedureQuery();
+ Logger.LogInformation(String.Format(
+ Resources.HardProcQuery, spName));
}
else
+ {
conn.PerfMonitor.AddSoftProcedureQuery();
+ Logger.LogInformation(String.Format(
+ Resources.SoftProcQuery, spName));
+ }
return ds;
}
@@ -100,9 +106,18 @@
restrictions[1] = schema;
restrictions[2] = name;
DataTable procTable = connection.GetSchema("procedures", restrictions);
+ if (procTable.Rows.Count > 1)
+ throw new InvalidOperationException(Resources.ProcAndFuncSameName);
+ if (procTable.Rows.Count == 0)
+ throw new InvalidOperationException(
+ String.Format(Resources.InvalidProcName, name, schema));
- DataTable parametersTable = connection.GetSchema("procedure parameters",
- restrictions);
+ // we don't use GetSchema here because that would cause another
+ // query of procedures and we don't need that since we already
+ // know the procedure we care about.
+ ISSchemaProvider isp = new ISSchemaProvider(connection);
+ DataTable parametersTable = isp.GetProcedureParameters(
+ restrictions, procTable);
DataSet ds = new DataSet();
ds.Tables.Add(procTable);
Added: trunk/mysqlclient/Resources.Designer.cs
===================================================================
--- trunk/mysqlclient/Resources.Designer.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/Resources.Designer.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -0,0 +1,468 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace MySql.Data.MySqlClient {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MySql.Data.MySqlClient.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Improper MySqlCommandBuilder state: adapter is null.
+ /// </summary>
+ internal static string AdapterIsNull {
+ get {
+ return ResourceManager.GetString("AdapterIsNull", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Improper MySqlCommandBuilder state: adapter's SelectCommand is null.
+ /// </summary>
+ internal static string AdapterSelectIsNull {
+ get {
+ return ResourceManager.GetString("AdapterSelectIsNull", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Version string not in acceptable format.
+ /// </summary>
+ internal static string BadVersionFormat {
+ get {
+ return ResourceManager.GetString("BadVersionFormat", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The buffer cannot be null.
+ /// </summary>
+ internal static string BufferCannotBeNull {
+ get {
+ return ResourceManager.GetString("BufferCannotBeNull", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Buffer is not large enough.
+ /// </summary>
+ internal static string BufferNotLargeEnough {
+ get {
+ return ResourceManager.GetString("BufferNotLargeEnough", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to MySqlCommandBuilder does not support multi-table statements.
+ /// </summary>
+ internal static string CBMultiTableNotSupported {
+ get {
+ return ResourceManager.GetString("CBMultiTableNotSupported", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to MySqlCommandBuilder cannot operate on tables with no unique or key columns.
+ /// </summary>
+ internal static string CBNoKeyColumn {
+ get {
+ return ResourceManager.GetString("CBNoKeyColumn", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Chaos isolation level is not supported.
+ /// </summary>
+ internal static string ChaosNotSupported {
+ get {
+ return ResourceManager.GetString("ChaosNotSupported", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The connection is already open..
+ /// </summary>
+ internal static string ConnectionAlreadyOpen {
+ get {
+ return ResourceManager.GetString("ConnectionAlreadyOpen", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Connection must be valid and open.
+ /// </summary>
+ internal static string ConnectionMustBeOpen {
+ get {
+ return ResourceManager.GetString("ConnectionMustBeOpen", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The connection is not open..
+ /// </summary>
+ internal static string ConnectionNotOpen {
+ get {
+ return ResourceManager.GetString("ConnectionNotOpen", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The connection property has not been set..
+ /// </summary>
+ internal static string ConnectionNotSet {
+ get {
+ return ResourceManager.GetString("ConnectionNotSet", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Count cannot be negative.
+ /// </summary>
+ internal static string CountCannotBeNegative {
+ get {
+ return ResourceManager.GetString("CountCannotBeNegative", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to SetLength is not a valid operation on CompressedStream.
+ /// </summary>
+ internal static string CSNoSetLength {
+ get {
+ return ResourceManager.GetString("CSNoSetLength", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to There is already an open DataReader associated with this Connection which must be closed first..
+ /// </summary>
+ internal static string DataReaderOpen {
+ get {
+ return ResourceManager.GetString("DataReaderOpen", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Error creating socket connection.
+ /// </summary>
+ internal static string ErrorCreatingSocket {
+ get {
+ return ResourceManager.GetString("ErrorCreatingSocket", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to From index and length use more bytes than from contains.
+ /// </summary>
+ internal static string FromAndLengthTooBig {
+ get {
+ return ResourceManager.GetString("FromAndLengthTooBig", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to From index must be a valid index inside the from buffer.
+ /// </summary>
+ internal static string FromIndexMustBeValid {
+ get {
+ return ResourceManager.GetString("FromIndexMustBeValid", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Retrieving procedure metadata for {0} from server..
+ /// </summary>
+ internal static string HardProcQuery {
+ get {
+ return ResourceManager.GetString("HardProcQuery", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Value has an unsupported format..
+ /// </summary>
+ internal static string ImproperValueFormat {
+ get {
+ return ResourceManager.GetString("ImproperValueFormat", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Index and length use more bytes than to has room for.
+ /// </summary>
+ internal static string IndexAndLengthTooBig {
+ get {
+ return ResourceManager.GetString("IndexAndLengthTooBig", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Index must be a valid position in the buffer.
+ /// </summary>
+ internal static string IndexMustBeValid {
+ get {
+ return ResourceManager.GetString("IndexMustBeValid", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Procedure or function '{0}' cannot be found in database '{1}'..
+ /// </summary>
+ internal static string InvalidProcName {
+ get {
+ return ResourceManager.GetString("InvalidProcName", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Keyword does not allow null values..
+ /// </summary>
+ internal static string KeywordNoNull {
+ get {
+ return ResourceManager.GetString("KeywordNoNull", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Keyword not supported..
+ /// </summary>
+ internal static string KeywordNotSupported {
+ get {
+ return ResourceManager.GetString("KeywordNotSupported", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to NamedPipeStream does not support seeking.
+ /// </summary>
+ internal static string NamedPipeNoSeek {
+ get {
+ return ResourceManager.GetString("NamedPipeNoSeek", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to NamedPipeStream doesn't support SetLength.
+ /// </summary>
+ internal static string NamedPipeNoSetLength {
+ get {
+ return ResourceManager.GetString("NamedPipeNoSetLength", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Offset cannot be negative.
+ /// </summary>
+ internal static string OffsetCannotBeNegative {
+ get {
+ return ResourceManager.GetString("OffsetCannotBeNegative", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Offset must be a valid position in buffer.
+ /// </summary>
+ internal static string OffsetMustBeValid {
+ get {
+ return ResourceManager.GetString("OffsetMustBeValid", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Parameter cannot have a negative value.
+ /// </summary>
+ internal static string ParameterCannotBeNegative {
+ get {
+ return ResourceManager.GetString("ParameterCannotBeNegative", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Parameter cannot be null.
+ /// </summary>
+ internal static string ParameterCannotBeNull {
+ get {
+ return ResourceManager.GetString("ParameterCannotBeNull", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Parameter is invalid..
+ /// </summary>
+ internal static string ParameterIsInvalid {
+ get {
+ return ResourceManager.GetString("ParameterIsInvalid", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Password must be valid and contain length characters.
+ /// </summary>
+ internal static string PasswordMustHaveLegalChars {
+ get {
+ return ResourceManager.GetString("PasswordMustHaveLegalChars", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to same name are not supported..
+ /// </summary>
+ internal static string ProcAndFuncSameName {
+ get {
+ return ResourceManager.GetString("ProcAndFuncSameName", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Packets larger than max_allowed_packet are not allowed..
+ /// </summary>
+ internal static string QueryTooLarge {
+ get {
+ return ResourceManager.GetString("QueryTooLarge", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Reading from the stream has failed..
+ /// </summary>
+ internal static string ReadFromStreamFailed {
+ get {
+ return ResourceManager.GetString("ReadFromStreamFailed", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Socket streams do not support seeking.
+ /// </summary>
+ internal static string SocketNoSeek {
+ get {
+ return ResourceManager.GetString("SocketNoSeek", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Retrieving procedure metadata for {0} from procedure cache..
+ /// </summary>
+ internal static string SoftProcQuery {
+ get {
+ return ResourceManager.GetString("SoftProcQuery", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Stored procedures are not supported on this version of MySQL.
+ /// </summary>
+ internal static string SPNotSupported {
+ get {
+ return ResourceManager.GetString("SPNotSupported", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The stream has already been closed.
+ /// </summary>
+ internal static string StreamAlreadyClosed {
+ get {
+ return ResourceManager.GetString("StreamAlreadyClosed", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The stream does not support reading.
+ /// </summary>
+ internal static string StreamNoRead {
+ get {
+ return ResourceManager.GetString("StreamNoRead", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The stream does not support writing.
+ /// </summary>
+ internal static string StreamNoWrite {
+ get {
+ return ResourceManager.GetString("StreamNoWrite", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Unable to execute stored procedure '{0}'..
+ /// </summary>
+ internal static string UnableToExecuteSP {
+ get {
+ return ResourceManager.GetString("UnableToExecuteSP", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Unix sockets are not supported on Windows.
+ /// </summary>
+ internal static string UnixSocketsNotSupported {
+ get {
+ return ResourceManager.GetString("UnixSocketsNotSupported", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Writing to the stream failed..
+ /// </summary>
+ internal static string WriteToStreamFailed {
+ get {
+ return ResourceManager.GetString("WriteToStreamFailed", resourceCulture);
+ }
+ }
+ }
+}
Modified: trunk/mysqlclient/Resources.resx
===================================================================
--- trunk/mysqlclient/Resources.resx 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/Resources.resx 2006-07-28 15:02:38 UTC (rev 277)
@@ -234,4 +234,22 @@
<data name="UnableToExecuteSP" xml:space="preserve">
<value>Unable to execute stored procedure '{0}'.</value>
</data>
-</root>
+ <data name="ProcAndFuncSameName" xml:space="preserve">
+ <value>same name are not supported.</value>
+ </data>
+ <data name="KeywordNoNull" xml:space="preserve">
+ <value>Keyword does not allow null values.</value>
+ </data>
+ <data name="ImproperValueFormat" xml:space="preserve">
+ <value>Value has an unsupported format.</value>
+ </data>
+ <data name="InvalidProcName" xml:space="preserve">
+ <value>Procedure or function '{0}' cannot be found in database '{1}'.</value>
+ </data>
+ <data name="HardProcQuery" xml:space="preserve">
+ <value>Retrieving procedure metadata for {0} from server.</value>
+ </data>
+ <data name="SoftProcQuery" xml:space="preserve">
+ <value>Retrieving procedure metadata for {0} from procedure cache.</value>
+ </data>
+</root>
\ No newline at end of file
Modified: trunk/mysqlclient/Statement.cs
===================================================================
--- trunk/mysqlclient/Statement.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/Statement.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -52,6 +52,10 @@
get { return statementId; }
}
+ public virtual void Close()
+ {
+ }
+
public virtual void Execute(MySqlParameterCollection parameters)
{
// we keep a reference to this until we are done
@@ -199,7 +203,9 @@
sqlPart.Remove(0, sqlPart.Length);
}
else if (sqlPart.Length > 0 && sqlPart[0] == connection.ParameterMarker &&
- !Char.IsLetterOrDigit(c) && c != '_' && c != '.' && c != '$')
+ !Char.IsLetterOrDigit(c) && c != '_' && c != '.' && c != '$' &&
+ ((c != '@' && c != connection.ParameterMarker) &&
+ (c != '?' && c != connection.ParameterMarker)))
{
tokens.Add(sqlPart.ToString());
sqlPart.Remove(0, sqlPart.Length);
Modified: trunk/mysqlclient/StoredProcedure.cs
===================================================================
--- trunk/mysqlclient/StoredProcedure.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/StoredProcedure.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -32,6 +32,7 @@
{
private string hash;
private string outSelect;
+ private DataTable parametersTable;
public StoredProcedure(MySqlConnection connection, string text) :
base(connection, text)
@@ -49,19 +50,6 @@
return null;
}
- private string PrepareAsFunction(MySqlCommand cmd)
- {
- return null;
- }
-
- public override bool ExecuteNext()
- {
- bool returnVal = base.ExecuteNext();
- if (!returnVal)
- UpdateParameters();
- return returnVal;
- }
-
protected override void BindParameters()
{
// first retrieve the procedure definition from our
@@ -72,49 +60,138 @@
DataSet ds = connection.ProcedureCache.GetProcedure(connection, spName);
DataTable procTable = ds.Tables["procedures"];
- DataTable paramTable = ds.Tables["procedure parameters"];
+ parametersTable = ds.Tables["procedure parameters"];
- string sqlStr = String.Empty;
- string setStr = String.Empty;
+ StringBuilder sqlStr = new StringBuilder();
+ StringBuilder setStr = new StringBuilder();
+ outSelect = String.Empty;
string retParm = GetReturnParameter();
- foreach (DataRow param in paramTable.Rows)
+ foreach (DataRow param in parametersTable.Rows)
{
if (param["ordinal_position"].Equals(0)) continue;
string mode = (string)param["parameter_mode"];
string name = (string)param["parameter_name"];
- string pName = connection.ParameterMarker + name;
- string vName = "@" + hash + name;
+ string datatype = (string)param["DATA_TYPE"];
- sqlStr += pName + ", ";
- if (mode == "OUT")
- outSelect += vName + ", ";
+ // make sure the parameters given to us have an appropriate
+ // type set if it's not already
+ MySqlParameter p = parameters[name];
+ if (!p.TypeHasBeenSet)
+ p.MySqlDbType = GetTypeFromName(datatype,
+ param["FLAGS"].ToString().IndexOf("UNSIGNED") != -1,
+ procTable.Rows[0]["SQL_MODE"].ToString().IndexOf("REAL_AS_FLOAT") != -1);
+
+ string pName = String.Format("{0}{1}",
+ connection.ParameterMarker, name);
+ string vName = string.Format("@{0}{1}", hash, name);
+
+ if (mode == "OUT" || mode == "INOUT")
+ {
+ outSelect += vName + ", ";
+ sqlStr.Append(vName);
+ sqlStr.Append(", ");
+ }
else
{
- setStr += "SET " + vName + "=" + pName + ";";
+ sqlStr.Append(pName);
+ sqlStr.Append(", ");
+ }
+
+ if (mode == "INOUT")
+ {
+ setStr.AppendFormat("SET {0}={1};", vName, pName);
outSelect += vName + ", ";
}
+ }
+ string sqlCmd = sqlStr.ToString().TrimEnd(' ', ',');
+ outSelect = outSelect.TrimEnd(' ', ',');
+ if (procTable.Rows[0]["ROUTINE_TYPE"].Equals("PROCEDURE"))
+ sqlCmd = String.Format("call {0} ({1})", commandText, sqlCmd);
+ else
+ {
+ sqlCmd = String.Format("set @{0}={1} ({2})", retParm,
+ commandText, sqlCmd);
+ outSelect = String.Format("@{0}", retParm);
}
- sqlStr = sqlStr.TrimEnd(' ', ',');
- outSelect = outSelect.TrimEnd(' ', ',');
- if (procTable.Rows[0]["ROUTINE_TYPE"].Equals("PROCEDURE"))
- sqlStr = "call " + commandText + "(" + sqlStr + ")";
- else
- {
- sqlStr = "set @" + retParm + "=" + commandText + "(" + sqlStr + ")";
- outSelect = "@" + retParm;
- }
if (setStr.Length > 0)
- sqlStr = setStr + sqlStr;
- commandText = sqlStr;
+ sqlCmd = setStr.ToString() + sqlCmd;
+ string oldCmdText = commandText;
// now call our base version
+ // we save our original command text because we are about to
+ // overwrite it. We restore it once our base class gets done
+ // binding the parameters
+ commandText = sqlCmd;
base.BindParameters();
+ commandText = oldCmdText;
}
- public void UpdateParameters()
+ private MySqlDbType GetTypeFromName(string typeName, bool unsigned,
+ bool realAsFloat)
+ {
+ switch (typeName)
+ {
+ case "char": return MySqlDbType.String;
+ case "varchar": return MySqlDbType.VarChar;
+ case "date": return MySqlDbType.Date;
+ case "datetime": return MySqlDbType.Datetime;
+ case "numeric":
+ case "decimal":
+ case "dec":
+ case "fixed":
+ if (connection.driver.Version.isAtLeast(5, 0, 3))
+ return MySqlDbType.NewDecimal;
+ else
+ return MySqlDbType.Decimal;
+ case "year":
+ return MySqlDbType.Year;
+ case "time":
+ return MySqlDbType.Time;
+ case "timestamp":
+ return MySqlDbType.Timestamp;
+ case "set": return MySqlDbType.Set;
+ case "enum": return MySqlDbType.Enum;
+ case "bit": return MySqlDbType.Bit;
+
+ case "tinyint":
+ case "bool":
+ case "boolean":
+ return MySqlDbType.Byte;
+ case "smallint":
+ return unsigned ? MySqlDbType.UInt16 : MySqlDbType.Int16;
+ case "mediumint":
+ return unsigned ? MySqlDbType.UInt24 : MySqlDbType.Int24;
+ case "int":
+ case "integer":
+ return unsigned ? MySqlDbType.UInt32 : MySqlDbType.Int32;
+ case "serial":
+ return MySqlDbType.UInt64;
+ case "bigint":
+ return unsigned ? MySqlDbType.UInt64 : MySqlDbType.Int64;
+ case "float": return MySqlDbType.Float;
+ case "double": return MySqlDbType.Double;
+ case "real": return
+ realAsFloat ? MySqlDbType.Float : MySqlDbType.Double;
+ case "blob":
+ case "text":
+ return MySqlDbType.Blob;
+ case "longblob":
+ case "longtext":
+ return MySqlDbType.LongBlob;
+ case "mediumblob":
+ case "mediumtext":
+ return MySqlDbType.MediumBlob;
+ case "tinyblob":
+ case "tinytext":
+ return MySqlDbType.TinyBlob;
+ }
+ throw new MySqlException("Unhandled type encountered");
+ }
+
+ public override void Close()
{
if (outSelect.Length == 0) return;
@@ -123,20 +200,23 @@
MySqlCommand cmd = new MySqlCommand("SELECT " + outSelect, connection);
MySqlDataReader reader = cmd.ExecuteReader();
-/* for (int i=0; i < reader.FieldCount; i++)
+ // since MySQL likes to return user variables as strings
+ // we reset the types of the readers internal value objects
+ // this will allow those value objects to parse the string based
+ // return values
+ for (int i=0; i < reader.FieldCount; i++)
{
string fieldName = reader.GetName(i);
fieldName = marker + fieldName.Remove(0, hash.Length+1);
- reader.GetField(i) = MySqlField.GetIMySqlValue(parameters[fieldName].MySqlDbType, true);
- reader.fi
+ reader.values[i] = MySqlField.GetIMySqlValue(parameters[fieldName].MySqlDbType, true);
}
-*/
+
reader.Read();
for (int i=0; i < reader.FieldCount; i++)
{
string fieldName = reader.GetName(i);
fieldName = marker + fieldName.Remove(0, hash.Length+1);
- parameters[fieldName].Value = reader.GetValue(i);
+ parameters[fieldName].Value = reader.GetValue(i);
}
reader.Close();
}
Modified: trunk/mysqlclient/Types/MySqlBinary.cs
===================================================================
--- trunk/mysqlclient/Types/MySqlBinary.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/Types/MySqlBinary.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -100,20 +100,24 @@
if (val is System.Byte[])
buffToWrite = (byte[])val;
else if (val is String)
- {
- string s = (val as string).Substring(0, length);
+ {
+ string s = (val as string);
+ if (length == 0)
+ length = s.Length;
+ else
+ s = s.Substring(0, length);
buffToWrite = writer.Encoding.GetBytes(s);
- length = buffToWrite.Length;
}
else if (val is Char[])
- {
buffToWrite = writer.Encoding.GetBytes(val as char[]);
- length = buffToWrite.Length;
- }
- if ( buffToWrite == null )
- throw new MySqlException( "Only byte arrays and strings can be serialized by MySqlBinary" );
+ // we assume zero length means write all of the value
+ if (length == 0)
+ length = buffToWrite.Length;
+ if (buffToWrite == null)
+ throw new MySqlException("Only byte arrays and strings can be serialized by MySqlBinary");
+
if (binary)
{
writer.WriteLength(length);
@@ -122,11 +126,11 @@
else
{
if (writer.Version.isAtLeast(4,1,0))
- writer.WriteStringNoNull( "_binary " );
+ writer.WriteStringNoNull("_binary ");
- writer.WriteByte( (byte)'\'');
- EscapeByteArray( buffToWrite, length, writer );
writer.WriteByte((byte)'\'');
+ EscapeByteArray(buffToWrite, length, writer);
+ writer.WriteByte((byte)'\'');
}
}
Modified: trunk/mysqlclient/Types/MySqlByte.cs
===================================================================
--- trunk/mysqlclient/Types/MySqlByte.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/Types/MySqlByte.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -20,7 +20,8 @@
using System;
using System.Data;
-using MySql.Data.MySqlClient;
+using MySql.Data.MySqlClient;
+using System.Globalization;
namespace MySql.Data.Types
{
@@ -89,12 +90,15 @@
IMySqlValue IMySqlValue.ReadValue(MySqlStreamReader reader, long length, bool nullVal)
{
- if (nullVal) return new MySqlByte(true);
-
- if (length == -1)
- return new MySqlByte((sbyte)reader.ReadByte());
- else
- return new MySqlByte(SByte.Parse(reader.ReadString(length)));
+ if (nullVal) return new MySqlByte(true);
+
+ if (length == -1)
+ return new MySqlByte((sbyte)reader.ReadByte());
+ else
+ {
+ string s = reader.ReadString(length);
+ return new MySqlByte(SByte.Parse(s, CultureInfo.InvariantCulture));
+ }
}
void IMySqlValue.SkipValue(MySqlStreamReader reader)
Modified: trunk/mysqlclient/command.cs
===================================================================
--- trunk/mysqlclient/command.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/command.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -49,7 +49,6 @@
private bool designTimeVisible;
internal Int64 lastInsertedId;
private Statement statement;
- private MySqlCommandType mysqlCmdType;
/// <include file='docs/mysqlcommand.xml' path='docs/ctor1/*'/>
public MySqlCommand()
@@ -105,15 +104,19 @@
public override string CommandText
{
get { return cmdText; }
- set { cmdText = value; statement=null; }
+ set
+ {
+ cmdText = value;
+ statement=null;
+ if (cmdText.EndsWith("DEFAULT VALUES"))
+ {
+ cmdText = cmdText.Substring(0, cmdText.Length - 14);
+ cmdText = cmdText + "() VALUES ()";
+ }
+
+ }
}
- public MySqlCommandType MySqlCommandType
- {
- get { return mysqlCmdType; }
- set { mysqlCmdType = value; SyncCommandType(false); }
- }
-
internal int UpdateCount
{
get { return (int)updatedRowCount; }
@@ -449,6 +452,12 @@
return (int)this.updatedRowCount;*/
}
+ internal void Close()
+ {
+ if (statement != null)
+ statement.Close();
+ }
+
/// <include file='docs/mysqlcommand.xml' path='docs/ExecuteReader/*'/>
public new MySqlDataReader ExecuteReader()
{
Modified: trunk/mysqlclient/common/ContextString.cs
===================================================================
--- trunk/mysqlclient/common/ContextString.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/common/ContextString.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -36,6 +36,12 @@
this.escapeBackslash = escapeBackslash;
}
+ public string ContextMarkers
+ {
+ get { return contextMarkers; }
+ set { contextMarkers = value; }
+ }
+
public int IndexOf(string src, char target)
{
char contextMarker = Char.MinValue;
@@ -91,17 +97,27 @@
else
{
int contextIndex = contextMarkers.IndexOf(c);
- if (contextIndex > -1 && contextMarker != Char.MinValue)
- contextIndex++;
+ if (!escaped && contextIndex != -1)
+ {
+ // if we have found the closing marker for our open
+ // marker, then close the context
+ if ((contextIndex % 2) == 1)
+ {
+ if (contextMarker == contextMarkers[contextIndex - 1])
+ contextMarker = Char.MinValue;
+ }
+ else
+ {
+ // if the opening and closing context markers are
+ // the same then we will always find the opening
+ // marker.
+ if (contextMarker == contextMarkers[contextIndex + 1])
+ contextMarker = Char.MinValue;
+ else if (contextMarker == Char.MinValue)
+ contextMarker = c;
+ }
+ }
- // if we have found the closing marker for our open marker, then close the context
- if ((contextIndex % 2) == 1 && contextMarker == contextMarkers[contextIndex-1] && !escaped)
- contextMarker = Char.MinValue;
-
- // if we have found a context marker and we are not in a context yet, then start one
- else if (contextMarker == Char.MinValue && (contextMarkers.IndexOf(c) % 2 == 0) && !escaped)
- contextMarker = c;
-
sb.Append( c );
}
}
Added: trunk/mysqlclient/common/SocketStream.cs
===================================================================
--- trunk/mysqlclient/common/SocketStream.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/common/SocketStream.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -0,0 +1,118 @@
+using System;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Collections;
+
+namespace MySql.Data.Common
+{
+ /// <summary>
+ /// Summary description for MySqlSocket.
+ /// </summary>
+ internal sealed class SocketStream : Stream
+ {
+ private Socket socket;
+
+ public SocketStream(AddressFamily addressFamily, SocketType socketType, ProtocolType protocol)
+ : base()
+ {
+ socket = new Socket(addressFamily, socketType, protocol);
+ }
+
+ #region Properties
+
+ public Socket Socket
+ {
+ get { return socket; }
+ }
+
+ public override bool CanRead
+ {
+ get { return true; }
+ }
+
+ public override bool CanSeek
+ {
+ get { return false; }
+ }
+
+ public override bool CanWrite
+ {
+ get { return true; }
+ }
+
+ public override long Length
+ {
+ get { return 0; }
+ }
+
+ public override long Position
+ {
+ get { return 0; }
+ set { throw new NotSupportedException("SocketStream does not support seek"); }
+ }
+
+ #endregion
+
+ #region Stream Implementation
+
+ public override void Flush()
+ {
+ }
+
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ return socket.Receive(buffer, offset, count, SocketFlags.None);
+ }
+
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ throw new NotSupportedException("SocketStream does not support seek");
+ }
+
+ public override void SetLength(long value)
+ {
+ }
+
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ socket.Send(buffer, offset, count, SocketFlags.None);
+ }
+
+
+ #endregion
+
+ public bool Connect(EndPoint remoteEP, int timeout)
+ {
+ // set the socket to non blocking
+ socket.Blocking = false;
+
+ // then we star the connect
+ SocketAddress addr = remoteEP.Serialize();
+ byte[] buff = new byte[addr.Size];
+ for (int i=0; i<addr.Size; i++)
+ buff[i] = addr[i];
+
+ int result = NativeMethods.connect(socket.Handle, buff, addr.Size);
+ int wsaerror = NativeMethods.WSAGetLastError();
+ if (wsaerror != 10035)
+ throw new Exception("Error creating MySQLSocket");
+
+ // next we wait for our connect timeout or until the socket is connected
+ ArrayList write = new ArrayList();
+ write.Add(socket);
+ ArrayList error = new ArrayList();
+ error.Add(socket);
+
+ Socket.Select(null, write, error, timeout*1000*1000);
+
+ if (write.Count == 0) return false;
+
+ // set socket back to blocking mode
+ socket.Blocking = true;
+ return true;
+ }
+
+
+ }
+}
Modified: trunk/mysqlclient/common/StreamCreator.cs
===================================================================
--- trunk/mysqlclient/common/StreamCreator.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/common/StreamCreator.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -1,170 +1,170 @@
-// Copyright (C) 2004-2006 MySQL AB
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as published by
-// the Free Software Foundation
-//
-// There are special exceptions to the terms and conditions of the GPL
-// as it is applied to this software. View the full text of the
-// exception in file EXCEPTIONS in the directory of this software
-// distribution.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-using System;
-using System.IO;
-using System.Net;
-using System.Net.Sockets;
-using System.Collections;
-using System.Threading;
-using System.Reflection;
-using MySql.Data.MySqlClient;
-
-namespace MySql.Data.Common
-{
- /// <summary>
- /// Summary description for StreamCreator.
- /// </summary>
- internal class StreamCreator
- {
- string hostList;
- uint port;
- string pipeName;
- uint timeOut;
-
- public StreamCreator( string hosts, uint port, string pipeName)
- {
- hostList = hosts;
- if (hostList == null || hostList.Length == 0)
- hostList = "localhost";
- this.port = port;
- this.pipeName = pipeName;
- }
-
- public Stream GetStream(uint timeOut)
- {
- this.timeOut = timeOut;
-
- if (hostList.StartsWith("/"))
- return CreateSocketStream(null, 0, true);
-
- string [] dnsHosts = hostList.Split('&');
- ArrayList ipAddresses = new ArrayList();
- ArrayList hostNames = new ArrayList();
-
- //
- // Each host name specified may contain multiple IP addresses
- // Lets look at the DNS entries for each host name
- foreach (string h in dnsHosts)
+// Copyright (C) 2004-2006 MySQL AB
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation
+//
+// There are special exceptions to the terms and conditions of the GPL
+// as it is applied to this software. View the full text of the
+// exception in file EXCEPTIONS in the directory of this software
+// distribution.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+using System;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Collections;
+using System.Threading;
+using System.Reflection;
+using MySql.Data.MySqlClient;
+
+namespace MySql.Data.Common
+{
+ /// <summary>
+ /// Summary description for StreamCreator.
+ /// </summary>
+ internal class StreamCreator
+ {
+ string hostList;
+ uint port;
+ string pipeName;
+ uint timeOut;
+
+ public StreamCreator( string hosts, uint port, string pipeName)
+ {
+ hostList = hosts;
+ if (hostList == null || hostList.Length == 0)
+ hostList = "localhost";
+ this.port = port;
+ this.pipeName = pipeName;
+ }
+
+ public Stream GetStream(uint timeOut)
+ {
+ this.timeOut = timeOut;
+
+ if (hostList.StartsWith("/"))
+ return CreateSocketStream(null, 0, true);
+
+ string [] dnsHosts = hostList.Split('&');
+ ArrayList ipAddresses = new ArrayList();
+ ArrayList hostNames = new ArrayList();
+
+ //
+ // Each host name specified may contain multiple IP addresses
+ // Lets look at the DNS entries for each host name
+ foreach (string h in dnsHosts)
{
#if NET20
- IPHostEntry hostAddress = Dns.GetHostEntry(h);
-#else
- IPHostEntry hostAddress = Dns.GetHostByName(h);
-#endif
- foreach (IPAddress addr in hostAddress.AddressList)
- {
- ipAddresses.Add( addr );
- hostNames.Add( hostAddress.HostName );
- }
- }
-
- System.Random random = new Random((int)DateTime.Now.Ticks);
- int index = random.Next(ipAddresses.Count);
-
- bool usePipe = (pipeName != null && pipeName.Length != 0);
- Stream stream = null;
- for (int i=0; i < ipAddresses.Count; i++)
- {
- if (usePipe)
- stream = CreateNamedPipeStream( (string)hostNames[index] );
- else
- stream = CreateSocketStream( (IPAddress)ipAddresses[index], port, false );
- if (stream != null) return stream;
-
- index++;
- if (index == ipAddresses.Count) index = 0;
- }
-
- return stream;
- }
-
- private Stream CreateNamedPipeStream( string hostname )
- {
- string pipePath;
- if (0 == String.Compare(hostname, "localhost", true))
- pipePath = @"\\.\pipe\" + pipeName;
- else
- pipePath = String.Format(@"\\{0}\pipe\{1}", hostname.ToString(), pipeName);
- return new NamedPipeStream(pipePath, FileAccess.ReadWrite);
- }
-
- private EndPoint CreateUnixEndPoint(string host)
- {
- // first we need to load the Mono.posix assembly
-#if NET20
- Assembly a = Assembly.Load("Mono.Posix");
-#else
- Assembly a = Assembly.LoadWithPartialName("Mono.Posix");
-#endif
-
- // then we need to construct a UnixEndPoint object
- EndPoint ep = (EndPoint)a.CreateInstance("Mono.Posix.UnixEndPoint",
- false, BindingFlags.CreateInstance, null,
- new object[1] { host }, null, null);
- return ep;
- }
-
- private Stream CreateSocketStream( IPAddress ip, uint port, bool unix )
- {
- SocketStream ss = null;
- try
- {
- //
- // Lets try to connect
- EndPoint endPoint;
-
- if (!Platform.IsWindows() && unix)
- endPoint = CreateUnixEndPoint(hostList);
- else
- endPoint = new IPEndPoint(ip, (int)port);
-
- ss = unix ?
- new SocketStream(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP) :
- new SocketStream(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- ss.Connect(endPoint, (int)timeOut);
- ss.Socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1);
- return ss;
- }
- catch (ArgumentOutOfRangeException are)
- {
- Logger.LogException(are);
- ss = null;
- }
- catch (SocketException se)
- {
- Logger.LogException(se);
- ss = null;
- }
- catch (ObjectDisposedException ode)
- {
- Logger.LogException(ode);
- ss = null;
- }
- catch (MySqlException me)
- {
- Logger.LogException(me);
- ss = null;
- }
- return ss;
- }
-
- }
-}
+ IPHostEntry hostAddress = Dns.GetHostEntry(h);
+#else
+ IPHostEntry hostAddress = Dns.GetHostByName(h);
+#endif
+ foreach (IPAddress addr in hostAddress.AddressList)
+ {
+ ipAddresses.Add( addr );
+ hostNames.Add( hostAddress.HostName );
+ }
+ }
+
+ System.Random random = new Random((int)DateTime.Now.Ticks);
+ int index = random.Next(ipAddresses.Count);
+
+ bool usePipe = (pipeName != null && pipeName.Length != 0);
+ Stream stream = null;
+ for (int i=0; i < ipAddresses.Count; i++)
+ {
+ if (usePipe)
+ stream = CreateNamedPipeStream( (string)hostNames[index] );
+ else
+ stream = CreateSocketStream( (IPAddress)ipAddresses[index], port, false );
+ if (stream != null) return stream;
+
+ index++;
+ if (index == ipAddresses.Count) index = 0;
+ }
+
+ return stream;
+ }
+
+ private Stream CreateNamedPipeStream( string hostname )
+ {
+ string pipePath;
+ if (0 == String.Compare(hostname, "localhost", true))
+ pipePath = @"\\.\pipe\" + pipeName;
+ else
+ pipePath = String.Format(@"\\{0}\pipe\{1}", hostname.ToString(), pipeName);
+ return new NamedPipeStream(pipePath, FileAccess.ReadWrite);
+ }
+
+ private EndPoint CreateUnixEndPoint(string host)
+ {
+ // first we need to load the Mono.posix assembly
+#if NET20
+ Assembly a = Assembly.Load("Mono.Posix");
+#else
+ Assembly a = Assembly.LoadWithPartialName("Mono.Posix");
+#endif
+
+ // then we need to construct a UnixEndPoint object
+ EndPoint ep = (EndPoint)a.CreateInstance("Mono.Posix.UnixEndPoint",
+ false, BindingFlags.CreateInstance, null,
+ new object[1] { host }, null, null);
+ return ep;
+ }
+
+ private Stream CreateSocketStream( IPAddress ip, uint port, bool unix )
+ {
+ SocketStream ss = null;
+ try
+ {
+ //
+ // Lets try to connect
+ EndPoint endPoint;
+
+ if (!Platform.IsWindows() && unix)
+ endPoint = CreateUnixEndPoint(hostList);
+ else
+ endPoint = new IPEndPoint(ip, (int)port);
+
+ ss = unix ?
+ new SocketStream(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP) :
+ new SocketStream(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ ss.Connect(endPoint, (int)timeOut);
+ ss.Socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1);
+ return ss;
+ }
+ catch (ArgumentOutOfRangeException are)
+ {
+ Logger.LogException(are);
+ ss = null;
+ }
+ catch (SocketException se)
+ {
+ Logger.LogException(se);
+ ss = null;
+ }
+ catch (ObjectDisposedException ode)
+ {
+ Logger.LogException(ode);
+ ss = null;
+ }
+ catch (MySqlException me)
+ {
+ Logger.LogException(me);
+ ss = null;
+ }
+ return ss;
+ }
+
+ }
+}
Modified: trunk/mysqlclient/datareader.cs
===================================================================
--- trunk/mysqlclient/datareader.cs 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/datareader.cs 2006-07-28 15:02:38 UTC (rev 277)
@@ -36,7 +36,7 @@
// Keep track of the results and position
// within the resultset (starts prior to first record).
private MySqlField[] fields;
- private IMySqlValue[] values;
+ internal IMySqlValue[] values;
private CommandBehavior commandBehavior;
private MySqlCommand command;
private bool canRead;
@@ -48,7 +48,7 @@
private Statement statement;
private int seqIndex;
private bool hasRead;
-// private ServerStatusFlags serverFlags;
+ private bool nextResultDone;
/*
* Keep track of the connection in order to implement the
@@ -70,6 +70,7 @@
driver = connection.driver;
affectedRows = -1;
this.statement = statement;
+ nextResultDone = false;
}
#region Properties
@@ -133,7 +134,7 @@
// RecordsAffected returns the number of rows affected in batch
// statments from insert/delete/update statments. This property
// is not completely accurate until .Close() has been called.
- get { return (affectedRows >= 0) ? (int)(affectedRows + 1) : -1; }
+ get { return (int)affectedRows; }
}
/// <summary>
@@ -169,8 +170,17 @@
commandBehavior = CommandBehavior.Default;
connection.Reader = null;
- while (NextResult()) { }
+ // we set the nextResultDone var to true inside NextResult when
+ // it returns false. This allows us to avoid calling NextResult
+ // here unnecessarily. Calling NextResult here will work but this
+ // is just an optimization.
+ if (!nextResultDone)
+ while (NextResult()) { }
+ // we now give the command a chance to terminate. In the case of
+ // stored procedures it needs to update out and inout parameters
+ command.Close();
+
if (shouldCloseConnection)
connection.Close();
@@ -313,23 +323,21 @@
public override DateTime GetDateTime(int index)
{
IMySqlValue val = GetFieldValue(index);
- if (val is MySqlDateTime)
+ MySqlDateTime dt;
+
+ // we need to do this because functions like date_add return string
+ if (val is MySqlString)
{
- MySqlDateTime dt = (MySqlDateTime)val;
- if (connection.Settings.ConvertZeroDateTime && !dt.IsValidDateTime)
- return DateTime.MinValue;
-// else
-// return dt.GetDateTime();
- }
- else if (val is MySqlString)
- {
- MySqlDateTime dt = MySqlDateTime.Parse(val.ToString(), this.connection.driver.Version);
- val = dt;
-// MySqlDateTime d = new MySqlDateTime(MySqlDbType.Datetime);
-// d = d.ParseMySql( (val as MySqlString).Value, true );
-// return d.GetDateTime();
+ string s = ((MySqlString)val).Value;
+ dt = MySqlDateTime.Parse(s, this.connection.driver.Version);
}
- return Convert.ToDateTime(val);
+ else
+ dt = (MySqlDateTime)val;
+
+ if (connection.Settings.ConvertZeroDateTime && !dt.IsValidDateTime)
+ return DateTime.MinValue;
+ else
+ return dt.GetDateTime();
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetDecimal/*'/>
@@ -658,7 +666,10 @@
else if (fieldCount == 0)
{
command.lastInsertedId = lastInsertId;
- affectedRows += (long)affectedRowsTemp;
+ if (affectedRows == -1)
+ affectedRows = (long)affectedRowsTemp;
+ else
+ affectedRows += (long)affectedRowsTemp;
}
else if (fieldCount == -1)
if (!statement.ExecuteNext())
@@ -694,7 +705,11 @@
{
long fieldCount = GetResultSet();
if (fieldCount == -1)
+ {
+ nextResultDone = true;
+ hasRows = canRead = false;
return false;
+ }
// issue any requested UA warnings
if (connection.Settings.UseUsageAdvisor)
Modified: trunk/mysqlclient/docs/MySqlConnectionStringBuilder.xml
===================================================================
--- trunk/mysqlclient/docs/MySqlConnectionStringBuilder.xml 2006-07-28 02:10:33 UTC (rev 276)
+++ trunk/mysqlclient/docs/MySqlConnectionStringBuilder.xml 2006-07-28 15:02:38 UTC (rev 277)
@@ -1,55 +1,55 @@
-<docs>
- <Server>
- <summary>
- Gets or sets the name or address of the MySQL instance to connect to.
- </summary>
- <remarks>
- If this property is not set, then the provider will attempt to
- connect to <b>localhost</b> even though this property will return
- <b>String.Empty</b>.
- </remarks>
- <example>
- </example>
- </Server>
-
- <Database>
- <summary>
- Gets or sets the name of the database that should be selected
- when the connection is first opened.
- </summary>
- <remarks>
- There is no default for this property and, if not set, the
- connection will not have a current database until one is set
- using the <see cref="ChangeDatabase"/> method.
- </remarks>
- <example>
- </example>
- </Database>
-
- <ConnectionProtocol>
- <summary>
- Gets or sets the connection protocol that is being used for this
- connection.
- </summary>
- <remarks>
- </remarks>
- <example>
- </example>
- </ConnectionProtocol>
-
+<docs>
+ <Server>
+ <summary>
+ Gets or sets the name or address of the MySQL instance to connect to.
+ </summary>
+ <remarks>
+ If this property is not set, then the provider will attempt to
+ connect to <b>localhost</b> even though this property will return
+ <b>String.Empty</b>.
+ </remarks>
+ <example>
+ </example>
+ </Server>
- <PipeName>
- <summary>
- Gets or sets the name of the named pipe object that the provider
- should use.
- </summary>
- <remarks>
- This property has no effect unless the <see cref="ConnectionProtocol"/>
- property has been set to <b>NamedPipe</b>.
- </remarks>
- <example>
- </example>
- </PipeName>
-
-
+ <Database>
+ <summary>
+ Gets or sets the name of the database that should be selected
+ when the connection is first opened.
+ </summary>
+ <remarks>
+ There is no default for this property and, if not set, the
+ connection will not have a current database until one is set
+ using the <see cref="ChangeDatabase"/> method.
+ </remarks>
+ <example>
+ </example>
+ </Database>
+
+ <ConnectionProtocol>
+ <summary>
+ Gets or sets the connection protocol that is being used for this
+ connection.
+ </summary>
+ <remarks>
+ </remarks>
+ <example>
+ </example>
+ </ConnectionProtocol>
+
+
+ <PipeName>
+ <summary>
+ Gets or sets the name of the named pipe object that the provider
+ should use.
+ </summary>
+ <remarks>
+ This property has no effect unless the <see cref="ConnectionProtocol"/>
+ property has been set to <b>NamedPipe</b>.
+ </remarks>
+ <example>
+ </example>
+ </PipeName>
+
+
</docs>
\ No newline at end of file
| Thread |
|---|
| • Connector/NET commit: r277 - in trunk: . mysqlclient mysqlclient/Types mysqlclient/common mysqlclient/docs | rburnett | 28 Jul |