mysql-connector-net-6.2.3 added to repository

main
Inga 🏳‍🌈 14 years ago
parent f330e5a73a
commit 8d7c83de66
  1. 20
      FLocal.sln
  2. 4
      IISMainHandler/IISMainHandler.csproj
  3. 5
      MySQLConnector/MySQLConnector.csproj
  4. 47
      ThirdParty/mysql-connector-net-6.2.3/CHANGES
  5. 343
      ThirdParty/mysql-connector-net-6.2.3/COPYING
  6. 119
      ThirdParty/mysql-connector-net-6.2.3/EXCEPTIONS
  7. 3
      ThirdParty/mysql-connector-net-6.2.3/License.txt
  8. 96
      ThirdParty/mysql-connector-net-6.2.3/MySQL-VS2005.sln
  9. 136
      ThirdParty/mysql-connector-net-6.2.3/MySQLClient-VS2010.sln
  10. 166
      ThirdParty/mysql-connector-net-6.2.3/MySQLClient-mono.sln
  11. 305
      ThirdParty/mysql-connector-net-6.2.3/MySQLClient.sln
  12. 178
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/MySql.Data.CF.csproj
  13. 315
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/MySql.Data.csproj
  14. 6971
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/MySql.Data.xml
  15. 75
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Properties/AssemblyInfo.cs
  16. 76
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Properties/ReservedWords.txt
  17. 1147
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Properties/Resources.Designer.cs
  18. 460
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Properties/Resources.resx
  19. 39
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Properties/VersionInfo.cs
  20. 229
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Properties/keywords.txt
  21. 391
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/BulkLoader.cs
  22. 197
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/CharSetMap.cs
  23. 281
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/CommandBuilder.cs
  24. 308
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/CompressedStream.cs
  25. 867
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Connection.cs
  26. 338
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Crypt.cs
  27. 513
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Driver.cs
  28. 94
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Exception.cs
  29. 417
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Field.cs
  30. 694
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/ISSchemaProvider.cs
  31. 192
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Installer.cs
  32. 159
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/MySqlClientFactory.cs
  33. 929
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/MySqlConnectionStringBuilder.cs
  34. 351
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/MySqlError.cs
  35. 406
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/MySqlHelper.cs
  36. 356
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/MySqlPacket.cs
  37. 330
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/MySqlPool.cs
  38. 153
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/MySqlPoolManager.cs
  39. 125
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/MySqlPromotableTransaction.cs
  40. 433
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/MySqlScript.cs
  41. 241
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/MySqlStream.cs
  42. 109
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/MySqlTrace.cs
  43. 410
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/MysqlDefs.cs
  44. 880
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/NativeDriver.cs
  45. 88
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/PerformanceMonitor.cs
  46. 211
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/PreparableStatement.cs
  47. 137
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/ProcedureCache.cs
  48. 282
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/ResultSet.cs
  49. 26
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Runtime.cs
  50. 1030
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/SchemaProvider.cs
  51. 215
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Statement.cs
  52. 289
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/StoredProcedure.cs
  53. 297
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/TimedStream.cs
  54. 248
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/TracingDriver.cs
  55. 137
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MetaData.cs
  56. 226
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlBinary.cs
  57. 137
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlBit.cs
  58. 171
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlByte.cs
  59. 39
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlConversionException.cs
  60. 646
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlDateTime.cs
  61. 173
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlDecimal.cs
  62. 147
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlDouble.cs
  63. 241
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlGuid.cs
  64. 140
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlInt16.cs
  65. 160
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlInt32.cs
  66. 140
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlInt64.cs
  67. 146
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlSingle.cs
  68. 165
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlString.cs
  69. 206
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlTime.cs
  70. 140
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlUByte.cs
  71. 140
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlUInt16.cs
  72. 159
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlUInt32.cs
  73. 140
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlUInt64.cs
  74. 41
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/Types/MySqlValue.cs
  75. 339
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/base/DbConnectionStringBuilder.cs
  76. 60
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/base/DbException.cs
  77. 197
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/cf/BufferedStream.cs
  78. 70
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/cf/MissingAttributes.cs
  79. 34
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/cf/WinCE.cs
  80. 917
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/command.cs
  81. 76
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/common/Cache.cs
  82. 170
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/common/ContextString.cs
  83. 91
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/common/LowResolutionStopwatch.cs
  84. 180
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/common/MyNetworkStream.cs
  85. 312
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/common/MySqlTokenizer.cs
  86. 236
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/common/NamedPipeStream.cs
  87. 154
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/common/NativeMethods.cs
  88. 64
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/common/Platform.cs
  89. 392
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/common/QueryNormalizer.cs
  90. 275
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/common/SHA1.cs
  91. 353
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/common/SharedMemoryStream.cs
  92. 142
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/common/SocketStream.cs
  93. 264
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/common/StreamCreator.cs
  94. 100
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/common/Version.cs
  95. 309
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/dataadapter.cs
  96. 924
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/datareader.cs
  97. 934
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/docs/MySqlCommand.xml
  98. 321
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/docs/MySqlCommandBuilder.xml
  99. 1239
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/docs/MySqlConnection.xml
  100. 55
      ThirdParty/mysql-connector-net-6.2.3/MySql.Data/Provider/Source/docs/MySqlConnectionStringBuilder.xml
  101. Some files were not shown because too many files have changed in this diff Show More

@ -9,28 +9,48 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "Common\Common.csp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySQLConnector", "MySQLConnector\MySQLConnector.csproj", "{E38DE5B1-F9C2-43BA-A5DF-0743ABD4DFC7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Data", "ThirdParty\mysql-connector-net-6.2.3\MySql.Data\Provider\MySql.Data.csproj", "{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9A902732-E7F1-4F41-869B-316AF2254B36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9A902732-E7F1-4F41-869B-316AF2254B36}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9A902732-E7F1-4F41-869B-316AF2254B36}.Debug|x86.ActiveCfg = Debug|Any CPU
{9A902732-E7F1-4F41-869B-316AF2254B36}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9A902732-E7F1-4F41-869B-316AF2254B36}.Release|Any CPU.Build.0 = Release|Any CPU
{9A902732-E7F1-4F41-869B-316AF2254B36}.Release|x86.ActiveCfg = Release|Any CPU
{6F532626-E9F8-498E-9683-1538E7CD62CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6F532626-E9F8-498E-9683-1538E7CD62CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6F532626-E9F8-498E-9683-1538E7CD62CB}.Debug|x86.ActiveCfg = Debug|Any CPU
{6F532626-E9F8-498E-9683-1538E7CD62CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6F532626-E9F8-498E-9683-1538E7CD62CB}.Release|Any CPU.Build.0 = Release|Any CPU
{6F532626-E9F8-498E-9683-1538E7CD62CB}.Release|x86.ActiveCfg = Release|Any CPU
{CE888859-9E46-41F7-91CE-8EC106F3A625}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CE888859-9E46-41F7-91CE-8EC106F3A625}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CE888859-9E46-41F7-91CE-8EC106F3A625}.Debug|x86.ActiveCfg = Debug|Any CPU
{CE888859-9E46-41F7-91CE-8EC106F3A625}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CE888859-9E46-41F7-91CE-8EC106F3A625}.Release|Any CPU.Build.0 = Release|Any CPU
{CE888859-9E46-41F7-91CE-8EC106F3A625}.Release|x86.ActiveCfg = Release|Any CPU
{E38DE5B1-F9C2-43BA-A5DF-0743ABD4DFC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E38DE5B1-F9C2-43BA-A5DF-0743ABD4DFC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E38DE5B1-F9C2-43BA-A5DF-0743ABD4DFC7}.Debug|x86.ActiveCfg = Debug|Any CPU
{E38DE5B1-F9C2-43BA-A5DF-0743ABD4DFC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E38DE5B1-F9C2-43BA-A5DF-0743ABD4DFC7}.Release|Any CPU.Build.0 = Release|Any CPU
{E38DE5B1-F9C2-43BA-A5DF-0743ABD4DFC7}.Release|x86.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|x86.ActiveCfg = Debug|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|x86.Build.0 = Debug|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Any CPU.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|x86.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

@ -78,6 +78,10 @@
<Project>{E38DE5B1-F9C2-43BA-A5DF-0743ABD4DFC7}</Project>
<Name>MySQLConnector</Name>
</ProjectReference>
<ProjectReference Include="..\ThirdParty\mysql-connector-net-6.2.3\MySql.Data\Provider\MySql.Data.csproj">
<Project>{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}</Project>
<Name>MySql.Data</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

@ -31,7 +31,6 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="MySql.Data, Version=6.2.3.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL" />
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
@ -58,6 +57,10 @@
<Project>{6F532626-E9F8-498E-9683-1538E7CD62CB}</Project>
<Name>Core</Name>
</ProjectReference>
<ProjectReference Include="..\ThirdParty\mysql-connector-net-6.2.3\MySql.Data\Provider\MySql.Data.csproj">
<Project>{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}</Project>
<Name>MySql.Data</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

@ -0,0 +1,47 @@
Version 6.2.3
- fixed InvalidOperationException when accessing Stream.ReadTimeout or Stream.WriteTimeout on CF
(bug #50321)
- fixed entity framework function processing so that it handles stored functions properly
(bug #45277)
- fixed a bug with prepared statements and unsigned bigint. Patch also provided a nice speedup to reading
integer values from the wire (bug #49794)
- fixed problem where not specifying the data type of the return value of a function caused it to
mistakenly use Decimal as the return type (bug #49642)
- fixed bug where a scipt that had an empty last line would cause an InvalidOperationException (bug #50344)
- fixed bug in logging that kept no index and bad index warnings from being sent
- fixed bug where giving a connection string option like (option=) and then trying to read
the option back via the property would fail (bug #51209)
- fixed bug where a connection could not be reused in the IDE in some circumstances (bug #41629)
- small performance fix (bug #51149)
- fixed issue with script execution & multi-char delimiters (bug #46429)
- fixed bug in table editor where clicking back on the last row added can sometimes
cause a ArgumentOutOfRange exception
- fixed bug where a commands batchable command text was not getting reset when the
command text was reset (bug #50444)
- fixed bug where using a currently non-batchable command in a batch would throw an exception
(bug #50123)
- fixed bug where binary or blob columns would prevent columns after that from appearing in the
query builder (bug #50171)
- ScriptCompleted event handler now uses EventArgs.Empty instead of null
- fixed parsing bug that was caused by special characters being jammed up beside a quoted identifier (bug #51610)
- added feature where sql queries that are longer than 300 chars are normalized and a new
query normalized log line is issues right after query opened to give the query normalized text
- fixed bug in sql generation when using a negated binary fragment in EF (bug #49850)
- fixed bug in tokenization where a nonterminated string in sql will cause a CLR exception
rather than throwing a syntax exception (bug #51788)
- added two requested features -- MySqlDataReader.GetFieldType(string columnname) &
MySqlDataReader.GetOrdinal() includes the name of the column in the exception when not found
(bug #47467)
Version 6.2.2
- Fix race condition during TransactionScope rollback (bug#35330)
- When sending file to server (LOAD DATA INFILE) open the file for read only, not for read/write
(bug #48944)
- Fixed precision calculation on decimal and newdecimal columns (bug #48171)
- Fixed problem caused by us not including a 'REFERENCED_TABLE_CATALOG' column in our
foreign keys collection (bug #48974)
Version 6.2.1
- fixed SessionProvider to be compatible with 4.x MySQL, replaced TIMESTAMPDIFF with TIME_TO_SEC
(bug#47219)
- implemented support for client SSL certificates

@ -0,0 +1,343 @@
GNU General Public License
**************************
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

@ -0,0 +1,119 @@
MySQL FLOSS License Exception
The MySQL AB Exception for Free/Libre and Open Source
Software-only Applications Using MySQL Client Libraries (the
"FLOSS Exception").
Version 0.6, 7 March 2007
Exception Intent
We want specified Free/Libre and Open Source Software (``FLOSS'')
applications to be able to use specified GPL-licensed MySQL client
libraries (the ``Program'') despite the fact that not all FLOSS
licenses are compatible with version 2 of the GNU General Public
License (the ``GPL'').
Legal Terms and Conditions
As a special exception to the terms and conditions of version 2.0
of the GPL:
1. You are free to distribute a Derivative Work that is formed
entirely from the Program and one or more works (each, a
"FLOSS Work") licensed under one or more of the licenses
listed below in section 1, as long as:
a. You obey the GPL in all respects for the Program and the
Derivative Work, except for identifiable sections of the
Derivative Work which are not derived from the Program,
and which can reasonably be considered independent and
separate works in themselves,
b. all identifiable sections of the Derivative Work which
are not derived from the Program, and which can
reasonably be considered independent and separate works
in themselves,
i. are distributed subject to one of the FLOSS licenses
listed below, and
ii. the object code or executable form of those sections
are accompanied by the complete corresponding
machine-readable source code for those sections on
the same medium and under the same FLOSS license as
the corresponding object code or executable forms of
those sections, and
c. any works which are aggregated with the Program or with a
Derivative Work on a volume of a storage or distribution
medium in accordance with the GPL, can reasonably be
considered independent and separate works in themselves
which are not derivatives of either the Program, a
Derivative Work or a FLOSS Work.
If the above conditions are not met, then the Program may only
be copied, modified, distributed or used under the terms and
conditions of the GPL or another valid licensing option from
MySQL AB.
2. FLOSS License List
License name Version(s)/Copyright Date
Academic Free License 2.0
Apache Software License 1.0/1.1/2.0
Apple Public Source License 2.0
Artistic license From Perl 5.8.0
BSD license "July 22 1999"
Common Development and Distribution License (CDDL) 1.0
Common Public License 1.0
Eclipse Public License 1.0
GNU Library or "Lesser" General Public License (LGPL) 2.0/2.1
Jabber Open Source License 1.0
MIT license (As listed in file MIT-License.txt) ---
Mozilla Public License (MPL) 1.0/1.1
Open Software License 2.0
OpenSSL license (with original SSLeay license) "2003" ("1998")
PHP License 3.0
Python license (CNRI Python License) ---
Python Software Foundation License 2.1.1
Sleepycat License "1999"
University of Illinois/NCSA Open Source License ---
W3C License "2001"
X11 License "2001"
Zlib/libpng License ---
Zope Public License 2.0
Due to the many variants of some of the above licenses, we
require that any version follow the 2003 version of the Free
Software Foundation's Free Software Definition
(http://www.gnu.org/philosophy/free-sw.html) or version 1.9 of
the Open Source Definition by the Open Source Initiative
(http://www.opensource.org/docs/definition.php).
3. Definitions
a. Terms used, but not defined, herein shall have the
meaning provided in the GPL.
b. Derivative Work means a derivative work under copyright
law.
4. Applicability: This FLOSS Exception applies to all Programs
that contain a notice placed by MySQL AB saying that the
Program may be distributed under the terms of this FLOSS
Exception. If you create or distribute a work which is a
Derivative Work of both the Program and any other work
licensed under the GPL, then this FLOSS Exception is not
available for that work; thus, you must remove the FLOSS
Exception notice from that work and comply with the GPL in all
respects, including by retaining all GPL notices. You may
choose to redistribute a copy of the Program exclusively under
the terms of the GPL by removing the FLOSS Exception notice
from that copy of the Program, provided that the copy has
never been modified by you or any third party.
Appendix A. Qualified Libraries and Packages
The following is a non-exhaustive list of libraries and packages
which are covered by the FLOSS License Exception. Please note that
this appendix is provided merely as an additional service to
specific FLOSS projects wishing to simplify licensing information
for their users. Compliance with one of the licenses noted under
the "FLOSS license list" section remains a prerequisite.
Package Name Qualifying License and Version
Apache Portable Runtime (APR) Apache Software License 2.0

@ -0,0 +1,3 @@
This software product is not publicly available software.
This software product is MySQL commercial software and use of this
software is governed by your applicable license agreement with MySQL.

@ -0,0 +1,96 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Web", "MySql.Web\Providers\MySql.Web.csproj", "{C28B1166-1380-445D-AEC1-8A18B990DD18}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Web.Tests", "MySql.Web\Tests\MySql.Web.Tests.csproj", "{DC704374-EC50-4167-93AA-8D262136502E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Data", "MySql.Data\Provider\MySql.Data.csproj", "{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Data.CF", "MySql.Data\Provider\MySql.Data.CF.csproj", "{587A47FB-C1CC-459D-93B6-179D95E41EFB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Data.Tests", "MySql.Data\Tests\MySql.Data.Tests.csproj", "{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.VisualStudio", "MySql.VisualStudio\MySql.VisualStudio.csproj", "{DC3517FF-AC26-4755-9B7A-EF658FF69593}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|.NET 2.0 = Debug|.NET 2.0
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|.NET 2.0 = Release|.NET 2.0
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|.NET 2.0.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|x64.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|x86.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|.NET 2.0.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|Any CPU.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|x64.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|x86.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|.NET 2.0.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|x64.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|x86.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|.NET 2.0.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|Any CPU.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|x64.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|x86.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|.NET 2.0.ActiveCfg = Debug|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|x64.ActiveCfg = Debug|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|x86.ActiveCfg = Debug|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|x86.Build.0 = Debug|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|.NET 2.0.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Any CPU.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|x64.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|x86.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|x86.Build.0 = Release|x86
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Debug|.NET 2.0.ActiveCfg = Debug|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Debug|x64.ActiveCfg = Debug|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Debug|x86.ActiveCfg = Debug|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Release|.NET 2.0.ActiveCfg = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Release|Any CPU.Build.0 = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Release|x64.ActiveCfg = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Release|x86.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|.NET 2.0.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|x64.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|x86.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|.NET 2.0.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|Any CPU.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|x64.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|x86.ActiveCfg = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Debug|.NET 2.0.ActiveCfg = Debug|x64
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Debug|x64.ActiveCfg = Debug|x64
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Debug|x64.Build.0 = Debug|x64
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Debug|x86.ActiveCfg = Debug|x64
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Release|.NET 2.0.ActiveCfg = Release|x64
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Release|Any CPU.Build.0 = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Release|x64.ActiveCfg = Release|x64
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Release|x64.Build.0 = Release|x64
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Release|x86.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

@ -0,0 +1,136 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Web", "MySql.Web\Providers\MySql.Web.csproj", "{C28B1166-1380-445D-AEC1-8A18B990DD18}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Web.Tests", "MySql.Web\Tests\MySql.Web.Tests.csproj", "{DC704374-EC50-4167-93AA-8D262136502E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Data", "MySql.Data\Provider\MySql.Data.csproj", "{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Data.Tests", "MySql.Data\Tests\MySql.Data.Tests.csproj", "{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Commercial|Any CPU = Commercial|Any CPU
Commercial|Mixed Platforms = Commercial|Mixed Platforms
Commercial|x64 = Commercial|x64
Commercial|x86 = Commercial|x86
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
GPL|Any CPU = GPL|Any CPU
GPL|Mixed Platforms = GPL|Mixed Platforms
GPL|x64 = GPL|x64
GPL|x86 = GPL|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|Any CPU.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|x64.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|x86.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|x64.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|x86.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|Any CPU.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|x64.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|x86.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|Any CPU.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|x64.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|x86.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|Any CPU.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|x64.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|x86.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|x64.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|x86.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|Any CPU.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|x64.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|x86.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|Any CPU.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|x64.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|x86.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|Any CPU.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|x64.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|x86.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|x86.Build.0 = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|x64.ActiveCfg = Debug|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|x86.ActiveCfg = Debug|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|x86.Build.0 = Debug|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|Any CPU.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|x64.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|x86.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|x86.Build.0 = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Any CPU.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|x64.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|x86.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|x86.Build.0 = Release|x86
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|Any CPU.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|x64.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|x86.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|x64.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|x86.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|Any CPU.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|x64.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|x86.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|Any CPU.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|x64.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

@ -0,0 +1,166 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Web", "MySql.Web\Providers\MySql.Web.csproj", "{C28B1166-1380-445D-AEC1-8A18B990DD18}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Web.Tests", "MySql.Web\Tests\MySql.Web.Tests.csproj", "{DC704374-EC50-4167-93AA-8D262136502E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Data", "MySql.Data\Provider\MySql.Data.csproj", "{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Data.Tests", "MySql.Data\Tests\MySql.Data.Tests.csproj", "{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Commercial|Any CPU = Commercial|Any CPU
Commercial|Mixed Platforms = Commercial|Mixed Platforms
Commercial|x64 = Commercial|x64
Commercial|x86 = Commercial|x86
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
GPL|Any CPU = GPL|Any CPU
GPL|Mixed Platforms = GPL|Mixed Platforms
GPL|x64 = GPL|x64
GPL|x86 = GPL|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|Any CPU.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|x64.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|x86.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|x64.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|x86.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|Any CPU.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|x64.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|x86.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|Any CPU.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|x64.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|x86.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|Any CPU.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|x64.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|x86.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|x64.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|x86.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|Any CPU.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|x64.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|x86.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|Any CPU.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|x64.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|x86.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|Any CPU.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|x64.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|x86.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|x86.Build.0 = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|x64.ActiveCfg = Debug|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|x86.ActiveCfg = Debug|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|x86.Build.0 = Debug|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|Any CPU.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|x64.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|x86.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|x86.Build.0 = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Any CPU.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|x64.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|x86.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|x86.Build.0 = Release|x86
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|Any CPU.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|x64.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|x86.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|x64.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|x86.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|Any CPU.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|x64.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|x86.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|Any CPU.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|x64.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|x86.ActiveCfg = Release|Any CPU
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Commercial|Any CPU.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Commercial|Any CPU.Build.0 = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Commercial|Mixed Platforms.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Commercial|Mixed Platforms.Build.0 = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Commercial|x64.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Commercial|x86.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Commercial|x86.Build.0 = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Debug|Any CPU.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Debug|Mixed Platforms.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Debug|Mixed Platforms.Build.0 = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Debug|x64.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Debug|x86.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Debug|x86.Build.0 = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.GPL|Any CPU.ActiveCfg = GPL|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.GPL|Any CPU.Build.0 = GPL|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.GPL|Mixed Platforms.ActiveCfg = GPL|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.GPL|Mixed Platforms.Build.0 = GPL|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.GPL|x64.ActiveCfg = GPL|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.GPL|x86.ActiveCfg = GPL|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.GPL|x86.Build.0 = GPL|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Release|Any CPU.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Release|Mixed Platforms.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Release|Mixed Platforms.Build.0 = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Release|x64.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Release|x86.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Release|x86.Build.0 = Commercial|x86
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = MySql.Web\Providers\MySql.Web.csproj
version = 0.1
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

@ -0,0 +1,305 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Web", "MySql.Web\Providers\MySql.Web.csproj", "{C28B1166-1380-445D-AEC1-8A18B990DD18}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Web.Tests", "MySql.Web\Tests\MySql.Web.Tests.csproj", "{DC704374-EC50-4167-93AA-8D262136502E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Data", "MySql.Data\Provider\MySql.Data.csproj", "{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Data.CF", "MySql.Data\Provider\MySql.Data.CF.csproj", "{587A47FB-C1CC-459D-93B6-179D95E41EFB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Data.Tests", "MySql.Data\Tests\MySql.Data.Tests.csproj", "{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Data.CF.Tests", "MySql.Data\Tests\MySql.Data.CF.Tests.csproj", "{710D9251-17A3-4429-9A91-63F03267F310}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.VisualStudio", "MySql.VisualStudio\MySql.VisualStudio.csproj", "{DC3517FF-AC26-4755-9B7A-EF658FF69593}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Data.Entity", "MySql.Data.Entity\Provider\MySql.Data.Entity.csproj", "{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySql.Data.Entity.Tests", "MySql.Data.Entity\Tests\MySql.Data.Entity.Tests.csproj", "{77EC4E20-293A-48BA-8415-D0AD869D91FA}"
EndProject
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Installer", "Installer\Installer.wixproj", "{F533FC43-6C05-4A64-8AF6-72B690EB06C3}"
ProjectSection(ProjectDependencies) = postProject
{77EC4E20-293A-48BA-8415-D0AD869D91FA} = {77EC4E20-293A-48BA-8415-D0AD869D91FA}
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4} = {F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}
{710D9251-17A3-4429-9A91-63F03267F310} = {710D9251-17A3-4429-9A91-63F03267F310}
{C28B1166-1380-445D-AEC1-8A18B990DD18} = {C28B1166-1380-445D-AEC1-8A18B990DD18}
{DC704374-EC50-4167-93AA-8D262136502E} = {DC704374-EC50-4167-93AA-8D262136502E}
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5} = {A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D} = {E9DF5ED1-4CBD-4226-B931-9A51610AC14D}
{587A47FB-C1CC-459D-93B6-179D95E41EFB} = {587A47FB-C1CC-459D-93B6-179D95E41EFB}
{DC3517FF-AC26-4755-9B7A-EF658FF69593} = {DC3517FF-AC26-4755-9B7A-EF658FF69593}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Commercial|Any CPU = Commercial|Any CPU
Commercial|Mixed Platforms = Commercial|Mixed Platforms
Commercial|x64 = Commercial|x64
Commercial|x86 = Commercial|x86
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
GPL|Any CPU = GPL|Any CPU
GPL|Mixed Platforms = GPL|Mixed Platforms
GPL|x64 = GPL|x64
GPL|x86 = GPL|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|Any CPU.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|x64.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Commercial|x86.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|x64.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Debug|x86.ActiveCfg = Debug|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|Any CPU.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|x64.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.GPL|x86.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|Any CPU.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|x64.ActiveCfg = Release|Any CPU
{C28B1166-1380-445D-AEC1-8A18B990DD18}.Release|x86.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|Any CPU.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|x64.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Commercial|x86.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|x64.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Debug|x86.ActiveCfg = Debug|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|Any CPU.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|x64.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.GPL|x86.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|Any CPU.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|x64.ActiveCfg = Release|Any CPU
{DC704374-EC50-4167-93AA-8D262136502E}.Release|x86.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|Any CPU.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|x64.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|x86.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Commercial|x86.Build.0 = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|x64.ActiveCfg = Debug|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|x86.ActiveCfg = Debug|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Debug|x86.Build.0 = Debug|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|Any CPU.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|x64.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|x86.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.GPL|x86.Build.0 = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Any CPU.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|x64.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|x86.ActiveCfg = Release|x86
{E9DF5ED1-4CBD-4226-B931-9A51610AC14D}.Release|x86.Build.0 = Release|x86
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Commercial|Any CPU.Build.0 = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Commercial|x64.ActiveCfg = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Commercial|x86.ActiveCfg = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Debug|x64.ActiveCfg = Debug|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Debug|x86.ActiveCfg = Debug|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.GPL|Any CPU.Build.0 = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.GPL|x64.ActiveCfg = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.GPL|x86.ActiveCfg = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Release|Any CPU.Build.0 = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Release|x64.ActiveCfg = Release|Any CPU
{587A47FB-C1CC-459D-93B6-179D95E41EFB}.Release|x86.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|Any CPU.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|x64.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Commercial|x86.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|x64.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Debug|x86.ActiveCfg = Debug|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|Any CPU.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|x64.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.GPL|x86.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|Any CPU.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|x64.ActiveCfg = Release|Any CPU
{F29E5B3D-7F76-4CF9-BF5E-8E3A1377B1E4}.Release|x86.ActiveCfg = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Commercial|Any CPU.Build.0 = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Commercial|x64.ActiveCfg = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Commercial|x86.ActiveCfg = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Debug|Any CPU.Build.0 = Debug|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Debug|x64.ActiveCfg = Debug|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Debug|x86.ActiveCfg = Debug|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.GPL|Any CPU.Build.0 = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.GPL|x64.ActiveCfg = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.GPL|x86.ActiveCfg = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Release|Any CPU.ActiveCfg = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Release|Any CPU.Build.0 = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Release|x64.ActiveCfg = Release|Any CPU
{710D9251-17A3-4429-9A91-63F03267F310}.Release|x86.ActiveCfg = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Commercial|Any CPU.Build.0 = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Commercial|x64.ActiveCfg = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Commercial|x86.ActiveCfg = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Debug|x64.ActiveCfg = Debug|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Debug|x86.ActiveCfg = Debug|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.GPL|Any CPU.Build.0 = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.GPL|x64.ActiveCfg = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.GPL|x86.ActiveCfg = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Release|Any CPU.Build.0 = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Release|x64.ActiveCfg = Release|Any CPU
{DC3517FF-AC26-4755-9B7A-EF658FF69593}.Release|x86.ActiveCfg = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Commercial|Any CPU.Build.0 = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Commercial|x64.ActiveCfg = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Commercial|x86.ActiveCfg = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Debug|x64.ActiveCfg = Debug|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Debug|x86.ActiveCfg = Debug|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.GPL|Any CPU.Build.0 = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.GPL|x64.ActiveCfg = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.GPL|x86.ActiveCfg = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Release|Any CPU.Build.0 = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Release|x64.ActiveCfg = Release|Any CPU
{A8E799B1-D6AC-42BD-907E-B213D7E9B3C5}.Release|x86.ActiveCfg = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Commercial|Any CPU.ActiveCfg = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Commercial|Any CPU.Build.0 = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Commercial|Mixed Platforms.Build.0 = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Commercial|x64.ActiveCfg = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Commercial|x86.ActiveCfg = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Debug|x64.ActiveCfg = Debug|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Debug|x86.ActiveCfg = Debug|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.GPL|Any CPU.ActiveCfg = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.GPL|Any CPU.Build.0 = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.GPL|Mixed Platforms.ActiveCfg = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.GPL|Mixed Platforms.Build.0 = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.GPL|x64.ActiveCfg = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.GPL|x86.ActiveCfg = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Release|Any CPU.Build.0 = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Release|x64.ActiveCfg = Release|Any CPU
{77EC4E20-293A-48BA-8415-D0AD869D91FA}.Release|x86.ActiveCfg = Release|Any CPU
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Commercial|Any CPU.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Commercial|Any CPU.Build.0 = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Commercial|Mixed Platforms.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Commercial|Mixed Platforms.Build.0 = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Commercial|x64.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Commercial|x86.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Commercial|x86.Build.0 = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Debug|Any CPU.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Debug|Mixed Platforms.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Debug|Mixed Platforms.Build.0 = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Debug|x64.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Debug|x86.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Debug|x86.Build.0 = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.GPL|Any CPU.ActiveCfg = GPL|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.GPL|Any CPU.Build.0 = GPL|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.GPL|Mixed Platforms.ActiveCfg = GPL|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.GPL|Mixed Platforms.Build.0 = GPL|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.GPL|x64.ActiveCfg = GPL|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.GPL|x86.ActiveCfg = GPL|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.GPL|x86.Build.0 = GPL|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Release|Any CPU.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Release|Mixed Platforms.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Release|Mixed Platforms.Build.0 = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Release|x64.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Release|x86.ActiveCfg = Commercial|x86
{F533FC43-6C05-4A64-8AF6-72B690EB06C3}.Release|x86.Build.0 = Commercial|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

@ -0,0 +1,178 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{587A47FB-C1CC-459D-93B6-179D95E41EFB}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MySql.Data.CF</RootNamespace>
<AssemblyName>MySql.Data.CF</AssemblyName>
<ProjectTypeGuids>{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<PlatformFamilyName>WindowsCE</PlatformFamilyName>
<PlatformID>E2BECB1F-8C8C-41ba-B736-9BE7D946A398</PlatformID>
<OSVersion>5.00</OSVersion>
<DeployDirSuffix>MySql.Data.CF</DeployDirSuffix>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FormFactorID>
</FormFactorID>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<NativePlatformName>Windows CE</NativePlatformName>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;CF</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
<FileAlignment>512</FileAlignment>
<WarningLevel>4</WarningLevel>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<NoWarn>1699</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;CF</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
<FileAlignment>512</FileAlignment>
<WarningLevel>4</WarningLevel>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<NoWarn>1699</NoWarn>
</PropertyGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs" />
<Compile Include="Properties\VersionInfo.cs" />
<Compile Include="Source\base\DbConnectionStringBuilder.cs" />
<Compile Include="Source\base\DbException.cs" />
<Compile Include="Source\cf\BufferedStream.cs" />
<Compile Include="Source\cf\MissingAttributes.cs" />
<Compile Include="Source\cf\WinCE.cs" />
<Compile Include="Source\CharSetMap.cs" />
<Compile Include="Source\command.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Source\CommandBuilder.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Source\common\Cache.cs" />
<Compile Include="Source\common\ContextString.cs" />
<Compile Include="Source\common\LowResolutionStopwatch.cs" />
<Compile Include="Source\common\MyNetworkStream.cs" />
<Compile Include="Source\common\MySqlTokenizer.cs" />
<Compile Include="Source\common\NativeMethods.cs" />
<Compile Include="Source\common\Platform.cs" />
<Compile Include="Source\common\SHA1.cs" />
<Compile Include="Source\common\StreamCreator.cs" />
<Compile Include="Source\common\Version.cs" />
<Compile Include="Source\CompressedStream.cs" />
<Compile Include="Source\Connection.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Source\Crypt.cs" />
<Compile Include="Source\dataadapter.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Source\datareader.cs" />
<Compile Include="Source\Driver.cs" />
<Compile Include="Source\Exception.cs" />
<Compile Include="Source\Field.cs" />
<Compile Include="Source\ISSchemaProvider.cs" />
<Compile Include="Source\MySqlConnectionStringBuilder.cs" />
<Compile Include="Source\MysqlDefs.cs" />
<Compile Include="Source\MySqlError.cs" />
<Compile Include="Source\MySqlHelper.cs" />
<Compile Include="Source\MySqlPacket.cs" />
<Compile Include="Source\MySqlPool.cs" />
<Compile Include="Source\MySqlPoolManager.cs" />
<Compile Include="Source\MySqlScript.cs" />
<Compile Include="Source\MySqlStream.cs" />
<Compile Include="Source\MySqlTrace.cs" />
<Compile Include="Source\NativeDriver.cs" />
<Compile Include="Source\parameter.cs" />
<Compile Include="Source\parameter_collection.cs" />
<Compile Include="Source\PreparableStatement.cs" />
<Compile Include="Source\ProcedureCache.cs" />
<Compile Include="Source\ResultSet.cs" />
<Compile Include="Source\SchemaProvider.cs" />
<Compile Include="Source\Statement.cs" />
<Compile Include="Source\StoredProcedure.cs" />
<Compile Include="Source\TimedStream.cs" />
<Compile Include="Source\transaction.cs" />
<Compile Include="Source\Types\MetaData.cs" />
<Compile Include="Source\Types\MySqlBinary.cs" />
<Compile Include="Source\Types\MySqlBit.cs" />
<Compile Include="Source\Types\MySqlByte.cs" />
<Compile Include="Source\Types\MySqlConversionException.cs" />
<Compile Include="Source\Types\MySqlDateTime.cs" />
<Compile Include="Source\Types\MySqlDecimal.cs" />
<Compile Include="Source\Types\MySqlDouble.cs" />
<Compile Include="Source\Types\MySqlGuid.cs" />
<Compile Include="Source\Types\MySqlInt16.cs" />
<Compile Include="Source\Types\MySqlInt32.cs" />
<Compile Include="Source\Types\MySqlInt64.cs" />
<Compile Include="Source\Types\MySqlSingle.cs" />
<Compile Include="Source\Types\MySqlString.cs" />
<Compile Include="Source\Types\MySqlTime.cs" />
<Compile Include="Source\Types\MySqlUByte.cs" />
<Compile Include="Source\Types\MySqlUInt16.cs" />
<Compile Include="Source\Types\MySqlUInt32.cs" />
<Compile Include="Source\Types\MySqlUInt64.cs" />
<Compile Include="Source\Types\MySqlValue.cs" />
<Compile Include="Source\zlib\Adler32.cs" />
<Compile Include="Source\zlib\Deflate.cs" />
<Compile Include="Source\zlib\InfBlocks.cs" />
<Compile Include="Source\zlib\InfCodes.cs" />
<Compile Include="Source\zlib\Inflate.cs" />
<Compile Include="Source\zlib\InfTree.cs" />
<Compile Include="Source\zlib\StaticTree.cs" />
<Compile Include="Source\zlib\SupportClass.cs" />
<Compile Include="Source\zlib\Tree.cs" />
<Compile Include="Source\zlib\ZInputStream.cs" />
<Compile Include="Source\zlib\Zlib.cs" />
<Compile Include="Source\zlib\ZOutputStream.cs" />
<Compile Include="Source\zlib\ZStream.cs" />
<Compile Include="Source\zlib\ZStreamException.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx">
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<Import Condition="'$(TargetFrameworkVersion)' == 'v1.0'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.v1.targets" />
<Import Condition="'$(TargetFrameworkVersion)' == 'v2.0'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}">
<HostingProcess disable="1" />
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<Import Condition="'$(TargetFrameworkVersion)' == 'v3.5'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
<Import Condition="'$(TargetFrameworkVersion)' == 'v3.5'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
</Project>

@ -0,0 +1,315 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProductVersion>9.0.30729</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>false</SignAssembly>
<OldToolsVersion>3.5</OldToolsVersion>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>bin\Debug\</OutputPath>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>TRACE;DEBUG;WINDOWS</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DocumentationFile>MySql.Data.xml</DocumentationFile>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>1591</NoWarn>
<Optimize>false</Optimize>
<RegisterForComInterop>false</RegisterForComInterop>
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<RunCodeAnalysis>false</RunCodeAnalysis>
<CodeAnalysisRules>
</CodeAnalysisRules>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>bin\Release\</OutputPath>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>TRACE;DEBUG;WINDOWS</DefineConstants>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DocumentationFile>MySql.Data.xml</DocumentationFile>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>1591</NoWarn>
<RegisterForComInterop>false</RegisterForComInterop>
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;WINDOWS NET20</DefineConstants>
<BaseAddress>285212672</BaseAddress>
<DocumentationFile>doc.xml</DocumentationFile>
<PlatformTarget>x86</PlatformTarget>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>TRACE;DEBUG;WINDOWS NET20</DefineConstants>
<OutputPath>bin\x86\Release\</OutputPath>
<BaseAddress>285212672</BaseAddress>
<DocumentationFile>doc.xml</DocumentationFile>
<PlatformTarget>x86</PlatformTarget>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System">
<Name>System</Name>
</Reference>
<Reference Include="System.Configuration.Install" />
<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.Transactions" />
<Reference Include="System.Xml">
<Name>System.XML</Name>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Source\CharSetMap.cs" />
<Compile Include="Source\command.cs">
</Compile>
<Compile Include="Source\CommandBuilder.cs">
</Compile>
<Compile Include="Source\common\ContextString.cs" />
<Compile Include="Source\common\NamedPipeStream.cs" />
<Compile Include="Source\common\NativeMethods.cs" />
<Compile Include="Source\common\Platform.cs" />
<Compile Include="Source\common\SHA1.cs" />
<Compile Include="Source\common\SharedMemoryStream.cs" />
<Compile Include="Source\common\StreamCreator.cs" />
<Compile Include="Source\common\Version.cs" />
<Compile Include="Source\CompressedStream.cs" />
<Compile Include="Source\Connection.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Source\Crypt.cs" />
<Compile Include="Source\dataadapter.cs">
</Compile>
<Compile Include="Source\datareader.cs" />
<Compile Include="Source\Driver.cs" />
<Compile Include="Source\Exception.cs" />
<Compile Include="Source\Field.cs" />
<Compile Include="Source\Installer.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Source\ISSchemaProvider.cs" />
<Compile Include="Source\MySqlClientFactory.cs" />
<Compile Include="Source\MySqlConnectionStringBuilder.cs" />
<Compile Include="Source\MysqlDefs.cs" />
<Compile Include="Source\MySqlError.cs" />
<Compile Include="Source\MySqlHelper.cs" />
<Compile Include="Source\MySqlPool.cs" />
<Compile Include="Source\MySqlPoolManager.cs" />
<Compile Include="Source\MySqlPromotableTransaction.cs" />
<Compile Include="Source\MySqlStream.cs" />
<Compile Include="Source\NativeDriver.cs" />
<Compile Include="Source\parameter.cs" />
<Compile Include="Source\parameter_collection.cs" />
<Compile Include="Source\PerformanceMonitor.cs" />
<Compile Include="Source\PreparableStatement.cs" />
<Compile Include="Source\ProcedureCache.cs" />
<Compile Include="Source\SchemaProvider.cs" />
<Compile Include="Source\Statement.cs" />
<Compile Include="Source\StoredProcedure.cs" />
<Compile Include="Source\transaction.cs" />
<Compile Include="Source\Types\MetaData.cs" />
<Compile Include="Source\Types\MySqlBinary.cs" />
<Compile Include="Source\Types\MySqlBit.cs" />
<Compile Include="Source\Types\MySqlByte.cs" />
<Compile Include="Source\Types\MySqlConversionException.cs" />
<Compile Include="Source\Types\MySqlDateTime.cs" />
<Compile Include="Source\Types\MySqlDecimal.cs" />
<Compile Include="Source\Types\MySqlDouble.cs" />
<Compile Include="Source\Types\MySqlInt16.cs" />
<Compile Include="Source\Types\MySqlInt32.cs" />
<Compile Include="Source\Types\MySqlInt64.cs" />
<Compile Include="Source\Types\MySqlSingle.cs" />
<Compile Include="Source\Types\MySqlString.cs" />
<Compile Include="Source\Types\MySqlTime.cs" />
<Compile Include="Source\Types\MySqlUByte.cs" />
<Compile Include="Source\Types\MySqlUInt16.cs" />
<Compile Include="Source\Types\MySqlUInt32.cs" />
<Compile Include="Source\Types\MySqlUInt64.cs" />
<Compile Include="Source\Types\MySqlValue.cs" />
<Compile Include="Source\zlib\Adler32.cs" />
<Compile Include="Source\zlib\Deflate.cs" />
<Compile Include="Source\zlib\InfBlocks.cs" />
<Compile Include="Source\zlib\InfCodes.cs" />
<Compile Include="Source\zlib\Inflate.cs" />
<Compile Include="Source\zlib\InfTree.cs" />
<Compile Include="Source\zlib\StaticTree.cs" />
<Compile Include="Source\zlib\SupportClass.cs" />
<Compile Include="Source\zlib\Tree.cs" />
<Compile Include="Source\zlib\ZInputStream.cs" />
<Compile Include="Source\zlib\Zlib.cs" />
<Compile Include="Source\zlib\ZOutputStream.cs" />
<Compile Include="Source\zlib\ZStream.cs" />
<Compile Include="Source\zlib\ZStreamException.cs" />
<Compile Include="Properties\VersionInfo.cs" />
<Compile Include="Source\common\Cache.cs" />
<Compile Include="Source\common\MySqlTokenizer.cs" />
<Compile Include="Source\common\MyNetworkStream.cs" />
<Compile Include="Source\BulkLoader.cs" />
<Compile Include="Source\MySqlPacket.cs" />
<Compile Include="Source\MySqlScript.cs" />
<Compile Include="Source\Types\MySqlGuid.cs" />
<Compile Include="Source\ResultSet.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Properties\ReservedWords.txt" />
<EmbeddedResource Include="Properties\Resources.resx">
<SubType>Designer</SubType>
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="Properties\keywords.txt" />
<Content Include="Source\docs\MySqlCommand.xml" />
<Content Include="Source\docs\MySqlCommandBuilder.xml" />
<Content Include="Source\docs\MySqlConnection.xml" />
<Content Include="Source\docs\MySqlConnectionStringBuilder.xml" />
<Content Include="Source\docs\MySqlDataAdapter.xml" />
<Content Include="Source\docs\MySqlDataReader.xml" />
<Content Include="Source\docs\MySqlException.xml" />
<Content Include="Source\docs\MySqlHelper.xml" />
<Content Include="Source\docs\MySqlParameter.xml" />
<Content Include="Source\docs\MySqlParameterCollection.xml" />
<Content Include="Source\docs\MySqlTransaction.xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Source\common\LowResolutionStopwatch.cs" />
<Compile Include="Source\common\QueryNormalizer.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Source\MySqlTrace.cs" />
<Compile Include="Source\TimedStream.cs" />
<Compile Include="Source\TracingDriver.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\CHANGES">
<Link>CHANGES</Link>
</None>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
<Visible>False</Visible>
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.VisualBasic.PowerPacks.10.0">
<Visible>False</Visible>
<ProductName>Microsoft Visual Basic PowerPacks 10.0</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,75 @@
// Copyright (c) 2004-2007 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.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Security;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyDescription("ADO.Net driver for MySQL")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("MySQL AB")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("Copyright 2004-2007, MySQL AB")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: CLSCompliant(false)]
#if !CF
[assembly: AssemblyTitle("MySql.Data.dll")]
[assembly: AllowPartiallyTrustedCallers()]
#else
[assembly: AssemblyTitle("MySql.Data.CF.dll")]
#endif
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyName("ConnectorNet")]

@ -0,0 +1,76 @@
ACCESSIBLE ADD ALL
ALTER ANALYZE AND
AS ASC ASENSITIVE
BEFORE BETWEEN BIGINT
BINARY BLOB BOTH
BY CALL CASCADE
CASE CHANGE CHAR
CHARACTER CHECK COLLATE
COLUMN CONDITION CONNECTION
CONSTRAINT CONTINUE CONTRIBUTORS
CONVERT CREATE CROSS
CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP
CURRENT_USER CURSOR DATABASE
DATABASES DAY_HOUR DAY_MICROSECOND
DAY_MINUTE DAY_SECOND DEC
DECIMAL DECLARE DEFAULT
DELAYED DELETE DESC
DESCRIBE DETERMINISTIC DISTINCT
DISTINCTROW DIV DOUBLE
DROP DUAL EACH
ELSE ELSEIF ENCLOSED
ESCAPED EXISTS EXIT
EXPLAIN FALSE FETCH
FLOAT FLOAT4 FLOAT8
FOR FORCE FOREIGN
FROM FULLTEXT GRANT
GROUP HAVING HIGH_PRIORITY
HOUR_MICROSECOND HOUR_MINUTE HOUR_SECOND
IF IGNORE IN
INDEX INFILE INNER
INOUT INSENSITIVE INSERT
INT INT1 INT2
INT3 INT4 INT8
INTEGER INTERVAL INTO
IS ITERATE JOIN
KEY KEYS KILL
LEADING LEAVE LEFT
LIKE LIMIT LINEAR
LINES LOAD LOCALTIME
LOCALTIMESTAMP LOCK LONG
LONGBLOB LONGTEXT LOOP
LOW_PRIORITY MATCH MEDIUMBLOB
MEDIUMINT MEDIUMTEXT MIDDLEINT
MINUTE_MICROSECOND MINUTE_SECOND MOD
MODIFIES NATURAL NOT
NO_WRITE_TO_BINLOG NULL NUMERIC
ON OPTIMIZE OPTION
OPTIONALLY OR ORDER
OUT OUTER OUTFILE
PRECISION PRIMARY PROCEDURE
PURGE RANGE READ
READS READ_ONLY READ_WRITE
REAL REFERENCES REGEXP
RELEASE RENAME REPEAT
REPLACE REQUIRE RESTRICT
RETURN REVOKE RIGHT
RLIKE SCHEMA SCHEMAS
SECOND_MICROSECOND SELECT SENSITIVE
SEPARATOR SET SHOW
SMALLINT SPATIAL SPECIFIC
SQL SQLEXCEPTION SQLSTATE
SQLWARNING SQL_BIG_RESULT SQL_CALC_FOUND_ROWS
SQL_SMALL_RESULT SSL STARTING
STRAIGHT_JOIN TABLE TERMINATED
THEN TINYBLOB TINYINT
TINYTEXT TO TRAILING
TRIGGER TRUE UNDO
UNION UNIQUE UNLOCK
UNSIGNED UPDATE UPGRADE
USAGE USE USING
UTC_DATE UTC_TIME UTC_TIMESTAMP
VALUES VARBINARY VARCHAR
VARCHARACTER VARYING WHEN
WHERE WHILE WITH
WRITE X509 XOR
YEAR_MONTH ZEROFILL

File diff suppressed because it is too large Load Diff

@ -0,0 +1,460 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="BadVersionFormat" xml:space="preserve">
<value>Version string not in acceptable format</value>
</data>
<data name="NamedPipeNoSeek" xml:space="preserve">
<value>NamedPipeStream does not support seeking</value>
</data>
<data name="StreamAlreadyClosed" xml:space="preserve">
<value>The stream has already been closed</value>
</data>
<data name="BufferCannotBeNull" xml:space="preserve">
<value> The buffer cannot be null</value>
</data>
<data name="BufferNotLargeEnough" xml:space="preserve">
<value> Buffer is not large enough</value>
</data>
<data name="OffsetCannotBeNegative" xml:space="preserve">
<value> Offset cannot be negative</value>
</data>
<data name="CountCannotBeNegative" xml:space="preserve">
<value> Count cannot be negative</value>
</data>
<data name="StreamNoRead" xml:space="preserve">
<value> The stream does not support reading</value>
</data>
<data name="NamedPipeNoSetLength" xml:space="preserve">
<value>NamedPipeStream doesn't support SetLength</value>
</data>
<data name="StreamNoWrite" xml:space="preserve">
<value>The stream does not support writing</value>
</data>
<data name="ErrorCreatingSocket" xml:space="preserve">
<value>Error creating socket connection</value>
</data>
<data name="SocketNoSeek" xml:space="preserve">
<value>Socket streams do not support seeking</value>
</data>
<data name="UnixSocketsNotSupported" xml:space="preserve">
<value>Unix sockets are not supported on Windows</value>
</data>
<data name="OffsetMustBeValid" xml:space="preserve">
<value>Offset must be a valid position in buffer</value>
</data>
<data name="CSNoSetLength" xml:space="preserve">
<value>SetLength is not a valid operation on CompressedStream</value>
</data>
<data name="FromIndexMustBeValid" xml:space="preserve">
<value>From index must be a valid index inside the from buffer</value>
</data>
<data name="FromAndLengthTooBig" xml:space="preserve">
<value>From index and length use more bytes than from contains</value>
</data>
<data name="IndexMustBeValid" xml:space="preserve">
<value>Index must be a valid position in the buffer</value>
</data>
<data name="IndexAndLengthTooBig" xml:space="preserve">
<value>Index and length use more bytes than to has room for</value>
</data>
<data name="PasswordMustHaveLegalChars" xml:space="preserve">
<value>Password must be valid and contain length characters</value>
</data>
<data name="ParameterCannotBeNegative" xml:space="preserve">
<value>Parameter cannot have a negative value</value>
</data>
<data name="ConnectionMustBeOpen" xml:space="preserve">
<value>Connection must be valid and open</value>
</data>
<data name="DataReaderOpen" xml:space="preserve">
<value>There is already an open DataReader associated with this Connection which must be closed first.</value>
</data>
<data name="SPNotSupported" xml:space="preserve">
<value>Stored procedures are not supported on this version of MySQL</value>
</data>
<data name="ConnectionNotSet" xml:space="preserve">
<value>The connection property has not been set or is null.</value>
</data>
<data name="ConnectionNotOpen" xml:space="preserve">
<value>The connection is not open.</value>
</data>
<data name="AdapterIsNull" xml:space="preserve">
<value>Improper MySqlCommandBuilder state: adapter is null</value>
</data>
<data name="AdapterSelectIsNull" xml:space="preserve">
<value>Improper MySqlCommandBuilder state: adapter's SelectCommand is null</value>
</data>
<data name="CBMultiTableNotSupported" xml:space="preserve">
<value>MySqlCommandBuilder does not support multi-table statements</value>
</data>
<data name="CBNoKeyColumn" xml:space="preserve">
<value>MySqlCommandBuilder cannot operate on tables with no unique or key columns</value>
</data>
<data name="ParameterCannotBeNull" xml:space="preserve">
<value>Parameter cannot be null</value>
</data>
<data name="ChaosNotSupported" xml:space="preserve">
<value>Chaos isolation level is not supported</value>
</data>
<data name="ParameterIsInvalid" xml:space="preserve">
<value>Parameter is invalid.</value>
</data>
<data name="ConnectionAlreadyOpen" xml:space="preserve">
<value>The connection is already open.</value>
</data>
<data name="KeywordNotSupported" xml:space="preserve">
<value>Keyword not supported.</value>
</data>
<data name="WriteToStreamFailed" xml:space="preserve">
<value>Writing to the stream failed.</value>
</data>
<data name="ReadFromStreamFailed" xml:space="preserve">
<value>Reading from the stream has failed.</value>
</data>
<data name="QueryTooLarge" xml:space="preserve">
<value>Packets larger than max_allowed_packet are not allowed.</value>
</data>
<data name="UnableToExecuteSP" xml:space="preserve">
<value>Unable to execute stored procedure '{0}'.</value>
</data>
<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>
<data name="ConnectionBroken" xml:space="preserve">
<value>Connection unexpectedly terminated.</value>
</data>
<data name="IncorrectTransmission" xml:space="preserve">
<value>An incorrect response was received from the server.</value>
</data>
<data name="CancelNotSupported" xml:space="preserve">
<value>Canceling an active query is only supported on MySQL 5.0.0 and above. </value>
</data>
<data name="Timeout" xml:space="preserve">
<value>Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.</value>
</data>
<data name="CancelNeeds50" xml:space="preserve">
<value>Canceling an executing query requires MySQL 5.0 or higher.</value>
</data>
<data name="NoNestedTransactions" xml:space="preserve">
<value>Nested transactions are not supported.</value>
</data>
<data name="CommandTextNotInitialized" xml:space="preserve">
<value>The CommandText property has not been properly initialized.</value>
</data>
<data name="UnableToParseFK" xml:space="preserve">
<value>There was an error parsing the foreign key definition.</value>
</data>
<data name="PerfMonCategoryHelp" xml:space="preserve">
<value>This category includes a series of counters for MySQL.</value>
</data>
<data name="PerfMonCategoryName" xml:space="preserve">
<value>.NET Data Provider for MySQL</value>
</data>
<data name="PerfMonHardProcHelp" xml:space="preserve">
<value>The number of times a procedures metadata had to be queried from the server.</value>
</data>
<data name="PerfMonHardProcName" xml:space="preserve">
<value>Hard Procedure Queries</value>
</data>
<data name="PerfMonSoftProcHelp" xml:space="preserve">
<value>The number of times a procedures metadata was retrieved from the client-side cache.</value>
</data>
<data name="PerfMonSoftProcName" xml:space="preserve">
<value>Soft Procedure Queries</value>
</data>
<data name="WrongParameterName" xml:space="preserve">
<value>Parameter '{0}' is not found but a parameter with the name '{1}' is found. Parameter names must include the leading parameter marker.</value>
</data>
<data name="UnableToConnectToHost" xml:space="preserve">
<value>Unable to connect to any of the specified MySQL hosts.</value>
</data>
<data name="UnableToRetrieveSProcData" xml:space="preserve">
<value>Unable to retrieve stored procedure metadata for routine '{0}'. Either grant SELECT privilege to mysql.proc for this user or use "use procedure bodies=false" with your connection string.</value>
</data>
<data name="NextResultIsClosed" xml:space="preserve">
<value>Invalid attempt to call NextResult when the reader is closed.</value>
</data>
<data name="NoBodiesAndTypeNotSet" xml:space="preserve">
<value>When calling stored procedures and 'Use Procedure Bodies' is false, all parameters must have their type explicitly set.</value>
</data>
<data name="TimeoutGettingConnection" xml:space="preserve">
<value>error connecting: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.</value>
</data>
<data name="ParameterAlreadyDefined" xml:space="preserve">
<value>Parameter '{0}' has already been defined.</value>
</data>
<data name="ParameterMustBeDefined" xml:space="preserve">
<value>Parameter '{0}' must be defined.</value>
</data>
<data name="ObjectDisposed" xml:space="preserve">
<value>The object is not open or has been disposed.</value>
</data>
<data name="MultipleConnectionsInTransactionNotSupported" xml:space="preserve">
<value>Multiple simultaneous connections or connections with different connection strings inside the same transaction are not currently supported.</value>
</data>
<data name="DistributedTxnNotSupported" xml:space="preserve">
<value>MySQL Connector/Net does not currently support distributed transactions.</value>
</data>
<data name="FatalErrorDuringExecute" xml:space="preserve">
<value>Fatal error encountered during command execution.</value>
</data>
<data name="FatalErrorDuringRead" xml:space="preserve">
<value>Fatal error encountered during data read.</value>
</data>
<data name="FatalErrorReadingResult" xml:space="preserve">
<value>Fatal error encountered attempting to read the resultset.</value>
</data>
<data name="RoutineNotFound" xml:space="preserve">
<value>Routine '{0}' cannot be found. Either check the spelling or make sure you have sufficient rights to execute the routine.</value>
</data>
<data name="ParameterNotFoundDuringPrepare" xml:space="preserve">
<value>Parameter '{0}' was not found during prepare.</value>
</data>
<data name="ValueNotSupportedForGuid" xml:space="preserve">
<value>The requested column value could not be treated as or conveted to a Guid.</value>
</data>
<data name="UnableToDeriveParameters" xml:space="preserve">
<value>Unable to derive stored routine parameters. The 'Parameters' information schema table is not available and access to the stored procedure body has been disabled.</value>
</data>
<data name="UnableToRetrieveParameters" xml:space="preserve">
<value>Unable to retrieve stored routine parameters. Either grant access to the routine or add the 'Use Procedure Bodies=false' option to your connection string.</value>
</data>
<data name="DefaultEncodingNotFound" xml:space="preserve">
<value>The default connection encoding was not found. Please report this as a bug along with your connection string and system details.</value>
</data>
<data name="GetHostEntryFailed" xml:space="preserve">
<value>Call to GetHostEntry failed after {0} while querying for hostname '{1}': SocketErrorCode={2}, ErrorCode={3}, NativeErrorCode={4}.</value>
</data>
<data name="UnableToEnumerateUDF" xml:space="preserve">
<value>An error occured attempting to enumerate the user-defined functions. Do you have SELECT privileges on the mysql.func table?</value>
</data>
<data name="DataNotInSupportedFormat" xml:space="preserve">
<value>The given value was not in a supported format.</value>
</data>
<data name="NoServerSSLSupport" xml:space="preserve">
<value>The host {0} does not support SSL connections.</value>
</data>
<data name="CouldNotFindColumnName" xml:space="preserve">
<value>Could not find specified column in results: {0}</value>
</data>
<data name="InvalidColumnOrdinal" xml:space="preserve">
<value>You have specified an invalid column ordinal.</value>
</data>
<data name="ReadingPriorColumnUsingSeqAccess" xml:space="preserve">
<value>Invalid attempt to read a prior column using SequentialAccess</value>
</data>
<data name="AttemptToAccessBeforeRead" xml:space="preserve">
<value>Invalid attempt to access a field before calling Read()</value>
</data>
<data name="UnableToStartSecondAsyncOp" xml:space="preserve">
<value>Unable to start a second async operation while one is running.</value>
</data>
<data name="MoreThanOneOPRow" xml:space="preserve">
<value>INTERNAL ERROR: More than one output parameter row detected.</value>
</data>
<data name="InvalidValueForBoolean" xml:space="preserve">
<value>'{0}' is an illegal value for a boolean option.</value>
</data>
<data name="ServerTooOld" xml:space="preserve">
<value>Connector/Net no longer supports server versions prior to 4.1</value>
</data>
<data name="InvalidConnectionStringValue" xml:space="preserve">
<value>The requested value '{0}' is invalid for the given keyword '{1}'.</value>
</data>
<data name="TraceCloseConnection" xml:space="preserve">
<value>{0}: Connection Closed</value>
</data>
<data name="TraceOpenConnection" xml:space="preserve">
<value>{0}: Connection Opened: connection string = '{1}'</value>
</data>
<data name="TraceQueryOpened" xml:space="preserve">
<value>{0}: Query Opened: {2}</value>
</data>
<data name="TraceResult" xml:space="preserve">
<value>{0}: Resultset Opened: field(s) = {1}, affected rows = {2}, inserted id = {3}</value>
</data>
<data name="TraceQueryDone" xml:space="preserve">
<value>{0}: Query Closed</value>
</data>
<data name="TraceSetDatabase" xml:space="preserve">
<value>{0}: Set Database: {1}</value>
</data>
<data name="TraceUAWarningBadIndex" xml:space="preserve">
<value>{0}: Usage Advisor Warning: Query is using a bad index</value>
</data>
<data name="TraceUAWarningNoIndex" xml:space="preserve">
<value>{0}: Usage Advisor Warning: Query does not use an index</value>
</data>
<data name="TraceResultClosed" xml:space="preserve">
<value>{0}: Resultset Closed. Total rows={1}, skipped rows={2}, size (bytes)={3}</value>
</data>
<data name="TraceUAWarningSkippedRows" xml:space="preserve">
<value>{0}: Usage Advisor Warning: Skipped {2} rows. Consider a more focused query.</value>
</data>
<data name="TraceUAWarningSkippedColumns" xml:space="preserve">
<value>{0}: Usage Advisor Warning: The following columns were not accessed: {2}</value>
</data>
<data name="TraceUAWarningFieldConversion" xml:space="preserve">
<value>{0}: Usage Advisor Warning: The field '{2}' was converted to the following types: {3}</value>
</data>
<data name="TraceOpenResultError" xml:space="preserve">
<value>{0}: Error encountered attempting to open result: Number={1}, Message={2}</value>
</data>
<data name="TraceFetchError" xml:space="preserve">
<value>{0}: Error encountered during row fetch. Number = {1}, Message={2}</value>
</data>
<data name="TraceWarning" xml:space="preserve">
<value>{0}: MySql Warning: Level={1}, Code={2}, Message={3}</value>
</data>
<data name="TraceErrorMoreThanMaxValueConnections" xml:space="preserve">
<value>Unable to trace. There are more than Int32.MaxValue connections in use.</value>
</data>
<data name="TraceStatementPrepared" xml:space="preserve">
<value>{0}: Statement prepared: sql='{1}', statement id={2}</value>
</data>
<data name="TraceStatementClosed" xml:space="preserve">
<value>{0}: Statement closed: statement id = {1}</value>
</data>
<data name="TraceStatementExecuted" xml:space="preserve">
<value>{0}: Statement executed: statement id = {1}</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="keywords" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>keywords.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="TraceQueryNormalized" xml:space="preserve">
<value>{0}: Query Normalized: {2}</value>
</data>
</root>

@ -0,0 +1,39 @@
// Copyright (C) 2004-2007 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.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Security;
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("6.2.3")]

@ -0,0 +1,229 @@
ACCESSIBLE
ADD
ALL
ALTER
ANALYZE
AND
AS
ASC
ASENSITIVE
BEFORE
BETWEEN
BIGINT
BINARY
BLOB
BOTH
BY
CALL
CASCADE
CASE
CHANGE
CHAR
CHARACTER
CHECK
COLLATE
COLUMN
CONDITION
CONNECTION
CONSTRAINT
CONTINUE
CONVERT
CREATE
CROSS
CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_USER
CURSOR
DATABASE
DATABASES
DAY_HOUR
DAY_MICROSECOND
DAY_MINUTE
DAY_SECOND
DEC
DECIMAL
DECLARE
DEFAULT
DELAYED
DELETE
DESC
DESCRIBE
DETERMINISTIC
DISTINCT
DISTINCTROW
DIV
DOUBLE
DROP
DUAL
EACH
ELSE
ELSEIF
ENCLOSED
ESCAPED
EXISTS
EXIT
EXPLAIN
FALSE
FETCH
FLOAT
FLOAT4
FLOAT8
FOR
FORCE
FOREIGN
FROM
FULLTEXT
GOTO
GRANT
GROUP
HAVING
HIGH_PRIORITY
HOUR_MICROSECOND
HOUR_MINUTE
HOUR_SECOND
IF
IGNORE
IN
INDEX
INFILE
INNER
INOUT
INSENSITIVE
INSERT
INT
INT1
INT2
INT3
INT4
INT8
INTEGER
INTERVAL
INTO
IS
ITERATE
JOIN
KEY
KEYS
KILL
LABEL
LEADING
LEAVE
LEFT
LIKE
LIMIT
LINEAR
LINES
LOAD
LOCALTIME
LOCALTIMESTAMP
LOCK
LONG
LONGBLOB
LONGTEXT
LOOP
LOW_PRIORITY
MASTER_SSL_VERIFY_SERVER_CERT
MATCH
MEDIUMBLOB
MEDIUMINT
MEDIUMTEXT
MIDDLEINT
MINUTE_MICROSECOND
MINUTE_SECOND
MOD
MODIFIES
NATURAL
NOT
NO_WRITE_TO_BINLOG
NULL
NUMERIC
ON
OPTIMIZE
OPTION
OPTIONALLY
OR
ORDER
OUT
OUTER
OUTFILE
PRECISION
PRIMARY
PROCEDURE
PURGE
RANGE
READ
READS
READ_ONLY
READ_WRITE
REAL
REFERENCES
REGEXP
RELEASE
RENAME
REPEAT
REPLACE
REQUIRE
RESTRICT
RETURN
REVOKE
RIGHT
RLIKE
SCHEMA
SCHEMAS
SECOND_MICROSECOND
SELECT
SENSITIVE
SEPARATOR
SET
SHOW
SMALLINT
SPATIAL
SPECIFIC
SQL
SQLEXCEPTION
SQLSTATE
SQLWARNING
SQL_BIG_RESULT
SQL_CALC_FOUND_ROWS
SQL_SMALL_RESULT
SSL
STARTING
STRAIGHT_JOIN
TABLE
TERMINATED
THEN
TINYBLOB
TINYINT
TINYTEXT
TO
TRAILING
TRIGGER
TRUE
UNDO
UNION
UNIQUE
UNLOCK
UNSIGNED
UPDATE
UPGRADE
USAGE
USE
USING
UTC_DATE
UTC_TIME
UTC_TIMESTAMP
VALUE
VALUES
VARBINARY
VARCHAR
VARCHARACTER
VARYING
WHEN
WHERE
WHILE
WITH
WRITE
XOR
YEAR_MONTH
ZEROFILL

@ -0,0 +1,391 @@
// Copyright (c) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Text;
using System.IO;
using System.Data;
using System.Collections.Specialized;
using MySql.Data.MySqlClient.Properties;
namespace MySql.Data.MySqlClient
{
/// <summary>
///
/// </summary>
public class MySqlBulkLoader
{
// constant values
private const string defaultFieldTerminator = "\t";
private const string defaultLineTerminator = "\n";
private const char defaultEscapeCharacter = '\\';
// fields
private string fieldTerminator;
private string lineTerminator;
private string charSet;
private string tableName;
private int numLinesToIgnore;
private MySqlConnection connection;
private string filename;
private int timeout;
private bool local;
private string linePrefix;
private char fieldQuotationCharacter;
private bool fieldQuotationOptional;
private char escapeChar;
private MySqlBulkLoaderPriority priority;
private MySqlBulkLoaderConflictOption conflictOption;
private StringCollection columns;
private StringCollection expressions;
public MySqlBulkLoader(MySqlConnection connection)
{
Connection = connection;
Local = true;
FieldTerminator = defaultFieldTerminator;
LineTerminator = defaultLineTerminator;
FieldQuotationCharacter = Char.MinValue;
ConflictOption = MySqlBulkLoaderConflictOption.None;
columns = new StringCollection();
expressions = new StringCollection();
}
#region Properties
/// <summary>
/// Gets or sets the connection.
/// </summary>
/// <value>The connection.</value>
public MySqlConnection Connection
{
get { return connection; }
set { connection = value; }
}
/// <summary>
/// Gets or sets the field terminator.
/// </summary>
/// <value>The field terminator.</value>
public string FieldTerminator
{
get { return fieldTerminator; }
set { fieldTerminator = value; }
}
/// <summary>
/// Gets or sets the line terminator.
/// </summary>
/// <value>The line terminator.</value>
public string LineTerminator
{
get { return lineTerminator; }
set { lineTerminator = value; }
}
/// <summary>
/// Gets or sets the name of the table.
/// </summary>
/// <value>The name of the table.</value>
public string TableName
{
get { return tableName; }
set { tableName = value; }
}
/// <summary>
/// Gets or sets the character set.
/// </summary>
/// <value>The character set.</value>
public string CharacterSet
{
get { return charSet; }
set { charSet = value; }
}
/// <summary>
/// Gets or sets the name of the file.
/// </summary>
/// <value>The name of the file.</value>
public string FileName
{
get { return filename; }
set { filename = value; }
}
/// <summary>
/// Gets or sets the timeout.
/// </summary>
/// <value>The timeout.</value>
public int Timeout
{
get { return timeout; }
set { timeout = value; }
}
/// <summary>
/// Gets or sets a value indicating whether the filename that is to be loaded
/// is local to the client or not
/// </summary>
/// <value><c>true</c> if local; otherwise, <c>false</c>.</value>
public bool Local
{
get { return local; }
set { local = value; }
}
/// <summary>
/// Gets or sets the number of lines to skip.
/// </summary>
/// <value>The number of lines to skip.</value>
public int NumberOfLinesToSkip
{
get { return numLinesToIgnore; }
set { numLinesToIgnore = value; }
}
/// <summary>
/// Gets or sets the line prefix.
/// </summary>
/// <value>The line prefix.</value>
public string LinePrefix
{
get { return linePrefix; }
set { linePrefix = value; }
}
/// <summary>
/// Gets or sets the field quotation character.
/// </summary>
/// <value>The field quotation character.</value>
public char FieldQuotationCharacter
{
get { return fieldQuotationCharacter; }
set { fieldQuotationCharacter = value; }
}
/// <summary>
/// Gets or sets a value indicating whether [field quotation optional].
/// </summary>
/// <value>
/// <c>true</c> if [field quotation optional]; otherwise, <c>false</c>.
/// </value>
public bool FieldQuotationOptional
{
get { return fieldQuotationOptional; }
set { fieldQuotationOptional = value; }
}
/// <summary>
/// Gets or sets the escape character.
/// </summary>
/// <value>The escape character.</value>
public char EscapeCharacter
{
get { return escapeChar; }
set { escapeChar = value; }
}
/// <summary>
/// Gets or sets the conflict option.
/// </summary>
/// <value>The conflict option.</value>
public MySqlBulkLoaderConflictOption ConflictOption
{
get { return conflictOption; }
set { conflictOption = value; }
}
/// <summary>
/// Gets or sets the priority.
/// </summary>
/// <value>The priority.</value>
public MySqlBulkLoaderPriority Priority
{
get { return priority; }
set { priority = value; }
}
/// <summary>
/// Gets the columns.
/// </summary>
/// <value>The columns.</value>
public StringCollection Columns
{
get { return columns; }
}
/// <summary>
/// Gets the expressions.
/// </summary>
/// <value>The expressions.</value>
public StringCollection Expressions
{
get { return expressions; }
}
#endregion
/// <summary>
/// Execute the load operation
/// </summary>
/// <returns>The number of rows inserted.</returns>
public int Load()
{
bool openedConnection = false;
if (Connection == null)
throw new InvalidOperationException(Resources.ConnectionNotSet);
// next we open up the connetion if it is not already open
if (connection.State != ConnectionState.Open)
{
openedConnection = true;
connection.Open();
}
try
{
string sql = BuildSqlCommand();
MySqlCommand cmd = new MySqlCommand(sql, Connection);
cmd.CommandTimeout = Timeout;
return cmd.ExecuteNonQuery();
}
finally
{
if (openedConnection)
connection.Close();
}
}
private string BuildSqlCommand()
{
StringBuilder sql = new StringBuilder("LOAD DATA ");
if (Priority == MySqlBulkLoaderPriority.Low)
sql.Append("LOW_PRIORITY ");
else if (Priority == MySqlBulkLoaderPriority.Concurrent)
sql.Append("CONCURRENT ");
if (Local)
sql.Append("LOCAL ");
sql.Append("INFILE ");
if (Path.DirectorySeparatorChar == '\\')
sql.AppendFormat("'{0}' ", FileName.Replace(@"\", @"\\"));
else
sql.AppendFormat("'{0}' ", FileName);
if (ConflictOption == MySqlBulkLoaderConflictOption.Ignore)
sql.Append("IGNORE ");
else if (ConflictOption == MySqlBulkLoaderConflictOption.Replace)
sql.Append("REPLACE ");
sql.AppendFormat("INTO TABLE {0} ", TableName);
if (CharacterSet != null)
sql.AppendFormat("CHARACTER SET {0} ", CharacterSet);
StringBuilder optionSql = new StringBuilder(String.Empty);
if (FieldTerminator != defaultFieldTerminator)
optionSql.AppendFormat("TERMINATED BY '{0}' ", FieldTerminator);
if (FieldQuotationCharacter != Char.MinValue)
optionSql.AppendFormat("{0} ENCLOSED BY '{1}' ",
FieldQuotationOptional ? "OPTIONALLY" : "", FieldQuotationCharacter);
if (EscapeCharacter != defaultEscapeCharacter &&
EscapeCharacter != Char.MinValue)
optionSql.AppendFormat("ESCAPED BY '{0}' ", EscapeCharacter);
if (optionSql.Length > 0)
sql.AppendFormat("FIELDS {0}", optionSql.ToString());
optionSql = new StringBuilder(String.Empty);
if (LinePrefix != null && LinePrefix.Length > 0)
optionSql.AppendFormat("STARTING BY '{0}' ", LinePrefix);
if (LineTerminator != defaultLineTerminator)
optionSql.AppendFormat("TERMINATED BY '{0}' ", LineTerminator);
if (optionSql.Length > 0)
sql.AppendFormat("LINES {0}", optionSql.ToString());
if (NumberOfLinesToSkip > 0)
sql.AppendFormat("IGNORE {0} LINES ", NumberOfLinesToSkip);
if (Columns.Count > 0)
{
sql.Append("(");
sql.Append(Columns[0]);
for (int i = 1; i < Columns.Count; i++)
sql.AppendFormat(",{0}", Columns[i]);
sql.Append(") ");
}
if (Expressions.Count > 0)
{
sql.Append("SET ");
sql.Append(Expressions[0]);
for (int i = 1; i < Expressions.Count; i++)
sql.AppendFormat(",{0}", Expressions[i]);
}
return sql.ToString();
}
}
/// <summary>
///
/// </summary>
public enum MySqlBulkLoaderPriority
{
/// <summary>
/// This is the default and indicates normal priority
/// </summary>
None,
/// <summary>
/// Low priority will cause the load operation to wait until all readers of the table
/// have finished. This only affects storage engines that use only table-level locking
/// such as MyISAM, Memory, and Merge.
/// </summary>
Low,
/// <summary>
/// Concurrent priority is only relevant for MyISAM tables and signals that if the table
/// has no free blocks in the middle that other readers can retrieve data from the table
/// while the load operation is happening.
/// </summary>
Concurrent
}
/// <summary>
///
/// </summary>
public enum MySqlBulkLoaderConflictOption
{
/// <summary>
/// This is the default and indicates normal operation. In the event of a LOCAL load, this
/// is the same as ignore. When the data file is on the server, then a key conflict will
/// cause an error to be thrown and the rest of the data file ignored.
/// </summary>
None,
/// <summary>
/// Replace column values when a key conflict occurs.
/// </summary>
Replace,
/// <summary>
/// Ignore any rows where the primary key conflicts.
/// </summary>
Ignore
}
}

@ -0,0 +1,197 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Collections;
using System.Text;
using MySql.Data.Common;
using System.Collections.Generic;
using System.Data;
namespace MySql.Data.MySqlClient
{
/// <summary>
/// Summary description for CharSetMap.
/// </summary>
internal class CharSetMap
{
private static Dictionary<string, string> defaultCollations;
private static Dictionary<string, int> maxLengths;
private static Dictionary<string, CharacterSet> mapping;
private static object lockObject;
// we use a static constructor here since we only want to init
// the mapping once
static CharSetMap()
{
lockObject = new Object();
InitializeMapping();
}
public static CharacterSet GetCharacterSet(DBVersion version, string CharSetName)
{
CharacterSet cs = (CharacterSet) mapping[CharSetName];
if (cs == null)
throw new MySqlException("Character set '" + CharSetName + "' is not supported");
return cs;
}
/// <summary>
/// Returns the text encoding for a given MySQL character set name
/// </summary>
/// <param name="version">Version of the connection requesting the encoding</param>
/// <param name="CharSetName">Name of the character set to get the encoding for</param>
/// <returns>Encoding object for the given character set name</returns>
public static Encoding GetEncoding(DBVersion version, string CharSetName)
{
try
{
CharacterSet cs = GetCharacterSet(version, CharSetName);
return Encoding.GetEncoding(cs.name);
}
catch (NotSupportedException)
{
return Encoding.GetEncoding(0);
}
}
/// <summary>
///
/// </summary>
private static void InitializeMapping()
{
LoadCharsetMap();
}
private static void LoadCharsetMap()
{
mapping = new Dictionary<string, CharacterSet>();
mapping.Add("latin1", new CharacterSet("latin1", 1));
mapping.Add("big5", new CharacterSet("big5", 2));
mapping.Add("dec8", mapping["latin1"]);
mapping.Add("cp850", new CharacterSet("ibm850", 1));
mapping.Add("hp8", mapping["latin1"]);
mapping.Add("koi8r", new CharacterSet("koi8-u", 1));
mapping.Add("latin2", new CharacterSet("latin2", 1));
mapping.Add("swe7", mapping["latin1"]);
mapping.Add("ujis", new CharacterSet("EUC-JP", 3));
mapping.Add("eucjpms", mapping["ujis"]);
mapping.Add("sjis", new CharacterSet("sjis", 2));
mapping.Add("cp932", mapping["sjis"]);
mapping.Add("hebrew", new CharacterSet("hebrew", 1));
mapping.Add("tis620", new CharacterSet("windows-874", 1));
mapping.Add("euckr", new CharacterSet("euc-kr", 2));
mapping.Add("euc_kr", mapping["euckr"]);
mapping.Add("koi8u", new CharacterSet("koi8-u", 1));
mapping.Add("koi8_ru", mapping["koi8u"]);
mapping.Add("gb2312", new CharacterSet("gb2312", 2));
mapping.Add("gbk", mapping["gb2312"]);
mapping.Add("greek", new CharacterSet("greek", 1));
mapping.Add("cp1250", new CharacterSet("windows-1250", 1));
mapping.Add("win1250", mapping["cp1250"]);
mapping.Add("latin5", new CharacterSet("latin5", 1));
mapping.Add("armscii8", mapping["latin1"]);
mapping.Add("utf8", new CharacterSet("utf-8", 3));
mapping.Add("ucs2", new CharacterSet("UTF-16BE", 2));
mapping.Add("cp866", new CharacterSet("cp866", 1));
mapping.Add("keybcs2", mapping["latin1"]);
mapping.Add("macce", new CharacterSet("x-mac-ce", 1));
mapping.Add("macroman", new CharacterSet("x-mac-romanian", 1));
mapping.Add("cp852", new CharacterSet("ibm852", 2));
mapping.Add("latin7", new CharacterSet("iso-8859-7", 1));
mapping.Add("cp1251", new CharacterSet("windows-1251", 1));
mapping.Add("win1251ukr", mapping["cp1251"]);
mapping.Add("cp1251csas", mapping["cp1251"]);
mapping.Add("cp1251cias", mapping["cp1251"]);
mapping.Add("win1251", mapping["cp1251"]);
mapping.Add("cp1256", new CharacterSet("cp1256", 1));
mapping.Add("cp1257", new CharacterSet("windows-1257", 1));
mapping.Add("ascii", new CharacterSet("us-ascii", 1));
mapping.Add("usa7", mapping["ascii"]);
mapping.Add("binary", mapping["ascii"]);
mapping.Add("latin3", new CharacterSet("latin3", 1));
mapping.Add("latin4", new CharacterSet("latin4", 1));
mapping.Add("latin1_de", new CharacterSet("iso-8859-1", 1));
mapping.Add("german1", new CharacterSet("iso-8859-1", 1));
mapping.Add("danish", new CharacterSet("iso-8859-1", 1));
mapping.Add("czech", new CharacterSet("iso-8859-2", 1));
mapping.Add("hungarian", new CharacterSet("iso-8859-2", 1));
mapping.Add("croat", new CharacterSet("iso-8859-2", 1));
mapping.Add("latvian", new CharacterSet("iso-8859-13", 1));
mapping.Add("latvian1", new CharacterSet("iso-8859-13", 1));
mapping.Add("estonia", new CharacterSet("iso-8859-13", 1));
mapping.Add("dos", new CharacterSet("ibm437", 1));
}
internal static void InitCollections(MySqlConnection connection)
{
defaultCollations = new Dictionary<string, string>();
maxLengths = new Dictionary<string, int>();
MySqlCommand cmd = new MySqlCommand("SHOW CHARSET", connection);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
defaultCollations.Add(reader.GetString(0), reader.GetString(2));
maxLengths.Add(reader.GetString(0), Convert.ToInt32(reader.GetValue(3)));
}
}
}
internal static string GetDefaultCollation(string charset, MySqlConnection connection)
{
lock (lockObject)
{
if (defaultCollations == null)
InitCollections(connection);
}
if (!defaultCollations.ContainsKey(charset))
return null;
return defaultCollations[charset];
}
internal static int GetMaxLength(string charset, MySqlConnection connection)
{
lock (lockObject)
{
if (maxLengths == null)
InitCollections(connection);
}
if (!maxLengths.ContainsKey(charset))
return 1;
return maxLengths[charset];
}
}
internal class CharacterSet
{
public string name;
public int byteCount;
public CharacterSet(string name, int byteCount)
{
this.name = name;
this.byteCount = byteCount;
}
}
}

@ -0,0 +1,281 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.ComponentModel;
using System.Data.Common;
using System.Data;
using System.Text;
using MySql.Data.Common;
using System.Collections;
using MySql.Data.Types;
using System.Globalization;
using MySql.Data.MySqlClient.Properties;
using System.Collections.Generic;
namespace MySql.Data.MySqlClient
{
/// <include file='docs/MySqlCommandBuilder.xml' path='docs/class/*'/>
#if !CF
[ToolboxItem(false)]
[System.ComponentModel.DesignerCategory("Code")]
#endif
public sealed class MySqlCommandBuilder : DbCommandBuilder
{
/// <include file='docs/MySqlCommandBuilder.xml' path='docs/Ctor/*'/>
public MySqlCommandBuilder()
{
QuotePrefix = QuoteSuffix = "`";
}
/// <include file='docs/MySqlCommandBuilder.xml' path='docs/Ctor2/*'/>
public MySqlCommandBuilder(MySqlDataAdapter adapter)
: this()
{
DataAdapter = adapter;
}
/// <include file='docs/mysqlcommandBuilder.xml' path='docs/DataAdapter/*'/>
public new MySqlDataAdapter DataAdapter
{
get { return (MySqlDataAdapter)base.DataAdapter; }
set { base.DataAdapter = value; }
}
#region Public Methods
/// <summary>
/// Retrieves parameter information from the stored procedure specified
/// in the MySqlCommand and populates the Parameters collection of the
/// specified MySqlCommand object.
/// This method is not currently supported since stored procedures are
/// not available in MySql.
/// </summary>
/// <param name="command">The MySqlCommand referencing the stored
/// procedure from which the parameter information is to be derived.
/// The derived parameters are added to the Parameters collection of the
/// MySqlCommand.</param>
/// <exception cref="InvalidOperationException">The command text is not
/// a valid stored procedure name.</exception>
public static void DeriveParameters(MySqlCommand command)
{
if (!command.Connection.driver.Version.isAtLeast(5, 0, 0))
throw new MySqlException("DeriveParameters is not supported on MySQL versions " +
"prior to 5.0");
// retrieve the proc definitino from the cache.
string spName = command.CommandText;
if (spName.IndexOf(".") == -1)
spName = command.Connection.Database + "." + spName;
DataSet ds = command.Connection.ProcedureCache.GetProcedure(command.Connection, spName);
if (!ds.Tables.Contains("Procedure Parameters"))
throw new MySqlException(Resources.UnableToDeriveParameters);
DataTable parameters = ds.Tables["Procedure Parameters"];
DataTable procTable = ds.Tables["Procedures"];
command.Parameters.Clear();
foreach (DataRow row in parameters.Rows)
{
MySqlParameter p = new MySqlParameter();
p.ParameterName = String.Format("@{0}", row["PARAMETER_NAME"]);
if (row["ORDINAL_POSITION"].Equals(0) && p.ParameterName == "@")
p.ParameterName = "@RETURN_VALUE";
p.Direction = GetDirection(row);
bool unsigned = StoredProcedure.GetFlags(row["DTD_IDENTIFIER"].ToString()).IndexOf("UNSIGNED") != -1;
bool real_as_float = procTable.Rows[0]["SQL_MODE"].ToString().IndexOf("REAL_AS_FLOAT") != -1;
p.MySqlDbType = MetaData.NameToType(row["DATA_TYPE"].ToString(),
unsigned, real_as_float, command.Connection);
if (!row["CHARACTER_MAXIMUM_LENGTH"].Equals(DBNull.Value))
p.Size = (int)row["CHARACTER_MAXIMUM_LENGTH"];
if (!row["NUMERIC_PRECISION"].Equals(DBNull.Value))
p.Precision = Convert.ToByte(row["NUMERIC_PRECISION"]);
if (!row["NUMERIC_SCALE"].Equals(DBNull.Value))
p.Scale = Convert.ToByte(row["NUMERIC_SCALE"]);
if (p.MySqlDbType == MySqlDbType.Set || p.MySqlDbType == MySqlDbType.Enum)
p.PossibleValues = GetPossibleValues(row);
command.Parameters.Add(p);
}
}
private static List<string> GetPossibleValues(DataRow row)
{
string[] types = new string[] { "ENUM", "SET" };
string dtdIdentifier = row["DTD_IDENTIFIER"].ToString().Trim();
int index = 0;
for (; index < 2; index++)
if (dtdIdentifier.StartsWith(types[index], StringComparison.InvariantCultureIgnoreCase))
break;
if (index == 2) return null;
dtdIdentifier = dtdIdentifier.Substring(types[index].Length).Trim();
dtdIdentifier = dtdIdentifier.Trim('(', ')').Trim();
List<string> values = new List<string>();
MySqlTokenizer tokenzier = new MySqlTokenizer(dtdIdentifier);
string token = tokenzier.NextToken();
int start = tokenzier.StartIndex;
while (true)
{
if (token == null || token == ",")
{
int end = dtdIdentifier.Length - 1;
if (token == ",")
end = tokenzier.StartIndex;
string value = dtdIdentifier.Substring(start, end - start).Trim('\'', '\"').Trim();
values.Add(value);
start = tokenzier.StopIndex;
}
if (token == null) break;
token = tokenzier.NextToken();
}
return values;
}
private static ParameterDirection GetDirection(DataRow row)
{
string mode = row["PARAMETER_MODE"].ToString();
int ordinal = Convert.ToInt32(row["ORDINAL_POSITION"]);
if (0 == ordinal)
return ParameterDirection.ReturnValue;
else if (mode == "IN")
return ParameterDirection.Input;
else if (mode == "OUT")
return ParameterDirection.Output;
return ParameterDirection.InputOutput;
}
/// <summary>
/// Gets the delete command.
/// </summary>
/// <returns></returns>
public new MySqlCommand GetDeleteCommand()
{
return (MySqlCommand)base.GetDeleteCommand();
}
/// <summary>
/// Gets the update command.
/// </summary>
/// <returns></returns>
public new MySqlCommand GetUpdateCommand()
{
return (MySqlCommand)base.GetUpdateCommand();
}
/// <summary>
/// Gets the insert command.
/// </summary>
/// <returns></returns>
public new MySqlCommand GetInsertCommand()
{
return (MySqlCommand)GetInsertCommand(false);
}
public override string QuoteIdentifier(string unquotedIdentifier)
{
if (unquotedIdentifier == null) throw new
ArgumentNullException("unquotedIdentifier");
// don't quote again if it is already quoted
if (unquotedIdentifier.StartsWith(QuotePrefix) &&
unquotedIdentifier.EndsWith(QuoteSuffix))
return unquotedIdentifier;
unquotedIdentifier = unquotedIdentifier.Replace(QuotePrefix, QuotePrefix + QuotePrefix);
return String.Format("{0}{1}{2}", QuotePrefix, unquotedIdentifier, QuoteSuffix);
}
public override string UnquoteIdentifier(string quotedIdentifier)
{
if (quotedIdentifier == null) throw new
ArgumentNullException("quotedIdentifier");
// don't unquote again if it is already unquoted
if (!quotedIdentifier.StartsWith(QuotePrefix) ||
!quotedIdentifier.EndsWith(QuoteSuffix))
return quotedIdentifier;
if (quotedIdentifier.StartsWith(QuotePrefix))
quotedIdentifier = quotedIdentifier.Substring(1);
if (quotedIdentifier.EndsWith(QuoteSuffix))
quotedIdentifier = quotedIdentifier.Substring(0, quotedIdentifier.Length - 1);
quotedIdentifier = quotedIdentifier.Replace(QuotePrefix + QuotePrefix, QuotePrefix);
return quotedIdentifier;
}
#endregion
/// <summary>
///
/// </summary>
/// <param name="parameterName"></param>
/// <returns></returns>
protected override string GetParameterName(string parameterName)
{
StringBuilder sb = new StringBuilder(parameterName);
sb.Replace(" ", "");
sb.Replace("/", "_per_");
sb.Replace("-", "_");
sb.Replace(")", "_cb_");
sb.Replace("(", "_ob_");
sb.Replace("%", "_pct_");
sb.Replace("<", "_lt_");
sb.Replace(">", "_gt_");
sb.Replace(".", "_pt_");
return String.Format("@{0}", sb.ToString());
}
protected override void ApplyParameterInfo(DbParameter parameter, DataRow row,
StatementType statementType, bool whereClause)
{
((MySqlParameter)parameter).MySqlDbType = (MySqlDbType)row["ProviderType"];
}
protected override string GetParameterName(int parameterOrdinal)
{
return String.Format("@p{0}", parameterOrdinal.ToString(CultureInfo.InvariantCulture));
}
protected override string GetParameterPlaceholder(int parameterOrdinal)
{
return String.Format("@p{0}", parameterOrdinal.ToString(CultureInfo.InvariantCulture));
}
protected override void SetRowUpdatingHandler(DbDataAdapter adapter)
{
MySqlDataAdapter myAdapter = (adapter as MySqlDataAdapter);
if (adapter != base.DataAdapter)
myAdapter.RowUpdating += new MySqlRowUpdatingEventHandler(RowUpdating);
else
myAdapter.RowUpdating -= new MySqlRowUpdatingEventHandler(RowUpdating);
}
private void RowUpdating(object sender, MySqlRowUpdatingEventArgs args)
{
base.RowUpdatingHandler(args);
}
}
}

@ -0,0 +1,308 @@
// Copyright (C) 2004-2007 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 zlib;
using MySql.Data.MySqlClient.Properties;
using MySql.Data.Common;
namespace MySql.Data.MySqlClient
{
/// <summary>
/// Summary description for CompressedStream.
/// </summary>
internal class CompressedStream : Stream
{
// writing fields
private Stream baseStream;
private MemoryStream cache;
// reading fields
private byte[] localByte;
private byte[] inBuffer;
private byte[] lengthBytes;
private WeakReference inBufferRef;
private int inPos;
private int maxInPos;
private ZInputStream zInStream;
public CompressedStream(Stream baseStream)
{
this.baseStream = baseStream;
localByte = new byte[1];
lengthBytes = new byte[7];
cache = new MemoryStream();
inBufferRef = new WeakReference(inBuffer, false);
}
#region Properties
public override bool CanRead
{
get { return baseStream.CanRead; }
}
public override bool CanWrite
{
get { return baseStream.CanWrite; }
}
public override bool CanSeek
{
get { return baseStream.CanSeek; }
}
public override long Length
{
get { return baseStream.Length; }
}
public override long Position
{
get { return baseStream.Position; }
set { baseStream.Position = value; }
}
#endregion
public override void Close()
{
baseStream.Close();
base.Close();
}
public override void SetLength(long value)
{
throw new NotSupportedException(Resources.CSNoSetLength);
}
public override int ReadByte()
{
try
{
Read(localByte, 0, 1);
return localByte[0];
}
catch (EndOfStreamException)
{
return -1;
}
}
public override bool CanTimeout
{
get
{
return baseStream.CanTimeout;
}
}
public override int ReadTimeout
{
get
{
return baseStream.ReadTimeout;
}
set
{
baseStream.ReadTimeout = value;
}
}
public override int WriteTimeout
{
get
{
return baseStream.WriteTimeout;
}
set
{
baseStream.WriteTimeout = value;
}
}
public override int Read(byte[] buffer, int offset, int count)
{
if (buffer == null)
throw new ArgumentNullException("buffer", Resources.BufferCannotBeNull);
if (offset < 0 || offset >= buffer.Length)
throw new ArgumentOutOfRangeException("offset", Resources.OffsetMustBeValid);
if ((offset + count) > buffer.Length)
throw new ArgumentException(Resources.BufferNotLargeEnough, "buffer");
if (inPos == maxInPos)
PrepareNextPacket();
int countToRead = Math.Min(count, maxInPos - inPos);
int countRead;
if (zInStream != null)
countRead = zInStream.read(buffer, offset, countToRead);
else
countRead = baseStream.Read(buffer, offset, countToRead);
inPos += countRead;
// release the weak reference
if (inPos == maxInPos)
{
zInStream = null;
if (!Platform.IsMono())
{
inBufferRef = new WeakReference(inBuffer, false);
inBuffer = null;
}
}
return countRead;
}
private void PrepareNextPacket()
{
MySqlStream.ReadFully(baseStream, lengthBytes, 0, 7);
int compressedLength = lengthBytes[0] + (lengthBytes[1] << 8) + (lengthBytes[2] << 16);
// lengthBytes[3] is seq
int unCompressedLength = lengthBytes[4] + (lengthBytes[5] << 8) +
(lengthBytes[6] << 16);
if (unCompressedLength == 0)
{
unCompressedLength = compressedLength;
zInStream = null;
}
else
{
ReadNextPacket(compressedLength);
MemoryStream ms = new MemoryStream(inBuffer);
zInStream = new ZInputStream(ms);
zInStream.maxInput = compressedLength;
}
inPos = 0;
maxInPos = unCompressedLength;
}
private void ReadNextPacket(int len)
{
if (!Platform.IsMono())
inBuffer = inBufferRef.Target as byte[];
if (inBuffer == null || inBuffer.Length < len)
inBuffer = new byte[len];
MySqlStream.ReadFully(baseStream, inBuffer, 0, len);
}
private MemoryStream CompressCache()
{
// small arrays almost never yeild a benefit from compressing
if (cache.Length < 50)
return null;
byte[] cacheBytes = cache.GetBuffer();
MemoryStream compressedBuffer = new MemoryStream();
ZOutputStream zos = new ZOutputStream(compressedBuffer, zlibConst.Z_DEFAULT_COMPRESSION);
zos.Write(cacheBytes, 0, (int) cache.Length);
zos.finish();
// if the compression hasn't helped, then just return null
if (compressedBuffer.Length >= cache.Length)
return null;
return compressedBuffer;
}
private void CompressAndSendCache()
{
long compressedLength, uncompressedLength;
// we need to save the sequence byte that is written
byte[] cacheBuffer = cache.GetBuffer();
byte seq = cacheBuffer[3];
cacheBuffer[3] = 0;
// first we compress our current cache
MemoryStream compressedBuffer = CompressCache();
// now we set our compressed and uncompressed lengths
// based on if our compression is going to help or not
if (compressedBuffer == null)
{
compressedLength = cache.Length;
uncompressedLength = 0;
}
else
{
compressedLength = compressedBuffer.Length;
uncompressedLength = cache.Length;
}
baseStream.WriteByte((byte) (compressedLength & 0xff));
baseStream.WriteByte((byte) ((compressedLength >> 8) & 0xff));
baseStream.WriteByte((byte) ((compressedLength >> 16) & 0Xff));
baseStream.WriteByte(seq);
baseStream.WriteByte((byte) (uncompressedLength & 0xff));
baseStream.WriteByte((byte) ((uncompressedLength >> 8) & 0xff));
baseStream.WriteByte((byte) ((uncompressedLength >> 16) & 0Xff));
if (compressedBuffer == null)
baseStream.Write(cacheBuffer, 0, (int) cache.Length);
else
{
byte[] compressedBytes = compressedBuffer.GetBuffer();
baseStream.Write(compressedBytes, 0, (int) compressedBuffer.Length);
}
baseStream.Flush();
cache.SetLength(0);
}
public override void Flush()
{
if (!InputDone()) return;
CompressAndSendCache();
}
private bool InputDone()
{
// if we have not done so yet, see if we can calculate how many bytes we are expecting
if (cache.Length < 4) return false;
byte[] buf = cache.GetBuffer();
int expectedLen = buf[0] + (buf[1] << 8) + (buf[2] << 16);
if (cache.Length < (expectedLen + 4)) return false;
return true;
}
public override void WriteByte(byte value)
{
cache.WriteByte(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
cache.Write(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
return baseStream.Seek(offset, origin);
}
}
}

@ -0,0 +1,867 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.ComponentModel;
using System.Data;
using System.Data.Common;
#if !CF
using System.Drawing;
using System.Drawing.Design;
using System.Transactions;
#endif
using System.Text;
using IsolationLevel=System.Data.IsolationLevel;
using MySql.Data.Common;
using System.Diagnostics;
using MySql.Data.MySqlClient.Properties;
namespace MySql.Data.MySqlClient
{
/// <include file='docs/MySqlConnection.xml' path='docs/ClassSummary/*'/>
#if !CF
[ToolboxBitmap(typeof (MySqlConnection), "MySqlClient.resources.connection.bmp")]
[DesignerCategory("Code")]
[ToolboxItem(true)]
#endif
public sealed class MySqlConnection : DbConnection, ICloneable
{
internal ConnectionState connectionState;
internal Driver driver;
private MySqlConnectionStringBuilder settings;
private bool hasBeenOpen;
private SchemaProvider schemaProvider;
private ProcedureCache procedureCache;
#if !CF
private PerformanceMonitor perfMonitor;
#endif
private bool abortOnTimeout;
private string database;
private int commandTimeout;
/// <include file='docs/MySqlConnection.xml' path='docs/InfoMessage/*'/>
public event MySqlInfoMessageEventHandler InfoMessage;
private static Cache<string, MySqlConnectionStringBuilder> connectionStringCache =
new Cache<string, MySqlConnectionStringBuilder>(0, 25);
/// <include file='docs/MySqlConnection.xml' path='docs/DefaultCtor/*'/>
public MySqlConnection()
{
//TODO: add event data to StateChange docs
settings = new MySqlConnectionStringBuilder();
database = String.Empty;
}
/// <include file='docs/MySqlConnection.xml' path='docs/Ctor1/*'/>
public MySqlConnection(string connectionString)
: this()
{
ConnectionString = connectionString;
}
#region Interal Methods & Properties
#if !CF
internal PerformanceMonitor PerfMonitor
{
get { return perfMonitor; }
}
#endif
internal ProcedureCache ProcedureCache
{
get { return procedureCache; }
}
internal MySqlConnectionStringBuilder Settings
{
get { return settings; }
}
internal MySqlDataReader Reader
{
get
{
if (driver == null)
return null;
return driver.reader;
}
set
{
driver.reader = value;
}
}
internal void OnInfoMessage(MySqlInfoMessageEventArgs args)
{
if (InfoMessage != null)
{
InfoMessage(this, args);
}
}
internal bool SoftClosed
{
get
{
#if !CF
return (State == ConnectionState.Closed) &&
driver != null &&
driver.CurrentTransaction != null;
#else
return false;
#endif
}
}
#endregion
#region Properties
/// <summary>
/// Returns the id of the server thread this connection is executing on
/// </summary>
#if !CF
[Browsable(false)]
#endif
public int ServerThread
{
get { return driver.ThreadID; }
}
/// <summary>
/// Gets the name of the MySQL server to which to connect.
/// </summary>
#if !CF
[Browsable(true)]
#endif
public override string DataSource
{
get { return settings.Server; }
}
/// <include file='docs/MySqlConnection.xml' path='docs/ConnectionTimeout/*'/>
#if !CF
[Browsable(true)]
#endif
public override int ConnectionTimeout
{
get { return (int) settings.ConnectionTimeout; }
}
/// <include file='docs/MySqlConnection.xml' path='docs/Database/*'/>
#if !CF
[Browsable(true)]
#endif
public override string Database
{
get { return database; }
}
/// <summary>
/// Indicates if this connection should use compression when communicating with the server.
/// </summary>
#if !CF
[Browsable(false)]
#endif
public bool UseCompression
{
get { return settings.UseCompression; }
}
/// <include file='docs/MySqlConnection.xml' path='docs/State/*'/>
#if !CF
[Browsable(false)]
#endif
public override ConnectionState State
{
get { return connectionState; }
}
/// <include file='docs/MySqlConnection.xml' path='docs/ServerVersion/*'/>
#if !CF
[Browsable(false)]
#endif
public override string ServerVersion
{
get { return driver.Version.ToString(); }
}
/// <include file='docs/MySqlConnection.xml' path='docs/ConnectionString/*'/>
#if !CF
[Editor("MySql.Data.MySqlClient.Design.ConnectionStringTypeEditor,MySqlClient.Design", typeof (UITypeEditor))]
[Browsable(true)]
[Category("Data")]
[Description(
"Information used to connect to a DataSource, such as 'Server=xxx;UserId=yyy;Password=zzz;Database=dbdb'.")]
#endif
public override string ConnectionString
{
get
{
// Always return exactly what the user set.
// Security-sensitive information may be removed.
return settings.GetConnectionString(!hasBeenOpen || settings.PersistSecurityInfo);
}
set
{
if (State != ConnectionState.Closed)
throw new MySqlException(
"Not allowed to change the 'ConnectionString' property while the connection (state=" + State +
").");
MySqlConnectionStringBuilder newSettings;
lock (connectionStringCache)
{
if (value == null)
newSettings = new MySqlConnectionStringBuilder();
else
{
newSettings = (MySqlConnectionStringBuilder)connectionStringCache[value];
if (null == newSettings)
{
newSettings = new MySqlConnectionStringBuilder(value);
connectionStringCache.Add(value, newSettings);
}
}
}
settings = newSettings;
if (settings.Database != null && settings.Database.Length > 0)
this.database = settings.Database;
if (driver != null)
driver.Settings = newSettings;
}
}
#if !CF && !__MonoCS__
protected override DbProviderFactory DbProviderFactory
{
get
{
return MySqlClientFactory.Instance;
}
}
#endif
#endregion
#region Transactions
#if !MONO && !CF
/// <summary>
/// Enlists in the specified transaction.
/// </summary>
/// <param name="transaction">
/// A reference to an existing <see cref="System.Transactions.Transaction"/> in which to enlist.
/// </param>
public override void EnlistTransaction(Transaction transaction)
{
// enlisting in the null transaction is a noop
if (transaction == null)
return;
// guard against trying to enlist in more than one transaction
if (driver.CurrentTransaction != null)
{
if (driver.CurrentTransaction.BaseTransaction == transaction)
return;
throw new MySqlException("Already enlisted");
}
// now see if we need to swap out drivers. We would need to do this since
// we have to make sure all ops for a given transaction are done on the
// same physical connection.
Driver existingDriver = DriverTransactionManager.GetDriverInTransaction(transaction);
if (existingDriver != null)
{
// we can't allow more than one driver to contribute to the same connection
if (existingDriver.IsInActiveUse)
throw new NotSupportedException(Resources.MultipleConnectionsInTransactionNotSupported);
// there is an existing driver and it's not being currently used.
// now we need to see if it is using the same connection string
string text1 = existingDriver.Settings.ConnectionString;
string text2 = Settings.ConnectionString;
if (String.Compare(text1, text2, true) != 0)
throw new NotSupportedException(Resources.MultipleConnectionsInTransactionNotSupported);
// close existing driver
// set this new driver as our existing driver
CloseFully();
driver = existingDriver;
}
if (driver.CurrentTransaction == null)
{
MySqlPromotableTransaction t = new MySqlPromotableTransaction(this, transaction);
if (!transaction.EnlistPromotableSinglePhase(t))
throw new NotSupportedException(Resources.DistributedTxnNotSupported);
driver.CurrentTransaction = t;
DriverTransactionManager.SetDriverInTransaction(driver);
driver.IsInActiveUse = true;
}
}
#endif
/// <include file='docs/MySqlConnection.xml' path='docs/BeginTransaction/*'/>
public new MySqlTransaction BeginTransaction()
{
return BeginTransaction(IsolationLevel.RepeatableRead);
}
/// <include file='docs/MySqlConnection.xml' path='docs/BeginTransaction1/*'/>
public new MySqlTransaction BeginTransaction(IsolationLevel iso)
{
//TODO: check note in help
if (State != ConnectionState.Open)
throw new InvalidOperationException(Resources.ConnectionNotOpen);
// First check to see if we are in a current transaction
if (driver.HasStatus(ServerStatusFlags.InTransaction))
throw new InvalidOperationException(Resources.NoNestedTransactions);
MySqlTransaction t = new MySqlTransaction(this, iso);
MySqlCommand cmd = new MySqlCommand("", this);
cmd.CommandText = "SET SESSION TRANSACTION ISOLATION LEVEL ";
switch (iso)
{
case IsolationLevel.ReadCommitted:
cmd.CommandText += "READ COMMITTED";
break;
case IsolationLevel.ReadUncommitted:
cmd.CommandText += "READ UNCOMMITTED";
break;
case IsolationLevel.RepeatableRead:
cmd.CommandText += "REPEATABLE READ";
break;
case IsolationLevel.Serializable:
cmd.CommandText += "SERIALIZABLE";
break;
case IsolationLevel.Chaos:
throw new NotSupportedException(Resources.ChaosNotSupported);
}
cmd.ExecuteNonQuery();
cmd.CommandText = "BEGIN";
cmd.ExecuteNonQuery();
return t;
}
#endregion
/// <include file='docs/MySqlConnection.xml' path='docs/ChangeDatabase/*'/>
public override void ChangeDatabase(string databaseName)
{
if (databaseName == null || databaseName.Trim().Length == 0)
throw new ArgumentException(Resources.ParameterIsInvalid, "databaseName");
if (State != ConnectionState.Open)
throw new InvalidOperationException(Resources.ConnectionNotOpen);
// This lock prevents promotable transaction rollback to run
// in parallel
lock (driver)
{
#if !CF
if (Transaction.Current != null &&
Transaction.Current.TransactionInformation.Status == TransactionStatus.Aborted)
{
throw new TransactionAbortedException();
}
#endif
// We use default command timeout for SetDatabase
using (new CommandTimer(this, (int)Settings.DefaultCommandTimeout))
{
driver.SetDatabase(databaseName);
}
}
this.database = databaseName;
}
internal void SetState(ConnectionState newConnectionState, bool broadcast)
{
if (newConnectionState == connectionState && !broadcast)
return;
ConnectionState oldConnectionState = connectionState;
connectionState = newConnectionState;
if (broadcast)
OnStateChange(new StateChangeEventArgs(oldConnectionState, connectionState));
}
/// <summary>
/// Ping
/// </summary>
/// <returns></returns>
public bool Ping()
{
if (driver != null && driver.Ping())
return true;
driver = null;
SetState(ConnectionState.Closed, true);
return false;
}
/// <include file='docs/MySqlConnection.xml' path='docs/Open/*'/>
public override void Open()
{
if (State == ConnectionState.Open)
throw new InvalidOperationException(Resources.ConnectionAlreadyOpen);
SetState(ConnectionState.Connecting, true);
#if !CF
// if we are auto enlisting in a current transaction, then we will be
// treating the connection as pooled
if (settings.AutoEnlist && Transaction.Current != null)
{
driver = DriverTransactionManager.GetDriverInTransaction(Transaction.Current);
if (driver != null &&
(driver.IsInActiveUse ||
!driver.Settings.EquivalentTo(this.Settings)))
throw new NotSupportedException(Resources.MultipleConnectionsInTransactionNotSupported);
}
#endif
try
{
if (settings.Pooling)
{
MySqlPool pool = MySqlPoolManager.GetPool(settings);
if (driver == null)
driver = pool.GetConnection();
procedureCache = pool.ProcedureCache;
}
else
{
if (driver == null)
driver = Driver.Create(settings);
procedureCache = new ProcedureCache((int) settings.ProcedureCacheSize);
}
}
catch (Exception)
{
SetState(ConnectionState.Closed, true);
throw;
}
// if the user is using old syntax, let them know
if (driver.Settings.UseOldSyntax)
MySqlTrace.LogWarning(ServerThread,
"You are using old syntax that will be removed in future versions");
SetState(ConnectionState.Open, false);
driver.Configure(this);
if (settings.Database != null && settings.Database != String.Empty)
ChangeDatabase(settings.Database);
// setup our schema provider
if (driver.Version.isAtLeast(5, 0, 0))
schemaProvider = new ISSchemaProvider(this);
else
schemaProvider = new SchemaProvider(this);
#if !CF
perfMonitor = new PerformanceMonitor(this);
#endif
// if we are opening up inside a current transaction, then autoenlist
// TODO: control this with a connection string option
#if !MONO && !CF
if (Transaction.Current != null && settings.AutoEnlist)
EnlistTransaction(Transaction.Current);
#endif
hasBeenOpen = true;
SetState(ConnectionState.Open, true);
}
/// <include file='docs/MySqlConnection.xml' path='docs/CreateCommand/*'/>
public new MySqlCommand CreateCommand()
{
// Return a new instance of a command object.
MySqlCommand c = new MySqlCommand();
c.Connection = this;
return c;
}
#region ICloneable
/// <summary>
/// Creates a new MySqlConnection object with the exact same ConnectionString value
/// </summary>
/// <returns>A cloned MySqlConnection object</returns>
public MySqlConnection Clone()
{
MySqlConnection clone = new MySqlConnection();
string connectionString = settings.ConnectionString;
if (connectionString != null)
clone.ConnectionString = connectionString;
return clone;
}
object ICloneable.Clone()
{
return this.Clone();
}
#endregion
#region IDisposeable
protected override void Dispose(bool disposing)
{
if (State == ConnectionState.Open)
Close();
base.Dispose(disposing);
}
#endregion
protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
{
if (isolationLevel == IsolationLevel.Unspecified)
return BeginTransaction();
return BeginTransaction(isolationLevel);
}
protected override DbCommand CreateDbCommand()
{
return CreateCommand();
}
internal void Abort()
{
try
{
if (settings.Pooling)
MySqlPoolManager.ReleaseConnection(driver);
else
driver.Close();
}
catch (Exception)
{
}
SetState(ConnectionState.Closed, true);
}
internal void CloseFully()
{
if (settings.Pooling && driver.IsOpen)
{
// if we are in a transaction, roll it back
if (driver.HasStatus(ServerStatusFlags.InTransaction))
{
MySqlTransaction t = new MySqlTransaction(this, IsolationLevel.Unspecified);
t.Rollback();
}
MySqlPoolManager.ReleaseConnection(driver);
}
else
driver.Close();
driver = null;
}
/// <include file='docs/MySqlConnection.xml' path='docs/Close/*'/>
public override void Close()
{
if (State == ConnectionState.Closed) return;
if (Reader != null)
Reader.Close();
// if the reader was opened with CloseConnection then driver
// will be null on the second time through
if (driver != null)
{
#if !CF
if (driver.CurrentTransaction == null)
#endif
CloseFully();
#if !CF
else
driver.IsInActiveUse = false;
#endif
}
SetState(ConnectionState.Closed, true);
}
internal string CurrentDatabase()
{
if (Database != null && Database.Length > 0)
return Database;
MySqlCommand cmd = new MySqlCommand("SELECT database()", this);
return cmd.ExecuteScalar().ToString();
}
internal void HandleTimeout(TimeoutException tex)
{
bool isFatal = false;
if (abortOnTimeout)
{
// Special connection started to cancel a query.
// Timeout handler is disabled to prevent recursive connection
// spawning when original query and KILL time out.
Abort();
throw new MySqlException(Resources.Timeout, true , tex);
}
try
{
// Do a fast cancel.The reason behind small values for connection
// and command timeout is that we do not want user to wait longer
// after command has already expired.
// Microsoft's SqlClient seems to be using 5 seconds timeouts
// here as well.
// Read the error packet with "interrupted" message.
CancelQuery(5);
driver.ResetTimeout(5000);
if (Reader != null)
{
Reader.Close();
Reader = null;
}
}
catch (Exception ex)
{
MySqlTrace.LogWarning(ServerThread, "Could not kill query in timeout handler, " +
" aborting connection. Exception was " + ex.Message);
Abort();
isFatal = true;
}
throw new MySqlException(Resources.Timeout, isFatal, tex);
}
public void CancelQuery(int timeout)
{
if (!driver.Version.isAtLeast(5, 0, 0))
throw new NotSupportedException(Resources.CancelNotSupported);
MySqlConnectionStringBuilder cb = new MySqlConnectionStringBuilder(
Settings.ConnectionString);
cb.Pooling = false;
cb.ConnectionTimeout = (uint) timeout;
using(MySqlConnection c = new MySqlConnection(cb.ConnectionString))
{
c.abortOnTimeout = true;
c.Open();
string commandText = "KILL QUERY " + ServerThread;
MySqlCommand cmd = new MySqlCommand(commandText, c);
cmd.CommandTimeout = timeout;
cmd.ExecuteNonQuery();
}
}
#region Routines for timeout support.
// Problem description:
// Sometimes, ExecuteReader is called recursively. This is the case if
// command behaviors are used and we issue "set sql_select_limit"
// before and after command. This is also the case with prepared
// statements , where we set session variables. In these situations, we
// have to prevent recursive ExecuteReader calls from overwriting
// timeouts set by the top level command.
// To solve the problem, SetCommandTimeout() and ClearCommandTimeout() are
// introduced . Query timeout here is "sticky", that is once set with
// SetCommandTimeout, it only be overwritten after ClearCommandTimeout
// (SetCommandTimeout would return false if it timeout has not been
// cleared).
// The proposed usage pattern of there routines is following:
// When timed operations starts, issue SetCommandTimeout(). When it
// finishes, issue ClearCommandTimeout(), but _only_ if call to
// SetCommandTimeout() was successful.
/// <summary>
/// Sets query timeout. If timeout has been set prior and not
/// yet cleared ClearCommandTimeout(), it has no effect.
/// </summary>
/// <param name="value">timeout in seconds</param>
/// <returns>true if </returns>
internal bool SetCommandTimeout(int value)
{
if (!hasBeenOpen)
// Connection timeout is handled by driver
return false;
if (commandTimeout != 0)
// someone is trying to set a timeout while command is already
// running. It could be for example recursive call to ExecuteReader
// Ignore the request, as only top-level (non-recursive commands)
// can set timeouts.
return false;
if (driver == null)
return false;
commandTimeout = value;
driver.ResetTimeout(commandTimeout * 1000);
return true;
}
/// <summary>
/// Clears query timeout, allowing next SetCommandTimeout() to succeed.
/// </summary>
internal void ClearCommandTimeout()
{
if (!hasBeenOpen)
return;
commandTimeout = 0;
if (driver != null)
{
driver.ResetTimeout(0);
}
}
#endregion
#region GetSchema Support
/// <summary>
/// Returns schema information for the data source of this <see cref="DbConnection"/>.
/// </summary>
/// <returns>A <see cref="DataTable"/> that contains schema information. </returns>
public override DataTable GetSchema()
{
return GetSchema(null);
}
/// <summary>
/// Returns schema information for the data source of this
/// <see cref="DbConnection"/> using the specified string for the schema name.
/// </summary>
/// <param name="collectionName">Specifies the name of the schema to return. </param>
/// <returns>A <see cref="DataTable"/> that contains schema information. </returns>
public override DataTable GetSchema(string collectionName)
{
if (collectionName == null)
collectionName = SchemaProvider.MetaCollection;
return GetSchema(collectionName, null);
}
/// <summary>
/// Returns schema information for the data source of this <see cref="DbConnection"/>
/// using the specified string for the schema name and the specified string array
/// for the restriction values.
/// </summary>
/// <param name="collectionName">Specifies the name of the schema to return.</param>
/// <param name="restrictionValues">Specifies a set of restriction values for the requested schema.</param>
/// <returns>A <see cref="DataTable"/> that contains schema information.</returns>
public override DataTable GetSchema(string collectionName, string[] restrictionValues)
{
if (collectionName == null)
collectionName = SchemaProvider.MetaCollection;
string[] restrictions = schemaProvider.CleanRestrictions(restrictionValues);
DataTable dt = schemaProvider.GetSchema(collectionName, restrictions);
return dt;
}
#endregion
#region Pool Routines
/// <include file='docs/MySqlConnection.xml' path='docs/ClearPool/*'/>
public static void ClearPool(MySqlConnection connection)
{
MySqlPoolManager.ClearPool(connection.Settings);
}
/// <include file='docs/MySqlConnection.xml' path='docs/ClearAllPools/*'/>
public static void ClearAllPools()
{
MySqlPoolManager.ClearAllPools();
}
#endregion
}
/// <summary>
/// Represents the method that will handle the <see cref="MySqlConnection.InfoMessage"/> event of a
/// <see cref="MySqlConnection"/>.
/// </summary>
public delegate void MySqlInfoMessageEventHandler(object sender, MySqlInfoMessageEventArgs args);
/// <summary>
/// Provides data for the InfoMessage event. This class cannot be inherited.
/// </summary>
public class MySqlInfoMessageEventArgs : EventArgs
{
/// <summary>
///
/// </summary>
public MySqlError[] errors;
}
/// <summary>
/// IDisposable wrapper around SetCommandTimeout and ClearCommandTimeout
/// functionality
/// </summary>
internal class CommandTimer:IDisposable
{
bool timeoutSet;
MySqlConnection connection;
public CommandTimer(MySqlConnection connection, int timeout)
{
this.connection = connection;
if (connection != null)
{
timeoutSet = connection.SetCommandTimeout(timeout);
}
}
#region IDisposable Members
public void Dispose()
{
if (timeoutSet)
{
timeoutSet = false;
connection.ClearCommandTimeout();
connection = null;
}
}
#endregion
}
}

@ -0,0 +1,338 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Globalization;
using System.Text;
using MySql.Data.Common;
using MySql.Data.MySqlClient.Properties;
//using System.Security.Cryptography;
//#if CF
//using OpenNETCF.Security.Cryptography;
//#endif
namespace MySql.Data.MySqlClient
{
/// <summary>
/// Summary description for Crypt.
/// </summary>
internal class Crypt
{
// private ctor to prevent creating a default one
private Crypt()
{
}
/* private void Create41Password( string password )
{
SHA1 sha = new SHA1CryptoServiceProvider();
byte[] firstPassBytes = sha.ComputeHash( System.Text.Encoding.Default.GetBytes( password ));
byte[] salt = packet.GetBuffer();
byte[] input = new byte[ firstPassBytes.Length + 4 ];
salt.CopyTo( input, 0 );
firstPassBytes.CopyTo( input, 4 );
byte[] outPass = new byte[100];
byte[] secondPassBytes = sha.ComputeHash( input );
byte[] cryptSalt = new byte[20];
Security.ArrayCrypt( salt, 4, cryptSalt, 0, secondPassBytes, 20 );
Security.ArrayCrypt( cryptSalt, 0, firstPassBytes, 0, firstPassBytes, 20 );
// send the packet
packet = CreatePacket(null);
packet.Write( firstPassBytes, 0, 20 );
SendPacket(packet);
}
*/
/// <summary>
/// Simple XOR scramble
/// </summary>
/// <param name="from">Source array</param>
/// <param name="fromIndex">Index inside source array</param>
/// <param name="to">Destination array</param>
/// <param name="toIndex">Index inside destination array</param>
/// <param name="password">Password used to xor the bits</param>
/// <param name="length">Number of bytes to scramble</param>
private static void XorScramble(byte[] from, int fromIndex, byte[] to, int toIndex,
byte[] password, int length)
{
// make sure we were called properly
if (fromIndex < 0 || fromIndex >= from.Length)
throw new ArgumentException(Resources.IndexMustBeValid, "fromIndex");
if ((fromIndex + length) > from.Length)
throw new ArgumentException(Resources.FromAndLengthTooBig, "fromIndex");
if (from == null)
throw new ArgumentException(Resources.BufferCannotBeNull, "from");
if (to == null)
throw new ArgumentException(Resources.BufferCannotBeNull, "to");
if (toIndex < 0 || toIndex >= to.Length)
throw new ArgumentException(Resources.IndexMustBeValid, "toIndex");
if ((toIndex + length) > to.Length)
throw new ArgumentException(Resources.IndexAndLengthTooBig, "toIndex");
if (password == null || password.Length < length)
throw new ArgumentException(Resources.PasswordMustHaveLegalChars, "password");
if (length < 0)
throw new ArgumentException(Resources.ParameterCannotBeNegative, "count");
// now perform the work
for (int i = 0; i < length; i++)
to[toIndex++] = (byte) (from[fromIndex++] ^ password[i]);
}
/// <summary>
/// Generate a scrambled password for 4.1.0 using new passwords
/// </summary>
/// <param name="password">The password to scramble</param>
/// <param name="seedBytes">The seedbytes used to scramble</param>
/// <returns>Array of bytes containing the scrambled password</returns>
public static byte[] Get410Password(string password, byte[] seedBytes)
{
SHA1Hash sha = new SHA1Hash();
//SHA1 sha = new SHA1CryptoServiceProvider();
// clean it and then digest it
password = password.Replace(" ", "").Replace("\t", "");
byte[] passBytes = Encoding.Default.GetBytes(password);
byte[] firstPass = sha.ComputeHash(passBytes);
byte[] input = new byte[24];
Array.Copy(seedBytes, 0, input, 0, 4);
Array.Copy(firstPass, 0, input, 4, 20);
byte[] secondPass = sha.ComputeHash(input);
byte[] scrambledBuff = new byte[20];
XorScramble(seedBytes, 4, scrambledBuff, 0, secondPass, 20);
byte[] finalBuff = new byte[20];
XorScramble(scrambledBuff, 0, finalBuff, 0, firstPass, 20);
return finalBuff;
}
/// <summary>
/// Generates a proper hash for old style 4.1.0 passwords. This would be used
/// if a 4.1.0 server contained old 16 byte hashes.
/// </summary>
/// <param name="password">The password to hash</param>
/// <param name="seedBytes">Seed bytes received from the server</param>
/// <returns>Byte array containing the password hash</returns>
public static byte[] GetOld410Password(string password, byte[] seedBytes)
{
long[] passwordHash = Hash(password);
string passHex = String.Format(CultureInfo.InvariantCulture,
"{0,8:X}{1,8:X}", passwordHash[0], passwordHash[1]);
int[] salt = getSaltFromPassword(passHex);
// compute binary password
byte[] binaryPassword = new byte[20];
int offset = 0;
for (int i = 0; i < 2; i++)
{
int val = salt[i];
for (int t = 3; t >= 0; t--)
{
binaryPassword[t + offset] = (byte) (val%256);
val >>= 8; /* Scroll 8 bits to get next part*/
}
offset += 4;
}
//SHA1 sha = new SHA1CryptoServiceProvider();
SHA1Hash sha = new SHA1Hash();
byte[] temp = new byte[8];
Buffer.BlockCopy(binaryPassword, 0, temp, 0, 8);
byte[] binaryHash = sha.ComputeHash(temp);
byte[] scrambledBuff = new byte[20];
XorScramble(seedBytes, 4, scrambledBuff, 0, binaryHash, 20);
string scrambleString = Encoding.Default.GetString(scrambledBuff, 0, scrambledBuff.Length).Substring(0, 8);
long[] hashPass = Hash(password);
long[] hashMessage = Hash(scrambleString);
long max = 0x3FFFFFFFL;
byte[] to = new byte[20];
int msgPos = 0;
int msgLength = scrambleString.Length;
int toPos = 0;
long seed1 = (hashPass[0] ^ hashMessage[0])%max;
long seed2 = (hashPass[1] ^ hashMessage[1])%max;
while (msgPos++ < msgLength)
to[toPos++] = (byte) (Math.Floor(rand(ref seed1, ref seed2, max)*31) + 64);
/* Make it harder to break */
byte extra = (byte) (Math.Floor(rand(ref seed1, ref seed2, max)*31));
for (int i = 0; i < 8; i++)
to[i] ^= extra;
return to;
}
/// <summary>
/// Returns a byte array containing the proper encryption of the
/// given password/seed according to the new 4.1.1 authentication scheme.
/// </summary>
/// <param name="password"></param>
/// <param name="seed"></param>
/// <returns></returns>
public static byte[] Get411Password(string password, string seed)
{
// if we have no password, then we just return 1 zero byte
if (password.Length == 0) return new byte[1];
//SHA1 sha = new SHA1CryptoServiceProvider();
SHA1Hash sha = new SHA1Hash();
byte[] firstHash = sha.ComputeHash(Encoding.Default.GetBytes(password));
byte[] secondHash = sha.ComputeHash(firstHash);
byte[] seedBytes = Encoding.Default.GetBytes(seed);
byte[] input = new byte[seedBytes.Length + secondHash.Length];
Array.Copy(seedBytes, 0, input, 0, seedBytes.Length);
Array.Copy(secondHash, 0, input, seedBytes.Length, secondHash.Length);
byte[] thirdHash = sha.ComputeHash(input);
byte[] finalHash = new byte[thirdHash.Length + 1];
finalHash[0] = 0x14;
Array.Copy(thirdHash, 0, finalHash, 1, thirdHash.Length);
for (int i = 1; i < finalHash.Length; i++)
finalHash[i] = (byte) (finalHash[i] ^ firstHash[i - 1]);
return finalHash;
}
private static int[] getSaltFromPassword(String password)
{
int[] result = new int[6];
if (password == null || password.Length == 0)
return result;
int resultPos = 0;
int pos = 0;
while (pos < password.Length)
{
int val = 0;
for (int i = 0; i < 8; i++)
val = (val << 4) + HexValue(password[pos++]);
result[resultPos++] = val;
}
return result;
}
private static int HexValue(char c)
{
if (c >= 'A' && c <= 'Z') return (c - 'A') + 10;
if (c >= 'a' && c <= 'z') return (c - 'a') + 10;
return c - '0';
}
private static double rand(ref long seed1, ref long seed2, long max)
{
seed1 = (seed1*3) + seed2;
seed1 %= max;
seed2 = (seed1 + seed2 + 33)%max;
return (seed1/(double) max);
}
/// <summary>
/// Encrypts a password using the MySql encryption scheme
/// </summary>
/// <param name="password">The password to encrypt</param>
/// <param name="seed">The encryption seed the server gave us</param>
/// <param name="new_ver">Indicates if we should use the old or new encryption scheme</param>
/// <returns></returns>
public static String EncryptPassword(String password, String seed, bool new_ver)
{
long max = 0x3fffffff;
if (! new_ver)
max = 0x01FFFFFF;
if (password == null || password.Length == 0)
return password;
long[] hash_seed = Hash(seed);
long[] hash_pass = Hash(password);
long seed1 = (hash_seed[0] ^ hash_pass[0])%max;
long seed2 = (hash_seed[1] ^ hash_pass[1])%max;
if (! new_ver)
seed2 = seed1/2;
char[] scrambled = new char[seed.Length];
for (int x = 0; x < seed.Length; x++)
{
double r = rand(ref seed1, ref seed2, max);
scrambled[x] = (char) (Math.Floor(r*31) + 64);
}
if (new_ver)
{
/* Make it harder to break */
char extra = (char) Math.Floor(rand(ref seed1, ref seed2, max)*31);
for (int x = 0; x < scrambled.Length; x++)
scrambled[x] ^= extra;
}
return new string(scrambled);
}
/// <summary>
/// Hashes a password using the algorithm from Monty's code.
/// The first element in the return is the result of the "old" hash.
/// The second element is the rest of the "new" hash.
/// </summary>
/// <param name="P">Password to be hashed</param>
/// <returns>Two element array containing the hashed values</returns>
private static long[] Hash(String P)
{
long val1 = 1345345333;
long val2 = 0x12345671;
long inc = 7;
for (int i = 0; i < P.Length; i++)
{
if (P[i] == ' ' || P[i] == '\t') continue;
long temp = (0xff & P[i]);
val1 ^= (((val1 & 63) + inc)*temp) + (val1 << 8);
val2 += (val2 << 8) ^ val1;
inc += temp;
}
long[] hash = new long[2];
hash[0] = val1 & 0x7fffffff;
hash[1] = val2 & 0x7fffffff;
return hash;
}
}
}

@ -0,0 +1,513 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Collections;
using System.Globalization;
using System.Text;
using MySql.Data.Common;
using MySql.Data.Types;
using MySql.Data.MySqlClient.Properties;
using System.Diagnostics;
using System.Collections.Generic;
namespace MySql.Data.MySqlClient
{
/// <summary>
/// Summary description for BaseDriver.
/// </summary>
internal class Driver : IDisposable
{
protected Encoding encoding;
protected MySqlConnectionStringBuilder connectionString;
protected ClientFlags serverCaps;
protected bool isOpen;
protected DateTime creationTime;
protected string serverCharSet;
protected int serverCharSetIndex;
protected Hashtable serverProps;
protected Hashtable charSets;
protected long maxPacketSize;
private DateTime idleSince;
#if !CF
protected MySqlPromotableTransaction currentTransaction;
protected bool inActiveUse;
#endif
protected MySqlPool pool;
private bool firstResult;
protected IDriver handler;
internal MySqlDataReader reader;
/// <summary>
/// For pooled connections, time when the driver was
/// put into idle queue
/// </summary>
public DateTime IdleSince
{
get { return idleSince; }
set { idleSince = value; }
}
public Driver(MySqlConnectionStringBuilder settings)
{
encoding = Encoding.GetEncoding(1252);
if (encoding == null)
throw new MySqlException(Resources.DefaultEncodingNotFound);
connectionString = settings;
serverCharSet = "latin1";
serverCharSetIndex = -1;
maxPacketSize = 1024;
handler = new NativeDriver(this);
}
~Driver()
{
Close();
}
#region Properties
public int ThreadID
{
get { return handler.ThreadId; }
}
public DBVersion Version
{
get { return handler.Version; }
}
public MySqlConnectionStringBuilder Settings
{
get { return connectionString; }
set { connectionString = value; }
}
public Encoding Encoding
{
get { return encoding; }
set { encoding = value; }
}
#if !CF
public MySqlPromotableTransaction CurrentTransaction
{
get { return currentTransaction; }
set { currentTransaction = value; }
}
public bool IsInActiveUse
{
get { return inActiveUse; }
set { inActiveUse = value; }
}
#endif
public bool IsOpen
{
get { return isOpen; }
}
public MySqlPool Pool
{
get { return pool; }
set { pool = value; }
}
public long MaxPacketSize
{
get { return maxPacketSize; }
}
internal int ConnectionCharSetIndex
{
get { return serverCharSetIndex; }
set { serverCharSetIndex = value; }
}
internal Hashtable CharacterSets
{
get { return charSets; }
}
public bool SupportsOutputParameters
{
get { return Version.isAtLeast(6,0,8); }
}
/// <summary>
/// Returns true if this connection can handle batch SQL natively
/// This means MySQL 4.1.1 or later.
/// </summary>
public bool SupportsBatch
{
get
{
if ((handler.Flags & ClientFlags.MULTI_STATEMENTS) != 0)
{
if (Version.isAtLeast(4, 1, 0) && !Version.isAtLeast(4, 1, 10))
{
object qtType = serverProps["query_cache_type"];
object qtSize = serverProps["query_cache_size"];
if (qtType != null && qtType.Equals("ON") &&
(qtSize != null && !qtSize.Equals("0")))
return false;
}
return true;
}
return false;
}
}
#endregion
public string Property(string key)
{
return (string) serverProps[key];
}
public bool ConnectionLifetimeExpired()
{
TimeSpan ts = DateTime.Now.Subtract(creationTime);
if (Settings.ConnectionLifeTime != 0 &&
ts.TotalSeconds > Settings.ConnectionLifeTime)
return true;
return false;
}
public static Driver Create(MySqlConnectionStringBuilder settings)
{
Driver d = null;
#if !CF
if (settings.Logging || settings.UseUsageAdvisor)
d = new TracingDriver(settings);
else
#endif
d = new Driver(settings);
d.Open();
return d;
}
public bool HasStatus(ServerStatusFlags flag)
{
return (handler.ServerStatus & flag) != 0;
}
public virtual void Open()
{
creationTime = DateTime.Now;
handler.Open();
isOpen = true;
}
public virtual void Close()
{
Dispose();
}
public virtual void Configure(MySqlConnection connection)
{
bool firstConfigure = false;
// if we have not already configured our server variables
// then do so now
if (serverProps == null)
{
firstConfigure = true;
// load server properties
serverProps = new Hashtable();
MySqlCommand cmd = new MySqlCommand("SHOW VARIABLES", connection);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
try
{
while (reader.Read())
{
string key = reader.GetString(0);
string value = reader.GetString(1);
serverProps[key] = value;
}
}
catch (Exception ex)
{
MySqlTrace.LogError(ThreadID, ex.Message);
throw;
}
}
if (serverProps.Contains("max_allowed_packet"))
maxPacketSize = Convert.ToInt64(serverProps["max_allowed_packet"]);
LoadCharacterSets(connection);
}
#if AUTHENTICATED
string licenseType = serverProps["license"];
if (licenseType == null || licenseType.Length == 0 ||
licenseType != "commercial")
throw new MySqlException( "This client library licensed only for use with commercially-licensed MySQL servers." );
#endif
// if the user has indicated that we are not to reset
// the connection and this is not our first time through,
// then we are done.
if (!Settings.ConnectionReset && !firstConfigure) return;
string charSet = connectionString.CharacterSet;
if (charSet == null || charSet.Length == 0)
{
if (serverCharSetIndex >= 0)
charSet = (string) charSets[serverCharSetIndex];
else
charSet = serverCharSet;
}
// now tell the server which character set we will send queries in and which charset we
// want results in
MySqlCommand charSetCmd = new MySqlCommand("SET character_set_results=NULL",
connection);
object clientCharSet = serverProps["character_set_client"];
object connCharSet = serverProps["character_set_connection"];
if ((clientCharSet != null && clientCharSet.ToString() != charSet) ||
(connCharSet != null && connCharSet.ToString() != charSet))
{
MySqlCommand setNamesCmd = new MySqlCommand("SET NAMES " + charSet, connection);
setNamesCmd.ExecuteNonQuery();
}
charSetCmd.ExecuteNonQuery();
if (charSet != null)
Encoding = CharSetMap.GetEncoding(Version, charSet);
else
Encoding = CharSetMap.GetEncoding(Version, "latin1");
handler.Configure();
}
/// <summary>
/// Loads all the current character set names and ids for this server
/// into the charSets hashtable
/// </summary>
private void LoadCharacterSets(MySqlConnection connection)
{
MySqlCommand cmd = new MySqlCommand("SHOW COLLATION", connection);
// now we load all the currently active collations
try
{
using (MySqlDataReader reader = cmd.ExecuteReader())
{
charSets = new Hashtable();
while (reader.Read())
{
charSets[Convert.ToInt32(reader["id"], NumberFormatInfo.InvariantInfo)] =
reader.GetString(reader.GetOrdinal("charset"));
}
}
}
catch (Exception ex)
{
MySqlTrace.LogError(ThreadID, ex.Message);
throw;
}
}
public virtual List<MySqlError> ReportWarnings(MySqlConnection connection)
{
List<MySqlError> warnings = new List<MySqlError>();
MySqlCommand cmd = new MySqlCommand("SHOW WARNINGS", connection);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
warnings.Add(new MySqlError(reader.GetString(0),
reader.GetInt32(1), reader.GetString(2)));
}
}
MySqlInfoMessageEventArgs args = new MySqlInfoMessageEventArgs();
args.errors = warnings.ToArray();
if (connection != null)
connection.OnInfoMessage(args);
return warnings;
}
public virtual void SendQuery(MySqlPacket p)
{
handler.SendQuery(p);
firstResult = true;
}
public virtual ResultSet NextResult(int statementId)
{
if (!firstResult && !HasStatus(ServerStatusFlags.AnotherQuery | ServerStatusFlags.MoreResults))
return null;
firstResult = false;
int affectedRows = -1, insertedId = -1, warnings = 0;
int fieldCount = GetResult(statementId, ref affectedRows, ref insertedId);
if (fieldCount == -1)
return null;
if (fieldCount > 0)
return new ResultSet(this, statementId, fieldCount);
else
return new ResultSet(affectedRows, insertedId);
}
protected virtual int GetResult(int statementId, ref int affectedRows, ref int insertedId)
{
return handler.GetResult(ref affectedRows, ref insertedId);
}
public virtual bool FetchDataRow(int statementId, int columns)
{
return handler.FetchDataRow(statementId, columns);
}
public virtual bool SkipDataRow()
{
return FetchDataRow(-1, 0);
}
public virtual void ExecuteDirect(string sql)
{
MySqlPacket p = new MySqlPacket(Encoding);
p.WriteString(sql);
SendQuery(p);
NextResult(0);
}
public MySqlField[] GetColumns(int count)
{
MySqlField[] fields = new MySqlField[count];
for (int i = 0; i < count; i++)
fields[i] = new MySqlField(this);
handler.GetColumnsData(fields);
return fields;
}
public virtual int PrepareStatement(string sql, ref MySqlField[] parameters)
{
return handler.PrepareStatement(sql, ref parameters);
}
public IMySqlValue ReadColumnValue(int index, MySqlField field, IMySqlValue value)
{
return handler.ReadColumnValue(index, field, value);
}
public void SkipColumnValue(IMySqlValue valObject)
{
handler.SkipColumnValue(valObject);
}
public void ResetTimeout(int timeoutMilliseconds)
{
handler.ResetTimeout(timeoutMilliseconds);
}
public bool Ping()
{
return handler.Ping();
}
public virtual void SetDatabase(string dbName)
{
handler.SetDatabase(dbName);
}
public virtual void ExecuteStatement(MySqlPacket packetToExecute)
{
handler.ExecuteStatement(packetToExecute);
}
public virtual void CloseStatement(int id)
{
handler.CloseStatement(id);
}
public virtual void Reset()
{
handler.Reset();
}
public virtual void CloseQuery(MySqlConnection connection, int statementId)
{
if (handler.WarningCount > 0)
ReportWarnings(connection);
}
#region IDisposable Members
protected virtual void Dispose(bool disposing)
{
ResetTimeout(1000);
if (disposing)
handler.Close(isOpen);
// if we are pooling, then release ourselves
if (connectionString.Pooling)
MySqlPoolManager.RemoveConnection(this);
isOpen = false;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
internal bool isExecutingBuggyQuery;
internal bool IsExecutingBuggyQuery
{
get { return isExecutingBuggyQuery; }
set { isExecutingBuggyQuery = value; }
}
#endregion
}
internal interface IDriver
{
int ThreadId { get; }
DBVersion Version { get; }
ServerStatusFlags ServerStatus { get; }
ClientFlags Flags { get; }
void Configure();
void Open();
void SendQuery(MySqlPacket packet);
void Close(bool isOpen);
bool Ping();
int GetResult(ref int affectedRows, ref int insertedId);
bool FetchDataRow(int statementId, int columns);
int PrepareStatement(string sql, ref MySqlField[] parameters);
void ExecuteStatement(MySqlPacket packet);
void CloseStatement(int statementId);
void SetDatabase(string dbName);
void Reset();
IMySqlValue ReadColumnValue(int index, MySqlField field, IMySqlValue valObject);
void SkipColumnValue(IMySqlValue valueObject);
void GetColumnsData(MySqlField[] columns);
void ResetTimeout(int timeout);
int WarningCount { get; }
}
}

@ -0,0 +1,94 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Common;
#if !CF
using System.Runtime.Serialization;
#endif
namespace MySql.Data.MySqlClient
{
/// <summary>
/// The exception that is thrown when MySQL returns an error. This class cannot be inherited.
/// </summary>
/// <include file='docs/MySqlException.xml' path='MyDocs/MyMembers[@name="Class"]/*'/>
#if !CF
[Serializable]
#endif
public sealed class MySqlException : DbException
{
private int errorCode;
private bool isFatal;
internal MySqlException()
{
}
internal MySqlException(string msg) : base(msg)
{
}
internal MySqlException(string msg, Exception ex) : base(msg, ex)
{
}
internal MySqlException(string msg, bool isFatal, Exception inner) : base (msg, inner)
{
this.isFatal = isFatal;
}
internal MySqlException(string msg, int errno, Exception inner)
: this(msg, inner)
{
errorCode = errno;
#if !CF
Data.Add("Server Error Code", errno);
#endif
}
internal MySqlException(string msg, int errno)
: this(msg, errno, null)
{
}
#if !CF
private MySqlException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
#endif
/// <summary>
/// Gets a number that identifies the type of error.
/// </summary>
public int Number
{
get { return errorCode; }
}
/// <summary>
/// True if this exception was fatal and cause the closing of the connection, false otherwise.
/// </summary>
internal bool IsFatal
{
get { return isFatal; }
}
}
}

@ -0,0 +1,417 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Text;
using MySql.Data.Common;
using MySql.Data.Types;
using System.Globalization;
using System.Text.RegularExpressions;
using System;
using System.Collections;
using System.Collections.Generic;
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;
public int maxLength;
// protected fields
protected ColumnFlags colFlags;
protected int charSetIndex;
protected byte precision;
protected byte scale;
protected MySqlDbType mySqlDbType;
protected DBVersion connVersion;
protected Driver driver;
protected bool binaryOk;
protected List<Type> typeConversions = new List<Type>();
#endregion
public MySqlField(Driver driver)
{
this.driver = driver;
connVersion = driver.Version;
maxLength = 1;
binaryOk = true;
}
#region Properties
public int CharacterSetIndex
{
get { return charSetIndex; }
set { charSetIndex = value; SetFieldEncoding(); }
}
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 int MaxLength
{
get { return maxLength; }
set { maxLength = 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 (mySqlDbType >= MySqlDbType.TinyBlob &&
mySqlDbType <= MySqlDbType.Blob) ||
(mySqlDbType >= MySqlDbType.TinyText &&
mySqlDbType <= MySqlDbType.Text) ||
(colFlags & ColumnFlags.BLOB) > 0;
}
}
public bool IsBinary
{
get
{
return binaryOk && (CharacterSetIndex == 63);
}
}
public bool IsUnsigned
{
get { return (colFlags & ColumnFlags.UNSIGNED) > 0; }
}
public bool IsTextField
{
get
{
return Type == MySqlDbType.VarString || Type == MySqlDbType.VarChar ||
(IsBlob && !IsBinary);
}
}
public int CharacterLength
{
get { return ColumnLength / MaxLength; }
}
public List<Type> TypeConversions
{
get { return typeConversions; }
}
#endregion
public void SetTypeAndFlags(MySqlDbType type, ColumnFlags flags)
{
colFlags = flags;
mySqlDbType = type;
if (String.IsNullOrEmpty(TableName) && String.IsNullOrEmpty(RealTableName) &&
driver.Settings.FunctionsReturnString)
{
mySqlDbType = MySqlDbType.VarString;
// we are treating a binary as string so we have to choose some
// charset index. Connection seems logical.
CharacterSetIndex = driver.ConnectionCharSetIndex;
binaryOk = false;
}
// if our type is an unsigned number, then we need
// to bump it up into our unsigned types
// we're trusting that the server is not going to set the UNSIGNED
// flag unless we are a number
if (IsUnsigned)
{
switch (type)
{
case MySqlDbType.Byte:
mySqlDbType = MySqlDbType.UByte;
return;
case MySqlDbType.Int16:
mySqlDbType = MySqlDbType.UInt16;
return;
case MySqlDbType.Int24:
mySqlDbType = MySqlDbType.UInt24;
return;
case MySqlDbType.Int32:
mySqlDbType = MySqlDbType.UInt32;
return;
case MySqlDbType.Int64:
mySqlDbType = MySqlDbType.UInt64;
return;
}
}
if (IsBlob)
{
// handle blob to UTF8 conversion if requested. This is only activated
// on binary blobs
if (IsBinary && driver.Settings.TreatBlobsAsUTF8)
{
bool convertBlob = false;
Regex includeRegex = driver.Settings.GetBlobAsUTF8IncludeRegex();
Regex excludeRegex = driver.Settings.GetBlobAsUTF8ExcludeRegex();
if (includeRegex != null && includeRegex.IsMatch(ColumnName))
convertBlob = true;
else if (includeRegex == null && excludeRegex != null &&
!excludeRegex.IsMatch(ColumnName))
convertBlob = true;
if (convertBlob)
{
binaryOk = false;
Encoding = System.Text.Encoding.GetEncoding("UTF-8");
charSetIndex = -1; // lets driver know we are in charge of encoding
maxLength = 4;
}
}
if (!IsBinary)
{
if (type == MySqlDbType.TinyBlob)
mySqlDbType = MySqlDbType.TinyText;
else if (type == MySqlDbType.MediumBlob)
mySqlDbType = MySqlDbType.MediumText;
else if (type == MySqlDbType.Blob)
mySqlDbType = MySqlDbType.Text;
else if (type == MySqlDbType.LongBlob)
mySqlDbType = MySqlDbType.LongText;
}
}
// now determine if we really should be binary
if (driver.Settings.RespectBinaryFlags)
CheckForExceptions();
if (Type == MySqlDbType.String && CharacterLength == 36 && !driver.Settings.OldGuids)
mySqlDbType = MySqlDbType.Guid;
if (!IsBinary) return;
if (driver.Settings.RespectBinaryFlags)
{
if (type == MySqlDbType.String)
mySqlDbType = MySqlDbType.Binary;
else if (type == MySqlDbType.VarChar ||
type == MySqlDbType.VarString)
mySqlDbType = MySqlDbType.VarBinary;
}
if (CharacterSetIndex == 63)
CharacterSetIndex = driver.ConnectionCharSetIndex;
if (Type == MySqlDbType.Binary && ColumnLength == 16 && driver.Settings.OldGuids)
mySqlDbType = MySqlDbType.Guid;
}
public void AddTypeConversion(Type t)
{
if (TypeConversions.Contains(t)) return;
TypeConversions.Add(t);
}
private void CheckForExceptions()
{
string colName = String.Empty;
if (OriginalColumnName != null)
colName = OriginalColumnName.ToUpper(CultureInfo.InvariantCulture);
if (colName.StartsWith("CHAR("))
binaryOk = false;
else if (driver.IsExecutingBuggyQuery)
binaryOk = false;
}
public IMySqlValue GetValueObject()
{
IMySqlValue v = GetIMySqlValue(Type);
if (v is MySqlByte && ColumnLength == 1 && driver.Settings.TreatTinyAsBoolean)
{
MySqlByte b = (MySqlByte)v;
b.TreatAsBoolean = true;
v = b;
}
else if (v is MySqlGuid)
{
MySqlGuid g = (MySqlGuid)v;
g.OldGuids = driver.Settings.OldGuids;
v = g;
}
return v;
}
public static IMySqlValue GetIMySqlValue(MySqlDbType type)
{
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.VarString:
case MySqlDbType.VarChar:
case MySqlDbType.Text:
case MySqlDbType.TinyText:
case MySqlDbType.MediumText:
case MySqlDbType.LongText:
case (MySqlDbType) Field_Type.NULL:
return new MySqlString(type, true);
case MySqlDbType.Geometry:
case MySqlDbType.Blob:
case MySqlDbType.MediumBlob:
case MySqlDbType.LongBlob:
case MySqlDbType.TinyBlob:
case MySqlDbType.Binary:
case MySqlDbType.VarBinary:
return new MySqlBinary(type, true);
case MySqlDbType.Guid:
return new MySqlGuid();
default:
throw new MySqlException("Unknown data type");
}
}
private void SetFieldEncoding()
{
Hashtable charSets = driver.CharacterSets;
DBVersion version = driver.Version;
if (charSets == null || CharacterSetIndex == -1) return;
if (charSets[CharacterSetIndex] == null) return;
CharacterSet cs = CharSetMap.GetCharacterSet(version, (string)charSets[CharacterSetIndex]);
// starting with 6.0.4 utf8 has a maxlen of 4 instead of 3. The old
// 3 byte utf8 is utf8mb3
if (cs.name.ToLower(System.Globalization.CultureInfo.InvariantCulture) == "utf-8" &&
version.Major >= 6)
MaxLength = 4;
else
MaxLength = cs.byteCount;
Encoding = CharSetMap.GetEncoding(version, (string)charSets[CharacterSetIndex]);
}
}
}

@ -0,0 +1,694 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Text;
using MySql.Data.Common;
using System.Globalization;
using System.Diagnostics;
using System.Data.SqlTypes;
using MySql.Data.Types;
using System.Collections;
using MySql.Data.MySqlClient.Properties;
namespace MySql.Data.MySqlClient
{
internal class ISSchemaProvider : SchemaProvider
{
public ISSchemaProvider(MySqlConnection connection) : base(connection)
{
}
protected override DataTable GetCollections()
{
DataTable dt = base.GetCollections();
object[][] collections = new object[][]
{
new object[] {"Views", 2, 3},
new object[] {"ViewColumns", 3, 4},
new object[] {"Procedure Parameters", 5, 1},
new object[] {"Procedures", 4, 3},
new object[] {"Triggers", 2, 4}
};
FillTable(dt, collections);
return dt;
}
protected override DataTable GetRestrictions()
{
DataTable dt = base.GetRestrictions();
object[][] restrictions = new object[][]
{
new object[] {"Procedure Parameters", "Database", "", 0},
new object[] {"Procedure Parameters", "Schema", "", 1},
new object[] {"Procedure Parameters", "Name", "", 2},
new object[] {"Procedure Parameters", "Type", "", 3},
new object[] {"Procedure Parameters", "Parameter", "", 4},
new object[] {"Procedures", "Database", "", 0},
new object[] {"Procedures", "Schema", "", 1},
new object[] {"Procedures", "Name", "", 2},
new object[] {"Procedures", "Type", "", 3},
new object[] {"Views", "Database", "", 0},
new object[] {"Views", "Schema", "", 1},
new object[] {"Views", "Table", "", 2},
new object[] {"ViewColumns", "Database", "", 0},
new object[] {"ViewColumns", "Schema", "", 1},
new object[] {"ViewColumns", "Table", "", 2},
new object[] {"ViewColumns", "Column", "", 3},
new object[] {"Triggers", "Database", "", 0},
new object[] {"Triggers", "Schema", "", 1},
new object[] {"Triggers", "Name", "", 2},
new object[] {"Triggers", "EventObjectTable", "", 3},
};
FillTable(dt, restrictions);
return dt;
}
public override DataTable GetDatabases(string[] restrictions)
{
string[] keys = new string[1];
keys[0] = "SCHEMA_NAME";
DataTable dt = Query("SCHEMATA", "", keys, restrictions);
dt.Columns[1].ColumnName = "database_name";
dt.TableName = "Databases";
return dt;
}
public override DataTable GetTables(string[] restrictions)
{
string[] keys = new string[4];
keys[0] = "TABLE_CATALOG";
keys[1] = "TABLE_SCHEMA";
keys[2] = "TABLE_NAME";
keys[3] = "TABLE_TYPE";
DataTable dt = Query("TABLES", "TABLE_TYPE != 'VIEW'", keys, restrictions);
dt.TableName = "Tables";
return dt;
}
public override DataTable GetColumns(string[] restrictions)
{
string[] keys = new string[4];
keys[0] = "TABLE_CATALOG";
keys[1] = "TABLE_SCHEMA";
keys[2] = "TABLE_NAME";
keys[3] = "COLUMN_NAME";
DataTable dt = Query("COLUMNS", null, keys, restrictions);
dt.Columns.Remove("CHARACTER_OCTET_LENGTH");
dt.TableName = "Columns";
return dt;
}
private DataTable GetViews(string[] restrictions)
{
string[] keys = new string[3];
keys[0] = "TABLE_CATALOG";
keys[1] = "TABLE_SCHEMA";
keys[2] = "TABLE_NAME";
DataTable dt = Query("VIEWS", null, keys, restrictions);
dt.TableName = "Views";
return dt;
}
private DataTable GetViewColumns(string[] restrictions)
{
StringBuilder where = new StringBuilder();
StringBuilder sql = new StringBuilder(
"SELECT C.* FROM information_schema.columns C");
sql.Append(" JOIN information_schema.views V ");
sql.Append("ON C.table_schema=V.table_schema AND C.table_name=V.table_name ");
if (restrictions != null && restrictions.Length >= 2 &&
restrictions[1] != null)
where.AppendFormat(CultureInfo.InvariantCulture, "C.table_schema='{0}' ", restrictions[1]);
if (restrictions != null && restrictions.Length >= 3 &&
restrictions[2] != null)
{
if (where.Length > 0)
where.Append("AND ");
where.AppendFormat(CultureInfo.InvariantCulture, "C.table_name='{0}' ", restrictions[2]);
}
if (restrictions != null && restrictions.Length == 4 &&
restrictions[3] != null)
{
if (where.Length > 0)
where.Append("AND ");
where.AppendFormat(CultureInfo.InvariantCulture, "C.column_name='{0}' ", restrictions[3]);
}
if (where.Length > 0)
sql.AppendFormat(CultureInfo.InvariantCulture, " WHERE {0}", where);
DataTable dt = GetTable(sql.ToString());
dt.TableName = "ViewColumns";
dt.Columns[0].ColumnName = "VIEW_CATALOG";
dt.Columns[1].ColumnName = "VIEW_SCHEMA";
dt.Columns[2].ColumnName = "VIEW_NAME";
return dt;
}
private DataTable GetTriggers(string[] restrictions)
{
string[] keys = new string[4];
keys[0] = "TRIGGER_CATALOG";
keys[1] = "TRIGGER_SCHEMA";
keys[2] = "EVENT_OBJECT_TABLE";
keys[3] = "TRIGGER_NAME";
DataTable dt = Query("TRIGGERS", null, keys, restrictions);
dt.TableName = "Triggers";
return dt;
}
/// <summary>
/// Return schema information about procedures and functions
/// Restrictions supported are:
/// schema, name, type
/// </summary>
/// <param name="restrictions"></param>
/// <returns></returns>
public override DataTable GetProcedures(string[] restrictions)
{
// if the user has said that we have access to mysql.proc then
// we use that as it is a lot faster
// if (connection.HasProcAccess)
// return base.GetProcedures(restrictions);
string[] keys = new string[4];
keys[0] = "ROUTINE_CATALOG";
keys[1] = "ROUTINE_SCHEMA";
keys[2] = "ROUTINE_NAME";
keys[3] = "ROUTINE_TYPE";
DataTable dt = Query("ROUTINES", null, keys, restrictions);
dt.TableName = "Procedures";
return dt;
}
private DataTable GetProceduresWithParameters(string[] restrictions)
{
DataTable dt = GetProcedures(restrictions);
dt.Columns.Add("ParameterList", typeof(string));
foreach (DataRow row in dt.Rows)
{
row["ParameterList"] = GetProcedureParameterLine(row);
}
return dt;
}
private string GetProcedureParameterLine(DataRow isRow)
{
string sql = "SHOW CREATE {0} `{1}`.`{2}`";
sql = String.Format(sql, isRow["ROUTINE_TYPE"], isRow["ROUTINE_SCHEMA"],
isRow["ROUTINE_NAME"]);
MySqlCommand cmd = new MySqlCommand(sql, connection);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
reader.Read();
// if we are not the owner of this proc or have permissions
// then we will get null for the body
if (reader.IsDBNull(2)) return null;
string sql_mode = reader.GetString(1);
string body = reader.GetString(2);
MySqlTokenizer tokenizer = new MySqlTokenizer(body);
tokenizer.AnsiQuotes = sql_mode.IndexOf("ANSI_QUOTES") != -1;
tokenizer.BackslashEscapes = sql_mode.IndexOf("NO_BACKSLASH_ESCAPES") == -1;
string token = tokenizer.NextToken();
while (token != "(")
token = tokenizer.NextToken();
int start = tokenizer.StartIndex + 1;
token = tokenizer.NextToken();
while (token != ")" || tokenizer.Quoted)
{
token = tokenizer.NextToken();
// if we see another ( and we are not quoted then we
// are in a size element and we need to look for the closing paren
if (token == "(" && !tokenizer.Quoted)
{
while (token != ")" || tokenizer.Quoted)
token = tokenizer.NextToken();
token = tokenizer.NextToken();
}
}
return body.Substring(start, tokenizer.StartIndex - start);
}
}
private void GetParametersForRoutineFromIS(DataTable dt, string[] restrictions)
{
Debug.Assert(dt != null);
string[] keys = new string[5];
keys[0] = "SPECIFIC_CATALOG";
keys[1] = "SPECIFIC_SCHEMA";
keys[2] = "SPECIFIC_NAME";
keys[3] = "ROUTINE_TYPE";
keys[4] = "PARAMETER_NAME";
StringBuilder sql = new StringBuilder(@"SELECT * FROM INFORMATION_SCHEMA.PARAMETERS");
// now get our where clause and append it if there is one
string where = GetWhereClause(null, keys, restrictions);
if (!String.IsNullOrEmpty(where))
sql.AppendFormat(CultureInfo.InvariantCulture, " WHERE {0}", where);
MySqlDataAdapter da = new MySqlDataAdapter(sql.ToString(), connection);
da.Fill(dt);
}
private DataTable GetParametersFromIS(string[] restrictions, DataTable routines)
{
DataTable parms = new DataTable();
if (routines == null || routines.Rows.Count == 0)
{
if (restrictions == null)
{
// first fill our table with the proper structure
MySqlDataAdapter da = new MySqlDataAdapter("SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE 1=2", connection);
da.Fill(parms);
}
else
GetParametersForRoutineFromIS(parms, restrictions);
}
else foreach (DataRow routine in routines.Rows)
{
if (restrictions != null && restrictions.Length >= 3)
restrictions[2] = routine["ROUTINE_NAME"].ToString();
GetParametersForRoutineFromIS(parms, restrictions);
}
parms.TableName = "Procedure Parameters";
return parms;
}
internal DataTable CreateParametersTable()
{
DataTable dt = new DataTable("Procedure Parameters");
dt.Columns.Add("SPECIFIC_CATALOG", typeof(string));
dt.Columns.Add("SPECIFIC_SCHEMA", typeof(string));
dt.Columns.Add("SPECIFIC_NAME", typeof(string));
dt.Columns.Add("ORDINAL_POSITION", typeof(Int32));
dt.Columns.Add("PARAMETER_MODE", typeof(string));
dt.Columns.Add("PARAMETER_NAME", typeof(string));
dt.Columns.Add("DATA_TYPE", typeof(string));
dt.Columns.Add("CHARACTER_MAXIMUM_LENGTH", typeof(Int32));
dt.Columns.Add("CHARACTER_OCTET_LENGTH", typeof(Int32));
dt.Columns.Add("NUMERIC_PRECISION", typeof(byte));
dt.Columns.Add("NUMERIC_SCALE", typeof(Int32));
dt.Columns.Add("CHARACTER_SET_NAME", typeof(string));
dt.Columns.Add("COLLATION_NAME", typeof(string));
dt.Columns.Add("DTD_IDENTIFIER", typeof(string));
dt.Columns.Add("ROUTINE_TYPE", typeof(string));
return dt;
}
/// <summary>
/// Return schema information about parameters for procedures and functions
/// Restrictions supported are:
/// schema, name, type, parameter name
/// </summary>
public virtual DataTable GetProcedureParameters(string[] restrictions,
DataTable routines)
{
if (connection.driver.Version.isAtLeast(6, 0, 6))
return GetParametersFromIS(restrictions, routines);
try
{
DataTable dt = CreateParametersTable();
GetParametersFromShowCreate(dt, restrictions, routines);
return dt;
}
catch (InvalidOperationException ioe)
{
throw new InvalidOperationException(Resources.UnableToRetrieveParameters, ioe);
}
}
protected override DataTable GetSchemaInternal(string collection, string[] restrictions)
{
DataTable dt = base.GetSchemaInternal(collection, restrictions);
if (dt != null)
return dt;
switch (collection)
{
case "VIEWS":
return GetViews(restrictions);
case "PROCEDURES":
return GetProcedures(restrictions);
case "PROCEDURES WITH PARAMETERS":
return GetProceduresWithParameters(restrictions);
case "PROCEDURE PARAMETERS":
return GetProcedureParameters(restrictions, null);
case "TRIGGERS":
return GetTriggers(restrictions);
case "VIEWCOLUMNS":
return GetViewColumns(restrictions);
}
return null;
}
private static string GetWhereClause(string initial_where, string[] keys, string[] values)
{
StringBuilder where = new StringBuilder(initial_where);
if (values != null)
{
for (int i = 0; i < keys.Length; i++)
{
if (i >= values.Length) break;
if (values[i] == null || values[i] == String.Empty) continue;
if (where.Length > 0)
where.Append(" AND ");
where.AppendFormat(CultureInfo.InvariantCulture,
"{0} LIKE '{1}'", keys[i], values[i]);
}
}
return where.ToString();
}
private DataTable Query(string table_name, string initial_where,
string[] keys, string[] values)
{
StringBuilder query = new StringBuilder("SELECT * FROM INFORMATION_SCHEMA.");
query.Append(table_name);
string where = GetWhereClause(initial_where, keys, values);
if (where.Length > 0)
query.AppendFormat(CultureInfo.InvariantCulture, " WHERE {0}", where);
return GetTable(query.ToString());
}
private DataTable GetTable(string sql)
{
DataTable table = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter(sql, connection);
da.Fill(table);
return table;
}
public override DataTable GetForeignKeys(string[] restrictions)
{
if (!connection.driver.Version.isAtLeast(5, 1, 16))
return base.GetForeignKeys(restrictions);
string sql = @"SELECT rc.constraint_catalog, rc.constraint_schema,
rc.constraint_name, kcu.table_catalog, kcu.table_schema, rc.table_name,
rc.match_option, rc.update_rule, rc.delete_rule,
NULL as referenced_table_catalog,
kcu.referenced_table_schema, rc.referenced_table_name
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu ON
kcu.constraint_catalog <=> rc.constraint_catalog AND
kcu.constraint_schema <=> rc.constraint_schema AND
kcu.constraint_name <=> rc.constraint_name AND
kcu.ORDINAL_POSITION=1 WHERE 1=1";
StringBuilder where =new StringBuilder();
if (restrictions.Length >= 2 && !String.IsNullOrEmpty(restrictions[1]))
where.AppendFormat(CultureInfo.InvariantCulture,
" AND rc.constraint_schema LIKE '{0}'", restrictions[1]);
if (restrictions.Length >= 3 && !String.IsNullOrEmpty(restrictions[2]))
where.AppendFormat(CultureInfo.InvariantCulture,
" AND rc.table_name LIKE '{0}'", restrictions[2]);
if (restrictions.Length >= 4 && !String.IsNullOrEmpty(restrictions[3]))
where.AppendFormat(CultureInfo.InvariantCulture,
" AND rc.constraint_name LIKE '{0}'", restrictions[2]);
sql += where.ToString();
return GetTable(sql);
}
public override DataTable GetForeignKeyColumns(string[] restrictions)
{
if (!connection.driver.Version.isAtLeast(5, 0, 6))
return base.GetForeignKeyColumns(restrictions);
string sql = @"SELECT kcu.* FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
WHERE kcu.referenced_table_name IS NOT NULL";
StringBuilder where = new StringBuilder();
if (restrictions.Length >= 2 && !String.IsNullOrEmpty(restrictions[1]))
where.AppendFormat(CultureInfo.InvariantCulture,
" AND kcu.constraint_schema LIKE '{0}'", restrictions[1]);
if (restrictions.Length >= 3 && !String.IsNullOrEmpty(restrictions[2]))
where.AppendFormat(CultureInfo.InvariantCulture,
" AND kcu.table_name LIKE '{0}'", restrictions[2]);
if (restrictions.Length >= 4 && !String.IsNullOrEmpty(restrictions[3]))
where.AppendFormat(CultureInfo.InvariantCulture,
" AND kcu.constraint_name LIKE '{0}'", restrictions[3]);
sql += where.ToString();
return GetTable(sql);
}
#region Procedures Support Rouines
internal void GetParametersFromShowCreate(DataTable parametersTable,
string[] restrictions, DataTable routines)
{
// 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();
foreach (DataRow routine in routines.Rows)
{
string showCreateSql = String.Format("SHOW CREATE {0} `{1}`.`{2}`",
routine["ROUTINE_TYPE"], routine["ROUTINE_SCHEMA"],
routine["ROUTINE_NAME"]);
cmd.CommandText = showCreateSql;
try
{
string nameToRestrict = null;
if (restrictions != null && restrictions.Length == 5 &&
restrictions[4] != null)
nameToRestrict = restrictions[4];
using (MySqlDataReader reader = cmd.ExecuteReader())
{
reader.Read();
string body = reader.GetString(2);
reader.Close();
ParseProcedureBody(parametersTable, body, routine, nameToRestrict);
}
}
catch (SqlNullValueException snex)
{
throw new InvalidOperationException(
String.Format(Resources.UnableToRetrieveSProcData, routine["ROUTINE_NAME"]), snex);
}
}
}
private void ParseProcedureBody(DataTable parametersTable, string body,
DataRow row, string nameToRestrict)
{
ArrayList modes = new ArrayList(new string[3] { "IN", "OUT", "INOUT" });
string sqlMode = row["SQL_MODE"].ToString();
int pos = 1;
MySqlTokenizer tokenizer = new MySqlTokenizer(body);
tokenizer.AnsiQuotes = sqlMode.IndexOf("ANSI_QUOTES") != -1;
tokenizer.BackslashEscapes = sqlMode.IndexOf("NO_BACKSLASH_ESCAPES") == -1;
tokenizer.ReturnComments = false;
string token = tokenizer.NextToken();
// this block will scan for the opening paren while also determining
// if this routine is a function. If so, then we need to add a
// parameter row for the return parameter since it is ordinal position
// 0 and should appear first.
while (token != "(")
{
if (String.Compare(token, "FUNCTION", true) == 0 &&
nameToRestrict == null)
{
parametersTable.Rows.Add(parametersTable.NewRow());
InitParameterRow(row, parametersTable.Rows[0]);
}
token = tokenizer.NextToken();
}
token = tokenizer.NextToken(); // now move to the next token past the (
while (token != ")")
{
DataRow parmRow = parametersTable.NewRow();
InitParameterRow(row, parmRow);
parmRow["ORDINAL_POSITION"] = pos++;
// handle mode and name for the parameter
string mode = token.ToUpper(CultureInfo.InvariantCulture);
if (!tokenizer.Quoted && modes.Contains(mode))
{
parmRow["PARAMETER_MODE"] = mode;
token = tokenizer.NextToken();
}
if (tokenizer.Quoted)
token = token.Substring(1, token.Length - 2);
parmRow["PARAMETER_NAME"] = token;
// now parse data type
token = ParseDataType(parmRow, tokenizer);
if (token == ",")
token = tokenizer.NextToken();
// now determine if we should include this row after all
// we need to parse it before this check so we are correctly
// positioned for the next parameter
if (nameToRestrict == null ||
String.Compare(parmRow["PARAMETER_NAME"].ToString(), nameToRestrict, true) == 0)
parametersTable.Rows.Add(parmRow);
}
// now parse out the return parameter if there is one.
token = tokenizer.NextToken().ToUpper(CultureInfo.InvariantCulture);
if (String.Compare(token, "RETURNS", true) == 0)
{
DataRow parameterRow = parametersTable.Rows[0];
parameterRow["PARAMETER_NAME"] = "RETURN_VALUE";
ParseDataType(parameterRow, tokenizer);
}
}
/// <summary>
/// Initializes a new row for the procedure parameters table.
/// </summary>
private static void InitParameterRow(DataRow procedure, DataRow parameter)
{
parameter["SPECIFIC_CATALOG"] = null;
parameter["SPECIFIC_SCHEMA"] = procedure["ROUTINE_SCHEMA"];
parameter["SPECIFIC_NAME"] = procedure["ROUTINE_NAME"];
parameter["PARAMETER_MODE"] = "IN";
parameter["ORDINAL_POSITION"] = 0;
parameter["ROUTINE_TYPE"] = procedure["ROUTINE_TYPE"];
}
/// <summary>
/// Parses out the elements of a procedure parameter data type.
/// </summary>
private string ParseDataType(DataRow row, MySqlTokenizer tokenizer)
{
StringBuilder dtd = new StringBuilder(
tokenizer.NextToken().ToUpper(CultureInfo.InvariantCulture));
row["DATA_TYPE"] = dtd.ToString();
string type = row["DATA_TYPE"].ToString();
string token = tokenizer.NextToken();
if (token == "(")
{
token = tokenizer.ReadParenthesis();
dtd.AppendFormat(CultureInfo.InvariantCulture, "{0}", token);
if (type != "ENUM" && type != "SET")
ParseDataTypeSize(row, token);
token = tokenizer.NextToken();
}
else
dtd.Append(GetDataTypeDefaults(type, row));
while (token != ")" &&
token != "," &&
String.Compare(token, "begin", true) != 0 &&
String.Compare(token, "return", true) != 0)
{
if (String.Compare(token, "CHARACTER", true) == 0 ||
String.Compare(token, "BINARY", true) == 0)
{ } // we don't need to do anything with this
else if (String.Compare(token, "SET", true) == 0 ||
String.Compare(token, "CHARSET", true) == 0)
row["CHARACTER_SET_NAME"] = tokenizer.NextToken();
else if (String.Compare(token, "ASCII", true) == 0)
row["CHARACTER_SET_NAME"] = "latin1";
else if (String.Compare(token, "UNICODE", true) == 0)
row["CHARACTER_SET_NAME"] = "ucs2";
else if (String.Compare(token, "COLLATE", true) == 0)
row["COLLATION_NAME"] = tokenizer.NextToken();
else
dtd.AppendFormat(CultureInfo.InvariantCulture, " {0}", token);
token = tokenizer.NextToken();
}
if (dtd.Length > 0)
row["DTD_IDENTIFIER"] = dtd.ToString();
// now default the collation if one wasn't given
if (row["COLLATION_NAME"].ToString().Length == 0 &&
row["CHARACTER_SET_NAME"].ToString().Length > 0)
row["COLLATION_NAME"] = CharSetMap.GetDefaultCollation(
row["CHARACTER_SET_NAME"].ToString(), connection);
// now set the octet length
if (row["CHARACTER_MAXIMUM_LENGTH"] != DBNull.Value)
row["CHARACTER_OCTET_LENGTH"] =
CharSetMap.GetMaxLength(row["CHARACTER_SET_NAME"].ToString(), connection) *
(int)row["CHARACTER_MAXIMUM_LENGTH"];
return token;
}
private static string GetDataTypeDefaults(string type, DataRow row)
{
string format = "({0},{1})";
if (MetaData.IsNumericType(type) &&
row["NUMERIC_PRECISION"].ToString().Length == 0)
{
row["NUMERIC_PRECISION"] = 10;
row["NUMERIC_SCALE"] = 0;
if (!MetaData.SupportScale(type))
format = "({0})";
return String.Format(format, row["NUMERIC_PRECISION"],
row["NUMERIC_SCALE"]);
}
return String.Empty;
}
private static void ParseDataTypeSize(DataRow row, string size)
{
size = size.Trim('(', ')');
string[] parts = size.Split(',');
if (!MetaData.IsNumericType(row["DATA_TYPE"].ToString()))
{
row["CHARACTER_MAXIMUM_LENGTH"] = Int32.Parse(parts[0]);
// will set octet length in a minute
}
else
{
row["NUMERIC_PRECISION"] = Int32.Parse(parts[0]);
if (parts.Length == 2)
row["NUMERIC_SCALE"] = Int32.Parse(parts[1]);
}
}
#endregion
}
}

@ -0,0 +1,192 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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
#if !MONO && !PocketPC
using System.Configuration.Install;
using System.ComponentModel;
using System.Reflection;
using System;
using Microsoft.Win32;
using System.Xml;
using System.IO;
using System.Diagnostics;
using System.Security;
using System.Security.Permissions;
namespace MySql.Data.MySqlClient
{
/// <summary>
/// We are adding a custom installer class to our assembly so our installer
/// can make proper changes to the machine.config file.
/// </summary>
[RunInstaller(true)]
public class CustomInstaller : Installer
{
/// <summary>
/// We override Install so we can add our assembly to the proper
/// machine.config files.
/// </summary>
/// <param name="stateSaver"></param>
public override void Install(System.Collections.IDictionary stateSaver)
{
base.Install(stateSaver);
AddProviderToMachineConfig();
}
private static void AddProviderToMachineConfig()
{
object installRoot = Registry.GetValue(
@"HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\",
"InstallRoot", null);
if (installRoot == null)
throw new Exception("Unable to retrieve install root for .NET framework");
AddProviderToMachineConfigInDir(installRoot.ToString());
string installRoot64 = installRoot.ToString();
installRoot64 = installRoot64.Substring(0, installRoot64.Length - 1);
installRoot64 = string.Format("{0}64{1}", installRoot64,
Path.DirectorySeparatorChar);
if (Directory.Exists(installRoot64))
AddProviderToMachineConfigInDir(installRoot64);
}
private static void AddProviderToMachineConfigInDir(string path)
{
string configPath = String.Format(@"{0}v2.0.50727\CONFIG\machine.config",
path);
// now read the config file into memory
StreamReader sr = new StreamReader(configPath);
string configXML = sr.ReadToEnd();
sr.Close();
// load the XML into the XmlDocument
XmlDocument doc = new XmlDocument();
doc.LoadXml(configXML);
// create our new node
XmlElement newNode = (XmlElement)doc.CreateNode(XmlNodeType.Element, "add", "");
// add the proper attributes
newNode.SetAttribute("name", "MySQL Data Provider");
newNode.SetAttribute("invariant", "MySql.Data.MySqlClient");
newNode.SetAttribute("description", ".Net Framework Data Provider for MySQL");
// add the type attribute by reflecting on the executing assembly
Assembly a = Assembly.GetExecutingAssembly();
string type = String.Format("MySql.Data.MySqlClient.MySqlClientFactory, {0}", a.FullName);
newNode.SetAttribute("type", type);
XmlNodeList nodes = doc.GetElementsByTagName("DbProviderFactories");
foreach (XmlNode node in nodes[0].ChildNodes)
{
if (node.Attributes == null) continue;
foreach (XmlAttribute attr in node.Attributes)
{
if (attr.Name == "invariant" && attr.Value == "MySql.Data.MySqlClient")
{
nodes[0].RemoveChild(node);
break;
}
}
}
nodes[0].AppendChild(newNode);
// Save the document to a file and auto-indent the output.
XmlTextWriter writer = new XmlTextWriter(configPath, null);
writer.Formatting = Formatting.Indented;
doc.Save(writer);
writer.Flush();
writer.Close();
}
/// <summary>
/// We override Uninstall so we can remove out assembly from the
/// machine.config files.
/// </summary>
/// <param name="savedState"></param>
public override void Uninstall(System.Collections.IDictionary savedState)
{
base.Uninstall(savedState);
RemoveProviderFromMachineConfig();
}
private static void RemoveProviderFromMachineConfig()
{
object installRoot = Registry.GetValue(
@"HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\",
"InstallRoot", null);
if (installRoot == null)
throw new Exception("Unable to retrieve install root for .NET framework");
RemoveProviderFromMachineConfigInDir(installRoot.ToString());
string installRoot64 = installRoot.ToString();
installRoot64 = installRoot64.Substring(0, installRoot64.Length - 1);
installRoot64 = string.Format("{0}64{1}", installRoot64,
Path.DirectorySeparatorChar);
if (Directory.Exists(installRoot64))
RemoveProviderFromMachineConfigInDir(installRoot64);
}
private static void RemoveProviderFromMachineConfigInDir(string path)
{
string configPath = String.Format(@"{0}v2.0.50727\CONFIG\machine.config",
path);
// now read the config file into memory
StreamReader sr = new StreamReader(configPath);
string configXML = sr.ReadToEnd();
sr.Close();
// load the XML into the XmlDocument
XmlDocument doc = new XmlDocument();
doc.LoadXml(configXML);
XmlNodeList nodes = doc.GetElementsByTagName("DbProviderFactories");
foreach (XmlNode node in nodes[0].ChildNodes)
{
if (node.Attributes == null) continue;
string name = node.Attributes["name"].Value;
if (name == "MySQL Data Provider")
{
nodes[0].RemoveChild(node);
break;
}
}
// Save the document to a file and auto-indent the output.
XmlTextWriter writer = new XmlTextWriter(configPath, null);
writer.Formatting = Formatting.Indented;
doc.Save(writer);
writer.Flush();
writer.Close();
}
}
}
#endif

@ -0,0 +1,159 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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
#if !PocketPC
using System.Data.Common;
using System;
using System.Reflection;
namespace MySql.Data.MySqlClient
{
/// <summary>
/// DBProviderFactory implementation for MysqlClient.
/// </summary>
public sealed class MySqlClientFactory : DbProviderFactory, IServiceProvider
{
/// <summary>
/// Gets an instance of the <see cref="MySqlClientFactory"/>.
/// This can be used to retrieve strongly typed data objects.
/// </summary>
public static MySqlClientFactory Instance = new MySqlClientFactory();
private Type dbServicesType;
private FieldInfo mySqlDbProviderServicesInstance;
/// <summary>
/// Returns a strongly typed <see cref="DbCommandBuilder"/> instance.
/// </summary>
/// <returns>A new strongly typed instance of <b>DbCommandBuilder</b>.</returns>
public override DbCommandBuilder CreateCommandBuilder()
{
return new MySqlCommandBuilder();
}
/// <summary>
/// Returns a strongly typed <see cref="DbCommand"/> instance.
/// </summary>
/// <returns>A new strongly typed instance of <b>DbCommand</b>.</returns>
public override DbCommand CreateCommand()
{
return new MySqlCommand();
}
/// <summary>
/// Returns a strongly typed <see cref="DbConnection"/> instance.
/// </summary>
/// <returns>A new strongly typed instance of <b>DbConnection</b>.</returns>
public override DbConnection CreateConnection()
{
return new MySqlConnection();
}
/// <summary>
/// Returns a strongly typed <see cref="DbDataAdapter"/> instance.
/// </summary>
/// <returns>A new strongly typed instance of <b>DbDataAdapter</b>. </returns>
public override DbDataAdapter CreateDataAdapter()
{
return new MySqlDataAdapter();
}
/// <summary>
/// Returns a strongly typed <see cref="DbParameter"/> instance.
/// </summary>
/// <returns>A new strongly typed instance of <b>DbParameter</b>.</returns>
public override DbParameter CreateParameter()
{
return new MySqlParameter();
}
/// <summary>
/// Returns a strongly typed <see cref="DbConnectionStringBuilder"/> instance.
/// </summary>
/// <returns>A new strongly typed instance of <b>DbConnectionStringBuilder</b>.</returns>
public override DbConnectionStringBuilder CreateConnectionStringBuilder()
{
return new MySqlConnectionStringBuilder();
}
/// <summary>
/// Returns true if a <b>MySqlDataSourceEnumerator</b> can be created;
/// otherwise false.
/// </summary>
public override bool CanCreateDataSourceEnumerator
{
get { return false; }
}
#region IServiceProvider Members
/// <summary>
/// Provide a simple caching layer
/// </summary>
private Type DbServicesType
{
get
{
if (dbServicesType == null)
{
// Get the type this way so we don't have to reference System.Data.Entity
// from our core provider
dbServicesType = Type.GetType(
@"System.Data.Common.DbProviderServices, System.Data.Entity,
Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
false);
}
return dbServicesType;
}
}
private FieldInfo MySqlDbProviderServicesInstance
{
get
{
if (mySqlDbProviderServicesInstance == null)
{
string fullName = Assembly.GetExecutingAssembly().FullName;
fullName = fullName.Replace("MySql.Data", "MySql.Data.Entity");
fullName = String.Format("MySql.Data.MySqlClient.MySqlProviderServices, {0}", fullName);
Type providerServicesType = Type.GetType(fullName, false);
mySqlDbProviderServicesInstance = providerServicesType.GetField("Instance",
BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
}
return mySqlDbProviderServicesInstance;
}
}
object IServiceProvider.GetService(Type serviceType)
{
// DbProviderServices is the only service we offer up right now
if (serviceType != DbServicesType) return null;
if (MySqlDbProviderServicesInstance == null) return null;
return MySqlDbProviderServicesInstance.GetValue(null);
}
#endregion
}
}
#endif

@ -0,0 +1,929 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Common;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Text;
using MySql.Data.MySqlClient.Properties;
using System.Collections;
using System.Globalization;
namespace MySql.Data.MySqlClient
{
public class MySqlConnectionStringBuilder : DbConnectionStringBuilder
{
private static Dictionary<string, string> validKeywords =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private static Dictionary<string, PropertyDefaultValue> defaultValues =
new Dictionary<string, PropertyDefaultValue>(StringComparer.OrdinalIgnoreCase);
private Dictionary<string, object> values =
new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
static MySqlConnectionStringBuilder()
{
// load up our valid keywords and default values only once
Initialize();
}
public MySqlConnectionStringBuilder()
{
Clear();
}
public MySqlConnectionStringBuilder(string connStr)
: this()
{
ConnectionString = connStr;
}
#region Server Properties
/// <summary>
/// Gets or sets the name of the server.
/// </summary>
/// <value>The server.</value>
[Category("Connection")]
[Description("Server to connect to")]
[DefaultValue("")]
[ValidKeywords("host, data source, datasource, address, addr, network address")]
[RefreshProperties(RefreshProperties.All)]
public string Server
{
get { return values["server"] as string; }
set { SetValue("server", value); }
}
/// <summary>
/// Gets or sets the name of the database the connection should
/// initially connect to.
/// </summary>
[Category("Connection")]
[Description("Database to use initially")]
[DefaultValue("")]
[ValidKeywords("initial catalog")]
[RefreshProperties(RefreshProperties.All)]
public string Database
{
get { return values["database"] as string; }
set { SetValue("database", value); }
}
/// <summary>
/// Gets or sets the protocol that should be used for communicating
/// with MySQL.
/// </summary>
[Category("Connection")]
[DisplayName("Connection Protocol")]
[Description("Protocol to use for connection to MySQL")]
[DefaultValue(MySqlConnectionProtocol.Sockets)]
[ValidKeywords("protocol")]
[RefreshProperties(RefreshProperties.All)]
public MySqlConnectionProtocol ConnectionProtocol
{
get { return (MySqlConnectionProtocol)values["Connection Protocol"]; }
set { SetValue("Connection Protocol", value); }
}
/// <summary>
/// Gets or sets the name of the named pipe that should be used
/// for communicating with MySQL.
/// </summary>
[Category("Connection")]
[DisplayName("Pipe Name")]
[Description("Name of pipe to use when connecting with named pipes (Win32 only)")]
[DefaultValue("MYSQL")]
[ValidKeywords("pipe")]
[RefreshProperties(RefreshProperties.All)]
public string PipeName
{
get { return (string)values["Pipe Name"]; }
set { SetValue("Pipe Name", value); }
}
/// <summary>
/// Gets or sets a boolean value that indicates whether this connection
/// should use compression.
/// </summary>
[Category("Connection")]
[DisplayName("Use Compression")]
[Description("Should the connection ues compression")]
[DefaultValue(false)]
[ValidKeywords("compress")]
[RefreshProperties(RefreshProperties.All)]
public bool UseCompression
{
get { return (bool)values["Use Compression"]; }
set { SetValue("Use Compression", value); }
}
/// <summary>
/// Gets or sets a boolean value that indicates whether this connection will allow
/// commands to send multiple SQL statements in one execution.
/// </summary>
[Category("Connection")]
[DisplayName("Allow Batch")]
[Description("Allows execution of multiple SQL commands in a single statement")]
[DefaultValue(true)]
[RefreshProperties(RefreshProperties.All)]
public bool AllowBatch
{
get { return (bool)values["Allow Batch"]; }
set { SetValue("Allow Batch", value); }
}
/// <summary>
/// Gets or sets a boolean value that indicates whether logging is enabled.
/// </summary>
[Category("Connection")]
[Description("Enables output of diagnostic messages")]
[DefaultValue(false)]
[RefreshProperties(RefreshProperties.All)]
public bool Logging
{
get { return (bool)values["Logging"]; }
set { SetValue("Logging", value); }
}
/// <summary>
/// Gets or sets the base name of the shared memory objects used to
/// communicate with MySQL when the shared memory protocol is being used.
/// </summary>
[Category("Connection")]
[DisplayName("Shared Memory Name")]
[Description("Name of the shared memory object to use")]
[DefaultValue("MYSQL")]
[RefreshProperties(RefreshProperties.All)]
public string SharedMemoryName
{
get { return (string)values["Shared Memory Name"]; }
set { SetValue("Shared Memory Name", value); }
}
/// <summary>
/// Gets or sets a boolean value that indicates whether this connection uses
/// the old style (@) parameter markers or the new (?) style.
/// </summary>
[Category("Connection")]
[DisplayName("Use Old Syntax")]
[Description("Allows the use of old style @ syntax for parameters")]
[DefaultValue(false)]
[ValidKeywords("old syntax, oldsyntax")]
[RefreshProperties(RefreshProperties.All)]
[Obsolete("Use Old Syntax is no longer needed. See documentation")]
public bool UseOldSyntax
{
get { return (bool)values["Use Old Syntax"]; }
set { SetValue("Use Old Syntax", value); }
}
/// <summary>
/// Gets or sets the port number that is used when the socket
/// protocol is being used.
/// </summary>
[Category("Connection")]
[Description("Port to use for TCP/IP connections")]
[DefaultValue(3306)]
[RefreshProperties(RefreshProperties.All)]
public uint Port
{
get { return (uint)values["Port"]; }
set { SetValue("Port", value); }
}
/// <summary>
/// Gets or sets the connection timeout.
/// </summary>
[Category("Connection")]
[DisplayName("Connect Timeout")]
[Description("The length of time (in seconds) to wait for a connection " +
"to the server before terminating the attempt and generating an error.")]
[DefaultValue(15)]
[ValidKeywords("connection timeout")]
[RefreshProperties(RefreshProperties.All)]
public uint ConnectionTimeout
{
get { return (uint)values["Connect Timeout"]; }
set
{
// Timeout in milliseconds should not exceed maximum for 32 bit
// signed integer (~24 days). We truncate the value if it exceeds
// maximum (MySqlCommand.CommandTimeout uses the same technique
uint timeout = Math.Min(value, Int32.MaxValue / 1000);
if (timeout != value)
{
MySqlTrace.LogWarning(-1, "Connection timeout value too large ("
+ value + " seconds). Changed to max. possible value" +
+ timeout + " seconds)");
}
SetValue("Connect Timeout", timeout);
}
}
/// <summary>
/// Gets or sets the default command timeout.
/// </summary>
[Category("Connection")]
[DisplayName("Default Command Timeout")]
[Description(@"The default timeout that MySqlCommand objects will use
unless changed.")]
[DefaultValue(30)]
[ValidKeywords("command timeout")]
[RefreshProperties(RefreshProperties.All)]
public uint DefaultCommandTimeout
{
get { return (uint)values["Default Command Timeout"]; }
set { SetValue("Default Command Timeout", value); }
}
#endregion
#region Authentication Properties
/// <summary>
/// Gets or sets the user id that should be used to connect with.
/// </summary>
[Category("Security")]
[DisplayName("User Id")]
[Description("Indicates the user ID to be used when connecting to the data source.")]
[DefaultValue("")]
[ValidKeywords("uid, username, user name, user")]
[RefreshProperties(RefreshProperties.All)]
public string UserID
{
get { return (string)values["User Id"]; }
set { SetValue("User Id", value); }
}
/// <summary>
/// Gets or sets the password that should be used to connect with.
/// </summary>
[Category("Security")]
[Description("Indicates the password to be used when connecting to the data source.")]
[PasswordPropertyText(true)]
[DefaultValue("")]
[ValidKeywords("pwd")]
[RefreshProperties(RefreshProperties.All)]
public string Password
{
get { return (string)values["Password"]; }
set { SetValue("Password", value); }
}
/// <summary>
/// Gets or sets a boolean value that indicates if the password should be persisted
/// in the connection string.
/// </summary>
[Category("Security")]
[DisplayName("Persist Security Info")]
[Description("When false, security-sensitive information, such as the password, " +
"is not returned as part of the connection if the connection is open or " +
"has ever been in an open state.")]
[DefaultValue(false)]
[RefreshProperties(RefreshProperties.All)]
public bool PersistSecurityInfo
{
get { return (bool)values["Persist Security Info"]; }
set { SetValue("Persist Security Info", value); }
}
[Category("Authentication")]
[Description("Should the connection use SSL.")]
[DefaultValue(false)]
[Obsolete("Use Ssl Mode instead.")]
internal bool Encrypt
{
get { return SslMode != MySqlSslMode.None; }
set
{
SetValue("Ssl Mode", value ? MySqlSslMode.Prefered : MySqlSslMode.None);
}
}
[Category("Authentication")]
[DisplayName("Certificate File")]
[Description("Certificate file in PKCS#12 format (.pfx)")]
[DefaultValue(null)]
public string CertificateFile
{
get { return (string) values["Certificate File"];}
set
{
SetValue("Certificate File", value);
}
}
[Category("Authentication")]
[DisplayName("Certificate Password")]
[Description("Password for certificate file")]
[DefaultValue(null)]
public string CertificatePassword
{
get { return (string)values["Certificate Password"];}
set
{
SetValue("Certificate Password", value);
}
}
[Category("Authentication")]
[DisplayName("Certificate Store Location")]
[Description("Certificate Store Location for client certificates")]
[DefaultValue(MySqlCertificateStoreLocation.None)]
public MySqlCertificateStoreLocation CertificateStoreLocation
{
get { return (MySqlCertificateStoreLocation)values["Certificate Store Location"]; }
set
{
SetValue("Certificate Store Location", value);
}
}
[Category("Authentication")]
[DisplayName("Certificate Thumbprint")]
[Description("Certificate thumbprint. Can be used together with Certificate "+
"Store Location parameter to uniquely identify certificate to be used "+
"for SSL authentication.")]
[DefaultValue(null)]
public string CertificateThumbprint
{
get { return (string)values["Certificate Thumbprint"]; }
set
{
SetValue("Certificate Thumbprint", value);
}
}
#endregion
#region Other Properties
/// <summary>
/// Gets or sets a boolean value that indicates if zero date time values are supported.
/// </summary>
[Category("Advanced")]
[DisplayName("Allow Zero Datetime")]
[Description("Should zero datetimes be supported")]
[DefaultValue(false)]
[RefreshProperties(RefreshProperties.All)]
public bool AllowZeroDateTime
{
get { return (bool)values["Allow Zero Datetime"]; }
set { SetValue("Allow Zero DateTime", value); }
}
/// <summary>
/// Gets or sets a boolean value indicating if zero datetime values should be
/// converted to DateTime.MinValue.
/// </summary>
[Category("Advanced")]
[DisplayName("Convert Zero Datetime")]
[Description("Should illegal datetime values be converted to DateTime.MinValue")]
[DefaultValue(false)]
[RefreshProperties(RefreshProperties.All)]
public bool ConvertZeroDateTime
{
get { return (bool)values["Convert Zero Datetime"]; }
set { SetValue("Convert Zero DateTime", value); }
}
/// <summary>
/// Gets or sets a boolean value indicating if the Usage Advisor should be enabled.
/// </summary>
[Category("Advanced")]
[DisplayName("Use Usage Advisor")]
[Description("Logs inefficient database operations")]
[DefaultValue(false)]
[ValidKeywords("usage advisor")]
[RefreshProperties(RefreshProperties.All)]
public bool UseUsageAdvisor
{
get { return (bool)values["Use Usage Advisor"]; }
set { SetValue("Use Usage Advisor", value); }
}
/// <summary>
/// Gets or sets the size of the stored procedure cache.
/// </summary>
[Category("Advanced")]
[DisplayName("Procedure Cache Size")]
[Description("Indicates how many stored procedures can be cached at one time. " +
"A value of 0 effectively disables the procedure cache.")]
[DefaultValue(25)]
[ValidKeywords("procedure cache, procedurecache")]
[RefreshProperties(RefreshProperties.All)]
public uint ProcedureCacheSize
{
get { return (uint)values["Procedure Cache Size"]; }
set { SetValue("Procedure Cache Size", value); }
}
/// <summary>
/// Gets or sets a boolean value indicating if the permon hooks should be enabled.
/// </summary>
[Category("Advanced")]
[DisplayName("Use Performance Monitor")]
[Description("Indicates that performance counters should be updated during execution.")]
[DefaultValue(false)]
[ValidKeywords("userperfmon, perfmon")]
[RefreshProperties(RefreshProperties.All)]
public bool UsePerformanceMonitor
{
get { return (bool)values["Use Performance Monitor"]; }
set { SetValue("Use Performance Monitor", value); }
}
/// <summary>
/// Gets or sets a boolean value indicating if calls to Prepare() should be ignored.
/// </summary>
[Category("Advanced")]
[DisplayName("Ignore Prepare")]
[Description("Instructs the provider to ignore any attempts to prepare a command.")]
[DefaultValue(true)]
[RefreshProperties(RefreshProperties.All)]
public bool IgnorePrepare
{
get { return (bool)values["Ignore Prepare"]; }
set { SetValue("Ignore Prepare", value); }
}
[Category("Advanced")]
[DisplayName("Use Procedure Bodies")]
[Description("Indicates if stored procedure bodies will be available for parameter detection.")]
[DefaultValue(true)]
[ValidKeywords("procedure bodies")]
[RefreshProperties(RefreshProperties.All)]
public bool UseProcedureBodies
{
get { return (bool)values["Use Procedure Bodies"]; }
set { SetValue("Use Procedure Bodies", value); }
}
[Category("Advanced")]
[DisplayName("Auto Enlist")]
[Description("Should the connetion automatically enlist in the active connection, if there are any.")]
[DefaultValue(true)]
[RefreshProperties(RefreshProperties.All)]
public bool AutoEnlist
{
get { return (bool)values["Auto Enlist"]; }
set { SetValue("Auto Enlist", value); }
}
[Category("Advanced")]
[DisplayName("Respect Binary Flags")]
[Description("Should binary flags on column metadata be respected.")]
[DefaultValue(true)]
[RefreshProperties(RefreshProperties.All)]
public bool RespectBinaryFlags
{
get { return (bool)values["Respect Binary Flags"]; }
set { SetValue("Respect Binary Flags", value); }
}
[Category("Advanced")]
[DisplayName("Treat Tiny As Boolean")]
[Description("Should the provider treat TINYINT(1) columns as boolean.")]
[DefaultValue(true)]
[RefreshProperties(RefreshProperties.All)]
public bool TreatTinyAsBoolean
{
get { return (bool)values["Treat Tiny As Boolean"]; }
set { SetValue("Treat Tiny As Boolean", value); }
}
[Category("Advanced")]
[DisplayName("Allow User Variables")]
[Description("Should the provider expect user variables to appear in the SQL.")]
[DefaultValue(false)]
[RefreshProperties(RefreshProperties.All)]
public bool AllowUserVariables
{
get { return (bool)values["Allow User Variables"]; }
set { SetValue("Allow User Variables", value); }
}
[Category("Advanced")]
[DisplayName("Interactive Session")]
[Description("Should this session be considered interactive?")]
[DefaultValue(false)]
[ValidKeywords("interactive")]
[RefreshProperties(RefreshProperties.All)]
public bool InteractiveSession
{
get { return (bool)values["Interactive Session"]; }
set { SetValue("Interactive Session", value); }
}
[Category("Advanced")]
[DisplayName("Functions Return String")]
[Description("Should all server functions be treated as returning string?")]
[DefaultValue(false)]
public bool FunctionsReturnString
{
get { return (bool)values["Functions Return String"]; }
set { SetValue("Functions Return String", value); }
}
[Category("Advanced")]
[DisplayName("Use Affected Rows")]
[Description("Should the returned affected row count reflect affected rows instead of found rows?")]
[DefaultValue(false)]
public bool UseAffectedRows
{
get { return (bool)values["Use Affected Rows"]; }
set { SetValue("Use Affected Rows", value); }
}
[Category("Advanced")]
[DisplayName("Old Guids")]
[Description("Treat binary(16) columns as guids")]
[DefaultValue(false)]
public bool OldGuids
{
get { return (bool)values["Old Guids"]; }
set { SetValue("Old Guids", value); }
}
[DisplayName("Keep Alive")]
[Description("For TCP connections, idle connection time measured in seconds, before the first keepalive packet is sent." +
"A value of 0 indicates that keepalive is not used.")]
[DefaultValue(0)]
public uint Keepalive
{
get { return (uint)values["Keep Alive"]; }
set { SetValue("Keep Alive", value); }
}
#endregion
#region Pooling Properties
/// <summary>
/// Gets or sets the lifetime of a pooled connection.
/// </summary>
[Category("Pooling")]
[DisplayName("Connection Lifetime")]
[Description("The minimum amount of time (in seconds) for this connection to " +
"live in the pool before being destroyed.")]
[DefaultValue(0)]
[RefreshProperties(RefreshProperties.All)]
public uint ConnectionLifeTime
{
get { return (uint)values["Connection LifeTime"]; }
set { SetValue("Connection LifeTime", value); }
}
/// <summary>
/// Gets or sets a boolean value indicating if connection pooling is enabled.
/// </summary>
[Category("Pooling")]
[Description("When true, the connection object is drawn from the appropriate " +
"pool, or if necessary, is created and added to the appropriate pool.")]
[DefaultValue(true)]
[RefreshProperties(RefreshProperties.All)]
public bool Pooling
{
get { return (bool)values["Pooling"]; }
set { SetValue("Pooling", value); }
}
/// <summary>
/// Gets the minimum connection pool size.
/// </summary>
[Category("Pooling")]
[DisplayName("Minimum Pool Size")]
[Description("The minimum number of connections allowed in the pool.")]
[DefaultValue(0)]
[ValidKeywords("min pool size")]
[RefreshProperties(RefreshProperties.All)]
public uint MinimumPoolSize
{
get { return (uint)values["Minimum Pool Size"]; }
set { SetValue("Minimum Pool Size", value); }
}
/// <summary>
/// Gets or sets the maximum connection pool setting.
/// </summary>
[Category("Pooling")]
[DisplayName("Maximum Pool Size")]
[Description("The maximum number of connections allowed in the pool.")]
[DefaultValue(100)]
[ValidKeywords("max pool size")]
[RefreshProperties(RefreshProperties.All)]
public uint MaximumPoolSize
{
get { return (uint)values["Maximum Pool Size"]; }
set { SetValue("Maximum Pool Size", value); }
}
/// <summary>
/// Gets or sets a boolean value indicating if the connection should be reset when retrieved
/// from the pool.
/// </summary>
[Category("Pooling")]
[DisplayName("Connection Reset")]
[Description("When true, indicates the connection state is reset when " +
"removed from the pool.")]
[DefaultValue(false)]
[RefreshProperties(RefreshProperties.All)]
public bool ConnectionReset
{
get { return (bool)values["Connection Reset"]; }
set { SetValue("Connection Reset", value); }
}
#endregion
#region Language and Character Set Properties
/// <summary>
/// Gets or sets the character set that should be used for sending queries to the server.
/// </summary>
[DisplayName("Character Set")]
[Category("Advanced")]
[Description("Character set this connection should use")]
[DefaultValue("")]
[ValidKeywords("charset")]
[RefreshProperties(RefreshProperties.All)]
public string CharacterSet
{
get { return (string)values["Character Set"]; }
set { SetValue("Character Set", value); }
}
/// <summary>
/// Indicates whether the driver should treat binary blobs as UTF8
/// </summary>
[DisplayName("Treat Blobs As UTF8")]
[Category("Advanced")]
[Description("Should binary blobs be treated as UTF8")]
[DefaultValue(false)]
[RefreshProperties(RefreshProperties.All)]
public bool TreatBlobsAsUTF8
{
get { return (bool)values["Treat Blobs As UTF8"]; }
set { SetValue("Treat Blobs As UTF8", value); }
}
/// <summary>
/// Gets or sets the pattern that matches the columns that should be treated as UTF8
/// </summary>
[Category("Advanced")]
[Description("Pattern that matches columns that should be treated as UTF8")]
[DefaultValue("")]
[RefreshProperties(RefreshProperties.All)]
public string BlobAsUTF8IncludePattern
{
get { return (string)values["BlobAsUTF8IncludePattern"]; }
set { SetValue("BlobAsUTF8IncludePattern", value); }
}
/// <summary>
/// Gets or sets the pattern that matches the columns that should not be treated as UTF8
/// </summary>
[Category("Advanced")]
[Description("Pattern that matches columns that should not be treated as UTF8")]
[DefaultValue("")]
[RefreshProperties(RefreshProperties.All)]
public string BlobAsUTF8ExcludePattern
{
get { return (string)values["BlobAsUTF8ExcludePattern"]; }
set { SetValue("BlobAsUTF8ExcludePattern", value); }
}
/// <summary>
/// Indicates whether to use SSL connections and how to handle server certificate errors.
/// </summary>
[DisplayName("Ssl Mode")]
[Category("Security")]
[Description("SSL properties for connection")]
[DefaultValue(MySqlSslMode.None)]
public MySqlSslMode SslMode
{
get { return (MySqlSslMode)values["Ssl Mode"]; }
set { SetValue("Ssl Mode", value); }
}
#endregion
internal Regex GetBlobAsUTF8IncludeRegex()
{
if (String.IsNullOrEmpty(BlobAsUTF8IncludePattern)) return null;
return new Regex(BlobAsUTF8IncludePattern);
}
internal Regex GetBlobAsUTF8ExcludeRegex()
{
if (String.IsNullOrEmpty(BlobAsUTF8ExcludePattern)) return null;
return new Regex(BlobAsUTF8ExcludePattern);
}
public override object this[string keyword]
{
get { return values[validKeywords[keyword]]; }
set
{
ValidateKeyword(keyword);
if (value == null)
Remove(keyword);
else
SetValue(keyword, value);
}
}
public override void Clear()
{
base.Clear();
// make a copy of our default values array
foreach (string key in defaultValues.Keys)
values[key] = defaultValues[key].DefaultValue;
}
#if !CF
public override bool Remove(string keyword)
{
ValidateKeyword(keyword);
string primaryKey = validKeywords[keyword];
values.Remove(primaryKey);
base.Remove(primaryKey);
values[primaryKey] = defaultValues[primaryKey].DefaultValue;
return true;
}
public override bool TryGetValue(string keyword, out object value)
{
ValidateKeyword(keyword);
return values.TryGetValue(validKeywords[keyword], out value);
}
#endif
public string GetConnectionString(bool includePass)
{
if (includePass) return ConnectionString;
StringBuilder conn = new StringBuilder();
string delimiter = "";
foreach (string key in this.Keys)
{
if (String.Compare(key, "password", true) == 0 ||
String.Compare(key, "pwd", true) == 0) continue;
conn.AppendFormat(CultureInfo.CurrentCulture, "{0}{1}={2}",
delimiter, key, this[key]);
delimiter = ";";
}
return conn.ToString();
}
private void SetValue(string keyword, object value)
{
ValidateKeyword(keyword);
keyword = validKeywords[keyword];
Remove(keyword);
object val = null;
if (value is string && defaultValues[keyword].DefaultValue is Enum)
val = ParseEnum(defaultValues[keyword].Type, (string)value, keyword);
else
val = ChangeType(value, defaultValues[keyword].Type);
values[keyword] = val;
base[keyword] = val;
}
private object ParseEnum(Type t, string requestedValue, string key)
{
try
{
return Enum.Parse(t, requestedValue, true);
}
catch (ArgumentException)
{
throw new InvalidOperationException(String.Format(
Resources.InvalidConnectionStringValue, requestedValue, key));
}
}
private object ChangeType(object value, Type t)
{
if (t == typeof(bool) && value is string)
{
string s = value.ToString().ToLower(CultureInfo.InvariantCulture);
if (s == "yes" || s == "true") return true;
if (s == "no" || s == "false") return false;
throw new FormatException(String.Format(Resources.InvalidValueForBoolean, value));
}
else
return Convert.ChangeType(value, t, CultureInfo.CurrentCulture);
}
private void ValidateKeyword(string keyword)
{
string key = keyword.ToLower(CultureInfo.InvariantCulture);
if (!validKeywords.ContainsKey(key))
throw new ArgumentException(Resources.KeywordNotSupported, keyword);
if (validKeywords[key] == "Use Old Syntax")
MySqlTrace.LogWarning(-1, "Use Old Syntax is now obsolete. Please see documentation");
if (validKeywords[key] == "Encrypt")
MySqlTrace.LogWarning(-1, "Encrypt is now obsolete. Use Ssl Mode instead");
}
private static void Initialize()
{
PropertyInfo[] properties = typeof(MySqlConnectionStringBuilder).GetProperties();
foreach (PropertyInfo pi in properties)
AddKeywordFromProperty(pi);
// remove this starting with 6.4
PropertyInfo encrypt = typeof(MySqlConnectionStringBuilder).GetProperty(
"Encrypt", BindingFlags.Instance | BindingFlags.NonPublic);
AddKeywordFromProperty(encrypt);
}
private static void AddKeywordFromProperty(PropertyInfo pi)
{
string name = pi.Name.ToLower(CultureInfo.InvariantCulture);
string displayName = name;
// now see if we have defined a display name for this property
object[] attr = pi.GetCustomAttributes(false);
foreach (Attribute a in attr)
if (a is DisplayNameAttribute)
{
displayName = (a as DisplayNameAttribute).DisplayName;
break;
}
validKeywords[name] = displayName;
validKeywords[displayName] = displayName;
foreach (Attribute a in attr)
{
if (a is ValidKeywordsAttribute)
{
foreach (string keyword in (a as ValidKeywordsAttribute).Keywords)
validKeywords[keyword.ToLower(CultureInfo.InvariantCulture).Trim()] = displayName;
}
else if (a is DefaultValueAttribute)
{
defaultValues[displayName] = new PropertyDefaultValue(pi.PropertyType,
Convert.ChangeType((a as DefaultValueAttribute).Value, pi.PropertyType, CultureInfo.CurrentCulture));
}
}
}
}
internal struct PropertyDefaultValue
{
public PropertyDefaultValue(Type t, object v)
{
Type = t;
DefaultValue = v;
}
public Type Type;
public object DefaultValue;
}
internal class ValidKeywordsAttribute : Attribute
{
private string keywords;
public ValidKeywordsAttribute(string keywords)
{
this.keywords = keywords.ToLower(CultureInfo.InvariantCulture);
}
public string[] Keywords
{
get { return keywords.Split(','); }
}
}
}

@ -0,0 +1,351 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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
namespace MySql.Data.MySqlClient
{
/// <summary>
/// Collection of error codes that can be returned by the server
/// </summary>
public class MySqlError
{
private string level;
private int code;
private string message;
/// <summary></summary>
/// <param name="level"></param>
/// <param name="code"></param>
/// <param name="message"></param>
public MySqlError(string level, int code, string message)
{
this.level = level;
this.code = code;
this.message = message;
}
/// <summary>
/// Error level
/// </summary>
public string Level
{
get { return level; }
}
/// <summary>
/// Error code
/// </summary>
public int Code
{
get { return code; }
}
/// <summary>
/// Error message
/// </summary>
public string Message
{
get { return message; }
}
};
/// <summary>
/// Provides a reference to error codes returned by MySQL.
/// </summary>
public enum MySqlErrorCode
{
None = 0,
/* ER_HASHCHK=1000,
ER_NISAMCHK=1001,
ER_NO=1002,
ER_YES 1003
ER_CANT_CREATE_FILE 1004
ER_CANT_CREATE_TABLE 1005
ER_CANT_CREATE_DB 1006
ER_DB_CREATE_EXISTS 1007
ER_DB_DROP_EXISTS 1008
ER_DB_DROP_DELETE 1009
ER_DB_DROP_RMDIR 1010
ER_CANT_DELETE_FILE 1011
ER_CANT_FIND_SYSTEM_REC 1012
ER_CANT_GET_STAT 1013
ER_CANT_GET_WD 1014
ER_CANT_LOCK 1015
ER_CANT_OPEN_FILE 1016
ER_FILE_NOT_FOUND 1017
ER_CANT_READ_DIR 1018
ER_CANT_SET_WD 1019
ER_CHECKREAD 1020
ER_DISK_FULL 1021
*/
/// <summary>
/// There is already a key with the given values.
/// </summary>
DuplicateKey = 1022,
/* ER_ERROR_ON_CLOSE 1023
ER_ERROR_ON_READ 1024
ER_ERROR_ON_RENAME 1025
ER_ERROR_ON_WRITE 1026
ER_FILE_USED 1027
ER_FILSORT_ABORT 1028
ER_FORM_NOT_FOUND 1029
ER_GET_ERRNO 1030
ER_ILLEGAL_HA 1031*/
/// <summary>
/// The specified key was not found.
/// </summary>
KeyNotFound = 1032,
/* ER_NOT_FORM_FILE 1033
ER_NOT_KEYFILE 1034
ER_OLD_KEYFILE 1035
ER_OPEN_AS_READONLY 1036
ER_OUTOFMEMORY 1037
ER_OUT_OF_SORTMEMORY 1038
ER_UNEXPECTED_EOF 1039
ER_CON_COUNT_ERROR 1040
ER_OUT_OF_RESOURCES 1041*/
/// <summary>
/// Given when the connection is unable to successfully connect to host.
/// </summary>
UnableToConnectToHost = 1042,
/* ER_HANDSHAKE_ERROR 1043
ER_DBACCESS_DENIED_ERROR 1044*/
/// <summary>
/// Normally returned when an incorrect password is given
/// </summary>
AccessDenied = 1045,
/* ER_NO_DB_ERROR 1046
ER_UNKNOWN_COM_ERROR 1047
ER_BAD_NULL_ERROR 1048*/
UnknownDatabase = 1049,
/*ER_BAD_DB_ERROR 1049
ER_TABLE_EXISTS_ERROR 1050
ER_BAD_TABLE_ERROR 1051
ER_NON_UNIQ_ERROR 1052
ER_SERVER_SHUTDOWN 1053
ER_BAD_FIELD_ERROR 1054
ER_WRONG_FIELD_WITH_GROUP 1055
ER_WRONG_GROUP_FIELD 1056
ER_WRONG_SUM_SELECT 1057
ER_WRONG_VALUE_COUNT 1058
ER_TOO_LONG_IDENT 1059
ER_DUP_FIELDNAME 1060*/
/// <summary>
/// Duplicate Key Name
/// </summary>
DuplicateKeyName = 1061,
/// <summary>
/// Duplicate Key Entry
/// </summary>
DuplicateKeyEntry = 1062,
/* ER_WRONG_FIELD_SPEC 1063
ER_PARSE_ERROR 1064
ER_EMPTY_QUERY 1065
ER_NONUNIQ_TABLE 1066
ER_INVALID_DEFAULT 1067
ER_MULTIPLE_PRI_KEY 1068
ER_TOO_MANY_KEYS 1069
ER_TOO_MANY_KEY_PARTS 1070
ER_TOO_LONG_KEY 1071
ER_KEY_COLUMN_DOES_NOT_EXITS 1072
ER_BLOB_USED_AS_KEY 1073
ER_TOO_BIG_FIELDLENGTH 1074
ER_WRONG_AUTO_KEY 1075
ER_READY 1076
ER_NORMAL_SHUTDOWN 1077
ER_GOT_SIGNAL 1078
ER_SHUTDOWN_COMPLETE 1079
ER_FORCING_CLOSE 1080
ER_IPSOCK_ERROR 1081
ER_NO_SUCH_INDEX 1082
ER_WRONG_FIELD_TERMINATORS 1083
ER_BLOBS_AND_NO_TERMINATED 1084
ER_TEXTFILE_NOT_READABLE 1085
ER_FILE_EXISTS_ERROR 1086
ER_LOAD_INFO 1087
ER_ALTER_INFO 1088
ER_WRONG_SUB_KEY 1089
ER_CANT_REMOVE_ALL_FIELDS 1090
ER_CANT_DROP_FIELD_OR_KEY 1091
ER_INSERT_INFO 1092
ER_INSERT_TABLE_USED 1093
ER_NO_SUCH_THREAD 1094
ER_KILL_DENIED_ERROR 1095
ER_NO_TABLES_USED 1096
ER_TOO_BIG_SET 1097
ER_NO_UNIQUE_LOGFILE 1098
ER_TABLE_NOT_LOCKED_FOR_WRITE 1099
ER_TABLE_NOT_LOCKED 1100
ER_BLOB_CANT_HAVE_DEFAULT 1101
ER_WRONG_DB_NAME 1102
ER_WRONG_TABLE_NAME 1103
ER_TOO_BIG_SELECT 1104
ER_UNKNOWN_ERROR 1105
ER_UNKNOWN_PROCEDURE 1106
ER_WRONG_PARAMCOUNT_TO_PROCEDURE 1107
ER_WRONG_PARAMETERS_TO_PROCEDURE 1108
ER_UNKNOWN_TABLE 1109
ER_FIELD_SPECIFIED_TWICE 1110
ER_INVALID_GROUP_FUNC_USE 1111
ER_UNSUPPORTED_EXTENSION 1112
ER_TABLE_MUST_HAVE_COLUMNS 1113
ER_RECORD_FILE_FULL 1114
ER_UNKNOWN_CHARACTER_SET 1115
ER_TOO_MANY_TABLES 1116
ER_TOO_MANY_FIELDS 1117
ER_TOO_BIG_ROWSIZE 1118
ER_STACK_OVERRUN 1119
ER_WRONG_OUTER_JOIN 1120
ER_NULL_COLUMN_IN_INDEX 1121
ER_CANT_FIND_UDF 1122
ER_CANT_INITIALIZE_UDF 1123
ER_UDF_NO_PATHS 1124
ER_UDF_EXISTS 1125
ER_CANT_OPEN_LIBRARY 1126
ER_CANT_FIND_DL_ENTRY 1127
ER_FUNCTION_NOT_DEFINED 1128
ER_HOST_IS_BLOCKED 1129
*/
/// <summary>
/// The given host is not allowed to connect
/// </summary>
HostNotPrivileged = 1130,
/// <summary>
/// The anonymous user is not allowed to connect
/// </summary>
AnonymousUser = 1131,
/// <summary>
/// The given password is not allowed
/// </summary>
PasswordNotAllowed = 1132,
/// <summary>
/// The given password does not match
/// </summary>
PasswordNoMatch = 1133,
/* ER_UPDATE_INFO 1134
ER_CANT_CREATE_THREAD 1135
ER_WRONG_VALUE_COUNT_ON_ROW 1136
ER_CANT_REOPEN_TABLE 1137
ER_INVALID_USE_OF_NULL 1138
ER_REGEXP_ERROR 1139
ER_MIX_OF_GROUP_FUNC_AND_FIELDS 1140
ER_NONEXISTING_GRANT 1141*/ TableAccessDenied = 1142, ColumnAccessDenied = 1143, IllegalGrantForTable = 1144,/* ER_GRANT_WRONG_HOST_OR_USER 1145 */ NoSuchTable = 1146,
NonExistingTableGrant = 1147,
/* ER_NOT_ALLOWED_COMMAND 1148
ER_SYNTAX_ERROR 1149
ER_DELAYED_CANT_CHANGE_LOCK 1150
ER_TOO_MANY_DELAYED_THREADS 1151
ER_ABORTING_CONNECTION 1152
*/
/// <summary>
/// An attempt was made to send or receive a packet larger than
/// max_allowed_packet_size
/// </summary>
PacketTooLarge=1153
/*
ER_NET_READ_ERROR_FROM_PIPE 1154
ER_NET_FCNTL_ERROR 1155
ER_NET_PACKETS_OUT_OF_ORDER 1156
ER_NET_UNCOMPRESS_ERROR 1157
ER_NET_READ_ERROR 1158
ER_NET_READ_INTERRUPTED 1159
ER_NET_ERROR_ON_WRITE 1160
ER_NET_WRITE_INTERRUPTED 1161
ER_TOO_LONG_STRING 1162
ER_TABLE_CANT_HANDLE_BLOB 1163
ER_TABLE_CANT_HANDLE_AUTO_INCREMENT 1164
ER_DELAYED_INSERT_TABLE_LOCKED 1165
ER_WRONG_COLUMN_NAME 1166
ER_WRONG_KEY_COLUMN 1167
ER_WRONG_MRG_TABLE 1168
ER_DUP_UNIQUE 1169
ER_BLOB_KEY_WITHOUT_LENGTH 1170
ER_PRIMARY_CANT_HAVE_NULL 1171
ER_TOO_MANY_ROWS 1172
ER_REQUIRES_PRIMARY_KEY 1173
ER_NO_RAID_COMPILED 1174
ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE 1175
ER_KEY_DOES_NOT_EXITS 1176
ER_CHECK_NO_SUCH_TABLE 1177
ER_CHECK_NOT_IMPLEMENTED 1178
ER_CANT_DO_THIS_DURING_AN_TRANSACTION 1179
ER_ERROR_DURING_COMMIT 1180
ER_ERROR_DURING_ROLLBACK 1181
ER_ERROR_DURING_FLUSH_LOGS 1182
ER_ERROR_DURING_CHECKPOINT 1183
ER_NEW_ABORTING_CONNECTION 1184
ER_DUMP_NOT_IMPLEMENTED 1185
ER_FLUSH_MASTER_BINLOG_CLOSED 1186
ER_INDEX_REBUILD 1187
ER_MASTER 1188
ER_MASTER_NET_READ 1189
ER_MASTER_NET_WRITE 1190
ER_FT_MATCHING_KEY_NOT_FOUND 1191
ER_LOCK_OR_ACTIVE_TRANSACTION 1192
ER_UNKNOWN_SYSTEM_VARIABLE 1193
ER_CRASHED_ON_USAGE 1194
ER_CRASHED_ON_REPAIR 1195
ER_WARNING_NOT_COMPLETE_ROLLBACK 1196
ER_TRANS_CACHE_FULL 1197
ER_SLAVE_MUST_STOP 1198
ER_SLAVE_NOT_RUNNING 1199
ER_BAD_SLAVE 1200
ER_MASTER_INFO 1201
ER_SLAVE_THREAD 1202
ER_TOO_MANY_USER_CONNECTIONS 1203
ER_SET_CONSTANTS_ONLY 1204
ER_LOCK_WAIT_TIMEOUT 1205
ER_LOCK_TABLE_FULL 1206
ER_READ_ONLY_TRANSACTION 1207
ER_DROP_DB_WITH_READ_LOCK 1208
ER_CREATE_DB_WITH_READ_LOCK 1209
ER_WRONG_ARGUMENTS 1210
ER_NO_PERMISSION_TO_CREATE_USER 1211
ER_UNION_TABLES_IN_DIFFERENT_DIR 1212
ER_LOCK_DEADLOCK 1213
ER_TABLE_CANT_HANDLE_FULLTEXT 1214
ER_CANNOT_ADD_FOREIGN 1215
ER_NO_REFERENCED_ROW 1216
ER_ROW_IS_REFERENCED 1217
ER_CONNECT_TO_MASTER 1218
ER_QUERY_ON_MASTER 1219
ER_ERROR_WHEN_EXECUTING_COMMAND 1220
ER_WRONG_USAGE 1221
ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT 1222
ER_CANT_UPDATE_WITH_READLOCK 1223
ER_MIXING_NOT_ALLOWED 1224
ER_DUP_ARGUMENT 1225
ER_USER_LIMIT_REACHED 1226
ER_SPECIFIC_ACCESS_DENIED_ERROR 1227
ER_LOCAL_VARIABLE 1228
ER_GLOBAL_VARIABLE 1229
ER_NO_DEFAULT 1230
ER_WRONG_VALUE_FOR_VAR 1231
ER_WRONG_TYPE_FOR_VAR 1232
ER_VAR_CANT_BE_READ 1233
ER_CANT_USE_OPTION_HERE 1234
ER_NOT_SUPPORTED_YET 1235
ER_MASTER_FATAL_ERROR_READING_BINLOG 1236
ER_SLAVE_IGNORED_TABLE 1237 // only the slave SQL thread can be sent this
ER_ERROR_MESSAGES 238*/
}
}

@ -0,0 +1,406 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Data;
using MySql.Data.MySqlClient;
using System.Text;
namespace MySql.Data.MySqlClient
{
/// <summary>
/// Helper class that makes it easier to work with the provider.
/// </summary>
public sealed class MySqlHelper
{
private static string stringOfBackslashChars = "\u005c\u00a5\u0160\u20a9\u2216\ufe68\uff3c";
private static string stringOfQuoteChars =
"\u0027\u0060\u00b4\u02b9\u02ba\u02bb\u02bc\u02c8\u02ca\u02cb\u02d9\u0300\u0301\u2018\u2019\u201a\u2032\u2035\u275b\u275c\uff07";
// this class provides only static methods
private MySqlHelper()
{
}
#region ExecuteNonQuery
/// <summary>
/// Executes a single command against a MySQL database. The <see cref="MySqlConnection"/> is assumed to be
/// open when the method is called and remains open after the method completes.
/// </summary>
/// <param name="connection"><see cref="MySqlConnection"/> object to use</param>
/// <param name="commandText">SQL command to be executed</param>
/// <param name="commandParameters">Array of <see cref="MySqlParameter"/> objects to use with the command.</param>
/// <returns></returns>
public static int ExecuteNonQuery( MySqlConnection connection, string commandText, params MySqlParameter[] commandParameters )
{
//create a command and prepare it for execution
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = connection;
cmd.CommandText = commandText;
cmd.CommandType = CommandType.Text;
if (commandParameters != null)
foreach (MySqlParameter p in commandParameters)
cmd.Parameters.Add( p );
int result = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return result;
}
/// <summary>
/// Executes a single command against a MySQL database. A new <see cref="MySqlConnection"/> is created
/// using the <see cref="MySqlConnection.ConnectionString"/> given.
/// </summary>
/// <param name="connectionString"><see cref="MySqlConnection.ConnectionString"/> to use</param>
/// <param name="commandText">SQL command to be executed</param>
/// <param name="parms">Array of <see cref="MySqlParameter"/> objects to use with the command.</param>
/// <returns></returns>
public static int ExecuteNonQuery( string connectionString, string commandText, params MySqlParameter[] parms )
{
//create & open a SqlConnection, and dispose of it after we are done.
using (MySqlConnection cn = new MySqlConnection(connectionString))
{
cn.Open();
//call the overload that takes a connection in place of the connection string
return ExecuteNonQuery(cn, commandText, parms );
}
}
#endregion
#region ExecuteDataSet
/// <summary>
/// Executes a single SQL command and returns the first row of the resultset. A new MySqlConnection object
/// is created, opened, and closed during this method.
/// </summary>
/// <param name="connectionString">Settings to be used for the connection</param>
/// <param name="commandText">Command to execute</param>
/// <param name="parms">Parameters to use for the command</param>
/// <returns>DataRow containing the first row of the resultset</returns>
public static DataRow ExecuteDataRow( string connectionString, string commandText, params MySqlParameter[] parms )
{
DataSet ds = ExecuteDataset( connectionString, commandText, parms );
if (ds == null) return null;
if (ds.Tables.Count == 0) return null;
if (ds.Tables[0].Rows.Count == 0) return null;
return ds.Tables[0].Rows[0];
}
/// <summary>
/// Executes a single SQL command and returns the resultset in a <see cref="DataSet"/>.
/// A new MySqlConnection object is created, opened, and closed during this method.
/// </summary>
/// <param name="connectionString">Settings to be used for the connection</param>
/// <param name="commandText">Command to execute</param>
/// <returns><see cref="DataSet"/> containing the resultset</returns>
public static DataSet ExecuteDataset(string connectionString, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteDataset(connectionString, commandText, (MySqlParameter[])null);
}
/// <summary>
/// Executes a single SQL command and returns the resultset in a <see cref="DataSet"/>.
/// A new MySqlConnection object is created, opened, and closed during this method.
/// </summary>
/// <param name="connectionString">Settings to be used for the connection</param>
/// <param name="commandText">Command to execute</param>
/// <param name="commandParameters">Parameters to use for the command</param>
/// <returns><see cref="DataSet"/> containing the resultset</returns>
public static DataSet ExecuteDataset(string connectionString, string commandText, params MySqlParameter[] commandParameters)
{
//create & open a SqlConnection, and dispose of it after we are done.
using (MySqlConnection cn = new MySqlConnection(connectionString))
{
cn.Open();
//call the overload that takes a connection in place of the connection string
return ExecuteDataset(cn, commandText, commandParameters);
}
}
/// <summary>
/// Executes a single SQL command and returns the resultset in a <see cref="DataSet"/>.
/// The state of the <see cref="MySqlConnection"/> object remains unchanged after execution
/// of this method.
/// </summary>
/// <param name="connection"><see cref="MySqlConnection"/> object to use</param>
/// <param name="commandText">Command to execute</param>
/// <returns><see cref="DataSet"/> containing the resultset</returns>
public static DataSet ExecuteDataset(MySqlConnection connection, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteDataset(connection, commandText, (MySqlParameter[])null);
}
/// <summary>
/// Executes a single SQL command and returns the resultset in a <see cref="DataSet"/>.
/// The state of the <see cref="MySqlConnection"/> object remains unchanged after execution
/// of this method.
/// </summary>
/// <param name="connection"><see cref="MySqlConnection"/> object to use</param>
/// <param name="commandText">Command to execute</param>
/// <param name="commandParameters">Parameters to use for the command</param>
/// <returns><see cref="DataSet"/> containing the resultset</returns>
public static DataSet ExecuteDataset(MySqlConnection connection, string commandText, params MySqlParameter[] commandParameters)
{
//create a command and prepare it for execution
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = connection;
cmd.CommandText = commandText;
cmd.CommandType = CommandType.Text;
if (commandParameters != null)
foreach (MySqlParameter p in commandParameters)
cmd.Parameters.Add( p );
//create the DataAdapter & DataSet
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
DataSet ds = new DataSet();
//fill the DataSet using default values for DataTable names, etc.
da.Fill(ds);
// detach the MySqlParameters from the command object, so they can be used again.
cmd.Parameters.Clear();
//return the dataset
return ds;
}
/// <summary>
/// Updates the given table with data from the given <see cref="DataSet"/>
/// </summary>
/// <param name="connectionString">Settings to use for the update</param>
/// <param name="commandText">Command text to use for the update</param>
/// <param name="ds"><see cref="DataSet"/> containing the new data to use in the update</param>
/// <param name="tablename">Tablename in the dataset to update</param>
public static void UpdateDataSet( string connectionString, string commandText, DataSet ds, string tablename )
{
MySqlConnection cn = new MySqlConnection( connectionString );
cn.Open();
MySqlDataAdapter da = new MySqlDataAdapter( commandText, cn );
MySqlCommandBuilder cb = new MySqlCommandBuilder(da);
cb.ToString();
da.Update( ds, tablename );
cn.Close();
}
#endregion
#region ExecuteDataReader
/// <summary>
/// Executes a single command against a MySQL database, possibly inside an existing transaction.
/// </summary>
/// <param name="connection"><see cref="MySqlConnection"/> object to use for the command</param>
/// <param name="transaction"><see cref="MySqlTransaction"/> object to use for the command</param>
/// <param name="commandText">Command text to use</param>
/// <param name="commandParameters">Array of <see cref="MySqlParameter"/> objects to use with the command</param>
/// <param name="ExternalConn">True if the connection should be preserved, false if not</param>
/// <returns><see cref="MySqlDataReader"/> object ready to read the results of the command</returns>
private static MySqlDataReader ExecuteReader(MySqlConnection connection, MySqlTransaction transaction, string commandText, MySqlParameter[] commandParameters, bool ExternalConn )
{
//create a command and prepare it for execution
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = connection;
cmd.Transaction = transaction;
cmd.CommandText = commandText;
cmd.CommandType = CommandType.Text;
if (commandParameters != null)
foreach (MySqlParameter p in commandParameters)
cmd.Parameters.Add( p );
//create a reader
MySqlDataReader dr;
// call ExecuteReader with the appropriate CommandBehavior
if (ExternalConn)
{
dr = cmd.ExecuteReader();
}
else
{
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
// detach the SqlParameters from the command object, so they can be used again.
cmd.Parameters.Clear();
return dr;
}
/// <summary>
/// Executes a single command against a MySQL database.
/// </summary>
/// <param name="connectionString">Settings to use for this command</param>
/// <param name="commandText">Command text to use</param>
/// <returns><see cref="MySqlDataReader"/> object ready to read the results of the command</returns>
public static MySqlDataReader ExecuteReader(string connectionString, string commandText)
{
//pass through the call providing null for the set of SqlParameters
return ExecuteReader(connectionString, commandText, (MySqlParameter[])null);
}
/// <summary>
/// Executes a single command against a MySQL database.
/// </summary>
/// <param name="connectionString">Settings to use for this command</param>
/// <param name="commandText">Command text to use</param>
/// <param name="commandParameters">Array of <see cref="MySqlParameter"/> objects to use with the command</param>
/// <returns><see cref="MySqlDataReader"/> object ready to read the results of the command</returns>
public static MySqlDataReader ExecuteReader(string connectionString, string commandText, params MySqlParameter[] commandParameters)
{
//create & open a SqlConnection
MySqlConnection cn = new MySqlConnection(connectionString);
cn.Open();
try
{
//call the private overload that takes an internally owned connection in place of the connection string
return ExecuteReader(cn, null, commandText, commandParameters, false );
}
catch
{
//if we fail to return the SqlDatReader, we need to close the connection ourselves
cn.Close();
throw;
}
}
#endregion
#region ExecuteScalar
/// <summary>
/// Execute a single command against a MySQL database.
/// </summary>
/// <param name="connectionString">Settings to use for the update</param>
/// <param name="commandText">Command text to use for the update</param>
/// <returns>The first column of the first row in the result set, or a null reference if the result set is empty.</returns>
public static object ExecuteScalar(string connectionString, string commandText)
{
//pass through the call providing null for the set of MySqlParameters
return ExecuteScalar(connectionString, commandText, (MySqlParameter[])null);
}
/// <summary>
/// Execute a single command against a MySQL database.
/// </summary>
/// <param name="connectionString">Settings to use for the command</param>
/// <param name="commandText">Command text to use for the command</param>
/// <param name="commandParameters">Parameters to use for the command</param>
/// <returns>The first column of the first row in the result set, or a null reference if the result set is empty.</returns>
public static object ExecuteScalar(string connectionString, string commandText, params MySqlParameter[] commandParameters)
{
//create & open a SqlConnection, and dispose of it after we are done.
using (MySqlConnection cn = new MySqlConnection(connectionString))
{
cn.Open();
//call the overload that takes a connection in place of the connection string
return ExecuteScalar(cn, commandText, commandParameters);
}
}
/// <summary>
/// Execute a single command against a MySQL database.
/// </summary>
/// <param name="connection"><see cref="MySqlConnection"/> object to use</param>
/// <param name="commandText">Command text to use for the command</param>
/// <returns>The first column of the first row in the result set, or a null reference if the result set is empty.</returns>
public static object ExecuteScalar(MySqlConnection connection, string commandText)
{
//pass through the call providing null for the set of MySqlParameters
return ExecuteScalar(connection, commandText, (MySqlParameter[])null);
}
/// <summary>
/// Execute a single command against a MySQL database.
/// </summary>
/// <param name="connection"><see cref="MySqlConnection"/> object to use</param>
/// <param name="commandText">Command text to use for the command</param>
/// <param name="commandParameters">Parameters to use for the command</param>
/// <returns>The first column of the first row in the result set, or a null reference if the result set is empty.</returns>
public static object ExecuteScalar(MySqlConnection connection, string commandText, params MySqlParameter[] commandParameters)
{
//create a command and prepare it for execution
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = connection;
cmd.CommandText = commandText;
cmd.CommandType = CommandType.Text;
if (commandParameters != null)
foreach (MySqlParameter p in commandParameters)
cmd.Parameters.Add( p );
//execute the command & return the results
object retval = cmd.ExecuteScalar();
// detach the SqlParameters from the command object, so they can be used again.
cmd.Parameters.Clear();
return retval;
}
#endregion
#region Utility methods
/// <summary>
/// Escapes the string.
/// </summary>
/// <param name="value">The string to escape</param>
/// <returns>The string with all quotes escaped.</returns>
public static string EscapeString(string value)
{
StringBuilder sb = new StringBuilder();
foreach (char c in value)
{
if (stringOfQuoteChars.IndexOf(c) >= 0 ||
//sb.Append(c);
//else if (
stringOfBackslashChars.IndexOf(c) >= 0)
sb.Append("\\");
sb.Append(c);
}
return sb.ToString();
}
public static string DoubleQuoteString(string value)
{
StringBuilder sb = new StringBuilder();
foreach (char c in value)
{
if (stringOfQuoteChars.IndexOf(c) >= 0)
sb.Append(c);
else if (stringOfBackslashChars.IndexOf(c) >= 0)
sb.Append("\\");
sb.Append(c);
}
return sb.ToString();
}
#endregion
}
}

@ -0,0 +1,356 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Diagnostics;
using System.Text;
using System.IO;
using MySql.Data.Common;
using MySql.Data.MySqlClient.Properties;
namespace MySql.Data.MySqlClient
{
class MySqlPacket
{
private byte[] tempBuffer = new byte[256];
private Encoding encoding;
private MemoryStream buffer = new MemoryStream(5);
private DBVersion version;
private MySqlPacket()
{
Clear();
}
public MySqlPacket(Encoding enc) : this()
{
Encoding = enc;
}
public MySqlPacket(MemoryStream stream)
: this()
{
buffer = stream;
}
#region Properties
public Encoding Encoding
{
get { return encoding; }
set
{
Debug.Assert(value != null);
encoding = value;
}
}
public bool HasMoreData
{
get { return buffer.Position < buffer.Length; }
}
public int Position
{
get { return (int)buffer.Position; }
set { buffer.Position = (long)value; }
}
public int Length
{
get { return (int)buffer.Length; }
set { buffer.SetLength(value); }
}
public bool IsLastPacket
{
get
{
byte[] bits = buffer.GetBuffer();
return bits[0] == 0xfe && Length <= 5;
}
}
public byte[] Buffer
{
get { return buffer.GetBuffer(); }
}
public DBVersion Version
{
get { return version; }
set { version = value; }
}
#endregion
public void Clear()
{
Position = 4;
}
#region Byte methods
public byte ReadByte()
{
return (byte)buffer.ReadByte();
}
public int Read(byte[] byteBuffer, int offset, int count)
{
return buffer.Read(byteBuffer, offset, count);
}
public void WriteByte(byte b)
{
buffer.WriteByte(b);
}
public void Write(byte[] bytesToWrite)
{
Write(bytesToWrite, 0, bytesToWrite.Length);
}
public void Write(byte[] bytesToWrite, int offset, int countToWrite)
{
buffer.Write(bytesToWrite, offset, countToWrite);
}
public int ReadNBytes()
{
byte c = ReadByte();
if (c < 1 || c > 4)
throw new MySqlException(Resources.IncorrectTransmission);
return ReadInteger(c);
}
#endregion
#region Integer methods
public int ReadFieldLength()
{
byte c = ReadByte();
switch (c)
{
case 251: return -1;
case 252: return ReadInteger(2);
case 253: return ReadInteger(3);
case 254: return ReadInteger(8);
default: return c;
}
}
public ulong ReadBitValue(int numbytes)
{
ulong value = 0;
int pos = (int)buffer.Position;
byte[] bits = buffer.GetBuffer();
int shift = 0;
for (int i = 0; i < numbytes; i++)
{
value <<= shift;
value |= bits[pos++];
shift = 8;
}
buffer.Position += numbytes;
return value;
}
public long ReadLong(int numbytes)
{
Debug.Assert((buffer.Position + numbytes) <= buffer.Length);
byte[] bytes = buffer.GetBuffer();
int pos = (int)buffer.Position;
buffer.Position += numbytes;
switch (numbytes)
{
case 2: return BitConverter.ToUInt16(bytes, pos);
case 4: return BitConverter.ToUInt32(bytes, pos);
case 8: return BitConverter.ToInt64(bytes, pos);
}
throw new NotSupportedException("Only byte lengths of 2, 4, or 8 are supported");
}
public ulong ReadULong(int numbytes)
{
Debug.Assert((buffer.Position + numbytes) <= buffer.Length);
byte[] bytes = buffer.GetBuffer();
int pos = (int)buffer.Position;
buffer.Position += numbytes;
switch (numbytes)
{
case 2: return BitConverter.ToUInt16(bytes, pos);
case 4: return BitConverter.ToUInt32(bytes, pos);
case 8: return BitConverter.ToUInt64(bytes, pos);
}
throw new NotSupportedException("Only byte lengths of 2, 4, or 8 are supported");
}
public int Read3ByteInt()
{
int value = 0;
int pos = (int)buffer.Position;
byte[] bits = buffer.GetBuffer();
int shift = 0;
for (int i = 0; i < 3; i++)
{
value |= (int)(bits[pos++] << shift);
shift += 8;
}
buffer.Position += 3;
return value;
}
public int ReadInteger(int numbytes)
{
if (numbytes == 3)
return Read3ByteInt();
Debug.Assert(numbytes <= 4);
return (int)ReadLong(numbytes);
}
/// <summary>
/// WriteInteger
/// </summary>
/// <param name="v"></param>
/// <param name="numbytes"></param>
public void WriteInteger(long v, int numbytes)
{
long val = v;
Debug.Assert(numbytes > 0 && numbytes < 9);
for (int x = 0; x < numbytes; x++)
{
tempBuffer[x] = (byte)(val & 0xff);
val >>= 8;
}
Write(tempBuffer, 0, numbytes);
}
public int ReadPackedInteger()
{
byte c = ReadByte();
switch (c)
{
case 251: return -1;
case 252: return ReadInteger(2);
case 253: return ReadInteger(3);
case 254: return ReadInteger(4);
default: return c;
}
}
public void WriteLength(long length)
{
if (length < 251)
WriteByte((byte)length);
else if (length < 65536L)
{
WriteByte(252);
WriteInteger(length, 2);
}
else if (length < 16777216L)
{
WriteByte(253);
WriteInteger(length, 3);
}
else
{
WriteByte(254);
WriteInteger(length, 4);
}
}
#endregion
#region String methods
public void WriteLenString(string s)
{
byte[] bytes = encoding.GetBytes(s);
WriteLength(bytes.Length);
Write(bytes, 0, bytes.Length);
}
public void WriteStringNoNull(string v)
{
byte[] bytes = encoding.GetBytes(v);
Write(bytes, 0, bytes.Length);
}
public void WriteString(string v)
{
WriteStringNoNull(v);
WriteByte(0);
}
public string ReadLenString()
{
long len = ReadPackedInteger();
return ReadString(len);
}
public string ReadAsciiString(long length)
{
if (length == 0)
return String.Empty;
// byte[] buf = new byte[length];
Read(tempBuffer, 0, (int)length);
return ASCIIEncoding.ASCII.GetString(tempBuffer, 0, (int)length);
//return encoding.GetString(tempBuffer, 0, (int)length); //buf.Length);
}
public string ReadString(long length)
{
if (length == 0)
return String.Empty;
if (tempBuffer == null || length > tempBuffer.Length)
tempBuffer = new byte[length];
Read(tempBuffer, 0, (int)length);
return encoding.GetString(tempBuffer, 0, (int)length);
}
public string ReadString()
{
byte[] bits = buffer.GetBuffer();
int end = (int)buffer.Position;
while (end < (int)buffer.Length &&
bits[end] != 0 && (int)bits[end] != -1)
end++;
string s = encoding.GetString(bits,
(int)buffer.Position, end - (int)buffer.Position);
buffer.Position = end + 1;
return s;
}
#endregion
}
}

@ -0,0 +1,330 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using MySql.Data.MySqlClient.Properties;
namespace MySql.Data.MySqlClient
{
/// <summary>
/// Summary description for MySqlPool.
/// </summary>
internal sealed class MySqlPool
{
private List<Driver> inUsePool;
private Queue<Driver> idlePool;
private MySqlConnectionStringBuilder settings;
private uint minSize;
private uint maxSize;
private ProcedureCache procedureCache;
private bool beingCleared;
private int available;
private AutoResetEvent autoEvent;
private void EnqueueIdle(Driver driver)
{
driver.IdleSince = DateTime.Now;
idlePool.Enqueue(driver);
}
public MySqlPool(MySqlConnectionStringBuilder settings)
{
minSize = settings.MinimumPoolSize;
maxSize = settings.MaximumPoolSize;
available = (int)maxSize;
autoEvent = new AutoResetEvent(false);
if (minSize > maxSize)
minSize = maxSize;
this.settings = settings;
inUsePool = new List<Driver>((int)maxSize);
idlePool = new Queue<Driver>((int)maxSize);
// prepopulate the idle pool to minSize
for (int i = 0; i < minSize; i++)
EnqueueIdle(CreateNewPooledConnection());
procedureCache = new ProcedureCache((int)settings.ProcedureCacheSize);
}
#region Properties
public MySqlConnectionStringBuilder Settings
{
get { return settings; }
set { settings = value; }
}
public ProcedureCache ProcedureCache
{
get { return procedureCache; }
}
/// <summary>
/// It is assumed that this property will only be used from inside an active
/// lock.
/// </summary>
private bool HasIdleConnections
{
get { return idlePool.Count > 0; }
}
private int NumConnections
{
get { return idlePool.Count + inUsePool.Count; }
}
/// <summary>
/// Indicates whether this pool is being cleared.
/// </summary>
public bool BeingCleared
{
get { return beingCleared; }
}
#endregion
/// <summary>
/// It is assumed that this method is only called from inside an active lock.
/// </summary>
private Driver GetPooledConnection()
{
Driver driver = null;
// if we don't have an idle connection but we have room for a new
// one, then create it here.
lock ((idlePool as ICollection).SyncRoot)
{
if (HasIdleConnections)
driver = idlePool.Dequeue();
}
// Obey the connection timeout
if (driver != null)
{
try
{
driver.ResetTimeout((int)Settings.ConnectionTimeout * 1000);
}
catch (Exception)
{
driver.Close();
driver = null;
}
}
if (driver != null)
{
// first check to see that the server is still alive
if (!driver.Ping())
{
driver.Close();
driver = null;
}
else if (settings.ConnectionReset)
// if the user asks us to ping/reset pooled connections
// do so now
driver.Reset();
}
if (driver == null)
driver = CreateNewPooledConnection();
Debug.Assert(driver != null);
lock ((inUsePool as ICollection).SyncRoot)
{
inUsePool.Add(driver);
}
return driver;
}
/// <summary>
/// It is assumed that this method is only called from inside an active lock.
/// </summary>
private Driver CreateNewPooledConnection()
{
Debug.Assert((maxSize - NumConnections) > 0, "Pool out of sync.");
Driver driver = Driver.Create(settings);
driver.Pool = this;
return driver;
}
public void ReleaseConnection(Driver driver)
{
lock ((inUsePool as ICollection).SyncRoot)
{
if (inUsePool.Contains(driver))
inUsePool.Remove(driver);
}
if (driver.ConnectionLifetimeExpired() || beingCleared)
{
driver.Close();
Debug.Assert(!idlePool.Contains(driver));
}
else
{
lock ((idlePool as ICollection).SyncRoot)
{
EnqueueIdle(driver);
}
}
Interlocked.Increment(ref available);
autoEvent.Set();
}
/// <summary>
/// Removes a connection from the in use pool. The only situations where this method
/// would be called are when a connection that is in use gets some type of fatal exception
/// or when the connection is being returned to the pool and it's too old to be
/// returned.
/// </summary>
/// <param name="driver"></param>
public void RemoveConnection(Driver driver)
{
lock ((inUsePool as ICollection).SyncRoot)
{
if (inUsePool.Contains(driver))
{
inUsePool.Remove(driver);
Interlocked.Increment(ref available);
autoEvent.Set();
}
}
// if we are being cleared and we are out of connections then have
// the manager destroy us.
if (beingCleared && NumConnections == 0)
MySqlPoolManager.RemoveClearedPool(this);
}
private Driver TryToGetDriver()
{
int count = Interlocked.Decrement(ref available);
if (count < 0)
{
Interlocked.Increment(ref available);
return null;
}
try
{
Driver driver = GetPooledConnection();
return driver;
}
catch (Exception ex)
{
MySqlTrace.LogError(-1, ex.Message);
Interlocked.Increment(ref available);
throw;
}
}
public Driver GetConnection()
{
int fullTimeOut = (int)settings.ConnectionTimeout * 1000;
int timeOut = fullTimeOut;
DateTime start = DateTime.Now;
while (timeOut > 0)
{
Driver driver = TryToGetDriver();
if (driver != null) return driver;
// We have no tickets right now, lets wait for one.
if (!autoEvent.WaitOne(timeOut, false)) break;
timeOut = fullTimeOut - (int)DateTime.Now.Subtract(start).TotalMilliseconds;
}
throw new MySqlException(Resources.TimeoutGettingConnection);
}
/// <summary>
/// Clears this pool of all idle connections and marks this pool and being cleared
/// so all other connections are closed when they are returned.
/// </summary>
internal void Clear()
{
lock ((idlePool as ICollection).SyncRoot)
{
// first, mark ourselves as being cleared
beingCleared = true;
// then we remove all connections sitting in the idle pool
while (idlePool.Count > 0)
{
Driver d = idlePool.Dequeue();
d.Close();
}
// there is nothing left to do here. Now we just wait for all
// in use connections to be returned to the pool. When they are
// they will be closed. When the last one is closed, the pool will
// be destroyed.
}
}
/// <summary>
/// Remove expired drivers from the idle pool
/// </summary>
/// <returns></returns>
/// <remarks>
/// Closing driver is a potentially lengthy operation involving network
/// IO. Therefore we do not close expired drivers while holding
/// idlePool.SyncRoot lock. We just remove the old drivers from the idle
/// queue and return them to the caller. The caller will need to close
/// them (or let GC close them)
/// </remarks>
internal List<Driver> RemoveOldIdleConnections()
{
List<Driver> oldDrivers = new List<Driver>();
DateTime now = DateTime.Now;
lock ((idlePool as ICollection).SyncRoot)
{
// The drivers appear to be ordered by their age, i.e it is
// sufficient to remove them until the first element is not
// too old.
while(idlePool.Count > minSize)
{
Driver d = idlePool.Peek();
DateTime expirationTime = d.IdleSince.Add(
new TimeSpan(0,0, MySqlPoolManager.maxConnectionIdleTime));
if (expirationTime.CompareTo(now) < 0)
{
oldDrivers.Add(d);
idlePool.Dequeue();
}
else
{
break;
}
}
}
return oldDrivers;
}
}
}

@ -0,0 +1,153 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Collections;
using System.Diagnostics;
using System.Collections.Generic;
using System.Threading;
namespace MySql.Data.MySqlClient
{
/// <summary>
/// Summary description for MySqlPoolManager.
/// </summary>
internal class MySqlPoolManager
{
private static Hashtable pools = new Hashtable();
private static List<MySqlPool> clearingPools = new List<MySqlPool>();
// Timeout in seconds, after which an unused (idle) connection
// should be closed.
static internal int maxConnectionIdleTime = 180;
private static Timer timer = new Timer(new TimerCallback(CleanIdleConnections),
null, maxConnectionIdleTime*1000, maxConnectionIdleTime*1000);
public static MySqlPool GetPool(MySqlConnectionStringBuilder settings)
{
string text = settings.ConnectionString;
lock (pools.SyncRoot)
{
MySqlPool pool = (pools[text] as MySqlPool);
if (pool == null)
{
pool = new MySqlPool(settings);
pools.Add(text, pool);
}
else
pool.Settings = settings;
return pool;
}
}
public static void RemoveConnection(Driver driver)
{
Debug.Assert(driver != null);
MySqlPool pool = driver.Pool;
if (pool == null) return;
pool.RemoveConnection(driver);
}
public static void ReleaseConnection(Driver driver)
{
Debug.Assert(driver != null);
MySqlPool pool = driver.Pool;
if (pool == null) return;
pool.ReleaseConnection(driver);
}
public static void ClearPool(MySqlConnectionStringBuilder settings)
{
Debug.Assert(settings != null);
string text = settings.ConnectionString;
ClearPoolByText(text);
}
private static void ClearPoolByText(string key)
{
lock (pools.SyncRoot)
{
// if pools doesn't have it, then this pool must already have been cleared
if (!pools.ContainsKey(key)) return;
// add the pool to our list of pools being cleared
MySqlPool pool = (pools[key] as MySqlPool);
clearingPools.Add(pool);
// now tell the pool to clear itself
pool.Clear();
// and then remove the pool from the active pools list
pools.Remove(key);
}
}
public static void ClearAllPools()
{
lock (pools.SyncRoot)
{
// Create separate keys list.
List<string> keys = new List<string>(pools.Count);
foreach (string key in pools.Keys)
keys.Add(key);
// Remove all pools by key.
foreach (string key in keys)
ClearPoolByText(key);
}
}
public static void RemoveClearedPool(MySqlPool pool)
{
Debug.Assert(clearingPools.Contains(pool));
clearingPools.Remove(pool);
}
/// <summary>
/// Remove drivers that have been idle for too long.
/// </summary>
public static void CleanIdleConnections(object obj)
{
List<Driver> oldDrivers = new List<Driver>();
lock (pools.SyncRoot)
{
foreach (string key in pools.Keys)
{
MySqlPool pool = (pools[key] as MySqlPool);
oldDrivers.AddRange(pool.RemoveOldIdleConnections());
}
}
foreach(Driver driver in oldDrivers)
{
driver.Close();
}
}
}
}

@ -0,0 +1,125 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Transactions;
using System.Collections;
using System.Data;
namespace MySql.Data.MySqlClient
{
internal sealed class MySqlPromotableTransaction : IPromotableSinglePhaseNotification, ITransactionPromoter
{
private MySqlConnection connection;
private Transaction baseTransaction;
private MySqlTransaction simpleTransaction;
public MySqlPromotableTransaction(MySqlConnection connection, Transaction baseTransaction)
{
this.connection = connection;
this.baseTransaction = baseTransaction;
}
public Transaction BaseTransaction
{
get { return baseTransaction; }
}
void IPromotableSinglePhaseNotification.Initialize()
{
string valueName = Enum.GetName(
typeof(System.Transactions.IsolationLevel), baseTransaction.IsolationLevel);
System.Data.IsolationLevel dataLevel = (System.Data.IsolationLevel)Enum.Parse(
typeof(System.Data.IsolationLevel), valueName);
simpleTransaction = connection.BeginTransaction(dataLevel);
}
void IPromotableSinglePhaseNotification.Rollback(SinglePhaseEnlistment singlePhaseEnlistment)
{
// prevent commands in main thread to run concurrently
Driver driver = connection.driver;
lock (driver)
{
while (connection.Reader != null)
{
// wait for reader to finish. Maybe we should not wait
// forever and cancel it after some time?
System.Threading.Thread.Sleep(100);
}
simpleTransaction.Rollback();
singlePhaseEnlistment.Aborted();
DriverTransactionManager.RemoveDriverInTransaction(baseTransaction);
driver.CurrentTransaction = null;
if (connection.State == ConnectionState.Closed)
connection.CloseFully();
}
}
void IPromotableSinglePhaseNotification.SinglePhaseCommit(SinglePhaseEnlistment singlePhaseEnlistment)
{
simpleTransaction.Commit();
singlePhaseEnlistment.Committed();
DriverTransactionManager.RemoveDriverInTransaction(baseTransaction);
connection.driver.CurrentTransaction = null;
if (connection.State == ConnectionState.Closed)
connection.CloseFully();
}
byte[] ITransactionPromoter.Promote()
{
throw new NotSupportedException();
}
}
internal class DriverTransactionManager
{
private static Hashtable driversInUse = new Hashtable();
public static Driver GetDriverInTransaction(Transaction transaction)
{
lock (driversInUse.SyncRoot)
{
Driver d = (Driver)driversInUse[transaction.GetHashCode()];
return d;
}
}
public static void SetDriverInTransaction(Driver driver)
{
lock (driversInUse.SyncRoot)
{
driversInUse[driver.CurrentTransaction.BaseTransaction.GetHashCode()] = driver;
}
}
public static void RemoveDriverInTransaction(Transaction transaction)
{
lock (driversInUse.SyncRoot)
{
driversInUse.Remove(transaction.GetHashCode());
}
}
}
}

@ -0,0 +1,433 @@
// Copyright (c) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.Common;
using System.Collections.Generic;
using System.Text;
using System;
using System.Data;
using System.Globalization;
using System.IO;
using MySql.Data.MySqlClient.Properties;
namespace MySql.Data.MySqlClient
{
/// <summary>
/// Provides a class capable of executing a SQL script containing
/// multiple SQL statements including CREATE PROCEDURE statements
/// that require changing the delimiter
/// </summary>
public class MySqlScript
{
private MySqlConnection connection;
private string query;
private string delimiter;
public event MySqlStatementExecutedEventHandler StatementExecuted;
public event MySqlScriptErrorEventHandler Error;
public event EventHandler ScriptCompleted;
#region Constructors
/// <summary>
/// Initializes a new instance of the
/// <see cref="MySqlScript"/> class.
/// </summary>
public MySqlScript()
{
Delimiter = ";";
}
/// <summary>
/// Initializes a new instance of the
/// <see cref="MySqlScript"/> class.
/// </summary>
/// <param name="connection">The connection.</param>
public MySqlScript(MySqlConnection connection) : this()
{
this.connection = connection;
}
/// <summary>
/// Initializes a new instance of the
/// <see cref="MySqlScript"/> class.
/// </summary>
/// <param name="query">The query.</param>
public MySqlScript(string query) : this()
{
this.query = query;
}
/// <summary>
/// Initializes a new instance of the
/// <see cref="MySqlScript"/> class.
/// </summary>
/// <param name="connection">The connection.</param>
/// <param name="query">The query.</param>
public MySqlScript(MySqlConnection connection, string query)
:this()
{
this.connection = connection;
this.query = query;
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the connection.
/// </summary>
/// <value>The connection.</value>
public MySqlConnection Connection
{
get { return connection; }
set { connection = value; }
}
/// <summary>
/// Gets or sets the query.
/// </summary>
/// <value>The query.</value>
public string Query
{
get { return query; }
set { query = value; }
}
/// <summary>
/// Gets or sets the delimiter.
/// </summary>
/// <value>The delimiter.</value>
public string Delimiter
{
get { return delimiter; }
set { delimiter = value; }
}
#endregion
#region Public Methods
/// <summary>
/// Executes this instance.
/// </summary>
/// <returns>The number of statements executed as part of the script.</returns>
public int Execute()
{
bool openedConnection = false;
if (connection == null)
throw new InvalidOperationException(Resources.ConnectionNotSet);
if (query == null || query.Length == 0)
return 0;
// next we open up the connetion if it is not already open
if (connection.State != ConnectionState.Open)
{
openedConnection = true;
connection.Open();
}
// since we don't allow setting of parameters on a script we can
// therefore safely allow the use of user variables. no one should be using
// this connection while we are using it so we can temporarily tell it
// to allow the use of user variables
bool allowUserVars = connection.Settings.AllowUserVariables;
connection.Settings.AllowUserVariables = true;
try
{
string mode = connection.driver.Property("sql_mode");
mode = mode.ToUpper(CultureInfo.InvariantCulture);
bool ansiQuotes = mode.IndexOf("ANSI_QUOTES") != -1;
bool noBackslashEscapes = mode.IndexOf("NO_BACKSLASH_ESCAPES") != -1;
// first we break the query up into smaller queries
List<ScriptStatement> statements = BreakIntoStatements(ansiQuotes, noBackslashEscapes);
int count = 0;
MySqlCommand cmd = new MySqlCommand(null, connection);
foreach (ScriptStatement statement in statements)
{
if (String.IsNullOrEmpty(statement.text)) continue;
cmd.CommandText = statement.text;
try
{
cmd.ExecuteNonQuery();
count++;
OnQueryExecuted(statement);
}
catch (Exception ex)
{
if (Error == null)
throw;
if (!OnScriptError(ex))
break;
}
}
OnScriptCompleted();
return count;
}
finally
{
connection.Settings.AllowUserVariables = allowUserVars;
if (openedConnection)
{
connection.Close();
}
}
}
#endregion
private void OnQueryExecuted(ScriptStatement statement)
{
if (StatementExecuted != null)
{
MySqlScriptEventArgs args = new MySqlScriptEventArgs();
args.Statement = statement;
StatementExecuted(this, args);
}
}
private void OnScriptCompleted()
{
if (ScriptCompleted != null)
ScriptCompleted(this, EventArgs.Empty);
}
private bool OnScriptError(Exception ex)
{
if (Error != null)
{
MySqlScriptErrorEventArgs args = new MySqlScriptErrorEventArgs(ex);
Error(this, args);
return args.Ignore;
}
return false;
}
private List<int> BreakScriptIntoLines()
{
List<int> lineNumbers = new List<int>();
StringReader sr = new StringReader(query);
string line = sr.ReadLine();
int pos = 0;
while (line != null)
{
lineNumbers.Add(pos);
pos += line.Length;
line = sr.ReadLine();
}
return lineNumbers;
}
private static int FindLineNumber(int position, List<int> lineNumbers)
{
int i = 0;
while (i < lineNumbers.Count && position < lineNumbers[i])
i++;
return i;
}
private List<ScriptStatement> BreakIntoStatements(bool ansiQuotes, bool noBackslashEscapes)
{
string currentDelimiter = Delimiter;
int startPos = 0;
List<ScriptStatement> statements = new List<ScriptStatement>();
List<int> lineNumbers = BreakScriptIntoLines();
MySqlTokenizer tokenizer = new MySqlTokenizer(query);
tokenizer.AnsiQuotes = ansiQuotes;
tokenizer.BackslashEscapes = !noBackslashEscapes;
string token = tokenizer.NextToken();
while (token != null)
{
if (!tokenizer.Quoted)
{
if (token.ToLower(CultureInfo.InvariantCulture) == "delimiter")
{
tokenizer.NextToken();
AdjustDelimiterEnd(tokenizer);
currentDelimiter = query.Substring(tokenizer.StartIndex,
tokenizer.StopIndex - tokenizer.StartIndex + 1).Trim();
startPos = tokenizer.StopIndex;
}
else
{
// this handles the case where our tokenizer reads part of the
// delimiter
if (currentDelimiter.StartsWith(token))
{
if ((tokenizer.StartIndex + currentDelimiter.Length) <= query.Length)
{
if (query.Substring(tokenizer.StartIndex, currentDelimiter.Length) == currentDelimiter)
{
token = currentDelimiter;
tokenizer.Position = tokenizer.StartIndex + currentDelimiter.Length;
tokenizer.StopIndex = tokenizer.Position;
}
}
}
int delimiterPos = token.IndexOf(currentDelimiter, StringComparison.InvariantCultureIgnoreCase);
if (delimiterPos != -1)
{
int endPos = tokenizer.StopIndex - token.Length + delimiterPos;
if (tokenizer.StopIndex == query.Length - 1)
endPos++;
string currentQuery = query.Substring(startPos, endPos - startPos);
ScriptStatement statement = new ScriptStatement();
statement.text = currentQuery.Trim();
statement.line = FindLineNumber(startPos, lineNumbers);
statement.position = startPos - lineNumbers[statement.line];
statements.Add(statement);
startPos = endPos + currentDelimiter.Length;
}
}
}
token = tokenizer.NextToken();
}
// now clean up the last statement
if (startPos < query.Length-1)
{
string sqlLeftOver = query.Substring(startPos).Trim();
if (!String.IsNullOrEmpty(sqlLeftOver))
{
ScriptStatement statement = new ScriptStatement();
statement.text = sqlLeftOver;
statement.line = FindLineNumber(startPos, lineNumbers);
statement.position = startPos - lineNumbers[statement.line];
statements.Add(statement);
}
}
return statements;
}
private void AdjustDelimiterEnd(MySqlTokenizer tokenizer)
{
int pos = tokenizer.StopIndex;
char c = query[pos];
while (!Char.IsWhiteSpace(c) && pos < (query.Length-1))
{
c = query[++pos];
}
tokenizer.StopIndex = pos;
tokenizer.Position = pos;
}
}
/// <summary>
///
/// </summary>
public delegate void MySqlStatementExecutedEventHandler(object sender, MySqlScriptEventArgs args);
/// <summary>
///
/// </summary>
public delegate void MySqlScriptErrorEventHandler(object sender, MySqlScriptErrorEventArgs args);
/// <summary>
///
/// </summary>
public class MySqlScriptEventArgs : EventArgs
{
private ScriptStatement statement;
internal ScriptStatement Statement
{
set { this.statement = value; }
}
/// <summary>
/// Gets the statement text.
/// </summary>
/// <value>The statement text.</value>
public string StatementText
{
get { return statement.text; }
}
/// <summary>
/// Gets the line.
/// </summary>
/// <value>The line.</value>
public int Line
{
get { return statement.line; }
}
/// <summary>
/// Gets the position.
/// </summary>
/// <value>The position.</value>
public int Position
{
get { return statement.position; }
}
}
/// <summary>
///
/// </summary>
public class MySqlScriptErrorEventArgs : MySqlScriptEventArgs
{
private Exception exception;
private bool ignore;
/// <summary>
/// Initializes a new instance of the <see cref="MySqlScriptErrorEventArgs"/> class.
/// </summary>
/// <param name="exception">The exception.</param>
public MySqlScriptErrorEventArgs(Exception exception) : base()
{
this.exception = exception;
}
/// <summary>
/// Gets the exception.
/// </summary>
/// <value>The exception.</value>
public Exception Exception
{
get { return exception; }
}
/// <summary>
/// Gets or sets a value indicating whether this <see cref="MySqlScriptErrorEventArgs"/> is ignore.
/// </summary>
/// <value><c>true</c> if ignore; otherwise, <c>false</c>.</value>
public bool Ignore
{
get { return ignore; }
set { ignore = value; }
}
}
struct ScriptStatement
{
public string text;
public int line;
public int position;
}
}

@ -0,0 +1,241 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Diagnostics;
using System.Text;
using MySql.Data.Common;
using MySql.Data.MySqlClient.Properties;
namespace MySql.Data.MySqlClient
{
/// <summary>
/// Summary description for MySqlStream.
/// </summary>
internal class MySqlStream
{
private byte sequenceByte;
private MemoryStream bufferStream;
private int maxBlockSize;
private ulong maxPacketSize;
private byte[] packetHeader = new byte[4];
MySqlPacket packet;
TimedStream timedStream;
Stream inStream;
Stream outStream;
public MySqlStream(Encoding encoding)
{
// we have no idea what the real value is so we start off with the max value
// The real value will be set in NativeDriver.Configure()
maxPacketSize = ulong.MaxValue;
// we default maxBlockSize to MaxValue since we will get the 'real' value in
// the authentication handshake and we know that value will not exceed
// true maxBlockSize prior to that.
maxBlockSize = Int32.MaxValue;
packet = new MySqlPacket(encoding);
bufferStream = new MemoryStream();
}
public MySqlStream(Stream baseStream, Encoding encoding, bool compress)
: this(encoding)
{
timedStream = new TimedStream(baseStream);
Stream stream;
if (compress)
stream = new CompressedStream(timedStream);
else
stream = timedStream;
inStream = new BufferedStream(stream);
outStream = stream;
}
public void Close()
{
outStream.Close();
inStream.Close();
timedStream.Close();
}
#region Properties
public Encoding Encoding
{
get { return packet.Encoding; }
set { packet.Encoding = value; }
}
public void ResetTimeout(int timeout)
{
timedStream.ResetTimeout(timeout);
}
public byte SequenceByte
{
get { return sequenceByte; }
set { sequenceByte = value; }
}
public int MaxBlockSize
{
get { return maxBlockSize; }
set { maxBlockSize = value; }
}
public ulong MaxPacketSize
{
get { return maxPacketSize; }
set { maxPacketSize = value; }
}
#endregion
#region Packet methods
/// <summary>
/// ReadPacket is called by NativeDriver to start reading the next
/// packet on the stream.
/// </summary>
public MySqlPacket ReadPacket()
{
//Debug.Assert(packet.Position == packet.Length);
// make sure we have read all the data from the previous packet
//Debug.Assert(HasMoreData == false, "HasMoreData is true in OpenPacket");
LoadPacket();
// now we check if this packet is a server error
if (packet.Buffer[0] == 0xff)
{
packet.ReadByte(); // read off the 0xff
int code = packet.ReadInteger(2);
string msg = packet.ReadString();
if (msg.StartsWith("#"))
{
msg.Substring(1, 5); /* state code */
msg = msg.Substring(6);
}
throw new MySqlException(msg, code);
}
return packet;
}
/// <summary>
/// Reads the specified number of bytes from the stream and stores them at given
/// offset in the buffer.
/// Throws EndOfStreamException if not all bytes can be read.
/// </summary>
/// <param name="stream">Stream to read from</param>
/// <param name="buffer"> Array to store bytes read from the stream </param>
/// <param name="offset">The offset in buffer at which to begin storing the data read from the current stream. </param>
/// <param name="count">Number of bytes to read</param>
internal static void ReadFully(Stream stream, byte[] buffer, int offset, int count)
{
int numRead = 0;
int numToRead = count;
while (numToRead > 0)
{
int read = stream.Read(buffer, offset + numRead, numToRead);
if (read == 0)
{
throw new EndOfStreamException();
}
numRead += read;
numToRead -= read;
}
}
/// <summary>
/// LoadPacket loads up and decodes the header of the incoming packet.
/// </summary>
public void LoadPacket()
{
try
{
packet.Length = 0;
int offset = 0;
while (true)
{
ReadFully(inStream, packetHeader, 0, 4);
sequenceByte = (byte)(packetHeader[3]+1);
int length = (int)(packetHeader[0] + (packetHeader[1] << 8) +
(packetHeader[2] << 16));
// make roo for the next block
packet.Length += length;
ReadFully(inStream, packet.Buffer, offset, length);
offset += length;
// if this block was < maxBlock then it's last one in a multipacket series
if (length < maxBlockSize) break;
}
packet.Position = 0;
}
catch (IOException ioex)
{
throw new MySqlException(Resources.ReadFromStreamFailed, true, ioex);
}
}
public void SendPacket(MySqlPacket packet)
{
byte[] buffer = packet.Buffer;
int length = packet.Position-4;
if ((ulong)length > maxPacketSize)
throw new MySqlException(Resources.QueryTooLarge, (int)MySqlErrorCode.PacketTooLarge);
int offset = 0;
while (length > 0)
{
int lenToSend = length > maxBlockSize ? maxBlockSize : length;
buffer[offset] = (byte)(lenToSend & 0xff);
buffer[offset+1] = (byte)((lenToSend >> 8) & 0xff);
buffer[offset+2] = (byte)((lenToSend >> 16) & 0xff);
buffer[offset+3] = sequenceByte++;
outStream.Write(buffer, offset, lenToSend + 4);
outStream.Flush();
length -= lenToSend;
offset += lenToSend;
}
}
public void SendEntirePacketDirectly(byte[] buffer, int count)
{
buffer[0] = (byte)(count & 0xff);
buffer[1] = (byte)((count >> 8) & 0xff);
buffer[2] = (byte)((count >> 16) & 0xff);
buffer[3] = sequenceByte++;
outStream.Write(buffer, 0, count + 4);
outStream.Flush();
}
#endregion
}
}

@ -0,0 +1,109 @@
// Copyright (c) 2009-2010 Sun Microsystems, Inc.
//
// 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.Collections.Generic;
using System.Text;
using System.Diagnostics;
namespace MySql.Data.MySqlClient
{
public class MySqlTrace
{
#if !CF
private static TraceSource source = new TraceSource("mysql");
public static TraceListenerCollection Listeners
{
get { return source.Listeners; }
}
public static SourceSwitch Switch
{
get { return source.Switch; }
set { source.Switch = value; }
}
internal static TraceSource Source
{
get { return source; }
}
#endif
internal static void LogInformation(int id, string msg)
{
#if !CF
Source.TraceEvent(TraceEventType.Information, id, msg, MySqlTraceEventType.NonQuery, -1);
Trace.TraceInformation(msg);
#endif
}
internal static void LogWarning(int id, string msg)
{
#if !CF
Source.TraceEvent(TraceEventType.Warning, id, msg, MySqlTraceEventType.NonQuery, -1);
Trace.TraceWarning(msg);
#endif
}
internal static void LogError(int id, string msg)
{
#if !CF
Source.TraceEvent(TraceEventType.Error, id, msg, MySqlTraceEventType.NonQuery, -1);
Trace.TraceError(msg);
#endif
}
#if !CF
internal static void TraceEvent(TraceEventType eventType,
MySqlTraceEventType mysqlEventType, string msgFormat, params object[] args)
{
Source.TraceEvent(eventType, (int)mysqlEventType, msgFormat, args);
}
#endif
}
public enum MySqlTraceEventType : int
{
ConnectionOpened = 1,
ConnectionClosed,
QueryOpened,
ResultOpened,
ResultClosed,
QueryClosed,
StatementPrepared,
StatementExecuted,
StatementClosed,
NonQuery,
UsageAdvisorWarning,
Warning,
Error,
QueryNormalized
}
public enum UsageAdvisorWarningFlags
{
NoIndex = 1,
BadIndex,
SkippedRows,
SkippedColumns,
FieldConversion
}
}

@ -0,0 +1,410 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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;
namespace MySql.Data.MySqlClient
{
/// <summary>
/// Summary description for ClientParam.
/// </summary>
[Flags]
internal enum ClientFlags : ulong
{
LONG_PASSWORD = 1, // new more secure passwords
FOUND_ROWS = 2, // found instead of affected rows
LONG_FLAG = 4, // Get all column flags
CONNECT_WITH_DB = 8, // One can specify db on connect
NO_SCHEMA = 16, // Don't allow db.table.column
COMPRESS = 32, // Client can use compression protocol
ODBC = 64, // ODBC client
LOCAL_FILES = 128, // Can use LOAD DATA LOCAL
IGNORE_SPACE = 256, // Ignore spaces before '('
PROTOCOL_41 = 512, // Support new 4.1 protocol
INTERACTIVE = 1024, // This is an interactive client
SSL = 2048, // Switch to SSL after handshake
IGNORE_SIGPIPE = 4096, // IGNORE sigpipes
TRANSACTIONS = 8192, // Client knows about transactions
RESERVED = 16384, // old 4.1 protocol flag
SECURE_CONNECTION = 32768, // new 4.1 authentication
MULTI_STATEMENTS = 65536, // Allow multi-stmt support
MULTI_RESULTS = 131072, // Allow multiple resultsets
PS_MULTI_RESULTS = 1UL << 18 // allow multi results using PS protocol
}
[Flags]
internal enum ServerStatusFlags
{
InTransaction = 1, // Transaction has started
AutoCommitMode = 2, // Server in auto_commit mode
MoreResults = 4, // More results on server
AnotherQuery = 8, // Multi query - next query exists
BadIndex = 16,
NoIndex = 32,
CursorExists = 64,
LastRowSent = 128,
OutputParameters = 4096
}
/// <summary>
/// DB Operations Code
/// </summary>
internal enum DBCmd : byte
{
SLEEP = 0,
QUIT = 1,
INIT_DB = 2,
QUERY = 3,
FIELD_LIST = 4,
CREATE_DB = 5,
DROP_DB = 6,
RELOAD = 7,
SHUTDOWN = 8,
STATISTICS = 9,
PROCESS_INFO = 10,
CONNECT = 11,
PROCESS_KILL = 12,
DEBUG = 13,
PING = 14,
TIME = 15,
DELAYED_INSERT = 16,
CHANGE_USER = 17,
BINLOG_DUMP = 18,
TABLE_DUMP = 19,
CONNECT_OUT = 20,
REGISTER_SLAVE = 21,
PREPARE = 22,
EXECUTE = 23,
LONG_DATA = 24,
CLOSE_STMT = 25,
RESET_STMT = 26,
SET_OPTION = 27,
FETCH = 28
}
/// <summary>
/// Specifies MySQL specific data type of a field, property, for use in a <see cref="MySqlParameter"/>.
/// </summary>
public enum MySqlDbType
{
/// <summary>
/// <see cref="Decimal"/>
/// <para>A fixed precision and scale numeric value between -1038
/// -1 and 10 38 -1.</para>
/// </summary>
Decimal = 0,
/// <summary>
/// <see cref="Byte"/><para>The signed range is -128 to 127. The unsigned
/// range is 0 to 255.</para>
/// </summary>
Byte = 1,
/// <summary>
/// <see cref="Int16"/><para>A 16-bit signed integer. The signed range is
/// -32768 to 32767. The unsigned range is 0 to 65535</para>
/// </summary>
Int16 = 2,
/// <summary>
/// Specifies a 24 (3 byte) signed or unsigned value.
/// </summary>
Int24 = 9,
/// <summary>
/// <see cref="Int32"/><para>A 32-bit signed integer</para>
/// </summary>
Int32 = 3,
/// <summary>
/// <see cref="Int64"/><para>A 64-bit signed integer.</para>
/// </summary>
Int64 = 8,
/// <summary>
/// <see cref="Single"/><para>A small (single-precision) floating-point
/// number. Allowable values are -3.402823466E+38 to -1.175494351E-38,
/// 0, and 1.175494351E-38 to 3.402823466E+38.</para>
/// </summary>
Float = 4,
/// <summary>
/// <see cref="Double"/><para>A normal-size (double-precision)
/// floating-point number. Allowable values are -1.7976931348623157E+308
/// to -2.2250738585072014E-308, 0, and 2.2250738585072014E-308 to
/// 1.7976931348623157E+308.</para>
/// </summary>
Double = 5,
/// <summary>
/// A timestamp. The range is '1970-01-01 00:00:00' to sometime in the
/// year 2037
/// </summary>
Timestamp = 7,
///<summary>
///Date The supported range is '1000-01-01' to '9999-12-31'.
///</summary>
Date = 10,
/// <summary>
/// Time <para>The range is '-838:59:59' to '838:59:59'.</para>
/// </summary>
Time = 11,
///<summary>
///DateTime The supported range is '1000-01-01 00:00:00' to
///'9999-12-31 23:59:59'.
///</summary>
DateTime = 12,
///<summary>
///Datetime The supported range is '1000-01-01 00:00:00' to
///'9999-12-31 23:59:59'.
///</summary>
[Obsolete("The Datetime enum value is obsolete. Please use DateTime.")]
Datetime = 12,
/// <summary>
/// A year in 2- or 4-digit format (default is 4-digit). The
/// allowable values are 1901 to 2155, 0000 in the 4-digit year
/// format, and 1970-2069 if you use the 2-digit format (70-69).
/// </summary>
Year = 13,
/// <summary>
/// <b>Obsolete</b> Use Datetime or Date type
/// </summary>
Newdate = 14,
/// <summary>
/// A variable-length string containing 0 to 65535 characters
/// </summary>
VarString = 15,
/// <summary>
/// Bit-field data type
/// </summary>
Bit = 16,
/// <summary>
/// New Decimal
/// </summary>
NewDecimal = 246,
/// <summary>
/// An enumeration. A string object that can have only one value,
/// chosen from the list of values 'value1', 'value2', ..., NULL
/// or the special "" error value. An ENUM can have a maximum of
/// 65535 distinct values
/// </summary>
Enum = 247,
/// <summary>
/// A set. A string object that can have zero or more values, each
/// of which must be chosen from the list of values 'value1', 'value2',
/// ... A SET can have a maximum of 64 members.
/// </summary>
Set = 248,
/// <summary>
/// A binary column with a maximum length of 255 (2^8 - 1)
/// characters
/// </summary>
TinyBlob = 249,
/// <summary>
/// A binary column with a maximum length of 16777215 (2^24 - 1) bytes.
/// </summary>
MediumBlob = 250,
/// <summary>
/// A binary column with a maximum length of 4294967295 or
/// 4G (2^32 - 1) bytes.
/// </summary>
LongBlob = 251,
/// <summary>
/// A binary column with a maximum length of 65535 (2^16 - 1) bytes.
/// </summary>
Blob = 252,
/// <summary>
/// A variable-length string containing 0 to 255 bytes.
/// </summary>
VarChar = 253,
/// <summary>
/// A fixed-length string.
/// </summary>
String = 254,
/// <summary>
/// Geometric (GIS) data type.
/// </summary>
Geometry = 255,
/// <summary>
/// Unsigned 8-bit value.
/// </summary>
UByte = 501,
/// <summary>
/// Unsigned 16-bit value.
/// </summary>
UInt16 = 502,
/// <summary>
/// Unsigned 24-bit value.
/// </summary>
UInt24 = 509,
/// <summary>
/// Unsigned 32-bit value.
/// </summary>
UInt32 = 503,
/// <summary>
/// Unsigned 64-bit value.
/// </summary>
UInt64 = 508,
/// <summary>
/// Fixed length binary string.
/// </summary>
Binary = 600,
/// <summary>
/// Variable length binary string.
/// </summary>
VarBinary = 601,
/// <summary>
/// A text column with a maximum length of 255 (2^8 - 1) characters.
/// </summary>
TinyText = 749,
/// <summary>
/// A text column with a maximum length of 16777215 (2^24 - 1) characters.
/// </summary>
MediumText = 750,
/// <summary>
/// A text column with a maximum length of 4294967295 or
/// 4G (2^32 - 1) characters.
/// </summary>
LongText = 751,
/// <summary>
/// A text column with a maximum length of 65535 (2^16 - 1) characters.
/// </summary>
Text = 752,
/// <summary>
/// A guid column
/// </summary>
Guid = 800
} ;
internal enum Field_Type : byte
{
DECIMAL = 0,
BYTE = 1,
SHORT = 2,
LONG = 3,
FLOAT = 4,
DOUBLE = 5,
NULL = 6,
TIMESTAMP = 7,
LONGLONG = 8,
INT24 = 9,
DATE = 10,
TIME = 11,
DATETIME = 12,
YEAR = 13,
NEWDATE = 14,
ENUM = 247,
SET = 248,
TINY_BLOB = 249,
MEDIUM_BLOB = 250,
LONG_BLOB = 251,
BLOB = 252,
VAR_STRING = 253,
STRING = 254,
}
/// <summary>
/// Allows the user to specify the type of connection that should
/// be used.
/// </summary>
public enum MySqlConnectionProtocol
{
/// <summary>
/// TCP/IP style connection. Works everywhere.
/// </summary>
Sockets = 1,
Socket = 1,
Tcp = 1,
/// <summary>
/// Named pipe connection. Works only on Windows systems.
/// </summary>
Pipe = 2,
NamedPipe = 2,
/// <summary>
/// Unix domain socket connection. Works only with Unix systems.
/// </summary>
UnixSocket = 3,
Unix = 3,
/// <summary>
/// Shared memory connection. Currently works only with Windows systems.
/// </summary>
SharedMemory = 4,
Memory = 4
}
/// <summary>
/// SSL options for connection.
/// </summary>
public enum MySqlSslMode
{
/// <summary>
/// Do not use SSL.
/// </summary>
None,
/// <summary>
/// Use SSL, if server supports it.
/// </summary>
Preferred,
Prefered = Preferred,
/// <summary>
/// Always use SSL. Deny connection if server does not support SSL.
/// Do not perform server certificate validation.
/// </summary>
Required,
/// <summary>
/// Always use SSL. Validate server SSL certificate, but different host name mismatch.
/// </summary>
VerifyCA,
/// <summary>
/// Always use SSL and perform full certificate validation.
/// </summary>
VerifyFull
}
/// <summary>
/// Specifies the connection types supported
/// </summary>
public enum MySqlDriverType
{
/// <summary>
/// Use TCP/IP sockets.
/// </summary>
Native,
/// <summary>
/// Use client library.
/// </summary>
Client,
/// <summary>
/// Use MySQL embedded server.
/// </summary>
Embedded
}
public enum MySqlCertificateStoreLocation
{
/// <summary>
/// Do not use certificate store
/// </summary>
None,
/// <summary>
/// Use certificate store for the current user
/// </summary>
CurrentUser,
/// <summary>
/// User certificate store for the machine
/// </summary>
LocalMachine
}
}

@ -0,0 +1,880 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Collections;
using System.Diagnostics;
using System.IO;
using MySql.Data.Common;
using MySql.Data.Types;
using System.Security.Cryptography.X509Certificates;
using MySql.Data.MySqlClient.Properties;
using System.Text;
#if !CF
using System.Net.Security;
using System.Security.Authentication;
using System.Globalization;
using System.Text;
#endif
namespace MySql.Data.MySqlClient
{
/// <summary>
/// Summary description for Driver.
/// </summary>
internal class NativeDriver : IDriver
{
private DBVersion version;
private int threadId;
protected String encryptionSeed;
protected ServerStatusFlags serverStatus;
protected MySqlStream stream;
protected Stream baseStream;
private BitArray nullMap;
private MySqlPacket packet;
private ClientFlags connectionFlags;
private Driver owner;
private int warnings;
public NativeDriver(Driver owner)
{
this.owner = owner;
threadId = -1;
}
public ClientFlags Flags
{
get { return connectionFlags; }
}
public int ThreadId
{
get { return threadId; }
}
public DBVersion Version
{
get { return version; }
}
public ServerStatusFlags ServerStatus
{
get { return serverStatus; }
}
public int WarningCount
{
get { return warnings; }
}
public MySqlPacket Packet
{
get { return packet; }
}
private MySqlConnectionStringBuilder Settings
{
get { return owner.Settings; }
}
private Encoding Encoding
{
get { return owner.Encoding; }
}
private void HandleException(MySqlException ex)
{
if (ex.IsFatal)
owner.Close();
}
private void ReadOk(bool read)
{
try
{
if (read)
packet = stream.ReadPacket();
byte marker = (byte) packet.ReadByte();
if (marker != 0)
throw new MySqlException("Out of sync with server", true, null);
packet.ReadFieldLength(); /* affected rows */
packet.ReadFieldLength(); /* last insert id */
if (packet.HasMoreData)
{
serverStatus = (ServerStatusFlags) packet.ReadInteger(2);
packet.ReadInteger(2); /* warning count */
if (packet.HasMoreData)
{
packet.ReadLenString(); /* message */
}
}
}
catch (MySqlException ex)
{
HandleException(ex);
throw;
}
}
/// <summary>
/// Sets the current database for the this connection
/// </summary>
/// <param name="dbName"></param>
public void SetDatabase(string dbName)
{
byte[] dbNameBytes = Encoding.GetBytes(dbName);
packet.Clear();
packet.WriteByte((byte)DBCmd.INIT_DB);
packet.Write(dbNameBytes);
ExecutePacket(packet);
ReadOk(true);
}
public void Configure()
{
stream.MaxPacketSize = (ulong)owner.MaxPacketSize;
stream.Encoding = Encoding;
}
public void Open()
{
// connect to one of our specified hosts
try
{
#if !CF
if (Settings.ConnectionProtocol == MySqlConnectionProtocol.SharedMemory)
{
SharedMemoryStream str = new SharedMemoryStream(Settings.SharedMemoryName);
str.Open(Settings.ConnectionTimeout);
baseStream = str;
}
else
{
#endif
string pipeName = Settings.PipeName;
if (Settings.ConnectionProtocol != MySqlConnectionProtocol.NamedPipe)
pipeName = null;
StreamCreator sc = new StreamCreator(Settings.Server, Settings.Port, pipeName,
Settings.Keepalive);
baseStream = sc.GetStream(Settings.ConnectionTimeout);
#if !CF
}
#endif
}
catch (Exception ex)
{
throw new MySqlException(Resources.UnableToConnectToHost,
(int) MySqlErrorCode.UnableToConnectToHost, ex);
}
if (baseStream == null)
throw new MySqlException(Resources.UnableToConnectToHost,
(int)MySqlErrorCode.UnableToConnectToHost);
int maxSinglePacket = 255*255*255;
stream = new MySqlStream(baseStream, Encoding, false);
stream.ResetTimeout((int)Settings.ConnectionTimeout*1000);
// read off the welcome packet and parse out it's values
packet = stream.ReadPacket();
int protocol = packet.ReadByte();
string versionString = packet.ReadString();
version = DBVersion.Parse(versionString);
if (!version.isAtLeast(4, 1, 1))
throw new NotSupportedException(Resources.ServerTooOld);
threadId = packet.ReadInteger(4);
encryptionSeed = packet.ReadString();
maxSinglePacket = (256*256*256) - 1;
// read in Server capabilities if they are provided
ClientFlags serverCaps = 0;
if (packet.HasMoreData)
serverCaps = (ClientFlags) packet.ReadInteger(2);
/* New protocol with 16 bytes to describe server characteristics */
owner.ConnectionCharSetIndex = (int)packet.ReadByte();
serverStatus = (ServerStatusFlags) packet.ReadInteger(2);
packet.Position += 13;
string seedPart2 = packet.ReadString();
encryptionSeed += seedPart2;
// based on our settings, set our connection flags
SetConnectionFlags(serverCaps);
packet.Clear();
packet.WriteInteger((int) connectionFlags, 4);
#if !CF
if ((serverCaps & ClientFlags.SSL) ==0)
{
if ((Settings.SslMode != MySqlSslMode.None)
&& (Settings.SslMode != MySqlSslMode.Preferred))
{
// Client requires SSL connections.
string message = String.Format(Resources.NoServerSSLSupport,
Settings.Server);
throw new MySqlException(message);
}
}
else if (Settings.SslMode != MySqlSslMode.None)
{
stream.SendPacket(packet);
StartSSL();
packet.Clear();
packet.WriteInteger((int) connectionFlags, 4);
}
#endif
packet.WriteInteger(maxSinglePacket, 4);
packet.WriteByte(8);
packet.Write(new byte[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)
stream = new MySqlStream(baseStream, Encoding, true);
// give our stream the server version we are connected to.
// We may have some fields that are read differently based
// on the version of the server we are connected to.
packet.Version = version;
stream.MaxBlockSize = maxSinglePacket;
}
#if !CF
#region SSL
/// <summary>
/// Retrieve client SSL certificates. Dependent on connection string
/// settings we use either file or store based certificates.
/// </summary>
private X509CertificateCollection GetClientCertificates()
{
X509CertificateCollection certs = new X509CertificateCollection();
// Check for file-based certificate
if (Settings.CertificateFile != null)
{
X509Certificate2 clientCert = new X509Certificate2(Settings.CertificateFile,
Settings.CertificatePassword);
certs.Add(clientCert);
return certs;
}
if (Settings.CertificateStoreLocation == MySqlCertificateStoreLocation.None)
return certs;
StoreLocation location =
(Settings.CertificateStoreLocation == MySqlCertificateStoreLocation.CurrentUser) ?
StoreLocation.CurrentUser : StoreLocation.LocalMachine;
// Check for store-based certificate
X509Store store = new X509Store(StoreName.My, location);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
if (Settings.CertificateThumbprint == null)
{
// Return all certificates from the store.
certs.AddRange(store.Certificates);
return certs;
}
// Find certificate with given thumbprint
certs.AddRange(store.Certificates.Find(X509FindType.FindByThumbprint,
Settings.CertificateThumbprint, true));
if (certs.Count == 0)
{
throw new MySqlException("Certificate with Thumbprint " +
Settings.CertificateThumbprint + " not found");
}
return certs;
}
private void StartSSL()
{
RemoteCertificateValidationCallback sslValidateCallback =
new RemoteCertificateValidationCallback(ServerCheckValidation);
SslStream ss = new SslStream(baseStream, true, sslValidateCallback, null);
X509CertificateCollection certs = GetClientCertificates();
ss.AuthenticateAsClient(Settings.Server, certs, SslProtocols.Default, false);
baseStream = ss;
stream = new MySqlStream(ss, Encoding, false);
stream.SequenceByte = 2;
}
private bool ServerCheckValidation(object sender, X509Certificate certificate,
X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
if (Settings.SslMode == MySqlSslMode.Preferred ||
Settings.SslMode == MySqlSslMode.Required)
{
//Tolerate all certificate errors.
return true;
}
if (Settings.SslMode == MySqlSslMode.VerifyCA &&
sslPolicyErrors == SslPolicyErrors.RemoteCertificateNameMismatch)
{
// Tolerate name mismatch in certificate, if full validation is not requested.
return true;
}
return false;
}
#endregion
#endif
#region Authentication
/// <summary>
/// Return the appropriate set of connection flags for our
/// server capabilities and our user requested options.
/// </summary>
private void SetConnectionFlags(ClientFlags serverCaps)
{
// allow load data local infile
ClientFlags flags = ClientFlags.LOCAL_FILES;
if (!Settings.UseAffectedRows)
flags |= ClientFlags.FOUND_ROWS;
flags |= ClientFlags.PROTOCOL_41;
// Need this to get server status values
flags |= ClientFlags.TRANSACTIONS;
// user allows/disallows batch statements
if (Settings.AllowBatch)
flags |= ClientFlags.MULTI_STATEMENTS;
// We always allow multiple result sets
flags |= ClientFlags.MULTI_RESULTS;
// 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 && Settings.UseCompression)
flags |= ClientFlags.COMPRESS;
flags |= ClientFlags.LONG_PASSWORD; // for long passwords
// did the user request an interactive session?
if (Settings.InteractiveSession)
flags |= ClientFlags.INTERACTIVE;
// 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 &&
Settings.Database != null && Settings.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;
// if the server is capable of SSL and the user is requesting SSL
if ((serverCaps & ClientFlags.SSL) != 0 && Settings.SslMode != MySqlSslMode.None)
flags |= ClientFlags.SSL;
// if the server supports output parameters, then we do too
//if ((serverCaps & ClientFlags.PS_MULTI_RESULTS) != 0)
flags |= ClientFlags.PS_MULTI_RESULTS;
connectionFlags = flags;
}
/// <summary>
/// Perform an authentication against a 4.1.1 server
/// </summary>
private void AuthenticateNew()
{
if ((connectionFlags & ClientFlags.SECURE_CONNECTION) == 0)
AuthenticateOld();
packet.Write(Crypt.Get411Password(Settings.Password, encryptionSeed));
if ((connectionFlags & ClientFlags.CONNECT_WITH_DB) != 0 && Settings.Database != null)
packet.WriteString(Settings.Database);
stream.SendPacket(packet);
// this result means the server wants us to send the password using
// old encryption
packet = stream.ReadPacket();
if (packet.IsLastPacket)
{
packet.Clear();
packet.WriteString(Crypt.EncryptPassword(
Settings.Password, encryptionSeed.Substring(0, 8), true));
stream.SendPacket(packet);
ReadOk(true);
}
else
ReadOk(false);
}
private void AuthenticateOld()
{
packet.WriteString(Crypt.EncryptPassword(
Settings.Password, encryptionSeed, true));
if ((connectionFlags & ClientFlags.CONNECT_WITH_DB) != 0 && Settings.Database != null)
packet.WriteString(Settings.Database);
stream.SendPacket(packet);
ReadOk(true);
}
public void Authenticate()
{
// write the user id to the auth packet
packet.WriteString(Settings.UserID);
AuthenticateNew();
}
#endregion
public void Reset()
{
warnings = 0;
stream.SequenceByte = 0;
packet.Clear();
packet.WriteByte((byte)DBCmd.CHANGE_USER);
Authenticate();
}
/// <summary>
/// Query is the method that is called to send all queries to the server
/// </summary>
public void SendQuery(MySqlPacket queryPacket)
{
warnings = 0;
queryPacket.Buffer[4] = (byte)DBCmd.QUERY;
ExecutePacket(queryPacket);
// 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 stream.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 void Close(bool isOpen)
{
try
{
if (isOpen)
{
try
{
packet.Clear();
packet.WriteByte((byte)DBCmd.QUIT);
ExecutePacket(packet);
}
catch (Exception)
{
// Eat exception here. We should try to closing
// the stream anyway.
}
}
if (stream != null)
stream.Close();
stream = null;
}
catch (Exception)
{
// we are just going to eat any exceptions
// generated here
}
}
public bool Ping()
{
try
{
packet.Clear();
packet.WriteByte((byte)DBCmd.PING);
ExecutePacket(packet);
ReadOk(true);
return true;
}
catch (Exception)
{
return false;
}
}
public int GetResult(ref int affectedRow, ref int insertedId)
{
try
{
packet = stream.ReadPacket();
}
catch (TimeoutException)
{
// Do not reset serverStatus, allow to reenter, e.g when
// ResultSet is closed.
throw;
}
catch (Exception)
{
serverStatus = 0;
throw;
}
int fieldCount = (int)packet.ReadFieldLength();
if (-1 == fieldCount)
{
string filename = packet.ReadString();
SendFileToServer(filename);
return GetResult(ref affectedRow, ref insertedId);
}
else if (fieldCount == 0)
{
// the code to read last packet will set these server status vars
// again if necessary.
serverStatus &= ~(ServerStatusFlags.AnotherQuery |
ServerStatusFlags.MoreResults);
affectedRow = (int)packet.ReadFieldLength();
insertedId = (int)packet.ReadFieldLength();
serverStatus = (ServerStatusFlags)packet.ReadInteger(2);
warnings += packet.ReadInteger(2);
if (packet.HasMoreData)
{
packet.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[8196];
long len = 0;
try
{
using (FileStream fs = new FileStream(filename, FileMode.Open,
FileAccess.Read))
{
len = fs.Length;
while (len > 0)
{
int count = fs.Read(buffer, 4, (int)(len > 8192 ? 8192 : len));
stream.SendEntirePacketDirectly(buffer, count);
len -= count;
}
stream.SendEntirePacketDirectly(buffer, 0);
}
}
catch (Exception ex)
{
throw new MySqlException("Error during LOAD DATA LOCAL INFILE", ex);
}
}
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];
packet.ReadByte();
packet.Read(nullMapBytes, 0, nullMapBytes.Length);
nullMap = new BitArray(nullMapBytes);
}
public IMySqlValue ReadColumnValue(int index, MySqlField field, IMySqlValue valObject)
{
long length = -1;
bool isNull;
if (nullMap != null)
isNull = nullMap[index + 2];
else
{
length = packet.ReadFieldLength();
isNull = length == -1;
}
packet.Encoding = field.Encoding;
packet.Version = version;
return valObject.ReadValue(packet, length, isNull);
}
public void SkipColumnValue(IMySqlValue valObject)
{
int length = -1;
if (nullMap == null)
{
length = packet.ReadFieldLength();
if (length == -1) return;
}
if (length > -1)
packet.Position += length;
else
valObject.SkipValue(packet);
}
public void GetColumnsData(MySqlField[] columns)
{
for (int i = 0; i < columns.Length; i++)
GetColumnData(columns[i]);
ReadEOF();
}
private void GetColumnData(MySqlField field)
{
stream.Encoding = Encoding;
packet = stream.ReadPacket();
field.Encoding = Encoding;
field.CatalogName = packet.ReadLenString();
field.DatabaseName = packet.ReadLenString();
field.TableName = packet.ReadLenString();
field.RealTableName = packet.ReadLenString();
field.ColumnName = packet.ReadLenString();
field.OriginalColumnName = packet.ReadLenString();
packet.ReadByte();
field.CharacterSetIndex = packet.ReadInteger(2);
field.ColumnLength = packet.ReadInteger(4);
MySqlDbType type = (MySqlDbType)packet.ReadByte();
ColumnFlags colFlags;
if ((connectionFlags & ClientFlags.LONG_FLAG) != 0)
colFlags = (ColumnFlags)packet.ReadInteger(2);
else
colFlags = (ColumnFlags)packet.ReadByte();
field.Scale = (byte)packet.ReadByte();
if (packet.HasMoreData)
{
packet.ReadInteger(2); // reserved
}
if (type == MySqlDbType.Decimal || type == MySqlDbType.NewDecimal)
{
field.Precision = (byte)(field.ColumnLength - (int)field.Scale);
if ((colFlags & ColumnFlags.UNSIGNED) != 0)
field.Precision++;
}
field.SetTypeAndFlags(type, colFlags);
}
private void ExecutePacket(MySqlPacket packetToExecute)
{
try
{
warnings = 0;
stream.SequenceByte = 0;
stream.SendPacket(packetToExecute);
}
catch (MySqlException ex)
{
HandleException(ex);
throw;
}
}
public void ExecuteStatement(MySqlPacket packetToExecute)
{
warnings = 0;
packetToExecute.Buffer[4] = (byte)DBCmd.EXECUTE;
ExecutePacket(packetToExecute);
serverStatus |= ServerStatusFlags.AnotherQuery;
}
private void CheckEOF()
{
if (!packet.IsLastPacket)
throw new MySqlException("Expected end of data packet");
packet.ReadByte(); // read off the 254
if (packet.HasMoreData)
{
warnings += packet.ReadInteger(2);
serverStatus = (ServerStatusFlags)packet.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()
{
packet = stream.ReadPacket();
CheckEOF();
}
public int PrepareStatement(string sql, ref MySqlField[] parameters)
{
//TODO: check this
//ClearFetchedRow();
packet.Length = sql.Length*4 + 5;
byte[] buffer = packet.Buffer;
int len = Encoding.GetBytes(sql, 0, sql.Length, packet.Buffer, 5);
packet.Position = len + 5;
buffer[4] = (byte)DBCmd.PREPARE;
ExecutePacket(packet);
packet = stream.ReadPacket();
int marker = packet.ReadByte();
if (marker != 0)
throw new MySqlException("Expected prepared statement marker");
int statementId = packet.ReadInteger(4);
int numCols = packet.ReadInteger(2);
int numParams = packet.ReadInteger(2);
//TODO: find out what this is needed for
packet.ReadInteger(3);
if (numParams > 0)
{
parameters = owner.GetColumns(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)
{
packet = stream.ReadPacket();
//TODO: handle streaming packets
}
ReadEOF();
}
return statementId;
}
// private void ClearFetchedRow()
// {
// if (lastCommandResult == 0) return;
//TODO
/* CommandResult result = (CommandResult)commandResults[lastCommandResult];
result.ReadRemainingColumns();
stream.OpenPacket();
if (! stream.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 bool FetchDataRow(int statementId, int columns)
{
/* ClearFetchedRow();
if (!commandResults.ContainsKey(statementId)) return false;
if ( (serverStatus & ServerStatusFlags.LastRowSent) != 0)
return false;
stream.StartPacket(9, true);
stream.WriteByte((byte)DBCmd.FETCH);
stream.WriteInteger(statementId, 4);
stream.WriteInteger(1, 4);
stream.Flush();
lastCommandResult = statementId;
*/
packet = stream.ReadPacket();
if (packet.IsLastPacket)
{
CheckEOF();
return false;
}
nullMap = null;
if (statementId > 0)
ReadNullMap(columns);
return true;
}
public void CloseStatement(int statementId)
{
packet.Clear();
packet.WriteByte((byte)DBCmd.CLOSE_STMT);
packet.WriteInteger((long)statementId, 4);
stream.SequenceByte = 0;
stream.SendPacket(packet);
}
/// <summary>
/// Execution timeout, in milliseconds. When the accumulated time for network IO exceeds this value
/// TimeoutException is thrown. This timeout needs to be reset for every new command
/// </summary>
///
public void ResetTimeout(int timeout)
{
if (stream != null)
stream.ResetTimeout(timeout);
}
}
}

@ -0,0 +1,88 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Diagnostics;
using MySql.Data.MySqlClient.Properties;
namespace MySql.Data.MySqlClient
{
internal class PerformanceMonitor
{
private MySqlConnection connection;
private static PerformanceCounter procedureHardQueries;
private static PerformanceCounter procedureSoftQueries;
public PerformanceMonitor(MySqlConnection connection)
{
this.connection = connection;
string categoryName = Resources.PerfMonCategoryName;
if (connection.Settings.UsePerformanceMonitor && procedureHardQueries == null)
{
try
{
procedureHardQueries = new PerformanceCounter(categoryName,
"HardProcedureQueries", false);
procedureSoftQueries = new PerformanceCounter(categoryName,
"SoftProcedureQueries", false);
}
catch (Exception ex)
{
MySqlTrace.LogError(connection.ServerThread, ex.Message);
}
}
}
#if DEBUG
private void EnsurePerfCategoryExist()
{
CounterCreationDataCollection ccdc = new CounterCreationDataCollection();
CounterCreationData ccd = new CounterCreationData();
ccd.CounterType = PerformanceCounterType.NumberOfItems32;
ccd.CounterName = "HardProcedureQueries";
ccdc.Add(ccd);
ccd = new CounterCreationData();
ccd.CounterType = PerformanceCounterType.NumberOfItems32;
ccd.CounterName = "SoftProcedureQueries";
ccdc.Add(ccd);
if (!PerformanceCounterCategory.Exists(Resources.PerfMonCategoryName))
PerformanceCounterCategory.Create(Resources.PerfMonCategoryName, null, ccdc);
}
#endif
public void AddHardProcedureQuery()
{
if (!connection.Settings.UsePerformanceMonitor ||
procedureHardQueries == null) return;
procedureHardQueries.Increment();
}
public void AddSoftProcedureQuery()
{
if (!connection.Settings.UsePerformanceMonitor ||
procedureSoftQueries == null) return;
procedureSoftQueries.Increment();
}
}
}

@ -0,0 +1,211 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Collections;
using System.Text;
using System.Collections.Generic;
using MySql.Data.MySqlClient.Properties;
using System.Data;
namespace MySql.Data.MySqlClient
{
/// <summary>
/// Summary description for PreparedStatement.
/// </summary>
internal class PreparableStatement : Statement
{
private int executionCount;
private int statementId;
BitArray nullMap;
List<MySqlParameter> parametersToSend = new List<MySqlParameter>();
MySqlPacket packet;
int dataPosition;
int nullMapPosition;
public PreparableStatement(MySqlCommand command, string text)
: base(command, text)
{
}
#region Properties
public int ExecutionCount
{
get { return executionCount; }
set { executionCount = value; }
}
public bool IsPrepared
{
get { return statementId > 0; }
}
public int StatementId
{
get { return statementId; }
}
#endregion
public virtual void Prepare()
{
// strip out names from parameter markers
string text;
List<string> parameter_names = PrepareCommandText(out text);
// ask our connection to send the prepare command
MySqlField[] paramList = null;
statementId = Driver.PrepareStatement(text, ref paramList);
// now we need to assign our field names since we stripped them out
// for the prepare
for (int i = 0; i < parameter_names.Count; i++)
{
//paramList[i].ColumnName = (string) parameter_names[i];
string parameterName = (string)parameter_names[i];
int index = Parameters.IndexOf(parameterName);
if (index == -1)
throw new InvalidOperationException(
String.Format(Resources.ParameterNotFoundDuringPrepare, parameterName));
MySqlParameter p = Parameters[index];
p.Encoding = paramList[i].Encoding;
parametersToSend.Add(p);
}
// now prepare our null map
int numNullBytes = 0;
if (paramList != null && paramList.Length > 0)
{
nullMap = new BitArray(paramList.Length);
numNullBytes = (nullMap.Count + 7) / 8;
}
packet = new MySqlPacket(Driver.Encoding);
// write out some values that do not change run to run
packet.WriteByte(0);
packet.WriteInteger(statementId, 4);
packet.WriteByte((byte)0); // flags; always 0 for 4.1
packet.WriteInteger(1, 4); // interation count; 1 for 4.1
nullMapPosition = packet.Position;
packet.Position += numNullBytes; // leave room for our null map
packet.WriteByte(1); // rebound flag
// write out the parameter types
foreach (MySqlParameter p in parametersToSend)
packet.WriteInteger(p.GetPSType(), 2);
dataPosition = packet.Position;
}
public override void Execute()
{
// if we are not prepared, then call down to our base
if (!IsPrepared)
{
base.Execute();
return;
}
//TODO: support long data here
// create our null bitmap
// we check this because Mono doesn't ignore the case where nullMapBytes
// is zero length.
// if (nullMapBytes.Length > 0)
// {
// byte[] bits = packet.Buffer;
// nullMap.CopyTo(bits,
// nullMap.CopyTo(nullMapBytes, 0);
// start constructing our packet
// if (Parameters.Count > 0)
// nullMap.CopyTo(packet.Buffer, nullMapPosition);
//if (parameters != null && parameters.Count > 0)
//else
// packet.WriteByte( 0 );
//TODO: only send rebound if parms change
// now write out all non-null values
packet.Position = dataPosition;
for (int i = 0; i < parametersToSend.Count; i++)
{
MySqlParameter p = parametersToSend[i];
nullMap[i] = (p.Value == DBNull.Value || p.Value == null) ||
p.Direction == ParameterDirection.Output;
if (nullMap[i]) continue;
packet.Encoding = p.Encoding;
p.Serialize(packet, true, Connection.Settings);
}
if (nullMap != null)
nullMap.CopyTo(packet.Buffer, nullMapPosition);
executionCount++;
Driver.ExecuteStatement(packet);
}
public override bool ExecuteNext()
{
if (!IsPrepared)
return base.ExecuteNext();
return false;
}
/// <summary>
/// Prepares CommandText for use with the Prepare method
/// </summary>
/// <returns>Command text stripped of all paramter names</returns>
/// <remarks>
/// Takes the output of TokenizeSql and creates a single string of SQL
/// that only contains '?' markers for each parameter. It also creates
/// the parameterMap array list that includes all the paramter names in the
/// order they appeared in the SQL
/// </remarks>
private List<string> PrepareCommandText(out string stripped_sql)
{
StringBuilder newSQL = new StringBuilder();
List<string> parameterMap = new List<string>();
int startPos = 0;
string sql = ResolvedCommandText;
MySqlTokenizer tokenizer = new MySqlTokenizer(sql);
string parameter = tokenizer.NextParameter();
while (parameter != null)
{
newSQL.Append(sql.Substring(startPos, tokenizer.StartIndex - startPos));
newSQL.Append("?");
parameterMap.Add(parameter);
startPos = tokenizer.StopIndex;
parameter = tokenizer.NextParameter();
}
newSQL.Append(sql.Substring(startPos));
stripped_sql = newSQL.ToString();
return parameterMap;
}
public virtual void CloseStatement()
{
if (!IsPrepared) return;
Driver.CloseStatement(statementId);
statementId = 0;
}
}
}

@ -0,0 +1,137 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Collections;
using System.Data;
using System.Collections.Generic;
using MySql.Data.MySqlClient.Properties;
using System.Diagnostics;
namespace MySql.Data.MySqlClient
{
internal class ProcedureCache
{
private Hashtable procHash;
private Queue<int> hashQueue;
private int maxSize;
public ProcedureCache(int size)
{
maxSize = size;
hashQueue = new Queue<int>(maxSize);
procHash = new Hashtable(maxSize);
}
public DataSet GetProcedure(MySqlConnection conn, string spName)
{
int hash = spName.GetHashCode();
DataSet ds = null;
lock (procHash.SyncRoot)
{
ds = (DataSet)procHash[hash];
}
if (ds == null)
{
ds = AddNew(conn, spName);
#if !CF
conn.PerfMonitor.AddHardProcedureQuery();
#endif
MySqlTrace.LogInformation(conn.ServerThread,
String.Format(Resources.HardProcQuery, spName));
}
else
{
#if !CF
conn.PerfMonitor.AddSoftProcedureQuery();
#endif
MySqlTrace.LogInformation(conn.ServerThread,
String.Format(Resources.SoftProcQuery, spName));
}
return ds;
}
private DataSet AddNew(MySqlConnection connection, string spName)
{
DataSet procData = GetProcData(connection, spName);
if (maxSize > 0)
{
int hash = spName.GetHashCode();
lock (procHash.SyncRoot)
{
if (procHash.Keys.Count >= maxSize)
TrimHash();
if (!procHash.ContainsKey(hash))
{
procHash[hash] = procData;
hashQueue.Enqueue(hash);
}
}
}
return procData;
}
private void TrimHash()
{
int oldestHash = hashQueue.Dequeue();
procHash.Remove(oldestHash);
}
private static DataSet GetProcData(MySqlConnection connection, string spName)
{
string schema = String.Empty;
string name = spName;
int dotIndex = spName.IndexOf(".");
if (dotIndex != -1)
{
schema = spName.Substring(0, dotIndex);
name = spName.Substring(dotIndex + 1, spName.Length - dotIndex - 1);
}
string[] restrictions = new string[4];
restrictions[1] = schema.Length > 0 ? schema : connection.CurrentDatabase();
restrictions[2] = name;
DataTable procTable = connection.GetSchema("procedures", restrictions);
if (procTable.Rows.Count > 1)
throw new MySqlException(Resources.ProcAndFuncSameName);
if (procTable.Rows.Count == 0)
throw new MySqlException(String.Format(Resources.InvalidProcName, name, schema));
DataSet ds = new DataSet();
ds.Tables.Add(procTable);
// 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);
string[] rest = isp.CleanRestrictions(restrictions);
try
{
DataTable parametersTable = isp.GetProcedureParameters(rest, procTable);
ds.Tables.Add(parametersTable);
}
catch (Exception) { }
return ds;
}
}
}

@ -0,0 +1,282 @@
// Copyright (c) 2009 Sun Microsystems, Inc.
//
// 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.Collections;
using System.Data;
using MySql.Data.MySqlClient.Properties;
using MySql.Data.Types;
using System.Diagnostics;
namespace MySql.Data.MySqlClient
{
internal class ResultSet
{
private Driver driver;
private bool hasRows;
private bool[] uaFieldsUsed;
private MySqlField[] fields;
private IMySqlValue[] values;
private Hashtable fieldHashCS;
private Hashtable fieldHashCI;
private int rowIndex;
private bool readDone;
private bool isSequential;
private int seqIndex;
private bool isOutputParameters;
private int affectedRows;
private int insertedId;
private int statementId;
private int totalRows;
private int skippedRows;
public ResultSet(int affectedRows, int insertedId)
{
this.affectedRows = affectedRows;
this.insertedId = insertedId;
readDone = true;
}
public ResultSet(Driver d, int statementId, int numCols)
{
affectedRows = -1;
insertedId = -1;
driver = d;
this.statementId = statementId;
rowIndex = -1;
LoadColumns(numCols);
isOutputParameters = driver.HasStatus(ServerStatusFlags.OutputParameters);
hasRows = GetNextRow();
readDone = !hasRows;
}
#region Properties
public bool HasRows
{
get { return hasRows; }
}
public int Size
{
get { return fields == null ? 0 : fields.Length; }
}
public MySqlField[] Fields
{
get { return fields; }
}
public IMySqlValue[] Values
{
get { return values; }
}
public bool IsOutputParameters
{
get { return isOutputParameters; }
set { isOutputParameters = value; }
}
public int AffectedRows
{
get { return affectedRows; }
}
public int InsertedId
{
get { return insertedId; }
}
public int TotalRows
{
get { return totalRows; }
}
public int SkippedRows
{
get { return skippedRows; }
}
#endregion
/// <summary>
/// return the ordinal for the given column name
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public int GetOrdinal(string name)
{
// first we try a quick hash lookup
object ordinal = fieldHashCS[name];
if (ordinal != null)
return (int)ordinal;
// ok that failed so we use our CI hash
ordinal = fieldHashCI[name];
if (ordinal != null)
return (int)ordinal;
// Throw an exception if the ordinal cannot be found.
throw new IndexOutOfRangeException(
String.Format(Resources.CouldNotFindColumnName, name));
}
/// <summary>
/// Retrieve the value as the given column index
/// </summary>
/// <param name="index">The column value to retrieve</param>
/// <returns>The value as the given column</returns>
public IMySqlValue this[int index]
{
get
{
if (rowIndex < 0)
throw new MySqlException(Resources.AttemptToAccessBeforeRead);
// keep count of how many columns we have left to access
uaFieldsUsed[index] = true;
if (isSequential && index != seqIndex)
{
if (index < seqIndex)
throw new MySqlException(Resources.ReadingPriorColumnUsingSeqAccess);
while (seqIndex < (index - 1))
driver.SkipColumnValue(values[++seqIndex]);
values[index] = driver.ReadColumnValue(index, fields[index], values[index]);
seqIndex = index;
}
return values[index];
}
}
private bool GetNextRow()
{
bool fetched = driver.FetchDataRow(statementId, Size);
if (fetched)
totalRows++;
return fetched;
}
public bool NextRow(CommandBehavior behavior)
{
if (readDone) return false;
if ((behavior & CommandBehavior.SingleRow) != 0 && rowIndex == 0)
return false;
isSequential = (behavior & CommandBehavior.SequentialAccess) != 0;
seqIndex = -1;
// if we are at row index >= 0 then we need to fetch the data row and load it
if (rowIndex >= 0)
{
bool fetched = false;
try
{
fetched = GetNextRow();
}
catch (MySqlException ex)
{
if (ex.Number == 1317) fetched = false;
}
if (!fetched)
{
readDone = true;
return false;
}
}
if (!isSequential) ReadColumnData(false);
rowIndex++;
return true;
}
/// <summary>
/// Closes the current resultset, dumping any data still on the wire
/// </summary>
public void Close()
{
if (readDone) return;
// if we have rows but the user didn't read the first one then mark it as skipped
if (HasRows && rowIndex == -1)
skippedRows++;
while (driver.SkipDataRow())
{
totalRows++;
skippedRows++;
}
readDone = true;
}
public bool FieldRead(int index)
{
Debug.Assert(Size > index);
return uaFieldsUsed[index];
}
public void SetValueObject(int i, IMySqlValue valueObject)
{
Debug.Assert(values != null);
Debug.Assert(i < values.Length);
values[i] = valueObject;
}
/// <summary>
/// Loads the column metadata for the current resultset
/// </summary>
private void LoadColumns(int numCols)
{
fields = driver.GetColumns(numCols);
values = new IMySqlValue[numCols];
uaFieldsUsed = new bool[numCols];
fieldHashCS = new Hashtable();
fieldHashCI = new Hashtable(StringComparer.InvariantCultureIgnoreCase);
for (int i = 0; i < fields.Length; i++)
{
string columnName = fields[i].ColumnName;
if (!fieldHashCS.ContainsKey(columnName))
fieldHashCS.Add(columnName, i);
if (!fieldHashCI.ContainsKey(columnName))
fieldHashCI.Add(columnName, i);
values[i] = fields[i].GetValueObject();
}
}
private void ReadColumnData(bool outputParms)
{
for (int i = 0; i < Size; i++)
values[i] = driver.ReadColumnValue(i, fields[i], values[i]);
if (outputParms)
{
bool rowExists = driver.FetchDataRow(statementId, fields.Length);
rowIndex = 0;
if (rowExists)
throw new MySqlException(Resources.MoreThanOneOPRow);
}
}
}
}

@ -0,0 +1,26 @@
using System;
namespace MySql.Web.Security
{
internal static class Runtime
{
private static bool inited;
private static bool isMono;
public static bool IsMono
{
get
{
if (!inited)
Init();
return isMono;
}
}
private static void Init()
{
Type t = Type.GetType("Mono.Runtime");
isMono = t != null;
}
}
}

@ -0,0 +1,215 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Collections;
using System.IO;
using System.Text;
using MySql.Data.Common;
using System.Data;
using MySql.Data.MySqlClient.Properties;
using System.Collections.Generic;
namespace MySql.Data.MySqlClient
{
internal abstract class Statement
{
protected MySqlCommand command;
protected string commandText;
private ArrayList buffers;
private Statement(MySqlCommand cmd)
{
command = cmd;
buffers = new ArrayList();
}
public Statement(MySqlCommand cmd, string text) : this(cmd)
{
commandText = text;
}
#region Properties
public virtual string ResolvedCommandText
{
get { return commandText; }
}
protected Driver Driver
{
get { return command.Connection.driver; }
}
protected MySqlConnection Connection
{
get { return command.Connection; }
}
protected MySqlParameterCollection Parameters
{
get { return command.Parameters; }
}
#endregion
public virtual void Close(MySqlDataReader reader)
{
}
public virtual void Resolve(bool preparing)
{
}
public virtual void Execute()
{
// we keep a reference to this until we are done
BindParameters();
ExecuteNext();
}
public virtual bool ExecuteNext()
{
if (buffers.Count == 0)
return false;
MySqlPacket packet = (MySqlPacket)buffers[0];
//MemoryStream ms = stream.InternalBuffer;
Driver.SendQuery(packet);
buffers.RemoveAt(0);
return true;
}
protected virtual void BindParameters()
{
MySqlParameterCollection parameters = command.Parameters;
int index = 0;
while (true)
{
InternalBindParameters(ResolvedCommandText, parameters, null);
// if we are not batching, then we are done. This is only really relevant the
// first time through
if (command.Batch == null) return;
while (index < command.Batch.Count)
{
MySqlCommand batchedCmd = command.Batch[index++];
MySqlPacket packet = (MySqlPacket)buffers[buffers.Count - 1];
// now we make a guess if this statement will fit in our current stream
long estimatedCmdSize = batchedCmd.EstimatedSize();
if (((packet.Length-4) + estimatedCmdSize) > Connection.driver.MaxPacketSize)
{
// it won't, so we setup to start a new run from here
parameters = batchedCmd.Parameters;
break;
}
// looks like we might have room for it so we remember the current end of the stream
buffers.RemoveAt(buffers.Count - 1);
//long originalLength = packet.Length - 4;
// and attempt to stream the next command
string text = batchedCmd.BatchableCommandText;
if (text.StartsWith("("))
packet.WriteStringNoNull(", ");
else
packet.WriteStringNoNull("; ");
InternalBindParameters(text, batchedCmd.Parameters, packet);
if ((packet.Length-4) > Connection.driver.MaxPacketSize)
{
//TODO
//stream.InternalBuffer.SetLength(originalLength);
parameters = batchedCmd.Parameters;
break;
}
}
if (index == command.Batch.Count)
return;
}
}
private void InternalBindParameters(string sql, MySqlParameterCollection parameters,
MySqlPacket packet)
{
if (packet == null)
{
packet = new MySqlPacket(Driver.Encoding);
packet.Version = Driver.Version;
packet.WriteByte(0);
}
int startPos = 0;
MySqlTokenizer tokenizer = new MySqlTokenizer(sql);
tokenizer.ReturnComments = true;
string parameter = tokenizer.NextParameter();
while (parameter != null)
{
packet.WriteStringNoNull(sql.Substring(startPos, tokenizer.StartIndex - startPos));
bool serialized = SerializeParameter(parameters, packet, parameter);
startPos = tokenizer.StopIndex;
if (!serialized)
startPos = tokenizer.StartIndex;
parameter = tokenizer.NextParameter();
}
packet.WriteStringNoNull(sql.Substring(startPos));
buffers.Add(packet);
}
protected virtual bool ShouldIgnoreMissingParameter(string parameterName)
{
if (Connection.Settings.AllowUserVariables)
return true;
if (parameterName.StartsWith("@" +StoredProcedure.ParameterPrefix))
return true;
if (parameterName.Length > 1 &&
(parameterName[1] == '`' || parameterName[1] == '\''))
return true;
return false;
}
/// <summary>
/// Serializes the given parameter to the given memory stream
/// </summary>
/// <remarks>
/// <para>This method is called by PrepareSqlBuffers to convert the given
/// parameter to bytes and write those bytes to the given memory stream.
/// </para>
/// </remarks>
/// <returns>True if the parameter was successfully serialized, false otherwise.</returns>
private bool SerializeParameter(MySqlParameterCollection parameters,
MySqlPacket packet, string parmName)
{
MySqlParameter parameter = parameters.GetParameterFlexible(parmName, false);
if (parameter == null)
{
// if we are allowing user variables and the parameter name starts with @
// then we can't throw an exception
if (parmName.StartsWith("@") && ShouldIgnoreMissingParameter(parmName))
return false;
throw new MySqlException(
String.Format(Resources.ParameterMustBeDefined, parmName));
}
parameter.Serialize(packet, false, Connection.Settings);
return true;
}
}
}

@ -0,0 +1,289 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Types;
using MySql.Data.MySqlClient.Properties;
namespace MySql.Data.MySqlClient
{
/// <summary>
/// Summary description for StoredProcedure.
/// </summary>
internal class StoredProcedure : PreparableStatement
{
private string outSelect;
private DataTable parametersTable;
private string resolvedCommandText;
// Prefix used for to generate inout or output parameters names
internal const string ParameterPrefix = "_cnet_param_";
public StoredProcedure(MySqlCommand cmd, string text)
: base(cmd, text)
{
}
private string GetReturnParameter()
{
if (Parameters != null)
foreach (MySqlParameter p in Parameters)
if (p.Direction == ParameterDirection.ReturnValue)
return p.ParameterName.Substring(1);
return null;
}
public override string ResolvedCommandText
{
get { return resolvedCommandText; }
}
private DataSet GetParameters(string procName)
{
// if we can use mysql.proc, then do so
//if (Connection.Settings.UseProcedureBodies)
DataSet ds = Connection.ProcedureCache.GetProcedure(Connection, procName);
if(ds.Tables.Count == 2)
{
// if we got our parameters and our user says it is ok to use proc bodies
// then just return them
if (Connection.Settings.UseProcedureBodies) return ds;
// we got the parameters, but ignore them.
if(ds.Tables.Contains("Procedure Parameters"))
ds.Tables.Remove("Procedure Parameters");
}
// we were not able to retrieve parameter data so we have to make do by
// adding the parameters from the command object to our table
// we use an internal method to create our procedure parameters table.
ISSchemaProvider sp = new ISSchemaProvider(Connection);
DataTable pTable = sp.CreateParametersTable();
ds.Tables.Add(pTable);
// now we run through the parameters that were set and fill in the parameters table
// the best we can
int pos = 1;
foreach (MySqlParameter p in command.Parameters)
{
// in this mode, all parameters must have their type set
if (!p.TypeHasBeenSet)
throw new InvalidOperationException(Resources.NoBodiesAndTypeNotSet);
DataRow row = pTable.NewRow();
row["PARAMETER_NAME"] = p.ParameterName;
row["PARAMETER_MODE"] = "IN";
if (p.Direction == ParameterDirection.InputOutput)
row["PARAMETER_MODE"] = "INOUT";
else if (p.Direction == ParameterDirection.Output)
row["PARAMETER_MODE"] = "OUT";
else if (p.Direction == ParameterDirection.ReturnValue)
{
row["PARAMETER_MODE"] = "OUT";
row["ORDINAL_POSITION"] = 0;
}
else
row["ORDINAL_POSITION"] = pos++;
pTable.Rows.Add(row);
}
return ds;
}
public static string GetFlags(string dtd)
{
int x = dtd.Length - 1;
while (x > 0 && (Char.IsLetterOrDigit(dtd[x]) || dtd[x] == ' '))
x--;
return dtd.Substring(x).ToUpper(CultureInfo.InvariantCulture);
}
private string FixProcedureName(string name)
{
string[] parts = name.Split('.');
for (int i = 0; i < parts.Length; i++)
if (!parts[i].StartsWith("`"))
parts[i] = String.Format("`{0}`", parts[i]);
if (parts.Length == 1) return parts[0];
return String.Format("{0}.{1}", parts[0], parts[1]);
}
private MySqlParameter GetAndFixParameter(DataRow param, bool realAsFloat, string returnParameter)
{
string mode = (string)param["PARAMETER_MODE"];
string pName = (string)param["PARAMETER_NAME"];
if (param["ORDINAL_POSITION"].Equals(0))
pName = returnParameter;
if (pName == null) return null;
// make sure the parameters given to us have an appropriate
// type set if it's not already
MySqlParameter p = command.Parameters.GetParameterFlexible(pName, true);
if (!p.TypeHasBeenSet)
{
string datatype = (string)param["DATA_TYPE"];
bool unsigned = GetFlags(param["DTD_IDENTIFIER"].ToString()).IndexOf("UNSIGNED") != -1;
p.MySqlDbType = MetaData.NameToType(datatype, unsigned, realAsFloat, Connection);
}
return p;
}
public override void Resolve(bool preparing)
{
// check to see if we are already resolved
if (resolvedCommandText != null) return;
// first retrieve the procedure definition from our
// procedure cache
string spName = commandText;
if (spName.IndexOf(".") == -1 && !String.IsNullOrEmpty(Connection.Database))
spName = Connection.Database + "." + spName;
spName = FixProcedureName(spName);
DataSet ds = GetParameters(spName);
DataTable procTable = ds.Tables["procedures"];
parametersTable = ds.Tables["procedure parameters"];
if (procTable.Rows.Count == 0)
throw new InvalidOperationException(String.Format(Resources.RoutineNotFound, spName));
bool realAsFloat = procTable.Rows[0]["SQL_MODE"].ToString().IndexOf("REAL_AS_FLOAT") != -1;
StringBuilder sqlStr = new StringBuilder();
StringBuilder outSql = new StringBuilder();
string sqlDelimiter = "";
string outDelimiter = "";
string retParm = GetReturnParameter();
foreach (DataRow param in parametersTable.Rows)
{
MySqlParameter p = GetAndFixParameter(param, realAsFloat, retParm);
if (p == null) continue;
if (param["ORDINAL_POSITION"].Equals(0))
continue;
string baseName = p.ParameterName;
string pName = baseName;
if (baseName.StartsWith("@") || baseName.StartsWith("?"))
baseName = baseName.Substring(1);
else
pName = "@" + pName;
string inputVar = pName;
if (p.Direction != ParameterDirection.Input &&
!(Connection.driver.SupportsOutputParameters || preparing))
{
// set a user variable to our current value
string sql = String.Format("SET @{0}{1}={2}", ParameterPrefix, baseName, pName);
MySqlCommand cmd = new MySqlCommand(sql, Connection);
cmd.Parameters.Add(p);
cmd.ExecuteNonQuery();
inputVar = String.Format("@{0}{1}", ParameterPrefix, baseName);
outSql.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}", outDelimiter, inputVar);
outDelimiter = ", ";
}
sqlStr.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}", sqlDelimiter, inputVar);
sqlDelimiter = ", ";
}
string sqlCmd = sqlStr.ToString().TrimEnd(' ', ',');
outSelect = outSql.ToString().TrimEnd(' ', ',');
if (procTable.Rows[0]["ROUTINE_TYPE"].Equals("PROCEDURE"))
sqlCmd = String.Format("call {0} ({1})", spName, sqlCmd);
else
{
if (retParm == null)
retParm = ParameterPrefix + "dummy";
else
outSelect = String.Format("@{0}{1}", ParameterPrefix, retParm);
sqlCmd = String.Format("SET @{0}{1}={2}({3})", ParameterPrefix, retParm, spName, sqlCmd);
}
resolvedCommandText = sqlCmd;
}
private MySqlDataReader GetHackedOuputParameters()
{
if (outSelect.Length == 0) return null;
MySqlCommand cmd = new MySqlCommand("SELECT " + outSelect, Connection);
MySqlDataReader reader = cmd.ExecuteReader();
// 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
ResultSet results = reader.ResultSet;
for (int i = 0; i < reader.FieldCount; i++)
{
string fieldName = reader.GetName(i);
fieldName = fieldName.Remove(0, ParameterPrefix.Length + 1);
MySqlParameter parameter = Parameters.GetParameterFlexible(fieldName, true);
results.SetValueObject(i, MySqlField.GetIMySqlValue(parameter.MySqlDbType));
}
if (!reader.Read())
{
reader.Close();
return null;
}
return reader;
}
public override void Close(MySqlDataReader reader)
{
base.Close(reader);
ResultSet rs = reader.ResultSet;
// if our closing reader doesn't have output parameters then we may have to
// use the user variable hack
if (rs == null || !rs.IsOutputParameters)
{
MySqlDataReader rdr = GetHackedOuputParameters();
if (rdr == null) return;
reader = rdr;
}
using (reader)
{
string prefix = "@" + ParameterPrefix;
for (int i = 0; i < reader.FieldCount; i++)
{
string fieldName = reader.GetName(i);
if (fieldName.StartsWith(prefix))
fieldName = fieldName.Remove(0, prefix.Length);
MySqlParameter parameter = Parameters.GetParameterFlexible(fieldName, true);
parameter.Value = reader.GetValue(i);
}
reader.Close();
}
}
}
}

@ -0,0 +1,297 @@
// Copyright (c) 2009 Sun Microsystems, Inc.
//
// 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.Sockets;
using System.Diagnostics;
using MySql.Data.Common;
namespace MySql.Data.MySqlClient
{
/// <summary>
/// Stream that supports timeout of IO operations.
/// This class is used is used to support timeouts for SQL command, where a
/// typical operation involves several network reads/writes.
/// Timeout here is defined as the accumulated duration of all IO operations.
/// </summary>
internal class TimedStream : Stream
{
Stream baseStream;
int timeout;
int lastReadTimeout;
int lastWriteTimeout;
LowResolutionStopwatch stopwatch;
bool isClosed;
enum IOKind
{
Read,
Write
};
/// <summary>
/// Construct a TimedStream
/// </summary>
/// <param name="baseStream"> Undelying stream</param>
public TimedStream(Stream baseStream)
{
this.baseStream = baseStream;
#if !CF
timeout = baseStream.ReadTimeout;
#else
timeout = System.Threading.Timeout.Infinite;
#endif
isClosed = false;
stopwatch = new LowResolutionStopwatch();
}
/// <summary>
/// Figure out whether it is necessary to reset timeout on stream.
/// We track the current value of timeout and try to avoid
/// changing it too often, because setting Read/WriteTimeout property
/// on network stream maybe a slow operation that involves a system call
/// (setsockopt). Therefore, we allow a small difference, and do not
/// reset timeout if current value is slightly greater than the requested
/// one (within 0.1 second).
/// </summary>
private bool ShouldResetStreamTimeout(int currentValue, int newValue)
{
if (newValue == System.Threading.Timeout.Infinite
&& currentValue != newValue)
return true;
if (newValue > currentValue)
return true;
if (currentValue>= newValue + 100)
return true;
return false;
}
private void StartTimer(IOKind op)
{
int streamTimeout;
if (timeout == System.Threading.Timeout.Infinite)
streamTimeout = System.Threading.Timeout.Infinite;
else
streamTimeout = timeout - (int)stopwatch.ElapsedMilliseconds;
if (op == IOKind.Read)
{
if (ShouldResetStreamTimeout(lastReadTimeout, streamTimeout))
{
#if !CF
baseStream.ReadTimeout = streamTimeout;
#endif
lastReadTimeout = streamTimeout;
}
}
else
{
if (ShouldResetStreamTimeout(lastWriteTimeout, streamTimeout))
{
#if !CF
baseStream.WriteTimeout = streamTimeout;
#endif
lastWriteTimeout = streamTimeout;
}
}
if (timeout == System.Threading.Timeout.Infinite)
return;
stopwatch.Start();
}
private void StopTimer()
{
if (timeout == System.Threading.Timeout.Infinite)
return;
stopwatch.Stop();
// Normally, a timeout exception would be thrown by stream itself,
// since we set the read/write timeout for the stream. However
// there is a gap between end of IO operation and stopping the
// stop watch, and it makes it possible for timeout to exceed
// even after IO completed successfully.
if (stopwatch.ElapsedMilliseconds > timeout)
{
ResetTimeout(System.Threading.Timeout.Infinite);
throw new TimeoutException("Timeout in IO operation");
}
}
public override bool CanRead
{
get { return baseStream.CanRead; }
}
public override bool CanSeek
{
get { return baseStream.CanSeek; }
}
public override bool CanWrite
{
get { return baseStream.CanWrite; }
}
public override void Flush()
{
try
{
StartTimer(IOKind.Write);
baseStream.Flush();
StopTimer();
}
catch (Exception e)
{
HandleException(e);
throw;
}
}
public override long Length
{
get { return baseStream.Length; }
}
public override long Position
{
get
{
return baseStream.Position;
}
set
{
baseStream.Position = value;
}
}
public override int Read(byte[] buffer, int offset, int count)
{
try
{
StartTimer(IOKind.Read);
int retval = baseStream.Read(buffer, offset, count);
StopTimer();
return retval;
}
catch (Exception e)
{
HandleException(e);
throw;
}
}
public override int ReadByte()
{
try
{
StartTimer(IOKind.Read);
int retval = baseStream.ReadByte();
StopTimer();
return retval;
}
catch (Exception e)
{
HandleException(e);
throw;
}
}
public override long Seek(long offset, SeekOrigin origin)
{
return baseStream.Seek(offset, origin);
}
public override void SetLength(long value)
{
baseStream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
try
{
StartTimer(IOKind.Write);
baseStream.Write(buffer, offset, count);
StopTimer();
}
catch (Exception e)
{
HandleException(e);
throw;
}
}
public override bool CanTimeout
{
get { return baseStream.CanTimeout; }
}
public override int ReadTimeout
{
get { return baseStream.ReadTimeout; }
set { baseStream.ReadTimeout = value; }
}
public override int WriteTimeout
{
get { return baseStream.WriteTimeout; }
set { baseStream.WriteTimeout = value; }
}
public override void Close()
{
if (isClosed)
return;
isClosed = true;
baseStream.Close();
}
public void ResetTimeout(int newTimeout)
{
if (newTimeout == System.Threading.Timeout.Infinite || newTimeout == 0)
timeout = System.Threading.Timeout.Infinite;
else
timeout = newTimeout;
stopwatch.Reset();
}
/// <summary>
/// Common handler for IO exceptions.
/// Resets timeout to infinity if timeout exception is
/// detected and stops the times.
/// </summary>
/// <param name="e">original exception</param>
void HandleException(Exception e)
{
stopwatch.Stop();
ResetTimeout(-1);
}
}
}

@ -0,0 +1,248 @@
// Copyright (c) 2009 Sun Microsystems, Inc.
//
// 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.Text;
using MySql.Data.Types;
using System.Diagnostics;
using System.Collections.Generic;
using MySql.Data.MySqlClient.Properties;
using System.Threading;
using MySql.Data.Common;
namespace MySql.Data.MySqlClient
{
internal class TracingDriver : Driver
{
private static long driverCounter;
private long driverId;
private ResultSet activeResult;
private int rowSizeInBytes;
public TracingDriver(MySqlConnectionStringBuilder settings)
: base(settings)
{
driverId = Interlocked.Increment(ref driverCounter);
}
public override void Open()
{
base.Open();
MySqlTrace.TraceEvent(TraceEventType.Information, MySqlTraceEventType.ConnectionOpened,
Resources.TraceOpenConnection, driverId, Settings.ConnectionString, ThreadID);
}
public override void Close()
{
base.Close();
MySqlTrace.TraceEvent(TraceEventType.Information, MySqlTraceEventType.ConnectionClosed,
Resources.TraceCloseConnection, driverId);
}
public override void SendQuery(MySqlPacket p)
{
rowSizeInBytes = 0;
string cmdText = Encoding.GetString(p.Buffer, 5, p.Length - 5);
string normalized_query = null;
if (cmdText.Length > 300)
{
cmdText = cmdText.Substring(0, 300);
QueryNormalizer normalizer = new QueryNormalizer();
normalized_query = normalizer.Normalize(cmdText);
}
base.SendQuery(p);
MySqlTrace.TraceEvent(TraceEventType.Information, MySqlTraceEventType.QueryOpened,
Resources.TraceQueryOpened, driverId, ThreadID, cmdText);
if (normalized_query != null)
MySqlTrace.TraceEvent(TraceEventType.Information, MySqlTraceEventType.QueryNormalized,
Resources.TraceQueryNormalized, driverId, ThreadID, normalized_query);
}
protected override int GetResult(int statementId, ref int affectedRows, ref int insertedId)
{
try
{
int fieldCount = base.GetResult(statementId, ref affectedRows, ref insertedId);
MySqlTrace.TraceEvent(TraceEventType.Information, MySqlTraceEventType.ResultOpened,
Resources.TraceResult, driverId, fieldCount, affectedRows, insertedId);
return fieldCount;
}
catch (MySqlException ex)
{
// we got an error so we report it
MySqlTrace.TraceEvent(TraceEventType.Information, MySqlTraceEventType.Error,
Resources.TraceOpenResultError, driverId, ex.Number, ex.Message);
throw ex;
}
}
public override ResultSet NextResult(int statementId)
{
// first let's see if we already have a resultset on this statementId
if (activeResult != null)
{
//oldRS = activeResults[statementId];
if (Settings.UseUsageAdvisor)
ReportUsageAdvisorWarnings(statementId, activeResult);
MySqlTrace.TraceEvent(TraceEventType.Information, MySqlTraceEventType.ResultClosed,
Resources.TraceResultClosed, driverId, activeResult.TotalRows, activeResult.SkippedRows,
rowSizeInBytes);
rowSizeInBytes = 0;
activeResult = null;
}
activeResult = base.NextResult(statementId);
return activeResult;
}
public override int PrepareStatement(string sql, ref MySqlField[] parameters)
{
int statementId = base.PrepareStatement(sql, ref parameters);
MySqlTrace.TraceEvent(TraceEventType.Information, MySqlTraceEventType.StatementPrepared,
Resources.TraceStatementPrepared, driverId, sql, statementId);
return statementId;
}
public override void CloseStatement(int id)
{
base.CloseStatement(id);
MySqlTrace.TraceEvent(TraceEventType.Information, MySqlTraceEventType.StatementClosed,
Resources.TraceStatementClosed, driverId, id);
}
public override void SetDatabase(string dbName)
{
base.SetDatabase(dbName);
MySqlTrace.TraceEvent(TraceEventType.Information, MySqlTraceEventType.NonQuery,
Resources.TraceSetDatabase, driverId, dbName);
}
public override void ExecuteStatement(MySqlPacket packetToExecute)
{
base.ExecuteStatement(packetToExecute);
int pos = packetToExecute.Position;
packetToExecute.Position = 1;
int statementId = packetToExecute.ReadInteger(4);
packetToExecute.Position = pos;
MySqlTrace.TraceEvent(TraceEventType.Information, MySqlTraceEventType.StatementExecuted,
Resources.TraceStatementExecuted, driverId, statementId, ThreadID);
}
public override bool FetchDataRow(int statementId, int columns)
{
try
{
bool b = base.FetchDataRow(statementId, columns);
if (b)
rowSizeInBytes += (handler as NativeDriver).Packet.Length;
return b;
}
catch (MySqlException ex)
{
MySqlTrace.TraceEvent(TraceEventType.Error, MySqlTraceEventType.Error,
Resources.TraceFetchError, driverId, ex.Number, ex.Message);
throw ex;
}
}
public override void CloseQuery(MySqlConnection connection, int statementId)
{
base.CloseQuery(connection, statementId);
MySqlTrace.TraceEvent(TraceEventType.Information, MySqlTraceEventType.QueryClosed,
Resources.TraceQueryDone, driverId);
}
public override List<MySqlError> ReportWarnings(MySqlConnection connection)
{
List<MySqlError> warnings = base.ReportWarnings(connection);
foreach (MySqlError warning in warnings)
MySqlTrace.TraceEvent(TraceEventType.Warning, MySqlTraceEventType.Warning,
Resources.TraceWarning, driverId, warning.Level, warning.Code, warning.Message);
return warnings;
}
private bool AllFieldsAccessed(ResultSet rs)
{
if (rs.Fields == null || rs.Fields.Length == 0) return true;
for (int i = 0; i < rs.Fields.Length; i++)
if (!rs.FieldRead(i)) return false;
return true;
}
private void ReportUsageAdvisorWarnings(int statementId, ResultSet rs)
{
if (!Settings.UseUsageAdvisor) return;
if (HasStatus(ServerStatusFlags.NoIndex))
MySqlTrace.TraceEvent(TraceEventType.Warning, MySqlTraceEventType.UsageAdvisorWarning,
Resources.TraceUAWarningNoIndex, driverId, UsageAdvisorWarningFlags.NoIndex);
else if (HasStatus(ServerStatusFlags.BadIndex))
MySqlTrace.TraceEvent(TraceEventType.Warning, MySqlTraceEventType.UsageAdvisorWarning,
Resources.TraceUAWarningBadIndex, driverId, UsageAdvisorWarningFlags.BadIndex);
// report abandoned rows
if (rs.SkippedRows > 0)
MySqlTrace.TraceEvent(TraceEventType.Warning, MySqlTraceEventType.UsageAdvisorWarning,
Resources.TraceUAWarningSkippedRows, driverId, UsageAdvisorWarningFlags.SkippedRows, rs.SkippedRows);
// report not all fields accessed
if (!AllFieldsAccessed(rs))
{
StringBuilder notAccessed = new StringBuilder("");
string delimiter = "";
for (int i = 0; i < rs.Size; i++)
if (!rs.FieldRead(i))
{
notAccessed.AppendFormat("{0}{1}", delimiter, rs.Fields[i].ColumnName);
delimiter = ",";
}
MySqlTrace.TraceEvent(TraceEventType.Warning, MySqlTraceEventType.UsageAdvisorWarning,
Resources.TraceUAWarningSkippedColumns, driverId, UsageAdvisorWarningFlags.SkippedColumns,
notAccessed.ToString());
}
// report type conversions if any
if (rs.Fields != null)
{
foreach (MySqlField f in rs.Fields)
{
StringBuilder s = new StringBuilder();
string delimiter = "";
foreach (Type t in f.TypeConversions)
{
s.AppendFormat("{0}{1}", delimiter, t.Name);
delimiter = ",";
}
if (s.Length > 0)
MySqlTrace.TraceEvent(TraceEventType.Warning, MySqlTraceEventType.UsageAdvisorWarning,
Resources.TraceUAWarningFieldConversion, driverId, UsageAdvisorWarningFlags.FieldConversion,
f.ColumnName, s.ToString());
}
}
}
}
}

@ -0,0 +1,137 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
using System.Globalization;
namespace MySql.Data.Types
{
internal class MetaData
{
public static bool IsNumericType(string typename)
{
string lowerType = typename.ToLower(CultureInfo.InvariantCulture);
switch (lowerType)
{
case "int":
case "integer":
case "numeric":
case "decimal":
case "dec":
case "fixed":
case "tinyint":
case "mediumint":
case "bigint":
case "real":
case "double":
case "float":
case "serial":
case "smallint": return true;
}
return false;
}
public static bool SupportScale(string typename)
{
string lowerType = typename.ToLower(CultureInfo.InvariantCulture);
switch (lowerType)
{
case "numeric":
case "decimal":
case "dec":
case "real": return true;
}
return false;
}
public static MySqlDbType NameToType(string typeName, bool unsigned,
bool realAsFloat, MySqlConnection connection)
{
switch (typeName.ToUpper(CultureInfo.InvariantCulture))
{
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":
return unsigned ? MySqlDbType.UByte : MySqlDbType.Byte;
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 "TEXT":
return MySqlDbType.Text;
case "BLOB":
return MySqlDbType.Blob;
case "LONGBLOB":
return MySqlDbType.LongBlob;
case "LONGTEXT":
return MySqlDbType.LongText;
case "MEDIUMBLOB":
return MySqlDbType.MediumBlob;
case "MEDIUMTEXT":
return MySqlDbType.MediumText;
case "TINYBLOB":
return MySqlDbType.TinyBlob;
case "TINYTEXT":
return MySqlDbType.TinyText;
case "BINARY":
return MySqlDbType.Binary;
case "VARBINARY":
return MySqlDbType.VarBinary;
}
throw new MySqlException("Unhandled type encountered");
}
}
}

@ -0,0 +1,226 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
namespace MySql.Data.Types
{
internal struct MySqlBinary : IMySqlValue
{
private MySqlDbType type;
private byte[] mValue;
private bool isNull;
public MySqlBinary(MySqlDbType type, bool isNull)
{
this.type = type;
this.isNull = isNull;
mValue = null;
}
public MySqlBinary(MySqlDbType type, byte[] val)
{
this.type = type;
this.isNull = false;
mValue = val;
}
#region IMySqlValue Members
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return type; }
}
DbType IMySqlValue.DbType
{
get { return DbType.Binary; }
}
object IMySqlValue.Value
{
get { return mValue; }
}
public byte[] Value
{
get { return mValue; }
}
Type IMySqlValue.SystemType
{
get { return typeof(byte[]); }
}
string IMySqlValue.MySqlTypeName
{
get
{
switch (type)
{
case MySqlDbType.TinyBlob: return "TINY_BLOB";
case MySqlDbType.MediumBlob: return "MEDIUM_BLOB";
case MySqlDbType.LongBlob: return "LONG_BLOB";
case MySqlDbType.Blob:
default:
return "BLOB";
}
}
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
{
byte[] buffToWrite = (val as byte[]);
if (buffToWrite == null)
{
char[] valAsChar = (val as Char[]);
if (valAsChar != null)
buffToWrite = packet.Encoding.GetBytes(valAsChar);
else
{
string s = val.ToString();
if (length == 0)
length = s.Length;
else
s = s.Substring(0, length);
buffToWrite = packet.Encoding.GetBytes(s);
}
}
// 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)
{
packet.WriteLength(length);
packet.Write(buffToWrite, 0, length);
}
else
{
if (packet.Version.isAtLeast(4, 1, 0))
packet.WriteStringNoNull("_binary ");
packet.WriteByte((byte)'\'');
EscapeByteArray(buffToWrite, length, packet);
packet.WriteByte((byte)'\'');
}
}
private static void EscapeByteArray(byte[] bytes, int length, MySqlPacket packet)
{
for (int x = 0; x < length; x++)
{
byte b = bytes[x];
if (b == '\0')
{
packet.WriteByte((byte)'\\');
packet.WriteByte((byte)'0');
}
else if (b == '\\' || b == '\'' || b == '\"')
{
packet.WriteByte((byte)'\\');
packet.WriteByte(b);
}
else
packet.WriteByte(b);
}
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
MySqlBinary b;
if (nullVal)
b = new MySqlBinary(type, true);
else
{
if (length == -1)
length = (long)packet.ReadFieldLength();
byte[] newBuff = new byte[length];
packet.Read(newBuff, 0, (int)length);
b = new MySqlBinary(type, newBuff);
}
return b;
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
int len = packet.ReadFieldLength();
packet.Position += len;
}
#endregion
public static void SetDSInfo(DataTable dsTable)
{
string[] types = new string[] { "BLOB", "TINYBLOB", "MEDIUMBLOB", "LONGBLOB", "BINARY", "VARBINARY" };
MySqlDbType[] dbtype = new MySqlDbType[] { MySqlDbType.Blob,
MySqlDbType.TinyBlob, MySqlDbType.MediumBlob, MySqlDbType.LongBlob, MySqlDbType.Binary, MySqlDbType.VarBinary };
long[] sizes = new long[] { 65535L, 255L, 16777215L, 4294967295L, 255L, 65535L };
string[] format = new string[] { null, null, null, null, "binary({0})", "varbinary({0})" };
string[] parms = new string[] { null, null, null, null, "length", "length" };
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
for (int x = 0; x < types.Length; x++)
{
DataRow row = dsTable.NewRow();
row["TypeName"] = types[x];
row["ProviderDbType"] = dbtype[x];
row["ColumnSize"] = sizes[x];
row["CreateFormat"] = format[x];
row["CreateParameters"] = parms[x];
row["DataType"] = "System.Byte[]";
row["IsAutoincrementable"] = false;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = x < 4 ? false : true;
row["IsFixedPrecisionScale"] = false;
row["IsLong"] = sizes[x] > 255;
row["IsNullable"] = true;
row["IsSearchable"] = false;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = DBNull.Value;
row["MaximumScale"] = DBNull.Value;
row["MinimumScale"] = DBNull.Value;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = "0x";
row["LiteralSuffix"] = DBNull.Value;
row["NativeDataType"] = DBNull.Value;
dsTable.Rows.Add(row);
}
}
}
}

@ -0,0 +1,137 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
namespace MySql.Data.Types
{
/// <summary>
/// Summary description for MySqlUInt64.
/// </summary>
internal struct MySqlBit : IMySqlValue
{
private ulong mValue;
private bool isNull;
public MySqlBit(bool isnull)
{
mValue = 0;
isNull = isnull;
}
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return MySqlDbType.Bit; }
}
DbType IMySqlValue.DbType
{
get { return DbType.UInt64; }
}
object IMySqlValue.Value
{
get
{
return mValue;
}
}
Type IMySqlValue.SystemType
{
get
{
return typeof(UInt64);
}
}
string IMySqlValue.MySqlTypeName
{
get { return "BIT"; }
}
public void WriteValue(MySqlPacket packet, bool binary, object value, int length)
{
ulong v = (value is UInt64) ? (UInt64)value : Convert.ToUInt64(value);
if (binary)
packet.WriteInteger((long)v, 8);
else
packet.WriteStringNoNull(v.ToString());
}
public IMySqlValue ReadValue(MySqlPacket packet, long length, bool isNull)
{
this.isNull = isNull;
if (isNull)
return this;
if (length == -1)
length = packet.ReadFieldLength();
mValue = (UInt64)packet.ReadBitValue((int)length);
return this;
}
public void SkipValue(MySqlPacket packet)
{
int len = packet.ReadFieldLength();
packet.Position += len;
}
public static void SetDSInfo(DataTable dsTable)
{
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
DataRow row = dsTable.NewRow();
row["TypeName"] = "BIT";
row["ProviderDbType"] = MySqlDbType.Bit;
row["ColumnSize"] = 64;
row["CreateFormat"] = "BIT";
row["CreateParameters"] = DBNull.Value; ;
row["DataType"] = typeof(UInt64).ToString();
row["IsAutoincrementable"] = false;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = false;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = true;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = false;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = DBNull.Value;
row["LiteralSuffix"] = DBNull.Value;
row["NativeDataType"] = DBNull.Value;
dsTable.Rows.Add(row);
}
}
}

@ -0,0 +1,171 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
using System.Globalization;
namespace MySql.Data.Types
{
internal struct MySqlByte : IMySqlValue
{
private sbyte mValue;
private bool isNull;
private bool treatAsBool;
public MySqlByte(bool isNull)
{
this.isNull = isNull;
mValue = 0;
treatAsBool = false;
}
public MySqlByte(sbyte val)
{
this.isNull = false;
mValue = val;
treatAsBool = false;
}
#region IMySqlValue Members
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return MySqlDbType.Byte; }
}
DbType IMySqlValue.DbType
{
get
{
if (TreatAsBoolean)
return DbType.Boolean;
return DbType.SByte;
}
}
object IMySqlValue.Value
{
get
{
if (TreatAsBoolean)
return Convert.ToBoolean(mValue);
return mValue;
}
}
public sbyte Value
{
get { return mValue; }
set { mValue = value; }
}
Type IMySqlValue.SystemType
{
get
{
if (TreatAsBoolean)
return typeof(Boolean);
return typeof(sbyte);
}
}
string IMySqlValue.MySqlTypeName
{
get { return "TINYINT"; }
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
{
sbyte v = (val is sbyte) ? (sbyte)val : Convert.ToSByte(val);
if (binary)
packet.WriteByte((byte)v);
else
packet.WriteStringNoNull(v.ToString());
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
if (nullVal)
return new MySqlByte(true);
if (length == -1)
return new MySqlByte((sbyte)packet.ReadByte());
else
{
string s = packet.ReadString(length);
MySqlByte b = new MySqlByte(SByte.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture));
b.TreatAsBoolean = TreatAsBoolean;
return b;
}
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
packet.ReadByte();
}
#endregion
internal bool TreatAsBoolean
{
get { return treatAsBool; }
set { treatAsBool = value; }
}
internal static void SetDSInfo(DataTable dsTable)
{
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
DataRow row = dsTable.NewRow();
row["TypeName"] = "TINYINT";
row["ProviderDbType"] = MySqlDbType.Byte;
row["ColumnSize"] = 0;
row["CreateFormat"] = "TINYINT";
row["CreateParameters"] = null;
row["DataType"] = "System.SByte";
row["IsAutoincrementable"] = true;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = true;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = true;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = false;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = null;
row["LiteralSuffix"] = null;
row["NativeDataType"] = null;
dsTable.Rows.Add(row);
}
}
}

@ -0,0 +1,39 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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;
namespace MySql.Data.Types
{
/// <summary>
/// Summary description for MySqlConversionException.
/// </summary>
#if !CF
[Serializable]
#endif
public class MySqlConversionException : Exception
{
/// <summary>Ctor</summary>
public MySqlConversionException(string msg)
: base(msg)
{
}
}
}

@ -0,0 +1,646 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.IO;
using MySql.Data.MySqlClient;
using System.Globalization;
namespace MySql.Data.Types
{
/// <summary>
///
/// </summary>
public struct MySqlDateTime : IMySqlValue, IConvertible, IComparable
{
private bool isNull;
private MySqlDbType type;
private int year, month, day, hour, minute, second;
private int millisecond;
/// <summary>
/// Constructs a new <b>MySqlDateTime</b> object by setting the individual time properties to
/// the given values.
/// </summary>
/// <param name="year">The year to use.</param>
/// <param name="month">The month to use.</param>
/// <param name="day">The day to use.</param>
/// <param name="hour">The hour to use.</param>
/// <param name="minute">The minute to use.</param>
/// <param name="second">The second to use.</param>
public MySqlDateTime(int year, int month, int day, int hour, int minute, int second)
: this(MySqlDbType.DateTime, year, month, day, hour, minute, second)
{
}
/// <summary>
/// Constructs a new <b>MySqlDateTime</b> object by using values from the given <see cref="DateTime"/> object.
/// </summary>
/// <param name="dt">The <see cref="DateTime"/> object to copy.</param>
public MySqlDateTime(DateTime dt)
: this(MySqlDbType.DateTime, dt)
{
}
/// <summary>
/// Constructs a new <b>MySqlDateTime</b> object by copying the current value of the given object.
/// </summary>
/// <param name="mdt">The <b>MySqlDateTime</b> object to copy.</param>
public MySqlDateTime(MySqlDateTime mdt)
{
year = mdt.Year;
month = mdt.Month;
day = mdt.Day;
hour = mdt.Hour;
minute = mdt.Minute;
second = mdt.Second;
millisecond = 0;
type = MySqlDbType.DateTime;
isNull = false;
}
/// <summary>
/// Enables the contruction of a <b>MySqlDateTime</b> object by parsing a string.
/// </summary>
public MySqlDateTime(string dateTime)
: this(MySqlDateTime.Parse(dateTime))
{
}
internal MySqlDateTime(MySqlDbType type, int year, int month, int day, int hour, int minute,
int second)
{
this.isNull = false;
this.type = type;
this.year = year;
this.month = month;
this.day = day;
this.hour = hour;
this.minute = minute;
this.second = second;
this.millisecond = 0;
}
internal MySqlDateTime(MySqlDbType type, bool isNull)
: this(type, 0, 0, 0, 0, 0, 0)
{
this.isNull = isNull;
}
internal MySqlDateTime(MySqlDbType type, DateTime val)
: this(type, 0, 0, 0, 0, 0, 0)
{
this.isNull = false;
year = val.Year;
month = val.Month;
day = val.Day;
hour = val.Hour;
minute = val.Minute;
second = val.Second;
millisecond = val.Millisecond;
}
#region Properties
/// <summary>
/// Indicates if this object contains a value that can be represented as a DateTime
/// </summary>
public bool IsValidDateTime
{
get
{
return year != 0 && month != 0 && day != 0;
}
}
/// <summary>Returns the year portion of this datetime</summary>
public int Year
{
get { return year; }
set { year = value; }
}
/// <summary>Returns the month portion of this datetime</summary>
public int Month
{
get { return month; }
set { month = value; }
}
/// <summary>Returns the day portion of this datetime</summary>
public int Day
{
get { return day; }
set { day = value; }
}
/// <summary>Returns the hour portion of this datetime</summary>
public int Hour
{
get { return hour; }
set { hour = value; }
}
/// <summary>Returns the minute portion of this datetime</summary>
public int Minute
{
get { return minute; }
set { minute = value; }
}
/// <summary>Returns the second portion of this datetime</summary>
public int Second
{
get { return second; }
set { second = value; }
}
/// <summary>
/// Retrieves the millisecond value of this object.
/// </summary>
public int Millisecond
{
get { return millisecond; }
set { millisecond = value; }
}
#endregion
#region IMySqlValue Members
/// <summary>
/// Returns true if this datetime object has a null value
/// </summary>
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return type; }
}
DbType IMySqlValue.DbType
{
get
{
if (type == MySqlDbType.Date || type == MySqlDbType.Newdate)
return DbType.Date;
return DbType.DateTime;
}
}
object IMySqlValue.Value
{
get { return GetDateTime(); }
}
/// <summary>
/// Retrieves the value of this <see cref="MySqlDateTime"/> as a DateTime object.
/// </summary>
public DateTime Value
{
get { return GetDateTime(); }
}
Type IMySqlValue.SystemType
{
get { return typeof(DateTime); }
}
string IMySqlValue.MySqlTypeName
{
get
{
switch (type)
{
case MySqlDbType.Date: return "DATE";
case MySqlDbType.Newdate: return "NEWDATE";
case MySqlDbType.Timestamp: return "TIMESTAMP";
}
return "DATETIME";
}
}
private void SerializeText(MySqlPacket packet, MySqlDateTime value)
{
string val = String.Empty;
if (type == MySqlDbType.Timestamp && !packet.Version.isAtLeast(4, 1, 0))
val = String.Format("{0:0000}{1:00}{2:00}{3:00}{4:00}{5:00}",
value.Year, value.Month, value.Day, value.Hour, value.Minute, value.Second);
else
{
val = String.Format("{0:0000}-{1:00}-{2:00}",
value.Year, value.Month, value.Day);
if (type != MySqlDbType.Date)
val = String.Format("{0} {1:00}:{2:00}:{3:00}", val,
value.Hour, value.Minute, value.Second);
}
packet.WriteStringNoNull("'" + val + "'");
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object value, int length)
{
MySqlDateTime dtValue;
string valueAsString = value as string;
if (value is DateTime)
dtValue = new MySqlDateTime(type, (DateTime)value);
else if (valueAsString != null)
dtValue = new MySqlDateTime(type, DateTime.Parse(valueAsString, CultureInfo.CurrentCulture));
else if (value is MySqlDateTime)
dtValue = (MySqlDateTime)value;
else
throw new MySqlException("Unable to serialize date/time value.");
if (!binary)
{
SerializeText(packet, dtValue);
return;
}
if (type == MySqlDbType.Timestamp)
packet.WriteByte(11);
else
packet.WriteByte(7);
packet.WriteInteger(dtValue.Year, 2);
packet.WriteByte((byte)dtValue.Month);
packet.WriteByte((byte)dtValue.Day);
if (type == MySqlDbType.Date)
{
packet.WriteByte(0);
packet.WriteByte(0);
packet.WriteByte(0);
}
else
{
packet.WriteByte((byte)dtValue.Hour);
packet.WriteByte((byte)dtValue.Minute);
packet.WriteByte((byte)dtValue.Second);
}
if (type == MySqlDbType.Timestamp)
packet.WriteInteger(dtValue.Millisecond, 4);
}
private MySqlDateTime Parse40Timestamp(string s)
{
int pos = 0;
year = month = day = 1;
hour = minute = second = 0;
if (s.Length == 14 || s.Length == 8)
{
year = int.Parse(s.Substring(pos, 4));
pos += 4;
}
else
{
year = int.Parse(s.Substring(pos, 2));
pos += 2;
if (year >= 70)
year += 1900;
else
year += 2000;
}
if (s.Length > 2)
{
month = int.Parse(s.Substring(pos, 2));
pos += 2;
}
if (s.Length > 4)
{
day = int.Parse(s.Substring(pos, 2));
pos += 2;
}
if (s.Length > 8)
{
hour = int.Parse(s.Substring(pos, 2));
minute = int.Parse(s.Substring(pos + 2, 2));
pos += 4;
}
if (s.Length > 10)
second = int.Parse(s.Substring(pos, 2));
return new MySqlDateTime(type, year, month, day, hour,
minute, second);
}
static internal MySqlDateTime Parse(string s)
{
MySqlDateTime dt = new MySqlDateTime();
return dt.ParseMySql(s, true);
}
static internal MySqlDateTime Parse(string s, Common.DBVersion version)
{
MySqlDateTime dt = new MySqlDateTime();
return dt.ParseMySql(s, version.isAtLeast(4, 1, 0));
}
private MySqlDateTime ParseMySql(string s, bool is41)
{
if (type == MySqlDbType.Timestamp && !is41)
return Parse40Timestamp(s);
string[] parts = s.Split('-', ' ', ':', '/');
int year = int.Parse(parts[0]);
int month = int.Parse(parts[1]);
int day = int.Parse(parts[2]);
int hour = 0, minute = 0, second = 0;
if (parts.Length > 3)
{
hour = int.Parse(parts[3]);
minute = int.Parse(parts[4]);
second = int.Parse(parts[5]);
}
return new MySqlDateTime(type, year, month, day, hour, minute, second);
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
if (nullVal) return new MySqlDateTime(type, true);
if (length >= 0)
{
string value = packet.ReadString(length);
return ParseMySql(value, packet.Version.isAtLeast(4, 1, 0));
}
long bufLength = packet.ReadByte();
int year = 0, month = 0, day = 0;
int hour = 0, minute = 0, second = 0;
if (bufLength >= 4)
{
year = packet.ReadInteger(2);
month = packet.ReadByte();
day = packet.ReadByte();
}
if (bufLength > 4)
{
hour = packet.ReadByte();
minute = packet.ReadByte();
second = packet.ReadByte();
}
if (bufLength > 7)
packet.ReadInteger(4);
return new MySqlDateTime(type, year, month, day, hour, minute, second);
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
int len = packet.ReadByte();
packet.Position += len;
}
#endregion
/// <summary>Returns this value as a DateTime</summary>
public DateTime GetDateTime()
{
if (!IsValidDateTime)
throw new MySqlConversionException("Unable to convert MySQL date/time value to System.DateTime");
return new DateTime(year, month, day, hour, minute, second);
}
private static string FormatDateCustom(string format, int monthVal, int dayVal, int yearVal)
{
format = format.Replace("MM", "{0:00}");
format = format.Replace("M", "{0}");
format = format.Replace("dd", "{1:00}");
format = format.Replace("d", "{1}");
format = format.Replace("yyyy", "{2:0000}");
format = format.Replace("yy", "{3:00}");
format = format.Replace("y", "{4:0}");
int year2digit = yearVal - ((yearVal / 1000) * 1000);
year2digit -= ((year2digit / 100) * 100);
int year1digit = year2digit - ((year2digit / 10) * 10);
return String.Format(format, monthVal, dayVal, yearVal, year2digit, year1digit);
}
/// <summary>Returns a MySQL specific string representation of this value</summary>
public override string ToString()
{
if (this.IsValidDateTime)
{
DateTime d = new DateTime(year, month, day, hour, minute, second);
return (type == MySqlDbType.Date) ? d.ToString("d") : d.ToString();
}
string dateString = FormatDateCustom(
CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern, month, day, year);
if (type == MySqlDbType.Date)
return dateString;
DateTime dt = new DateTime(1, 2, 3, hour, minute, second);
dateString = String.Format("{0} {1}", dateString, dt.ToLongTimeString());
return dateString;
}
/// <summary></summary>
/// <param name="val"></param>
/// <returns></returns>
public static explicit operator DateTime(MySqlDateTime val)
{
if (!val.IsValidDateTime) return DateTime.MinValue;
return val.GetDateTime();
}
internal static void SetDSInfo(DataTable dsTable)
{
string[] types = new string[] { "DATE", "DATETIME", "TIMESTAMP" };
MySqlDbType[] dbtype = new MySqlDbType[] { MySqlDbType.Date,
MySqlDbType.DateTime, MySqlDbType.Timestamp };
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
for (int x = 0; x < types.Length; x++)
{
DataRow row = dsTable.NewRow();
row["TypeName"] = types[x];
row["ProviderDbType"] = dbtype[x];
row["ColumnSize"] = 0;
row["CreateFormat"] = types[x];
row["CreateParameters"] = null;
row["DataType"] = "System.DateTime";
row["IsAutoincrementable"] = false;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = true;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = true;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = false;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = null;
row["LiteralSuffix"] = null;
row["NativeDataType"] = null;
dsTable.Rows.Add(row);
}
}
#region IConvertible Members
ulong IConvertible.ToUInt64(IFormatProvider provider)
{
return 0;
}
sbyte IConvertible.ToSByte(IFormatProvider provider)
{
// TODO: Add MySqlDateTime.ToSByte implementation
return 0;
}
double IConvertible.ToDouble(IFormatProvider provider)
{
return 0;
}
DateTime IConvertible.ToDateTime(IFormatProvider provider)
{
return this.GetDateTime();
}
float IConvertible.ToSingle(IFormatProvider provider)
{
return 0;
}
bool IConvertible.ToBoolean(IFormatProvider provider)
{
return false;
}
int IConvertible.ToInt32(IFormatProvider provider)
{
return 0;
}
ushort IConvertible.ToUInt16(IFormatProvider provider)
{
return 0;
}
short IConvertible.ToInt16(IFormatProvider provider)
{
return 0;
}
string System.IConvertible.ToString(IFormatProvider provider)
{
return null;
}
byte IConvertible.ToByte(IFormatProvider provider)
{
return 0;
}
char IConvertible.ToChar(IFormatProvider provider)
{
return '\0';
}
long IConvertible.ToInt64(IFormatProvider provider)
{
return 0;
}
System.TypeCode IConvertible.GetTypeCode()
{
return new System.TypeCode();
}
decimal IConvertible.ToDecimal(IFormatProvider provider)
{
return 0;
}
object IConvertible.ToType(Type conversionType, IFormatProvider provider)
{
return null;
}
uint IConvertible.ToUInt32(IFormatProvider provider)
{
return 0;
}
#endregion
#region IComparable Members
int IComparable.CompareTo(object obj)
{
MySqlDateTime otherDate = (MySqlDateTime)obj;
if (Year < otherDate.Year) return -1;
else if (Year > otherDate.Year) return 1;
if (Month < otherDate.Month) return -1;
else if (Month > otherDate.Month) return 1;
if (Day < otherDate.Day) return -1;
else if (Day > otherDate.Day) return 1;
if (Hour < otherDate.Hour) return -1;
else if (Hour > otherDate.Hour) return 1;
if (Minute < otherDate.Minute) return -1;
else if (Minute > otherDate.Minute) return 1;
if (Second < otherDate.Second) return -1;
else if (Second > otherDate.Second) return 1;
if (Millisecond < otherDate.Millisecond) return -1;
else if (Millisecond > otherDate.Millisecond) return 1;
return 0;
}
#endregion
}
}

@ -0,0 +1,173 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
using System.Globalization;
namespace MySql.Data.Types
{
public struct MySqlDecimal : IMySqlValue
{
private byte precision;
private byte scale;
private string mValue;
private bool isNull;
internal MySqlDecimal(bool isNull)
{
this.isNull = isNull;
mValue = null;
precision = scale = 0;
}
internal MySqlDecimal(string val)
{
this.isNull = false;
precision = scale = 0;
mValue = val;
}
#region IMySqlValue Members
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return MySqlDbType.Decimal; }
}
public byte Precision
{
get { return precision; }
set { precision = value; }
}
public byte Scale
{
get { return scale; }
set { scale = value; }
}
DbType IMySqlValue.DbType
{
get { return DbType.Decimal; }
}
object IMySqlValue.Value
{
get { return this.Value; }
}
public decimal Value
{
get { return Convert.ToDecimal(mValue, CultureInfo.InvariantCulture); }
}
public double ToDouble()
{
return Double.Parse(mValue);
}
public override string ToString()
{
return mValue;
}
Type IMySqlValue.SystemType
{
get { return typeof(decimal); }
}
string IMySqlValue.MySqlTypeName
{
get { return "DECIMAL"; }
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
{
decimal v = (val is decimal) ? (decimal)val : Convert.ToDecimal(val);
string valStr = v.ToString(CultureInfo.InvariantCulture);
if (binary)
packet.WriteLenString(valStr);
else
packet.WriteStringNoNull(valStr);
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
if (nullVal)
return new MySqlDecimal(true);
string s = String.Empty;
if (length == -1)
s = packet.ReadLenString();
else
s = packet.ReadString(length);
return new MySqlDecimal(s);
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
int len = packet.ReadFieldLength();
packet.Position += len;
}
#endregion
internal static void SetDSInfo(DataTable dsTable)
{
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
DataRow row = dsTable.NewRow();
row["TypeName"] = "DECIMAL";
row["ProviderDbType"] = MySqlDbType.NewDecimal;
row["ColumnSize"] = 0;
row["CreateFormat"] = "DECIMAL({0},{1})";
row["CreateParameters"] = "precision,scale";
row["DataType"] = "System.Decimal";
row["IsAutoincrementable"] = false;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = true;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = true;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = false;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = null;
row["LiteralSuffix"] = null;
row["NativeDataType"] = null;
dsTable.Rows.Add(row);
}
}
}

@ -0,0 +1,147 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
namespace MySql.Data.Types
{
internal struct MySqlDouble : IMySqlValue
{
private double mValue;
private bool isNull;
public MySqlDouble(bool isNull)
{
this.isNull = isNull;
mValue = 0.0;
}
public MySqlDouble(double val)
{
this.isNull = false;
mValue = val;
}
#region IMySqlValue Members
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return MySqlDbType.Double; }
}
DbType IMySqlValue.DbType
{
get { return DbType.Double; }
}
object IMySqlValue.Value
{
get { return mValue; }
}
public double Value
{
get { return mValue; }
}
Type IMySqlValue.SystemType
{
get { return typeof(double); }
}
string IMySqlValue.MySqlTypeName
{
get { return "DOUBLE"; }
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
{
double v = (val is double) ? (double)val : Convert.ToDouble(val);
if (binary)
packet.Write(BitConverter.GetBytes(v));
else
packet.WriteStringNoNull(v.ToString("R", CultureInfo.InvariantCulture));
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length,
bool nullVal)
{
if (nullVal)
return new MySqlDouble(true);
if (length == -1)
{
byte[] b = new byte[8];
packet.Read(b, 0, 8);
return new MySqlDouble(BitConverter.ToDouble(b, 0));
}
return new MySqlDouble(Double.Parse(packet.ReadString(length),
CultureInfo.InvariantCulture));
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
packet.Position += 8;
}
#endregion
internal static void SetDSInfo(DataTable dsTable)
{
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
DataRow row = dsTable.NewRow();
row["TypeName"] = "DOUBLE";
row["ProviderDbType"] = MySqlDbType.Double;
row["ColumnSize"] = 0;
row["CreateFormat"] = "DOUBLE";
row["CreateParameters"] = null;
row["DataType"] = "System.Double";
row["IsAutoincrementable"] = false;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = true;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = true;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = false;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = null;
row["LiteralSuffix"] = null;
row["NativeDataType"] = null;
dsTable.Rows.Add(row);
}
}
}

@ -0,0 +1,241 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
using MySql.Data.MySqlClient.Properties;
namespace MySql.Data.Types
{
internal struct MySqlGuid : IMySqlValue
{
Guid mValue;
private bool isNull;
private byte[] bytes;
private bool oldGuids;
public MySqlGuid(byte[] buff)
{
oldGuids = false;
mValue = new Guid(buff);
isNull = false;
bytes = buff;
}
public byte[] Bytes
{
get { return bytes; }
}
public bool OldGuids
{
get { return oldGuids; }
set { oldGuids = value; }
}
#region IMySqlValue Members
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return MySqlDbType.Guid; }
}
DbType IMySqlValue.DbType
{
get { return DbType.Guid; }
}
object IMySqlValue.Value
{
get { return mValue; }
}
public Guid Value
{
get { return mValue; }
}
Type IMySqlValue.SystemType
{
get { return typeof(Guid); }
}
string IMySqlValue.MySqlTypeName
{
get { return OldGuids ? "BINARY(16)" : "CHAR(36)"; }
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
{
Guid guid = Guid.Empty;
string valAsString = val as string;
byte[] valAsByte = val as byte[];
if (val is Guid)
guid = (Guid)val;
else
{
try
{
if (valAsString != null)
guid = new Guid(valAsString);
else if (valAsByte != null)
guid = new Guid(valAsByte);
}
catch (Exception ex)
{
throw new MySqlException(Resources.DataNotInSupportedFormat, ex);
}
}
if (OldGuids)
WriteOldGuid(packet, guid, binary);
else
{
guid.ToString("D");
if (binary)
packet.WriteLenString(guid.ToString("D"));
else
packet.WriteStringNoNull("'" + MySqlHelper.EscapeString(guid.ToString("D")) + "'");
}
}
private void WriteOldGuid(MySqlPacket packet, Guid guid, bool binary)
{
byte[] bytes = guid.ToByteArray();
if (binary)
{
packet.WriteLength(bytes.Length);
packet.Write(bytes);
}
else
{
if (packet.Version.isAtLeast(4, 1, 0))
packet.WriteStringNoNull("_binary ");
packet.WriteByte((byte)'\'');
EscapeByteArray(bytes, bytes.Length, packet);
packet.WriteByte((byte)'\'');
}
}
private static void EscapeByteArray(byte[] bytes, int length, MySqlPacket packet)
{
for (int x = 0; x < length; x++)
{
byte b = bytes[x];
if (b == '\0')
{
packet.WriteByte((byte)'\\');
packet.WriteByte((byte)'0');
}
else if (b == '\\' || b == '\'' || b == '\"')
{
packet.WriteByte((byte)'\\');
packet.WriteByte(b);
}
else
packet.WriteByte(b);
}
}
private MySqlGuid ReadOldGuid(MySqlPacket packet, long length)
{
if (length == -1)
length = (long)packet.ReadFieldLength();
byte[] buff = new byte[length];
packet.Read(buff, 0, (int)length);
MySqlGuid g = new MySqlGuid(buff);
g.OldGuids = OldGuids;
return g;
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
MySqlGuid g = new MySqlGuid();
g.isNull = true;
g.OldGuids = OldGuids;
if (!nullVal)
{
if (OldGuids)
return ReadOldGuid(packet, length);
string s = String.Empty;
if (length == -1)
s = packet.ReadLenString();
else
s = packet.ReadString(length);
g.mValue = new Guid(s);
g.isNull = false;
}
return g;
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
int len = packet.ReadFieldLength();
packet.Position += len;
}
#endregion
public static void SetDSInfo(DataTable dsTable)
{
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
DataRow row = dsTable.NewRow();
row["TypeName"] = "GUID";
row["ProviderDbType"] = MySqlDbType.Guid;
row["ColumnSize"] = 0;
row["CreateFormat"] = "BINARY(16)";
row["CreateParameters"] = null;
row["DataType"] = "System.Guid";
row["IsAutoincrementable"] = false;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = true;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = false;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = false;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = null;
row["LiteralSuffix"] = null;
row["NativeDataType"] = null;
dsTable.Rows.Add(row);
}
}
}

@ -0,0 +1,140 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
namespace MySql.Data.Types
{
internal struct MySqlInt16 : IMySqlValue
{
private short mValue;
private bool isNull;
public MySqlInt16(bool isNull)
{
this.isNull = isNull;
mValue = 0;
}
public MySqlInt16(short val)
{
this.isNull = false;
mValue = val;
}
#region IMySqlValue Members
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return MySqlDbType.Int16; }
}
DbType IMySqlValue.DbType
{
get { return DbType.Int16; }
}
object IMySqlValue.Value
{
get { return mValue; }
}
public short Value
{
get { return mValue; }
}
Type IMySqlValue.SystemType
{
get { return typeof(short); }
}
string IMySqlValue.MySqlTypeName
{
get { return "SMALLINT"; }
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
{
int v = (val is Int32) ? (int)val : Convert.ToInt32(val);
if (binary)
packet.WriteInteger((long)v, 2);
else
packet.WriteStringNoNull(v.ToString());
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
if (nullVal)
return new MySqlInt16(true);
if (length == -1)
return new MySqlInt16((short)packet.ReadInteger(2));
else
return new MySqlInt16(Int16.Parse(packet.ReadString(length)));
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
packet.Position += 2;
}
#endregion
internal static void SetDSInfo(DataTable dsTable)
{
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
DataRow row = dsTable.NewRow();
row["TypeName"] = "SMALLINT";
row["ProviderDbType"] = MySqlDbType.Int16;
row["ColumnSize"] = 0;
row["CreateFormat"] = "SMALLINT";
row["CreateParameters"] = null;
row["DataType"] = "System.Int16";
row["IsAutoincrementable"] = true;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = true;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = true;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = false;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = null;
row["LiteralSuffix"] = null;
row["NativeDataType"] = null;
dsTable.Rows.Add(row);
}
}
}

@ -0,0 +1,160 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
using System.Globalization;
namespace MySql.Data.Types
{
internal struct MySqlInt32 : IMySqlValue
{
private int mValue;
private bool isNull;
private bool is24Bit;
private MySqlInt32(MySqlDbType type)
{
is24Bit = type == MySqlDbType.Int24 ? true : false;
isNull = true;
mValue = 0;
}
public MySqlInt32(MySqlDbType type, bool isNull)
: this(type)
{
this.isNull = isNull;
}
public MySqlInt32(MySqlDbType type, int val)
: this(type)
{
this.isNull = false;
mValue = val;
}
#region IMySqlValue Members
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return MySqlDbType.Int32; }
}
DbType IMySqlValue.DbType
{
get { return DbType.Int32; }
}
object IMySqlValue.Value
{
get { return mValue; }
}
public int Value
{
get { return mValue; }
}
Type IMySqlValue.SystemType
{
get { return typeof(Int32); }
}
string IMySqlValue.MySqlTypeName
{
get { return is24Bit ? "MEDIUMINT" : "INT"; }
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
{
int v = (val is Int32) ? (int)val : Convert.ToInt32(val);
if (binary)
packet.WriteInteger((long)v, is24Bit ? 3 : 4);
else
packet.WriteStringNoNull(v.ToString());
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
if (nullVal)
return new MySqlInt32((this as IMySqlValue).MySqlDbType, true);
if (length == -1)
return new MySqlInt32((this as IMySqlValue).MySqlDbType,
packet.ReadInteger(4));
else
return new MySqlInt32((this as IMySqlValue).MySqlDbType,
Int32.Parse(packet.ReadString(length),
CultureInfo.InvariantCulture));
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
packet.Position += 4;
}
#endregion
internal static void SetDSInfo(DataTable dsTable)
{
string[] types = new string[] { "INT", "YEAR", "MEDIUMINT" };
MySqlDbType[] dbtype = new MySqlDbType[] { MySqlDbType.Int32,
MySqlDbType.Year, MySqlDbType.Int24 };
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
for (int x = 0; x < types.Length; x++)
{
DataRow row = dsTable.NewRow();
row["TypeName"] = types[x];
row["ProviderDbType"] = dbtype[x];
row["ColumnSize"] = 0;
row["CreateFormat"] = types[x];
row["CreateParameters"] = null;
row["DataType"] = "System.Int32";
row["IsAutoincrementable"] = dbtype[x] == MySqlDbType.Year ? false : true;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = true;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = true;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = false;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = null;
row["LiteralSuffix"] = null;
row["NativeDataType"] = null;
dsTable.Rows.Add(row);
}
}
}
}

@ -0,0 +1,140 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
namespace MySql.Data.Types
{
internal struct MySqlInt64 : IMySqlValue
{
private long mValue;
private bool isNull;
public MySqlInt64(bool isNull)
{
this.isNull = isNull;
mValue = 0;
}
public MySqlInt64(long val)
{
this.isNull = false;
mValue = val;
}
#region IMySqlValue Members
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return MySqlDbType.Int64; }
}
DbType IMySqlValue.DbType
{
get { return DbType.Int64; }
}
object IMySqlValue.Value
{
get { return mValue; }
}
public long Value
{
get { return mValue; }
}
Type IMySqlValue.SystemType
{
get { return typeof(long); }
}
string IMySqlValue.MySqlTypeName
{
get { return "BIGINT"; }
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
{
long v = (val is Int64) ? (Int64)val : Convert.ToInt64(val);
if (binary)
packet.WriteInteger(v, 8);
else
packet.WriteStringNoNull(v.ToString());
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
if (nullVal)
return new MySqlInt64(true);
if (length == -1)
return new MySqlInt64((long)packet.ReadULong(8));
else
return new MySqlInt64(Int64.Parse(packet.ReadString(length)));
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
packet.Position += 8;
}
#endregion
internal static void SetDSInfo(DataTable dsTable)
{
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
DataRow row = dsTable.NewRow();
row["TypeName"] = "BIGINT";
row["ProviderDbType"] = MySqlDbType.Int64;
row["ColumnSize"] = 0;
row["CreateFormat"] = "BIGINT";
row["CreateParameters"] = null;
row["DataType"] = "System.Int64";
row["IsAutoincrementable"] = true;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = true;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = true;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = false;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = null;
row["LiteralSuffix"] = null;
row["NativeDataType"] = null;
dsTable.Rows.Add(row);
}
}
}

@ -0,0 +1,146 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
using System.Globalization;
namespace MySql.Data.Types
{
internal struct MySqlSingle : IMySqlValue
{
private float mValue;
private bool isNull;
public MySqlSingle(bool isNull)
{
this.isNull = isNull;
mValue = 0.0f;
}
public MySqlSingle(float val)
{
this.isNull = false;
mValue = val;
}
#region IMySqlValue Members
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return MySqlDbType.Float; }
}
DbType IMySqlValue.DbType
{
get { return DbType.Single; }
}
object IMySqlValue.Value
{
get { return mValue; }
}
public float Value
{
get { return mValue; }
}
Type IMySqlValue.SystemType
{
get { return typeof(float); }
}
string IMySqlValue.MySqlTypeName
{
get { return "FLOAT"; }
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
{
Single v = (val is Single) ? (Single)val : Convert.ToSingle(val);
if (binary)
packet.Write(BitConverter.GetBytes(v));
else
packet.WriteStringNoNull(v.ToString("R",
CultureInfo.InvariantCulture));
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
if (nullVal)
return new MySqlSingle(true);
if (length == -1)
{
byte[] b = new byte[4];
packet.Read(b, 0, 4);
return new MySqlSingle(BitConverter.ToSingle(b, 0));
}
return new MySqlSingle(Single.Parse(packet.ReadString(length),
CultureInfo.InvariantCulture));
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
packet.Position += 4;
}
#endregion
internal static void SetDSInfo(DataTable dsTable)
{
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
DataRow row = dsTable.NewRow();
row["TypeName"] = "FLOAT";
row["ProviderDbType"] = MySqlDbType.Float;
row["ColumnSize"] = 0;
row["CreateFormat"] = "FLOAT";
row["CreateParameters"] = null;
row["DataType"] = "System.Single";
row["IsAutoincrementable"] = false;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = true;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = true;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = false;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = null;
row["LiteralSuffix"] = null;
row["NativeDataType"] = null;
dsTable.Rows.Add(row);
}
}
}

@ -0,0 +1,165 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.IO;
using MySql.Data.MySqlClient;
namespace MySql.Data.Types
{
internal struct MySqlString : IMySqlValue
{
private string mValue;
private bool isNull;
private MySqlDbType type;
public MySqlString(MySqlDbType type, bool isNull)
{
this.type = type;
this.isNull = isNull;
mValue = String.Empty;
}
public MySqlString(MySqlDbType type, string val)
{
this.type = type;
this.isNull = false;
mValue = val;
}
#region IMySqlValue Members
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return type; }
}
DbType IMySqlValue.DbType
{
get { return DbType.String; }
}
object IMySqlValue.Value
{
get { return mValue; }
}
public string Value
{
get { return mValue; }
}
Type IMySqlValue.SystemType
{
get { return typeof(string); }
}
string IMySqlValue.MySqlTypeName
{
get { return type == MySqlDbType.Set ? "SET" : type == MySqlDbType.Enum ? "ENUM" : "VARCHAR"; }
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
{
string v = val.ToString();
if (length > 0)
{
length = Math.Min(length, v.Length);
v = v.Substring(0, length);
}
if (binary)
packet.WriteLenString(v);
else
packet.WriteStringNoNull("'" + MySqlHelper.EscapeString(v) + "'");
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
if (nullVal)
return new MySqlString(type, true);
string s = String.Empty;
if (length == -1)
s = packet.ReadLenString();
else
s = packet.ReadString(length);
MySqlString str = new MySqlString(type, s);
return str;
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
int len = packet.ReadFieldLength();
packet.Position += len;
}
#endregion
internal static void SetDSInfo(DataTable dsTable)
{
string[] types = new string[] { "CHAR", "NCHAR", "VARCHAR", "NVARCHAR", "SET",
"ENUM", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT" };
MySqlDbType[] dbtype = new MySqlDbType[] { MySqlDbType.String, MySqlDbType.String,
MySqlDbType.VarChar, MySqlDbType.VarChar, MySqlDbType.Set, MySqlDbType.Enum,
MySqlDbType.TinyText, MySqlDbType.Text, MySqlDbType.MediumText,
MySqlDbType.LongText };
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
for (int x = 0; x < types.Length; x++)
{
DataRow row = dsTable.NewRow();
row["TypeName"] = types[x];
row["ProviderDbType"] = dbtype[x];
row["ColumnSize"] = 0;
row["CreateFormat"] = x < 4 ? types[x] + "({0})" : types[x];
row["CreateParameters"] = x < 4 ? "size" : null;
row["DataType"] = "System.String";
row["IsAutoincrementable"] = false;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = false;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = true;
row["IsSearchableWithLike"] = true;
row["IsUnsigned"] = false;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = null;
row["LiteralSuffix"] = null;
row["NativeDataType"] = null;
dsTable.Rows.Add(row);
}
}
}
}

@ -0,0 +1,206 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
namespace MySql.Data.Types
{
internal struct MySqlTimeSpan : IMySqlValue
{
private TimeSpan mValue;
private bool isNull;
public MySqlTimeSpan(bool isNull)
{
this.isNull = isNull;
mValue = TimeSpan.MinValue;
}
public MySqlTimeSpan(TimeSpan val)
{
this.isNull = false;
mValue = val;
}
#region IMySqlValue Members
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return MySqlDbType.Time; }
}
DbType IMySqlValue.DbType
{
get { return DbType.Time; }
}
object IMySqlValue.Value
{
get { return mValue; }
}
public TimeSpan Value
{
get { return mValue; }
}
Type IMySqlValue.SystemType
{
get { return typeof(TimeSpan); }
}
string IMySqlValue.MySqlTypeName
{
get { return "TIME"; }
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
{
if (!(val is TimeSpan))
throw new MySqlException("Only TimeSpan objects can be serialized by MySqlTimeSpan");
TimeSpan ts = (TimeSpan)val;
bool negative = ts.TotalMilliseconds < 0;
ts = ts.Duration();
if (binary)
{
packet.WriteByte(8);
packet.WriteByte((byte)(negative ? 1 : 0));
packet.WriteInteger(ts.Days, 4);
packet.WriteByte((byte)ts.Hours);
packet.WriteByte((byte)ts.Minutes);
packet.WriteByte((byte)ts.Seconds);
}
else
{
String s = String.Format("'{0}{1} {2:00}:{3:00}:{4:00}.{5}'",
negative ? "-" : "", ts.Days, ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
packet.WriteStringNoNull(s);
}
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
if (nullVal) return new MySqlTimeSpan(true);
if (length >= 0)
{
string value = packet.ReadString(length);
ParseMySql(value, packet.Version.isAtLeast(4, 1, 0));
return this;
}
long bufLength = packet.ReadByte();
int negate = 0;
if (bufLength > 0)
negate = packet.ReadByte();
isNull = false;
if (bufLength == 0)
isNull = true;
else if (bufLength == 5)
mValue = new TimeSpan(packet.ReadInteger(4), 0, 0, 0);
else if (bufLength == 8)
mValue = new TimeSpan(packet.ReadInteger(4),
packet.ReadByte(), packet.ReadByte(), packet.ReadByte());
else
mValue = new TimeSpan(packet.ReadInteger(4),
packet.ReadByte(), packet.ReadByte(), packet.ReadByte(),
packet.ReadInteger(4) / 1000000);
if (negate == 1)
mValue = mValue.Negate();
return this;
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
int len = packet.ReadByte();
packet.Position += len;
}
#endregion
internal static void SetDSInfo(DataTable dsTable)
{
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
DataRow row = dsTable.NewRow();
row["TypeName"] = "TIME";
row["ProviderDbType"] = MySqlDbType.Time;
row["ColumnSize"] = 0;
row["CreateFormat"] = "TIME";
row["CreateParameters"] = null;
row["DataType"] = "System.TimeSpan";
row["IsAutoincrementable"] = false;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = true;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = true;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = false;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = null;
row["LiteralSuffix"] = null;
row["NativeDataType"] = null;
dsTable.Rows.Add(row);
}
public override string ToString()
{
return String.Format("{0} {1:00}:{2:00}:{3:00}.{4}",
mValue.Days, mValue.Hours, mValue.Minutes, mValue.Seconds, mValue.Milliseconds);
}
private void ParseMySql(string s, bool is41)
{
string[] parts = s.Split(':');
int hours = Int32.Parse(parts[0]);
int mins = Int32.Parse(parts[1]);
int secs = Int32.Parse(parts[2]);
if (hours < 0 || parts[0].StartsWith("-"))
{
mins *= -1;
secs *= -1;
}
int days = hours / 24;
hours = hours - (days * 24);
mValue = new TimeSpan(days, hours, mins, secs, 0);
isNull = false;
}
}
}

@ -0,0 +1,140 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
namespace MySql.Data.Types
{
internal struct MySqlUByte : IMySqlValue
{
private byte mValue;
private bool isNull;
public MySqlUByte(bool isNull)
{
this.isNull = isNull;
mValue = 0;
}
public MySqlUByte(byte val)
{
this.isNull = false;
mValue = val;
}
#region IMySqlValue Members
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return MySqlDbType.UByte; }
}
DbType IMySqlValue.DbType
{
get { return DbType.Byte; }
}
object IMySqlValue.Value
{
get { return mValue; }
}
public byte Value
{
get { return mValue; }
}
Type IMySqlValue.SystemType
{
get { return typeof(byte); }
}
string IMySqlValue.MySqlTypeName
{
get { return "TINYINT"; }
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
{
byte v = (val is byte) ? (byte)val : Convert.ToByte(val);
if (binary)
packet.WriteByte(v);
else
packet.WriteStringNoNull(v.ToString());
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
if (nullVal)
return new MySqlUByte(true);
if (length == -1)
return new MySqlUByte((byte)packet.ReadByte());
else
return new MySqlUByte(Byte.Parse(packet.ReadString(length)));
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
packet.ReadByte();
}
#endregion
internal static void SetDSInfo(DataTable dsTable)
{
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
DataRow row = dsTable.NewRow();
row["TypeName"] = "TINY INT";
row["ProviderDbType"] = MySqlDbType.UByte;
row["ColumnSize"] = 0;
row["CreateFormat"] = "TINYINT UNSIGNED";
row["CreateParameters"] = null;
row["DataType"] = "System.Byte";
row["IsAutoincrementable"] = true;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = true;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = true;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = true;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = null;
row["LiteralSuffix"] = null;
row["NativeDataType"] = null;
dsTable.Rows.Add(row);
}
}
}

@ -0,0 +1,140 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
namespace MySql.Data.Types
{
internal struct MySqlUInt16 : IMySqlValue
{
private ushort mValue;
private bool isNull;
public MySqlUInt16(bool isNull)
{
this.isNull = isNull;
mValue = 0;
}
public MySqlUInt16(ushort val)
{
this.isNull = false;
mValue = val;
}
#region IMySqlValue Members
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return MySqlDbType.UInt16; }
}
DbType IMySqlValue.DbType
{
get { return DbType.UInt16; }
}
object IMySqlValue.Value
{
get { return mValue; }
}
public ushort Value
{
get { return mValue; }
}
Type IMySqlValue.SystemType
{
get { return typeof(ushort); }
}
string IMySqlValue.MySqlTypeName
{
get { return "SMALLINT"; }
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
{
int v = (val is UInt16) ? (UInt16)val : Convert.ToUInt16(val);
if (binary)
packet.WriteInteger((long)v, 2);
else
packet.WriteStringNoNull(v.ToString());
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
if (nullVal)
return new MySqlUInt16(true);
if (length == -1)
return new MySqlUInt16((ushort)packet.ReadInteger(2));
else
return new MySqlUInt16(UInt16.Parse(packet.ReadString(length)));
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
packet.Position += 2;
}
#endregion
internal static void SetDSInfo(DataTable dsTable)
{
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
DataRow row = dsTable.NewRow();
row["TypeName"] = "SMALLINT";
row["ProviderDbType"] = MySqlDbType.UInt16;
row["ColumnSize"] = 0;
row["CreateFormat"] = "SMALLINT UNSIGNED";
row["CreateParameters"] = null;
row["DataType"] = "System.UInt16";
row["IsAutoincrementable"] = true;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = true;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = true;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = true;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = null;
row["LiteralSuffix"] = null;
row["NativeDataType"] = null;
dsTable.Rows.Add(row);
}
}
}

@ -0,0 +1,159 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
using System.Globalization;
namespace MySql.Data.Types
{
internal struct MySqlUInt32 : IMySqlValue
{
private uint mValue;
private bool isNull;
private bool is24Bit;
private MySqlUInt32(MySqlDbType type)
{
is24Bit = type == MySqlDbType.Int24 ? true : false;
isNull = true;
mValue = 0;
}
public MySqlUInt32(MySqlDbType type, bool isNull)
: this(type)
{
this.isNull = isNull;
}
public MySqlUInt32(MySqlDbType type, uint val)
: this(type)
{
this.isNull = false;
mValue = val;
}
#region IMySqlValue Members
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return MySqlDbType.UInt32; }
}
DbType IMySqlValue.DbType
{
get { return DbType.UInt32; }
}
object IMySqlValue.Value
{
get { return mValue; }
}
public uint Value
{
get { return mValue; }
}
Type IMySqlValue.SystemType
{
get { return typeof(UInt32); }
}
string IMySqlValue.MySqlTypeName
{
get { return is24Bit ? "MEDIUMINT" : "INT"; }
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object v, int length)
{
uint val = (v is uint) ? (uint)v : Convert.ToUInt32(v);
if (binary)
packet.WriteInteger((long)val, is24Bit ? 3 : 4);
else
packet.WriteStringNoNull(val.ToString());
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
if (nullVal)
return new MySqlUInt32((this as IMySqlValue).MySqlDbType, true);
if (length == -1)
return new MySqlUInt32((this as IMySqlValue).MySqlDbType,
(uint)packet.ReadInteger(4));
else
return new MySqlUInt32((this as IMySqlValue).MySqlDbType,
UInt32.Parse(packet.ReadString(length), NumberStyles.Any, CultureInfo.InvariantCulture));
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
packet.Position += 4;
}
#endregion
internal static void SetDSInfo(DataTable dsTable)
{
string[] types = new string[] { "MEDIUMINT", "INT" };
MySqlDbType[] dbtype = new MySqlDbType[] { MySqlDbType.UInt24,
MySqlDbType.UInt32 };
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
for (int x = 0; x < types.Length; x++)
{
DataRow row = dsTable.NewRow();
row["TypeName"] = types[x];
row["ProviderDbType"] = dbtype[x];
row["ColumnSize"] = 0;
row["CreateFormat"] = types[x] + " UNSIGNED";
row["CreateParameters"] = null;
row["DataType"] = "System.UInt32";
row["IsAutoincrementable"] = true;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = true;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = true;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = true;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = null;
row["LiteralSuffix"] = null;
row["NativeDataType"] = null;
dsTable.Rows.Add(row);
}
}
}
}

@ -0,0 +1,140 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
namespace MySql.Data.Types
{
internal struct MySqlUInt64 : IMySqlValue
{
private ulong mValue;
private bool isNull;
public MySqlUInt64(bool isNull)
{
this.isNull = isNull;
mValue = 0;
}
public MySqlUInt64(ulong val)
{
this.isNull = false;
mValue = val;
}
#region IMySqlValue Members
public bool IsNull
{
get { return isNull; }
}
MySqlDbType IMySqlValue.MySqlDbType
{
get { return MySqlDbType.UInt64; }
}
DbType IMySqlValue.DbType
{
get { return DbType.UInt64; }
}
object IMySqlValue.Value
{
get { return mValue; }
}
public ulong Value
{
get { return mValue; }
}
Type IMySqlValue.SystemType
{
get { return typeof(ulong); }
}
string IMySqlValue.MySqlTypeName
{
get { return "BIGINT"; }
}
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length)
{
ulong v = (val is ulong) ? (ulong)val : Convert.ToUInt64(val);
if (binary)
packet.WriteInteger((long)v, 8);
else
packet.WriteStringNoNull(v.ToString());
}
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
{
if (nullVal)
return new MySqlUInt64(true);
if (length == -1)
return new MySqlUInt64(packet.ReadULong(8));
else
return new MySqlUInt64(UInt64.Parse(packet.ReadString(length)));
}
void IMySqlValue.SkipValue(MySqlPacket packet)
{
packet.Position += 8;
}
#endregion
internal static void SetDSInfo(DataTable dsTable)
{
// we use name indexing because this method will only be called
// when GetSchema is called for the DataSourceInformation
// collection and then it wil be cached.
DataRow row = dsTable.NewRow();
row["TypeName"] = "BIGINT";
row["ProviderDbType"] = MySqlDbType.UInt64;
row["ColumnSize"] = 0;
row["CreateFormat"] = "BIGINT UNSIGNED";
row["CreateParameters"] = null;
row["DataType"] = "System.UInt64";
row["IsAutoincrementable"] = true;
row["IsBestMatch"] = true;
row["IsCaseSensitive"] = false;
row["IsFixedLength"] = true;
row["IsFixedPrecisionScale"] = true;
row["IsLong"] = false;
row["IsNullable"] = true;
row["IsSearchable"] = true;
row["IsSearchableWithLike"] = false;
row["IsUnsigned"] = true;
row["MaximumScale"] = 0;
row["MinimumScale"] = 0;
row["IsConcurrencyType"] = DBNull.Value;
row["IsLiteralSupported"] = false;
row["LiteralPrefix"] = null;
row["LiteralSuffix"] = null;
row["NativeDataType"] = null;
dsTable.Rows.Add(row);
}
}
}

@ -0,0 +1,41 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
namespace MySql.Data.Types
{
internal interface IMySqlValue
{
bool IsNull { get; }
MySqlDbType MySqlDbType { get; }
DbType DbType { get; }
object Value { get; /*set;*/ }
Type SystemType { get; }
string MySqlTypeName { get; }
void WriteValue(MySqlPacket packet, bool binary, object value, int length);
IMySqlValue ReadValue(MySqlPacket packet, long length, bool isNull);
void SkipValue(MySqlPacket packet);
}
}

@ -0,0 +1,339 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Collections;
using System.ComponentModel;
using System.Text;
namespace MySql.Data.MySqlClient
{
public class DbConnectionStringBuilder : IDictionary, ICollection, IEnumerable, ICustomTypeDescriptor
{
private string connectionString;
private Hashtable hash;
private bool browsable;
public DbConnectionStringBuilder()
{
hash = new Hashtable(StringComparer.InvariantCultureIgnoreCase);
browsable = false;
}
#region Properties
public bool BrowsableConnectionString
{
get { return browsable; }
set { browsable = value; }
}
public string ConnectionString
{
get { return connectionString; }
set
{
Clear();
ParseConnectionString(value);
connectionString = value;
}
}
public virtual object this[string key]
{
get { return hash[key]; }
set { Add(key, value); }
}
#endregion
#region IDictionary Members
public void Add(object key, object value)
{
hash[key] = value;
//TODO: update connection string
}
public virtual void Clear()
{
connectionString = null;
hash.Clear();
}
public bool Contains(object key)
{
return hash.ContainsKey(key);
}
public IDictionaryEnumerator GetEnumerator()
{
return hash.GetEnumerator();
}
public bool IsFixedSize
{
get { return false; }
}
public bool IsReadOnly
{
get { return false; }
}
public ICollection Keys
{
get { return hash.Keys; }
}
public void Remove(object key)
{
hash.Remove(key);
//TODO: update connection string
}
public ICollection Values
{
get { return hash.Values; }
}
public object this[object key]
{
get
{
return this[(string)key];
}
set
{
this[(string)key] = value;
}
}
#endregion
#region ICollection Members
public void CopyTo(Array array, int index)
{
hash.CopyTo(array, index);
}
public int Count
{
get { return hash.Count; }
}
public bool IsSynchronized
{
get { return hash.IsSynchronized; }
}
public object SyncRoot
{
get { return hash.SyncRoot; }
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
return hash.GetEnumerator();
}
#endregion
#region ICustomTypeDescriptor Members
public AttributeCollection GetAttributes()
{
throw new Exception("The method or operation is not implemented.");
}
public string GetClassName()
{
throw new Exception("The method or operation is not implemented.");
}
public string GetComponentName()
{
throw new Exception("The method or operation is not implemented.");
}
public TypeConverter GetConverter()
{
throw new Exception("The method or operation is not implemented.");
}
public EventDescriptor GetDefaultEvent()
{
throw new Exception("The method or operation is not implemented.");
}
public PropertyDescriptor GetDefaultProperty()
{
throw new Exception("The method or operation is not implemented.");
}
public object GetEditor(Type editorBaseType)
{
throw new Exception("The method or operation is not implemented.");
}
public EventDescriptorCollection GetEvents(Attribute[] attributes)
{
throw new Exception("The method or operation is not implemented.");
}
public EventDescriptorCollection GetEvents()
{
throw new Exception("The method or operation is not implemented.");
}
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
throw new Exception("The method or operation is not implemented.");
}
public PropertyDescriptorCollection GetProperties()
{
throw new Exception("The method or operation is not implemented.");
}
public object GetPropertyOwner(PropertyDescriptor pd)
{
throw new Exception("The method or operation is not implemented.");
}
#endregion
public virtual object TryGetValue(string keyword, out object value)
{
if (!hash.ContainsKey(keyword))
{
value = null;
return false;
}
value = hash[keyword];
return true;
}
private void ParseConnectionString(string connectString)
{
if (connectString == null) return;
StringBuilder key = new StringBuilder();
StringBuilder value = new StringBuilder();
bool keyDone = false;
foreach (char c in connectString)
{
if (c == '=')
keyDone = true;
else if (c == ';')
{
string keyStr = key.ToString().Trim();
string valueStr = value.ToString().Trim();
valueStr = CleanValue(valueStr);
if (keyStr.Length > 0)
this[keyStr] = valueStr;
keyDone = false;
key.Remove(0, key.Length);
value.Remove(0, value.Length);
}
else if (keyDone)
value.Append(c);
else
key.Append(c);
}
if (key.Length == 0) return;
this[key.ToString().Trim()] = CleanValue(value.ToString().Trim());
}
private string CleanValue(string value)
{
if ((value.StartsWith("'") && value.EndsWith("'")) ||
(value.StartsWith("\"") && value.EndsWith("\"")))
{
value = value.Substring(1);
value = value.Substring(0, value.Length - 1);
}
return value;
}
/* private void ParseConnectionString(string value)
{
String[] keyvalues = src.Split(';');
String[] newkeyvalues = new String[keyvalues.Length];
int x = 0;
// first run through the array and check for any keys that
// have ; in their value
foreach (String keyvalue in keyvalues)
{
// check for trailing ; at the end of the connection string
if (keyvalue.Length == 0) continue;
// this value has an '=' sign so we are ok
if (keyvalue.IndexOf('=') >= 0)
{
newkeyvalues[x++] = keyvalue;
}
else
{
newkeyvalues[x - 1] += ";";
newkeyvalues[x - 1] += keyvalue;
}
}
Hashtable hash = new Hashtable();
// now we run through our normalized key-values, splitting on equals
for (int y = 0; y < x; y++)
{
String[] parts = newkeyvalues[y].Split('=');
// first trim off any space and lowercase the key
parts[0] = parts[0].Trim().ToLower();
parts[1] = parts[1].Trim();
// we also want to clear off any quotes
if (parts[1].Length >= 2)
{
if ((parts[1][0] == '"' && parts[1][parts[1].Length - 1] == '"') ||
(parts[1][0] == '\'' && parts[1][parts[1].Length - 1] == '\''))
{
parts[1] = parts[1].Substring(1, parts[1].Length - 2);
}
}
else
{
parts[1] = parts[1];
}
parts[0] = parts[0].Trim('\'', '"');
hash[parts[0]] = parts[1];
}
return hash;
}*/
}
}

@ -0,0 +1,60 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Runtime.InteropServices;
namespace MySql.Data.MySqlClient
{
public abstract class DbException : ExternalException
{
private int errorCode;
public DbException()
: base()
{
}
public DbException(string message) : base(message)
{
}
public DbException(string message, Exception innerException)
: base(message, innerException)
{
}
public DbException(string message, int errorCode)
: base(message)
{
this.errorCode = errorCode;
}
#region Properties
// public int ErrorCode
// {
// get { return errorCode; }
// }
#endregion
}
}

@ -0,0 +1,197 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
using MySql.Data.MySqlClient.Properties;
namespace MySql.Data.Common
{
internal class BufferedStream : Stream
{
private byte[] writeBuffer;
private byte[] readBuffer;
private int writePos;
private int readLength;
private int readPos;
private int bufferSize;
private Stream baseStream;
public BufferedStream(Stream stream)
{
baseStream = stream;
bufferSize = 4096;
readBuffer = new byte[bufferSize];
writeBuffer = new byte[bufferSize];
}
#region Stream Implementation
public override bool CanRead
{
get
{
if (baseStream != null) return baseStream.CanRead;
return false;
}
}
public override bool CanSeek
{
get
{
if (baseStream != null) return baseStream.CanSeek;
return false;
}
}
public override bool CanWrite
{
get
{
if (baseStream != null) return baseStream.CanWrite;
return false;
}
}
public override void Flush()
{
if (baseStream == null)
throw new InvalidOperationException(Resources.ObjectDisposed);
if (writePos == 0) return;
baseStream.Write(writeBuffer, 0, writePos);
baseStream.Flush();
writePos = 0;
}
public override long Length
{
get
{
if (baseStream == null)
throw new InvalidOperationException(Resources.ObjectDisposed);
Flush();
return baseStream.Length;
}
}
public override long Position
{
get
{
throw new Exception("The method or operation is not implemented.");
}
set
{
throw new Exception("The method or operation is not implemented.");
}
}
public override int Read(byte[] buffer, int offset, int count)
{
if (buffer == null)
throw new ArgumentNullException("buffer", Resources.ParameterCannotBeNull);
if (offset < 0)
throw new ArgumentOutOfRangeException("offset", Resources.OffsetCannotBeNegative);
if (count < 0)
throw new ArgumentOutOfRangeException("count", Resources.CountCannotBeNegative);
if ((buffer.Length - offset) < count)
throw new ArgumentException(Resources.OffsetMustBeValid);
if (baseStream == null)
throw new InvalidOperationException(Resources.ObjectDisposed);
if ((readLength - readPos) == 0)
{
TryToFillReadBuffer();
if (readLength == 0) return 0;
}
int inBuffer = readLength - readPos;
int toRead = count;
if (toRead > inBuffer)
toRead = inBuffer;
Buffer.BlockCopy(readBuffer, readPos, buffer, offset, toRead);
readPos += toRead;
count -= toRead;
if (count > 0)
{
int read = baseStream.Read(buffer, offset + toRead, count);
toRead += read;
readPos = readLength = 0;
}
return toRead;
}
private void TryToFillReadBuffer()
{
int read = baseStream.Read(readBuffer, 0, bufferSize);
readPos = 0;
readLength = read;
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new Exception("The method or operation is not implemented.");
}
public override void SetLength(long value)
{
throw new Exception("The method or operation is not implemented.");
}
public override void Write(byte[] buffer, int offset, int count)
{
if (buffer == null)
throw new ArgumentNullException("buffer", Resources.ParameterCannotBeNull);
if (offset < 0)
throw new ArgumentOutOfRangeException("offset", Resources.OffsetCannotBeNegative);
if (count < 0)
throw new ArgumentOutOfRangeException("count", Resources.CountCannotBeNegative);
if ((buffer.Length - offset) < count)
throw new ArgumentException(Resources.OffsetMustBeValid);
if (baseStream == null)
throw new InvalidOperationException(Resources.ObjectDisposed);
// if we don't have enough room in our current write buffer for the data
// then flush the data
int roomLeft = bufferSize - writePos;
if (count > roomLeft)
Flush();
// if the data will not fit into a entire buffer, then there is no need to buffer it.
// We just send it down
if (count > bufferSize)
baseStream.Write(buffer, offset, count);
else
{
// if we get here then there is room in our buffer for the data. We store it and
// adjust our internal lengths.
Buffer.BlockCopy(buffer, offset, writeBuffer, writePos, count);
writePos += count;
}
}
#endregion
}
}

@ -0,0 +1,70 @@
// Copyright (c) 2009 Sun Microsystems, Inc.
//
// 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;
namespace MySql.Data.MySqlClient
{
#if CF
class CategoryAttribute : Attribute
{
public CategoryAttribute(string cat) { }
}
class DescriptionAttribute : Attribute
{
public DescriptionAttribute(string desc) { }
}
class DisplayNameAttribute : Attribute
{
private string displayName;
public DisplayNameAttribute(string name)
{
displayName = name;
}
public string DisplayName
{
get { return displayName; }
}
}
class RefreshPropertiesAttribute : Attribute
{
public RefreshPropertiesAttribute(RefreshProperties prop) { }
}
class PasswordPropertyTextAttribute : Attribute
{
public PasswordPropertyTextAttribute(bool v) { }
}
public enum RefreshProperties
{
None = 0,
All = 1,
Repaint = 2,
}
#endif
}

@ -0,0 +1,34 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Runtime.InteropServices;
namespace MySql.Data.Common
{
/// <summary>
/// Summary description for Win32.
/// </summary>
internal class WinCE
{
[DllImport("coredll", SetLastError=true)]
internal static extern Int32 WaitForSingleObject(IntPtr handle, Int32 milliseconds);
}
}

@ -0,0 +1,917 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Data.Common;
using System.IO;
using System.Collections;
using System.Text;
using MySql.Data.Common;
using System.ComponentModel;
using System.Threading;
using System.Diagnostics;
using System.Globalization;
using System.Collections.Generic;
using MySql.Data.MySqlClient.Properties;
#if !CF
using System.Transactions;
#endif
namespace MySql.Data.MySqlClient
{
/// <include file='docs/mysqlcommand.xml' path='docs/ClassSummary/*'/>
#if !CF
[System.Drawing.ToolboxBitmap(typeof(MySqlCommand), "MySqlClient.resources.command.bmp")]
[System.ComponentModel.DesignerCategory("Code")]
#endif
public sealed class MySqlCommand : DbCommand, ICloneable
{
MySqlConnection connection;
MySqlTransaction curTransaction;
string cmdText;
CommandType cmdType;
long updatedRowCount;
UpdateRowSource updatedRowSource;
MySqlParameterCollection parameters;
private IAsyncResult asyncResult;
private bool designTimeVisible;
internal Int64 lastInsertedId;
private PreparableStatement statement;
private int commandTimeout;
private bool resetSqlSelect;
List<MySqlCommand> batch;
private string batchableCommandText;
CommandTimer commandTimer;
/// <include file='docs/mysqlcommand.xml' path='docs/ctor1/*'/>
public MySqlCommand()
{
designTimeVisible = true;
cmdType = CommandType.Text;
parameters = new MySqlParameterCollection(this);
updatedRowSource = UpdateRowSource.Both;
cmdText = String.Empty;
}
/// <include file='docs/mysqlcommand.xml' path='docs/ctor2/*'/>
public MySqlCommand(string cmdText)
: this()
{
CommandText = cmdText;
}
/// <include file='docs/mysqlcommand.xml' path='docs/ctor3/*'/>
public MySqlCommand(string cmdText, MySqlConnection connection)
: this(cmdText)
{
Connection = connection;
}
/// <include file='docs/mysqlcommand.xml' path='docs/ctor4/*'/>
public MySqlCommand(string cmdText, MySqlConnection connection,
MySqlTransaction transaction)
:
this(cmdText, connection)
{
curTransaction = transaction;
}
#region Properties
/// <include file='docs/mysqlcommand.xml' path='docs/LastInseredId/*'/>
#if !CF
[Browsable(false)]
#endif
public Int64 LastInsertedId
{
get { return lastInsertedId; }
}
/// <include file='docs/mysqlcommand.xml' path='docs/CommandText/*'/>
#if !CF
[Category("Data")]
[Description("Command text to execute")]
[Editor("MySql.Data.Common.Design.SqlCommandTextEditor,MySqlClient.Design", typeof(System.Drawing.Design.UITypeEditor))]
#endif
public override string CommandText
{
get { return cmdText; }
set
{
cmdText = value;
statement = null;
batchableCommandText = null;
if (cmdText != null && cmdText.EndsWith("DEFAULT VALUES"))
{
cmdText = cmdText.Substring(0, cmdText.Length - 14);
cmdText = cmdText + "() VALUES ()";
}
}
}
/// <include file='docs/mysqlcommand.xml' path='docs/CommandTimeout/*'/>
#if !CF
[Category("Misc")]
[Description("Time to wait for command to execute")]
[DefaultValue(30)]
#endif
public override int CommandTimeout
{
get { return commandTimeout == 0 ? 30 : commandTimeout; }
set
{
if (commandTimeout < 0)
throw new ArgumentException("Command timeout must not be negative");
// Timeout in milliseconds should not exceed maximum for 32 bit
// signed integer (~24 days), because underlying driver (and streams)
// use milliseconds expressed ints for timeout values.
// Hence, truncate the value.
int timeout = Math.Min(value, Int32.MaxValue / 1000);
if (timeout != value)
{
MySqlTrace.LogWarning(connection.ServerThread,
"Command timeout value too large ("
+ value + " seconds). Changed to max. possible value ("
+ timeout + " seconds)");
}
commandTimeout = timeout;
}
}
/// <include file='docs/mysqlcommand.xml' path='docs/CommandType/*'/>
#if !CF
[Category("Data")]
#endif
public override CommandType CommandType
{
get { return cmdType; }
set { cmdType = value; }
}
/// <include file='docs/mysqlcommand.xml' path='docs/IsPrepared/*'/>
#if !CF
[Browsable(false)]
#endif
public bool IsPrepared
{
get { return statement != null && statement.IsPrepared; }
}
/// <include file='docs/mysqlcommand.xml' path='docs/Connection/*'/>
#if !CF
[Category("Behavior")]
[Description("Connection used by the command")]
#endif
public new MySqlConnection Connection
{
get { return connection; }
set
{
/*
* The connection is associated with the transaction
* so set the transaction object to return a null reference if the connection
* is reset.
*/
if (connection != value)
Transaction = null;
connection = value;
// if the user has not already set the command timeout, then
// take the default from the connection
if (connection != null && commandTimeout == 0)
commandTimeout = (int)connection.Settings.DefaultCommandTimeout;
}
}
/// <include file='docs/mysqlcommand.xml' path='docs/Parameters/*'/>
#if !CF
[Category("Data")]
[Description("The parameters collection")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
#endif
public new MySqlParameterCollection Parameters
{
get { return parameters; }
}
/// <include file='docs/mysqlcommand.xml' path='docs/Transaction/*'/>
#if !CF
[Browsable(false)]
#endif
public new MySqlTransaction Transaction
{
get { return curTransaction; }
set { curTransaction = value; }
}
/* /// <include file='docs/mysqlcommand.xml' path='docs/UpdatedRowSource/*'/>
#if !CF
[Category("Behavior")]
#endif
public override UpdateRowSource UpdatedRowSource
{
get { return updatedRowSource; }
set { updatedRowSource = value; }
}*/
internal List<MySqlCommand> Batch
{
get { return batch; }
}
internal string BatchableCommandText
{
get { return batchableCommandText; }
}
#endregion
#region Methods
/// <summary>
/// Attempts to cancel the execution of a currently active command
/// </summary>
/// <remarks>
/// Cancelling a currently active query only works with MySQL versions 5.0.0 and higher.
/// </remarks>
public override void Cancel()
{
connection.CancelQuery(connection.ConnectionTimeout);
}
/// <summary>
/// Creates a new instance of a <see cref="MySqlParameter"/> object.
/// </summary>
/// <remarks>
/// This method is a strongly-typed version of <see cref="IDbCommand.CreateParameter"/>.
/// </remarks>
/// <returns>A <see cref="MySqlParameter"/> object.</returns>
///
public new MySqlParameter CreateParameter()
{
return (MySqlParameter)CreateDbParameter();
}
/// <summary>
/// Check the connection to make sure
/// - it is open
/// - it is not currently being used by a reader
/// - and we have the right version of MySQL for the requested command type
/// </summary>
private void CheckState()
{
// There must be a valid and open connection.
if (connection == null)
throw new InvalidOperationException("Connection must be valid and open.");
if (connection.State != ConnectionState.Open && !connection.SoftClosed)
throw new InvalidOperationException("Connection must be valid and open.");
// Data readers have to be closed first
if (connection.Reader != null)
throw new MySqlException("There is already an open DataReader associated with this Connection which must be closed first.");
if (CommandType == CommandType.StoredProcedure && !connection.driver.Version.isAtLeast(5, 0, 0))
throw new MySqlException("Stored procedures are not supported on this version of MySQL");
}
/// <include file='docs/mysqlcommand.xml' path='docs/ExecuteNonQuery/*'/>
public override int ExecuteNonQuery()
{
MySqlDataReader reader = null;
using (reader = ExecuteReader())
{
}
return reader.RecordsAffected;
}
internal void ClearCommandTimer()
{
if (commandTimer != null)
{
commandTimer.Dispose();
commandTimer = null;
}
}
internal void Close(MySqlDataReader reader)
{
if (statement != null)
statement.Close(reader);
ResetSqlSelectLimit();
connection.driver.CloseQuery(connection, statement.StatementId);
ClearCommandTimer();
}
/// <summary>
/// Reset SQL_SELECT_LIMIT that could have been modified by CommandBehavior.
/// </summary>
internal void ResetSqlSelectLimit()
{
// if we are supposed to reset the sql select limit, do that here
if (resetSqlSelect)
{
resetSqlSelect = false;
new MySqlCommand("SET SQL_SELECT_LIMIT=-1", connection).ExecuteNonQuery();
}
}
/// <include file='docs/mysqlcommand.xml' path='docs/ExecuteReader/*'/>
public new MySqlDataReader ExecuteReader()
{
return ExecuteReader(CommandBehavior.Default);
}
/// <include file='docs/mysqlcommand.xml' path='docs/ExecuteReader1/*'/>
public new MySqlDataReader ExecuteReader (CommandBehavior behavior)
{
CheckState();
Driver driver = connection.driver;
lock (driver)
{
// We have to recheck that there is no reader, after we got the lock
if (connection.Reader != null)
{
throw new MySqlException(Resources.DataReaderOpen);
}
#if !CF
System.Transactions.Transaction curTrans = System.Transactions.Transaction.Current;
if (curTrans != null)
{
TransactionStatus status = TransactionStatus.InDoubt;
try
{
// in some cases (during state transitions) this throws
// an exception. Ignore exceptions, we're only interested
// whether transaction was aborted or not.
status = curTrans.TransactionInformation.Status;
}
catch(TransactionException)
{
}
if (status == TransactionStatus.Aborted)
throw new TransactionAbortedException();
}
#endif
commandTimer = new CommandTimer(connection, CommandTimeout);
lastInsertedId = -1;
if (cmdText == null ||
cmdText.Trim().Length == 0)
throw new InvalidOperationException(Resources.CommandTextNotInitialized);
string sql = TrimSemicolons(cmdText);
if (CommandType == CommandType.TableDirect)
sql = "SELECT * FROM " + sql;
// now we check to see if we are executing a query that is buggy
// in 4.1
connection.driver.IsExecutingBuggyQuery = false;
if (!connection.driver.Version.isAtLeast(5, 0, 0) &&
connection.driver.Version.isAtLeast(4, 1, 0))
{
string snippet = sql;
if (snippet.Length > 17)
snippet = sql.Substring(0, 17);
snippet = snippet.ToUpper(CultureInfo.InvariantCulture);
connection.driver.IsExecutingBuggyQuery =
snippet.StartsWith("DESCRIBE") ||
snippet.StartsWith("SHOW TABLE STATUS");
}
if (statement == null || !statement.IsPrepared)
{
if (CommandType == CommandType.StoredProcedure)
statement = new StoredProcedure(this, sql);
else
statement = new PreparableStatement(this, sql);
}
// stored procs are the only statement type that need do anything during resolve
statement.Resolve(false);
// Now that we have completed our resolve step, we can handle our
// command behaviors
HandleCommandBehaviors(behavior);
updatedRowCount = -1;
try
{
MySqlDataReader reader = new MySqlDataReader(this, statement, behavior);
connection.Reader = reader;
// execute the statement
statement.Execute();
// wait for data to return
reader.NextResult();
return reader;
}
catch (TimeoutException tex)
{
connection.HandleTimeout(tex);
return null;
}
catch (MySqlException ex)
{
connection.Reader = null;
if (ex.InnerException is TimeoutException)
throw ex; // already handled
try
{
ResetSqlSelectLimit();
}
catch (Exception ex2)
{
// Reset SqlLimit did not work, connection is hosed.
Connection.Abort();
throw new MySqlException(ex.Message, true, ex);
}
// if we caught an exception because of a cancel, then just return null
if (ex.Number == 1317)
return null;
if (ex.IsFatal)
Connection.Close();
if (ex.Number == 0)
throw new MySqlException(Resources.FatalErrorDuringExecute, ex);
throw;
}
finally
{
if (connection != null && connection.Reader == null)
{
// Comething want seriously wrong, and reader would not be
// able to clear timeout on closing.
// So we clear timeout here.
ClearCommandTimer();
}
}
}
}
/// <include file='docs/mysqlcommand.xml' path='docs/ExecuteScalar/*'/>
public override object ExecuteScalar()
{
lastInsertedId = -1;
object val = null;
using (MySqlDataReader reader = ExecuteReader())
{
if (reader == null) return null;
if (reader.Read())
val = reader.GetValue(0);
}
return val;
}
private void HandleCommandBehaviors(CommandBehavior behavior)
{
if ((behavior & CommandBehavior.SchemaOnly) != 0)
{
new MySqlCommand("SET SQL_SELECT_LIMIT=0", connection).ExecuteNonQuery();
resetSqlSelect = true;
}
else if ((behavior & CommandBehavior.SingleRow) != 0)
{
new MySqlCommand("SET SQL_SELECT_LIMIT=1", connection).ExecuteNonQuery();
resetSqlSelect = true;
}
}
/// <include file='docs/mysqlcommand.xml' path='docs/Prepare2/*'/>
private void Prepare(int cursorPageSize)
{
if (!connection.driver.Version.isAtLeast(5, 0, 0) && cursorPageSize > 0)
throw new InvalidOperationException("Nested commands are only supported on MySQL 5.0 and later");
using (new CommandTimer(Connection, CommandTimeout))
{
// if the length of the command text is zero, then just return
string psSQL = CommandText;
if (psSQL == null ||
psSQL.Trim().Length == 0)
return;
if (CommandType == CommandType.StoredProcedure)
statement = new StoredProcedure(this, CommandText);
else
statement = new PreparableStatement(this, CommandText);
statement.Resolve(true);
statement.Prepare();
}
}
/// <include file='docs/mysqlcommand.xml' path='docs/Prepare/*'/>
public override void Prepare()
{
if (connection == null)
throw new InvalidOperationException("The connection property has not been set.");
if (connection.State != ConnectionState.Open)
throw new InvalidOperationException("The connection is not open.");
if (connection.Settings.IgnorePrepare)
return;
Prepare(0);
}
#endregion
#region Async Methods
internal delegate object AsyncDelegate(int type, CommandBehavior behavior);
internal AsyncDelegate caller = null;
internal Exception thrownException;
private static string TrimSemicolons(string sql)
{
int start = 0;
while (sql[start] == ';')
start++;
int end = sql.Length - 1;
while (sql[end] == ';')
end--;
return sql.Substring(start, end-start+1);
}
internal object AsyncExecuteWrapper(int type, CommandBehavior behavior)
{
thrownException = null;
try
{
if (type == 1)
return ExecuteReader(behavior);
return ExecuteNonQuery();
}
catch (Exception ex)
{
thrownException = ex;
}
return null;
}
/// <summary>
/// Initiates the asynchronous execution of the SQL statement or stored procedure
/// that is described by this <see cref="MySqlCommand"/>, and retrieves one or more
/// result sets from the server.
/// </summary>
/// <returns>An <see cref="IAsyncResult"/> that can be used to poll, wait for results,
/// or both; this value is also needed when invoking EndExecuteReader,
/// which returns a <see cref="MySqlDataReader"/> instance that can be used to retrieve
/// the returned rows. </returns>
public IAsyncResult BeginExecuteReader()
{
return BeginExecuteReader(CommandBehavior.Default);
}
/// <summary>
/// Initiates the asynchronous execution of the SQL statement or stored procedure
/// that is described by this <see cref="MySqlCommand"/> using one of the
/// <b>CommandBehavior</b> values.
/// </summary>
/// <param name="behavior">One of the <see cref="CommandBehavior"/> values, indicating
/// options for statement execution and data retrieval.</param>
/// <returns>An <see cref="IAsyncResult"/> that can be used to poll, wait for results,
/// or both; this value is also needed when invoking EndExecuteReader,
/// which returns a <see cref="MySqlDataReader"/> instance that can be used to retrieve
/// the returned rows. </returns>
public IAsyncResult BeginExecuteReader(CommandBehavior behavior)
{
if (caller != null)
throw new MySqlException(Resources.UnableToStartSecondAsyncOp);
caller = new AsyncDelegate(AsyncExecuteWrapper);
asyncResult = caller.BeginInvoke(1, behavior, null, null);
return asyncResult;
}
/// <summary>
/// Finishes asynchronous execution of a SQL statement, returning the requested
/// <see cref="MySqlDataReader"/>.
/// </summary>
/// <param name="result">The <see cref="IAsyncResult"/> returned by the call to
/// <see cref="BeginExecuteReader()"/>.</param>
/// <returns>A <b>MySqlDataReader</b> object that can be used to retrieve the requested rows. </returns>
public MySqlDataReader EndExecuteReader(IAsyncResult result)
{
result.AsyncWaitHandle.WaitOne();
AsyncDelegate c = caller;
caller = null;
if (thrownException != null)
throw thrownException;
return (MySqlDataReader)c.EndInvoke(result);
}
/// <summary>
/// Initiates the asynchronous execution of the SQL statement or stored procedure
/// that is described by this <see cref="MySqlCommand"/>.
/// </summary>
/// <param name="callback">
/// An <see cref="AsyncCallback"/> delegate that is invoked when the command's
/// execution has completed. Pass a null reference (<b>Nothing</b> in Visual Basic)
/// to indicate that no callback is required.</param>
/// <param name="stateObject">A user-defined state object that is passed to the
/// callback procedure. Retrieve this object from within the callback procedure
/// using the <see cref="IAsyncResult.AsyncState"/> property.</param>
/// <returns>An <see cref="IAsyncResult"/> that can be used to poll or wait for results,
/// or both; this value is also needed when invoking <see cref="EndExecuteNonQuery"/>,
/// which returns the number of affected rows. </returns>
public IAsyncResult BeginExecuteNonQuery(AsyncCallback callback, object stateObject)
{
if (caller != null)
throw new MySqlException(Resources.UnableToStartSecondAsyncOp);
caller = new AsyncDelegate(AsyncExecuteWrapper);
asyncResult = caller.BeginInvoke(2, CommandBehavior.Default,
callback, stateObject);
return asyncResult;
}
/// <summary>
/// Initiates the asynchronous execution of the SQL statement or stored procedure
/// that is described by this <see cref="MySqlCommand"/>.
/// </summary>
/// <returns>An <see cref="IAsyncResult"/> that can be used to poll or wait for results,
/// or both; this value is also needed when invoking <see cref="EndExecuteNonQuery"/>,
/// which returns the number of affected rows. </returns>
public IAsyncResult BeginExecuteNonQuery()
{
if (caller != null)
throw new MySqlException(Resources.UnableToStartSecondAsyncOp);
caller = new AsyncDelegate(AsyncExecuteWrapper);
asyncResult = caller.BeginInvoke(2, CommandBehavior.Default, null, null);
return asyncResult;
}
/// <summary>
/// Finishes asynchronous execution of a SQL statement.
/// </summary>
/// <param name="asyncResult">The <see cref="IAsyncResult"/> returned by the call
/// to <see cref="BeginExecuteNonQuery()"/>.</param>
/// <returns></returns>
public int EndExecuteNonQuery(IAsyncResult asyncResult)
{
asyncResult.AsyncWaitHandle.WaitOne();
AsyncDelegate c = caller;
caller = null;
if (thrownException != null)
throw thrownException;
return (int)c.EndInvoke(asyncResult);
}
#endregion
#region Private Methods
/* private ArrayList PrepareSqlBuffers(string sql)
{
ArrayList buffers = new ArrayList();
MySqlStreamWriter writer = new MySqlStreamWriter(new MemoryStream(), connection.Encoding);
writer.Version = connection.driver.Version;
// if we are executing as a stored procedure, then we need to add the call
// keyword.
if (CommandType == CommandType.StoredProcedure)
{
if (storedProcedure == null)
storedProcedure = new StoredProcedure(this);
sql = storedProcedure.Prepare( CommandText );
}
// tokenize the SQL
sql = sql.TrimStart(';').TrimEnd(';');
ArrayList tokens = TokenizeSql( sql );
foreach (string token in tokens)
{
if (token.Trim().Length == 0) continue;
if (token == ";" && ! connection.driver.SupportsBatch)
{
MemoryStream ms = (MemoryStream)writer.Stream;
if (ms.Length > 0)
buffers.Add( ms );
writer = new MySqlStreamWriter(new MemoryStream(), connection.Encoding);
writer.Version = connection.driver.Version;
continue;
}
else if (token[0] == parameters.ParameterMarker)
{
if (SerializeParameter(writer, token)) continue;
}
// our fall through case is to write the token to the byte stream
writer.WriteStringNoNull(token);
}
// capture any buffer that is left over
MemoryStream mStream = (MemoryStream)writer.Stream;
if (mStream.Length > 0)
buffers.Add( mStream );
return buffers;
}*/
internal long EstimatedSize()
{
long size = CommandText.Length;
foreach (MySqlParameter parameter in Parameters)
size += parameter.EstimatedSize();
return size;
}
#endregion
#region ICloneable
/// <summary>
/// Creates a clone of this MySqlCommand object. CommandText, Connection, and Transaction properties
/// are included as well as the entire parameter list.
/// </summary>
/// <returns>The cloned MySqlCommand object</returns>
public MySqlCommand Clone()
{
MySqlCommand clone = new MySqlCommand(cmdText, connection, curTransaction);
clone.CommandType = CommandType;
clone.CommandTimeout = CommandTimeout;
clone.batchableCommandText = batchableCommandText;
clone.UpdatedRowSource = UpdatedRowSource;
foreach (MySqlParameter p in parameters)
{
clone.Parameters.Add(p.Clone());
}
return clone;
}
object ICloneable.Clone()
{
return this.Clone();
}
#endregion
#region Batching support
internal void AddToBatch(MySqlCommand command)
{
if (batch == null)
batch = new List<MySqlCommand>();
batch.Add(command);
}
internal string GetCommandTextForBatching()
{
if (batchableCommandText == null)
{
// if the command starts with insert and is "simple" enough, then
// we can use the multi-value form of insert
if (String.Compare(CommandText.Substring(0, 6), "INSERT", true) == 0)
{
MySqlCommand cmd = new MySqlCommand("SELECT @@sql_mode", Connection);
string sql_mode = cmd.ExecuteScalar().ToString().ToUpper(CultureInfo.InvariantCulture);
MySqlTokenizer tokenizer = new MySqlTokenizer(CommandText);
tokenizer.AnsiQuotes = sql_mode.IndexOf("ANSI_QUOTES") != -1;
tokenizer.BackslashEscapes = sql_mode.IndexOf("NO_BACKSLASH_ESCAPES") == -1;
string token = tokenizer.NextToken().ToLower(CultureInfo.InvariantCulture);
while (token != null)
{
if (token.ToUpper(CultureInfo.InvariantCulture) == "VALUES" &&
!tokenizer.Quoted)
{
token = tokenizer.NextToken();
Debug.Assert(token == "(");
while (token != null && token != ")")
{
batchableCommandText += token;
token = tokenizer.NextToken();
}
if (token != null)
batchableCommandText += token;
token = tokenizer.NextToken();
if (token != null && (token == "," ||
token.ToUpper(CultureInfo.InvariantCulture) == "ON"))
{
batchableCommandText = null;
break;
}
}
token = tokenizer.NextToken();
}
}
}
return batchableCommandText;
}
#endregion
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (statement != null && statement.IsPrepared)
statement.CloseStatement();
}
base.Dispose(disposing);
}
/// <summary>
/// Gets or sets a value indicating whether the command object should be visible in a Windows Form Designer control.
/// </summary>
#if !CF
[Browsable(false)]
#endif
public override bool DesignTimeVisible
{
get
{
return designTimeVisible;
}
set
{
designTimeVisible = value;
}
}
/// <summary>
/// Gets or sets how command results are applied to the DataRow when used by the
/// Update method of the DbDataAdapter.
/// </summary>
public override UpdateRowSource UpdatedRowSource
{
get
{
return updatedRowSource;
}
set
{
updatedRowSource = value;
}
}
protected override DbParameter CreateDbParameter()
{
return new MySqlParameter();
}
protected override DbConnection DbConnection
{
get { return Connection; }
set { Connection = (MySqlConnection)value; }
}
protected override DbParameterCollection DbParameterCollection
{
get { return Parameters; }
}
protected override DbTransaction DbTransaction
{
get { return Transaction; }
set { Transaction = (MySqlTransaction)value; }
}
protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
{
return ExecuteReader(behavior);
}
}
}

@ -0,0 +1,76 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Collections.Generic;
namespace MySql.Data.Common
{
internal class Cache<KeyType, ValueType>
{
private int _capacity;
private Queue<KeyType> _keyQ;
private Dictionary<KeyType, ValueType> _contents;
public Cache(int initialCapacity, int capacity)
{
_capacity = capacity;
_contents = new Dictionary<KeyType, ValueType>(initialCapacity);
if (capacity > 0)
_keyQ = new Queue<KeyType>(initialCapacity);
}
public ValueType this[KeyType key]
{
get
{
ValueType val;
if (_contents.TryGetValue(key, out val))
return val;
else
return default(ValueType);
}
set { InternalAdd(key, value); }
}
public void Add(KeyType key, ValueType value)
{
InternalAdd(key, value);
}
private void InternalAdd(KeyType key, ValueType value)
{
if (!_contents.ContainsKey(key))
{
if (_capacity > 0)
{
_keyQ.Enqueue(key);
if (_keyQ.Count > _capacity)
_contents.Remove(_keyQ.Dequeue());
}
}
_contents[key] = value;
}
}
}

@ -0,0 +1,170 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Collections;
using System.Text;
namespace MySql.Data.Common
{
internal class ContextString
{
string contextMarkers;
bool escapeBackslash;
// Create a private ctor so the compiler doesn't give us a default one
public ContextString(string contextMarkers, bool escapeBackslash)
{
this.contextMarkers = contextMarkers;
this.escapeBackslash = escapeBackslash;
}
public string ContextMarkers
{
get { return contextMarkers; }
set { contextMarkers = value; }
}
public int IndexOf(string src, string target)
{
return IndexOf(src, target, 0);
}
public int IndexOf(string src, string target, int startIndex)
{
int index = src.IndexOf(target, startIndex);
while (index != -1)
{
if (!IndexInQuotes(src, index, startIndex)) break;
index = src.IndexOf(target, index + 1);
}
return index;
}
private bool IndexInQuotes(string src, int index, int startIndex)
{
char contextMarker = Char.MinValue;
bool escaped = false;
for (int i = startIndex; i < index; i++)
{
char c = src[i];
int contextIndex = contextMarkers.IndexOf(c);
// if we have found the closing marker for our open marker, then close the context
if (contextIndex > -1 && contextMarker == contextMarkers[contextIndex] && !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 && contextIndex > -1 && !escaped)
contextMarker = c;
else if (c == '\\' && escapeBackslash)
escaped = !escaped;
}
return contextMarker != Char.MinValue || escaped;
}
public int IndexOf(string src, char target)
{
char contextMarker = Char.MinValue;
bool escaped = false;
int pos = 0;
foreach (char c in src)
{
int contextIndex = contextMarkers.IndexOf(c);
// if we have found the closing marker for our open marker, then close the context
if (contextIndex > -1 && contextMarker == contextMarkers[contextIndex] && !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 && contextIndex > -1 && !escaped)
contextMarker = c;
else if (contextMarker == Char.MinValue && c == target)
return pos;
else if (c == '\\' && escapeBackslash)
escaped = !escaped;
pos++;
}
return -1;
}
public string[] Split(string src, string delimiters)
{
ArrayList parts = new ArrayList();
StringBuilder sb = new StringBuilder();
bool escaped = false;
char contextMarker = Char.MinValue;
foreach (char c in src)
{
if (delimiters.IndexOf(c) != -1 && !escaped)
{
if (contextMarker != Char.MinValue)
sb.Append(c);
else
{
if (sb.Length > 0)
{
parts.Add( sb.ToString() );
sb.Remove( 0, sb.Length );
}
}
}
else if (c == '\\' && escapeBackslash)
escaped = !escaped;
else
{
int contextIndex = contextMarkers.IndexOf(c);
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;
}
}
sb.Append( c );
}
}
if (sb.Length > 0)
parts.Add( sb.ToString() );
return (string[])parts.ToArray( typeof(string) );
}
}
}

@ -0,0 +1,91 @@
// Copyright (c) 2009 Sun Microsystems, Inc.
//
// 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;
namespace MySql.Data.Common
{
/// <summary>
/// This class is modeled after .NET Stopwatch. It provides better
/// performance (no system calls).It is however less precise than
/// .NET Stopwatch, measuring in milliseconds. It is adequate to use
/// when high-precision is not required (e.g for measuring IO timeouts),
/// but not for other tasks.
/// </summary>
class LowResolutionStopwatch
{
long millis;
long startTime;
public static readonly long Frequency = 1000; // measure in milliseconds
public static readonly bool isHighResolution = false;
public LowResolutionStopwatch()
{
millis = 0;
}
public long ElapsedMilliseconds
{
get { return millis; }
}
public void Start()
{
startTime = Environment.TickCount;
}
public void Stop()
{
long now = Environment.TickCount;
// Calculate time different, handle possible overflow
long elapsed = (now < startTime)?Int32.MaxValue - startTime + now : now - startTime;
millis += elapsed;
}
public void Reset()
{
millis = 0;
startTime = 0;
}
public TimeSpan Elapsed
{
get
{
return new TimeSpan(0, 0, 0, 0, (int)millis);
}
}
public static LowResolutionStopwatch StartNew()
{
LowResolutionStopwatch sw = new LowResolutionStopwatch();
sw.Start();
return sw;
}
public static long GetTimestamp()
{
return Environment.TickCount;
}
bool IsRunning()
{
return (startTime != 0);
}
}
}

@ -0,0 +1,180 @@
// Copyright (c) 2009 Sun Microsystems, Inc.
//
// 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.Sockets;
internal class MyNetworkStream : NetworkStream
{
/// <summary>
/// Wrapper around NetworkStream.
///
/// MyNetworkStream is equivalent to NetworkStream, except
/// 1. It throws TimeoutException if read or write timeout occurs, instead
/// of IOException, to match behavior of other streams (named pipe and
/// shared memory). This property comes handy in TimedStream.
///
/// 2. It implements workarounds for WSAEWOULDBLOCK errors, that can start
/// occuring after stream has times out. For a discussion about the CLR bug,
/// refer to http://tinyurl.com/lhgpyf. This error should never occur, as
/// we're not using asynchronous operations, but apparerntly it does occur
/// directly after timeout has expired.
/// The workaround is hinted in the URL above and implemented like this:
/// For each IO operation, if it throws WSAEWOULDBLOCK, we explicitely set
/// the socket to Blocking and retry the operation once again.
/// </summary>
const int MaxRetryCount = 2;
Socket socket;
public MyNetworkStream(Socket socket, bool ownsSocket)
: base(socket, ownsSocket)
{
this.socket = socket;
}
bool IsTimeoutException(SocketException e)
{
#if CF
return (e.NativeErrorCode == 10060);
#else
return (e.SocketErrorCode == SocketError.TimedOut);
#endif
}
bool IsWouldBlockException(SocketException e)
{
#if CF
return (e.NativeErrorCode == 10035);
#else
return (e.SocketErrorCode == SocketError.WouldBlock);
#endif
}
void HandleOrRethrowException(Exception e)
{
Exception currentException = e;
while (currentException != null)
{
if (currentException is SocketException)
{
SocketException socketException = (SocketException)currentException;
if (IsWouldBlockException(socketException))
{
// Workaround for WSAEWOULDBLOCK
socket.Blocking= true;
// return to give the caller possibility to retry the call
return;
}
else if (IsTimeoutException(socketException))
{
throw new TimeoutException(socketException.Message, e);
}
}
currentException = currentException.InnerException;
}
throw (e);
}
public override int Read(byte[] buffer, int offset, int count)
{
int retry = 0;
Exception exception = null;
do
{
try
{
return base.Read(buffer, offset, count);
}
catch (Exception e)
{
exception = e;
HandleOrRethrowException(e);
}
}
while (++retry < MaxRetryCount);
throw exception;
}
public override int ReadByte()
{
int retry = 0;
Exception exception = null;
do
{
try
{
return base.ReadByte();
}
catch (Exception e)
{
exception = e;
HandleOrRethrowException(e);
}
}
while (++retry < MaxRetryCount);
throw exception;
}
public override void Write(byte[] buffer, int offset, int count)
{
int retry = 0;
Exception exception = null;
do
{
try
{
base.Write(buffer, offset, count);
return;
}
catch (Exception e)
{
exception = e;
HandleOrRethrowException(e);
}
}
while (++retry < MaxRetryCount);
throw exception;
}
public override void Flush()
{
int retry = 0;
Exception exception = null;
do
{
try
{
base.Flush();
return;
}
catch (Exception e)
{
exception = e;
HandleOrRethrowException(e);
}
}
while (++retry < MaxRetryCount);
throw exception;
}
}

@ -0,0 +1,312 @@
// Copyright (c) 2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Text;
using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
namespace MySql.Data.MySqlClient
{
internal class MySqlTokenizer
{
private string sql;
private int startIndex;
private int stopIndex;
private bool ansiQuotes;
private bool backslashEscapes;
private bool returnComments;
private bool multiLine;
private bool quoted;
private bool isComment;
private int pos;
public MySqlTokenizer()
{
backslashEscapes = true;
multiLine = true;
pos = 0;
}
public MySqlTokenizer(string input) : this()
{
sql = input;
}
#region Properties
public string Text
{
get { return sql; }
set { sql = value; pos = 0; }
}
public bool AnsiQuotes
{
get { return ansiQuotes; }
set { ansiQuotes = value; }
}
public bool BackslashEscapes
{
get { return backslashEscapes; }
set { backslashEscapes = value; }
}
public bool MultiLine
{
get { return multiLine; }
set { multiLine = value; }
}
public bool Quoted
{
get { return quoted; }
private set { quoted = value; }
}
public bool IsComment
{
get { return isComment; }
}
public int StartIndex
{
get { return startIndex; }
set { startIndex = value; }
}
public int StopIndex
{
get { return stopIndex; }
set { stopIndex = value; }
}
public int Position
{
get { return pos; }
set { pos = value; }
}
public bool ReturnComments
{
get { return returnComments; }
set { returnComments = value; }
}
#endregion
public List<string> GetAllTokens()
{
List<string> tokens = new List<string>();
string token = NextToken();
while (token != null)
{
tokens.Add(token);
token = NextToken();
}
return tokens;
}
public string NextToken()
{
while (FindToken())
{
string token = sql.Substring(startIndex, stopIndex - startIndex).Trim();
return token;
}
return null;
}
public string NextParameter()
{
while (FindToken())
{
if ((stopIndex - startIndex) < 2) continue;
string token = sql.Substring(startIndex, stopIndex - startIndex).Trim();
char c1 = sql[startIndex];
char c2 = sql[startIndex+1];
if (c1 == '?' ||
(c1 == '@' && c2 != '@'))
return sql.Substring(startIndex, stopIndex - startIndex);
}
return null;
}
public bool FindToken()
{
isComment = quoted = false; // reset our flags
startIndex = stopIndex = -1;
while (pos < sql.Length)
{
char c = sql[pos++];
if (Char.IsWhiteSpace(c)) continue;
if (c == '`' || c == '\'' || c == '"') //(c == '"' && AnsiQuotes))
ReadQuotedToken(c);
else if (c == '#' || c == '-' || c == '/')
{
if (!ReadComment(c))
ReadSpecialToken();
}
else
ReadUnquotedToken();
if (startIndex != -1) return true;
}
return false;
}
public string ReadParenthesis()
{
StringBuilder sb = new StringBuilder("(");
int start = StartIndex;
string token = NextToken();
while (true)
{
if (token == null)
throw new InvalidOperationException("Unable to parse SQL");
sb.Append(token);
if (token == ")" && !Quoted) break;
token = NextToken();
}
return sb.ToString();
}
private bool ReadComment(char c)
{
// make sure the comment starts correctly
if (c == '/' && (pos >= sql.Length || sql[pos] != '*')) return false;
if (c == '-' && ((pos + 1) >= sql.Length || sql[pos] != '-' || sql[pos + 1] != ' ')) return false;
string endingPattern = "\n";
if (sql[pos] == '*')
endingPattern = "*/";
int startingIndex = pos-1;
int index = sql.IndexOf(endingPattern, pos);
if (index == -1)
index = sql.Length - 1;
else
index += endingPattern.Length;
pos = index;
if (ReturnComments)
{
startIndex = startingIndex;
stopIndex = index;
isComment = true;
}
return true;
}
private void CalculatePosition(int start, int stop)
{
startIndex = start;
stopIndex = stop;
if (!MultiLine) return;
}
private void ReadUnquotedToken()
{
startIndex = pos-1;
if (!IsSpecialCharacter(sql[startIndex]))
{
while (pos < sql.Length)
{
char c = sql[pos];
if (Char.IsWhiteSpace(c)) break;
if (IsSpecialCharacter(c)) break;
pos++;
}
}
Quoted = false;
stopIndex = pos;
}
private void ReadSpecialToken()
{
startIndex = pos - 1;
Debug.Assert(IsSpecialCharacter(sql[startIndex]));
stopIndex = pos;
Quoted = false;
}
/// <summary>
/// Read a single quoted identifier from the stream
/// </summary>
/// <param name="quoteChar"></param>
/// <returns></returns>
private void ReadQuotedToken(char quoteChar)
{
startIndex = pos-1;
bool escaped = false;
bool found = false;
while (pos < sql.Length)
{
char c = sql[pos];
if (c == quoteChar && !escaped)
{
found = true;
break;
}
if (escaped)
escaped = false;
else if (c == '\\' && BackslashEscapes)
escaped = true;
pos++;
}
if (found) pos++;
Quoted = found;
stopIndex = pos;
}
private bool IsQuoteChar(char c)
{
return c == '`' || c == '\'' || c == '\"';
}
private bool IsParameterMarker(char c)
{
return c == '@' || c == '?';
}
private bool IsSpecialCharacter(char c)
{
if (Char.IsLetterOrDigit(c) ||
c == '$' || c == '_' || c == '.') return false;
if (IsParameterMarker(c)) return false;
return true;
}
}
}

@ -0,0 +1,236 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
using MySql.Data.MySqlClient.Properties;
using Microsoft.Win32.SafeHandles;
using System.Threading;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.ComponentModel;
namespace MySql.Data.Common
{
/// <summary>
/// Summary description for API.
/// </summary>
internal class NamedPipeStream : Stream
{
SafeFileHandle handle;
Stream fileStream;
int readTimeout = Timeout.Infinite;
int writeTimeout = Timeout.Infinite;
const int ERROR_PIPE_BUSY = 231;
const int ERROR_SEM_TIMEOUT = 121;
public NamedPipeStream(string path, FileAccess mode, uint timeout)
{
Open(path, mode, timeout);
}
void CancelIo()
{
bool ok = NativeMethods.CancelIo(handle.DangerousGetHandle());
if (!ok)
throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
}
public void Open( string path, FileAccess mode ,uint timeout )
{
IntPtr nativeHandle;
for (; ; )
{
nativeHandle = NativeMethods.CreateFile(path, NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE,
0, null, NativeMethods.OPEN_EXISTING, NativeMethods.FILE_FLAG_OVERLAPPED, 0);
if (nativeHandle != IntPtr.Zero)
break;
if (Marshal.GetLastWin32Error() != ERROR_PIPE_BUSY)
{
throw new Win32Exception(Marshal.GetLastWin32Error(),
"Error opening pipe");
}
LowResolutionStopwatch sw = LowResolutionStopwatch.StartNew();
bool success = NativeMethods.WaitNamedPipe(path, timeout);
sw.Stop();
if (!success)
{
if (timeout < sw.ElapsedMilliseconds ||
Marshal.GetLastWin32Error() == ERROR_SEM_TIMEOUT)
{
throw new TimeoutException("Timeout waiting for named pipe");
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error(),
"Error waiting for pipe");
}
}
timeout -= (uint)sw.ElapsedMilliseconds;
}
handle = new SafeFileHandle(nativeHandle, true);
fileStream = new FileStream(handle, mode, 4096, true);
}
public override bool CanRead
{
get { return fileStream.CanRead; }
}
public override bool CanWrite
{
get { return fileStream.CanWrite; }
}
public override bool CanSeek
{
get { throw new NotSupportedException(Resources.NamedPipeNoSeek); }
}
public override long Length
{
get { throw new NotSupportedException(Resources.NamedPipeNoSeek); }
}
public override long Position
{
get { throw new NotSupportedException(Resources.NamedPipeNoSeek); }
set { }
}
public override void Flush()
{
fileStream.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
if(readTimeout == Timeout.Infinite)
{
return fileStream.Read(buffer, offset, count);
}
IAsyncResult result = fileStream.BeginRead(buffer, offset, count, null, null);
if (result.CompletedSynchronously)
return fileStream.EndRead(result);
if (!result.AsyncWaitHandle.WaitOne(readTimeout))
{
CancelIo();
throw new TimeoutException("Timeout in named pipe read");
}
return fileStream.EndRead(result);
}
public override void Write(byte[] buffer, int offset, int count)
{
if (writeTimeout == Timeout.Infinite)
{
fileStream.Write(buffer, offset, count);
return;
}
IAsyncResult result = fileStream.BeginWrite(buffer, offset, count, null, null);
if (result.CompletedSynchronously)
{
fileStream.EndWrite(result);
}
if (!result.AsyncWaitHandle.WaitOne(readTimeout))
{
CancelIo();
throw new TimeoutException("Timeout in named pipe write");
}
fileStream.EndWrite(result);
}
public override void Close()
{
if (handle != null && !handle.IsInvalid && !handle.IsClosed)
{
fileStream.Close();
try
{
handle.Close();
}
catch (Exception)
{
}
}
}
public override void SetLength(long length)
{
throw new NotSupportedException(Resources.NamedPipeNoSetLength);
}
public override bool CanTimeout
{
get
{
return true;
}
}
public override int ReadTimeout
{
get
{
return readTimeout;
}
set
{
readTimeout = value;
}
}
public override int WriteTimeout
{
get
{
return writeTimeout;
}
set
{
writeTimeout = value;
}
}
public override long Seek( long offset, SeekOrigin origin )
{
throw new NotSupportedException(Resources.NamedPipeNoSeek);
}
internal static Stream Create(string pipeName, string hostname, uint timeout)
{
string pipePath;
if (0 == String.Compare(hostname, "localhost", true))
pipePath = @"\\.\pipe\" + pipeName;
else
pipePath = String.Format(@"\\{0}\pipe\{1}", hostname, pipeName);
return new NamedPipeStream(pipePath, FileAccess.ReadWrite, timeout);
}
}
}

@ -0,0 +1,154 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Runtime.InteropServices;
using System.Threading;
namespace MySql.Data.Common
{
internal class NativeMethods
{
// Keep the compiler from generating a default ctor
private NativeMethods()
{
}
//Constants for dwDesiredAccess:
public const UInt32 GENERIC_READ = 0x80000000;
public const UInt32 GENERIC_WRITE = 0x40000000;
//Constants for return value:
public const Int32 INVALIDpipeHandle_VALUE = -1;
//Constants for dwFlagsAndAttributes:
public const UInt32 FILE_FLAG_OVERLAPPED = 0x40000000;
public const UInt32 FILE_FLAG_NO_BUFFERING = 0x20000000;
//Constants for dwCreationDisposition:
public const UInt32 OPEN_EXISTING = 3;
[StructLayout(LayoutKind.Sequential)]
public class SecurityAttributes
{
public SecurityAttributes()
{
Length = Marshal.SizeOf(typeof(SecurityAttributes));
}
public int Length;
public IntPtr securityDescriptor = IntPtr.Zero;
public bool inheritHandle;
}
[DllImport("Kernel32", CharSet=CharSet.Unicode)]
static extern public IntPtr CreateFile(
String fileName,
uint desiredAccess,
uint shareMode,
SecurityAttributes securityAttributes,
uint creationDisposition,
uint flagsAndAttributes,
uint templateFile);
[return:MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", EntryPoint="PeekNamedPipe", SetLastError=true)]
static extern public bool PeekNamedPipe(IntPtr handle,
byte[] buffer,
uint nBufferSize,
ref uint bytesRead,
ref uint bytesAvail,
ref uint BytesLeftThisMessage);
[return:MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", SetLastError=true)]
static extern public bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer, uint nNumberOfBytesToRead,
out uint lpNumberOfBytesRead, IntPtr lpOverlapped);
[return:MarshalAs(UnmanagedType.Bool)]
[DllImport("Kernel32")]
public static extern bool WriteFile(IntPtr hFile, [In]byte[] buffer,
uint numberOfBytesToWrite, out uint numberOfBytesWritten, IntPtr lpOverlapped);
[return:MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", SetLastError=true)]
public static extern bool CloseHandle(IntPtr handle);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CancelIo(IntPtr handle);
[return:MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", SetLastError=true)]
public static extern bool FlushFileBuffers(IntPtr handle);
[DllImport("kernel32.dll", CharSet=CharSet.Unicode)]
public static extern IntPtr OpenEvent(uint dwDesiredAccess,
[MarshalAs(UnmanagedType.Bool)]bool bInheritHandle,
string lpName);
[DllImport("kernel32.dll", CharSet=CharSet.Unicode)]
public static extern IntPtr OpenFileMapping(uint dwDesiredAccess,
[MarshalAs(UnmanagedType.Bool)]bool bInheritHandle,
string lpName);
[DllImport("kernel32.dll")]
public static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, uint
dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow,
IntPtr dwNumberOfBytesToMap);
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int FlushViewOfFile(IntPtr address, uint numBytes);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WaitNamedPipe(string namedPipeName, uint timeOut);
#region Winsock functions
// SOcket routines
[DllImport("ws2_32.dll", SetLastError=true)]
static extern public IntPtr socket(int af, int type, int protocol);
[DllImport("ws2_32.dll", SetLastError=true)]
static extern public int ioctlsocket(IntPtr socket, uint cmd, ref UInt32 arg);
[DllImport("ws2_32.dll", SetLastError=true)]
public static extern int WSAIoctl(IntPtr s, uint dwIoControlCode, byte[] inBuffer, uint cbInBuffer,
byte[] outBuffer, uint cbOutBuffer, IntPtr lpcbBytesReturned, IntPtr lpOverlapped,
IntPtr lpCompletionRoutine);
[DllImport("ws2_32.dll", SetLastError=true)]
static extern public int WSAGetLastError();
[DllImport("ws2_32.dll", SetLastError=true)]
static extern public int connect(IntPtr socket, byte[] addr, int addrlen);
[DllImport("ws2_32.dll", SetLastError=true)]
static extern public int recv(IntPtr socket, byte[] buff, int len, int flags);
[DllImport("ws2_32.Dll", SetLastError=true)]
static extern public int send(IntPtr socket, byte[] buff, int len, int flags);
#endregion
}
}

@ -0,0 +1,64 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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;
namespace MySql.Data.Common
{
internal class Platform
{
private static bool inited;
private static bool isMono;
/// <summary>
/// By creating a private ctor, we keep the compiler from creating a default ctor
/// </summary>
private Platform()
{
}
public static bool IsWindows()
{
OperatingSystem os = Environment.OSVersion;
switch (os.Platform)
{
case PlatformID.Win32NT:
case PlatformID.Win32S:
case PlatformID.Win32Windows:
return true;
}
return false;
}
public static bool IsMono()
{
if (!inited)
Init();
return isMono;
}
private static void Init()
{
inited = true;
Type t = Type.GetType("Mono.Runtime");
isMono = t != null;
}
}
}

@ -0,0 +1,392 @@
// Copyright (c) 2009-2010 Sun Microsystems, Inc.
//
// 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.Collections.Generic;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Collections;
using MySql.Data.MySqlClient.Properties;
namespace MySql.Data.Common
{
internal class QueryNormalizer
{
private static List<string> keywords = new List<string>();
private List<Token> tokens = new List<Token>();
private int pos;
private string fullSql;
private string queryType;
static QueryNormalizer()
{
StringReader sr = new StringReader(Resources.keywords);
string keyword = sr.ReadLine();
while (keyword != null)
{
keywords.Add(keyword);
keyword = sr.ReadLine();
}
}
public string QueryType
{
get { return queryType; }
}
public string Normalize(string sql)
{
tokens.Clear();
StringBuilder newSql = new StringBuilder();
fullSql = sql;
TokenizeSql(sql);
DetermineStatementType(tokens);
ProcessMathSymbols(tokens);
CollapseValueLists(tokens);
CollapseInLists(tokens);
CollapseWhitespace(tokens);
foreach (Token t in tokens)
if (t.Output)
newSql.Append(t.Text);
return newSql.ToString();
}
private void DetermineStatementType(List<Token> tok)
{
foreach (Token t in tok)
{
if (t.Type == TokenType.Keyword)
{
queryType = t.Text.ToUpperInvariant();
//string s = t.Text.ToLowerInvariant();
//if (s == "select")
// queryType = "SELECT";
//else if (s == "update" || s == "insert")
// queryType = "UPSERT";
//else
// queryType = "OTHER";
break;
}
}
}
/// <summary>
/// Mark - or + signs that are unary ops as no output
/// </summary>
/// <param name="tok"></param>
private void ProcessMathSymbols(List<Token> tok)
{
Token lastToken = null;
foreach (Token t in tok)
{
if (t.Type == TokenType.Symbol &&
(t.Text == "-" || t.Text == "+"))
{
if (lastToken != null &&
lastToken.Type != TokenType.Number &&
lastToken.Type != TokenType.Identifier &&
(lastToken.Type != TokenType.Symbol || lastToken.Text != ")"))
t.Output = false;
}
if (t.IsRealToken)
lastToken = t;
}
}
private void CollapseWhitespace(List<Token> tok)
{
Token lastToken = null;
foreach (Token t in tok)
{
if (t.Output &&
t.Type == TokenType.Whitespace &&
lastToken != null &&
lastToken.Type == TokenType.Whitespace)
{
t.Output = false;
}
if (t.Output)
lastToken = t;
}
}
private void CollapseValueLists(List<Token> tok)
{
int pos = -1;
while (++pos < tok.Count)
{
Token t = tok[pos];
if (t.Type != TokenType.Keyword) continue;
if (!t.Text.StartsWith("VALUE")) continue;
CollapseValueList(tok, ref pos);
}
}
private void CollapseValueList(List<Token> tok, ref int pos)
{
List<int> parenIndices = new List<int>();
// this while loop will find all closing parens in this value list
while (true)
{
// find the close ')'
while (++pos < tok.Count)
if (tok[pos].Type == TokenType.Symbol && tok[pos].Text == ")") break;
Debug.Assert(pos < tok.Count);
parenIndices.Add(pos);
// now find the next "real" token
while (++pos < tok.Count)
if (tok[pos].IsRealToken) break;
if (pos == tok.Count) break;
if (tok[pos].Text != ",")
{
pos--;
break;
}
}
// if we only have 1 value then we don't collapse
if (parenIndices.Count < 2) return;
int index = parenIndices[0];
tok[++index] = new Token(TokenType.Whitespace, " ");
tok[++index] = new Token(TokenType.Comment, "/* , ... */");
index++;
// now mark all the other tokens as no output
while (index <= parenIndices[parenIndices.Count - 1])
tok[index++].Output = false;
}
private void CollapseInLists(List<Token> tok)
{
int pos = -1;
while (++pos < tok.Count)
{
Token t = tok[pos];
if (t.Type != TokenType.Keyword) continue;
if (!(t.Text == "IN")) continue;
CollapseInList(tok, ref pos);
}
}
private Token GetNextRealToken(List<Token> tok, ref int pos)
{
while (++pos < tok.Count)
{
if (tok[pos].IsRealToken) return tok[pos];
}
return null;
}
private void CollapseInList(List<Token> tok, ref int pos)
{
Token t = GetNextRealToken(tok, ref pos);
Debug.Assert(t.Text == "(");
// if the first token is a keyword then we likely have a
// SELECT .. IN (SELECT ...)
t = GetNextRealToken(tok, ref pos);
if (t.Type == TokenType.Keyword) return;
int start = pos;
// first find all the tokens that make up the in list
while (++pos < tok.Count)
{
t = tok[pos];
if (t.Type == TokenType.CommandComment) return;
if (!t.IsRealToken) continue;
if (t.Text == "(") return;
if (t.Text == ")") break;
}
int stop = pos;
for (int i = stop; i > start; i--)
tok.RemoveAt(i);
tok.Insert(++start, new Token(TokenType.Whitespace, " "));
tok.Insert(++start, new Token(TokenType.Comment, "/* , ... */"));
tok.Insert(++start, new Token(TokenType.Whitespace, " "));
tok.Insert(++start, new Token(TokenType.Symbol, ")"));
}
private void TokenizeSql(string sql)
{
pos = 0;
while (pos < sql.Length)
{
char c = sql[pos];
if (LetterStartsComment(c) && ConsumeComment())
continue;
if (Char.IsWhiteSpace(c))
ConsumeWhitespace();
else if (c == '\'' || c == '\"' || c == '`')
ConsumeQuotedToken(c);
else if (!IsSpecialCharacter(c))
ConsumeUnquotedToken();
else
ConsumeSymbol();
}
}
private bool LetterStartsComment(char c)
{
return c == '#' || c == '/' || c == '-';
}
private bool IsSpecialCharacter(char c)
{
if (Char.IsLetterOrDigit(c) ||
c == '$' || c == '_' || c == '.') return false;
return true;
}
private bool ConsumeComment()
{
char c = fullSql[pos];
// make sure the comment starts correctly
if (c == '/' && ((pos + 1) >= fullSql.Length || fullSql[pos + 1] != '*')) return false;
if (c == '-' && ((pos + 2) >= fullSql.Length || fullSql[pos + 1] != '-' || fullSql[pos + 2] != ' ')) return false;
string endingPattern = "\n";
if (c == '/')
endingPattern = "*/";
int startingIndex = pos;
int index = fullSql.IndexOf(endingPattern, pos);
if (index == -1)
index = fullSql.Length - 1;
else
index += endingPattern.Length;
string comment = fullSql.Substring(pos, index - pos);
if (comment.StartsWith("/*!"))
tokens.Add(new Token(TokenType.CommandComment, comment));
pos = index;
return true;
}
private void ConsumeSymbol()
{
char c = fullSql[pos++];
tokens.Add(new Token(TokenType.Symbol, c.ToString()));
}
private void ConsumeQuotedToken(char c)
{
bool escaped = false;
int start = pos;
pos++;
while (pos < fullSql.Length)
{
char x = fullSql[pos];
if (x == c && !escaped) break;
if (escaped)
escaped = false;
else if (x == '\\')
escaped = true;
pos++;
}
pos++;
if (c == '\'')
tokens.Add(new Token(TokenType.String, "?"));
else
tokens.Add(new Token(TokenType.Identifier, fullSql.Substring(start, pos - start)));
}
private void ConsumeUnquotedToken()
{
int startPos = pos;
while (pos < fullSql.Length && !IsSpecialCharacter(fullSql[pos]))
pos++;
string word = fullSql.Substring(startPos, pos - startPos);
double v;
if (Double.TryParse(word, out v))
tokens.Add(new Token(TokenType.Number, "?"));
else
{
Token t = new Token(TokenType.Identifier, word);
if (IsKeyword(word))
{
t.Type = TokenType.Keyword;
t.Text = t.Text.ToUpperInvariant();
}
tokens.Add(t);
}
}
private void ConsumeWhitespace()
{
tokens.Add(new Token(TokenType.Whitespace, " "));
while (pos < fullSql.Length && Char.IsWhiteSpace(fullSql[pos]))
pos++;
}
private bool IsKeyword(string word)
{
return keywords.Contains(word.ToUpperInvariant());
}
}
internal class Token
{
public TokenType Type;
public string Text;
public bool Output;
public Token(TokenType type, string text)
{
Type = type;
Text = text;
Output = true;
}
public bool IsRealToken
{
get
{
return Type != TokenType.Comment &&
Type != TokenType.CommandComment &&
Type != TokenType.Whitespace &&
Output; }
}
}
internal enum TokenType
{
Keyword,
String,
Number,
Symbol,
Identifier,
Comment,
CommandComment,
Whitespace
}
}

@ -0,0 +1,275 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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;
namespace MySql.Data.Common
{
class SHA1Hash
{
private const int SHA1_HASH_SIZE = 20; // Hash size in bytes
// Constants defined in SHA-1
private static uint[] K = new uint[4] {
0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 };
private static uint[] sha_const_key = new uint[5] {
0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 };
private ulong length; // Message length in bits
private uint[] intermediateHash; // Message Digest
private bool computed; // Is the digest computed?
// private bool corrupted; // Is the message digest corrupted?
private short messageBlockIndex; // Index into message block array
private byte[] messageBlock; // 512-bit message blocks
public SHA1Hash()
{
intermediateHash = new uint[SHA1_HASH_SIZE/4];
messageBlock = new byte[64];
Reset();
}
public void Reset()
{
/*#ifndef DBUG_OFF
if (!context)
return SHA_NULL;
#endif*/
length = 0;
messageBlockIndex = 0;
intermediateHash[0] = sha_const_key[0];
intermediateHash[1] = sha_const_key[1];
intermediateHash[2] = sha_const_key[2];
intermediateHash[3] = sha_const_key[3];
intermediateHash[4] = sha_const_key[4];
computed = false;
// corrupted = false;
}
public byte[] ComputeHash(byte[] buffer)
{
Reset();
Input(buffer, 0, buffer.Length);
return Result();
}
public void Input(byte[] buffer, int index, int bufLen)
{
if (buffer == null || bufLen == 0) return;
if (index < 0 || index > buffer.Length - 1)
throw new ArgumentException("Index must be a value between 0 and buffer.Length-1", "index");
if (bufLen < 0)
throw new ArgumentException("Length must be a value > 0", "length");
if ((bufLen+index) > buffer.Length)
throw new ArgumentException("Length + index would extend past the end of buffer", "length");
/*#ifndef DBUG_OFF
// We assume client konows what it is doing in non-debug mode
if (!context || !message_array)
return SHA_NULL;
if (context->Computed)
return (context->Corrupted= SHA_STATE_ERROR);
if (context->Corrupted)
return context->Corrupted;
#endif*/
while (bufLen-- > 0)
{
messageBlock[messageBlockIndex++] = (byte)(buffer[index++] & 0xFF);
length += 8; /* Length is in bits */
/*#ifndef DBUG_OFF
// Then we're not debugging we assume we never will get message longer
//2^64 bits.
if (context->Length == 0)
return (context->Corrupted= 1); // Message is too long
#endif*/
if (messageBlockIndex == 64)
ProcessMessageBlock();
}
}
private void ProcessMessageBlock()
{
uint temp; // Temporary word value
uint[] W; // Word sequence
uint A, B, C, D, E; // Word buffers
W = new uint[80];
//Initialize the first 16 words in the array W
for (int t = 0; t < 16; t++)
{
int index=t*4;
W[t] = (uint)messageBlock[index] << 24;
W[t] |= (uint)messageBlock[index + 1] << 16;
W[t] |= (uint)messageBlock[index + 2] << 8;
W[t] |= (uint)messageBlock[index + 3];
}
for (int t = 16; t < 80; t++)
{
W[t] = CircularShift(1, W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
}
A = intermediateHash[0];
B = intermediateHash[1];
C = intermediateHash[2];
D = intermediateHash[3];
E = intermediateHash[4];
for (int t = 0; t < 20; t++)
{
temp= CircularShift(5, A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
E = D;
D = C;
C = CircularShift(30, B);
B = A;
A = temp;
}
for (int t = 20; t < 40; t++)
{
temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
E = D;
D = C;
C = CircularShift(30,B);
B = A;
A = temp;
}
for (int t = 40; t < 60; t++)
{
temp= (CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]);
E = D;
D = C;
C = CircularShift(30,B);
B = A;
A = temp;
}
for (int t = 60; t < 80; t++)
{
temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
E = D;
D = C;
C = CircularShift(30,B);
B = A;
A = temp;
}
intermediateHash[0] += A;
intermediateHash[1] += B;
intermediateHash[2] += C;
intermediateHash[3] += D;
intermediateHash[4] += E;
messageBlockIndex = 0;
}
private static uint CircularShift(int bits, uint word)
{
return (((word) << (bits)) | ((word) >> (32-(bits))));
}
private void PadMessage()
{
/*
Check to see if the current message block is too small to hold
the initial padding bits and length. If so, we will pad the
block, process it, and then continue padding into a second
block.
*/
int i = messageBlockIndex;
if (i > 55)
{
messageBlock[i++] = 0x80;
Array.Clear(messageBlock, i, 64-i);
//bzero((char*) &context->Message_Block[i], sizeof(messageBlock[0])*(64-i));
messageBlockIndex = 64;
/* This function sets messageBlockIndex to zero */
ProcessMessageBlock();
Array.Clear(messageBlock, 0, 56);
//bzero((char*) &context->Message_Block[0], sizeof(messageBlock[0])*56);
messageBlockIndex = 56;
}
else
{
messageBlock[i++] = 0x80;
Array.Clear(messageBlock, i, 56-i);
//bzero((char*) &messageBlock[i], sizeof(messageBlock[0])*(56-i));
messageBlockIndex = 56;
}
// Store the message length as the last 8 octets
messageBlock[56] = (byte)(length >> 56);
messageBlock[57] = (byte)(length >> 48);
messageBlock[58] = (byte)(length >> 40);
messageBlock[59] = (byte)(length >> 32);
messageBlock[60] = (byte)(length >> 24);
messageBlock[61] = (byte)(length >> 16);
messageBlock[62] = (byte)(length >> 8);
messageBlock[63] = (byte)length;
ProcessMessageBlock();
}
public byte[] Result()
{
/*#ifndef DBUG_OFF
if (!context || !Message_Digest)
return SHA_NULL;
if (context->Corrupted)
return context->Corrupted;
#endif*/
if (!computed)
{
PadMessage();
// message may be sensitive, clear it out
Array.Clear(messageBlock, 0, 64);
//bzero((char*) messageBlock,64);
length = 0; /* and clear length */
computed = true;
}
byte[] messageDigest = new byte[SHA1_HASH_SIZE];
for (int i = 0; i < SHA1_HASH_SIZE; i++)
messageDigest[i] = (byte)((intermediateHash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) )));
return messageDigest;
}
}
}

@ -0,0 +1,353 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Runtime.InteropServices;
using System.Threading;
using System.IO;
using MySql.Data.MySqlClient;
using System.Diagnostics;
namespace MySql.Data.Common
{
#if !PocketPC
/// <summary>
/// Helper class to encapsulate shared memory functionality
/// Also cares of proper cleanup of file mapping object and cew
/// </summary>
internal class SharedMemory : IDisposable
{
private const uint FILE_MAP_WRITE = 0x0002;
IntPtr fileMapping;
IntPtr view;
public SharedMemory(string name, IntPtr size)
{
fileMapping = NativeMethods.OpenFileMapping(FILE_MAP_WRITE, false,
name);
if (fileMapping == IntPtr.Zero)
{
throw new MySqlException("Cannot open file mapping " + name);
}
view = NativeMethods.MapViewOfFile(fileMapping, FILE_MAP_WRITE, 0, 0, size);
}
public IntPtr View
{
get { return view; }
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (view != IntPtr.Zero)
{
NativeMethods.UnmapViewOfFile(view);
view = IntPtr.Zero;
}
if (fileMapping != IntPtr.Zero)
{
// Free the handle
NativeMethods.CloseHandle(fileMapping);
fileMapping = IntPtr.Zero;
}
}
}
}
/// <summary>
/// Summary description for SharedMemoryStream.
/// </summary>
internal class SharedMemoryStream : Stream
{
private string memoryName;
private EventWaitHandle serverRead;
private EventWaitHandle serverWrote;
private EventWaitHandle clientRead;
private EventWaitHandle clientWrote;
private EventWaitHandle connectionClosed;
private SharedMemory data;
private int bytesLeft;
private int position;
private int connectNumber;
private const int BUFFERLENGTH = 16004;
private int readTimeout = System.Threading.Timeout.Infinite;
private int writeTimeout = System.Threading.Timeout.Infinite;
public SharedMemoryStream(string memName)
{
memoryName = memName;
}
public void Open(uint timeOut)
{
if (connectionClosed != null)
{
Debug.Assert(false, "Connection is already open");
}
GetConnectNumber(timeOut);
SetupEvents();
}
public override void Close()
{
if (connectionClosed != null)
{
bool isClosed = connectionClosed.WaitOne(0);
if (!isClosed)
{
connectionClosed.Set();
connectionClosed.Close();
}
connectionClosed = null;
EventWaitHandle[] handles =
{serverRead, serverWrote, clientRead, clientWrote};
for(int i=0; i< handles.Length; i++)
{
if(handles[i] != null)
handles[i].Close();
}
if (data != null)
{
data.Dispose();
data = null;
}
}
}
private void GetConnectNumber(uint timeOut)
{
EventWaitHandle connectRequest;
try
{
connectRequest =
EventWaitHandle.OpenExisting(memoryName + "_CONNECT_REQUEST");
}
catch (Exception)
{
// If server runs as service, its shared memory is global
// And if connector runs in user session, it needs to prefix
// shared memory name with "Global\"
string prefixedMemoryName = @"Global\" + memoryName;
connectRequest =
EventWaitHandle.OpenExisting(prefixedMemoryName + "_CONNECT_REQUEST");
memoryName = prefixedMemoryName;
}
EventWaitHandle connectAnswer =
EventWaitHandle.OpenExisting(memoryName + "_CONNECT_ANSWER");
using (SharedMemory connectData =
new SharedMemory(memoryName + "_CONNECT_DATA", (IntPtr)4))
{
// now start the connection
if (!connectRequest.Set())
throw new MySqlException("Failed to open shared memory connection");
if (!connectAnswer.WaitOne((int)(timeOut * 1000), false))
throw new MySqlException("Timeout during connection");
connectNumber = Marshal.ReadInt32(connectData.View);
}
}
private void SetupEvents()
{
string prefix = memoryName + "_" + connectNumber;
data = new SharedMemory(prefix + "_DATA", (IntPtr)BUFFERLENGTH);
serverWrote = EventWaitHandle.OpenExisting(prefix + "_SERVER_WROTE");
serverRead = EventWaitHandle.OpenExisting(prefix + "_SERVER_READ");
clientWrote = EventWaitHandle.OpenExisting(prefix + "_CLIENT_WROTE");
clientRead = EventWaitHandle.OpenExisting(prefix + "_CLIENT_READ");
connectionClosed = EventWaitHandle.OpenExisting(prefix + "_CONNECTION_CLOSED");
// tell the server we are ready
serverRead.Set();
}
#region Properties
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 { throw new NotSupportedException("SharedMemoryStream does not support seeking - length"); }
}
public override long Position
{
get { throw new NotSupportedException("SharedMemoryStream does not support seeking - position"); }
set { }
}
#endregion
public override void Flush()
{
// No need to flush anything to disk ,as our shared memory is backed
// by the page file
}
public override int Read(byte[] buffer, int offset, int count)
{
int timeLeft = readTimeout;
WaitHandle[] waitHandles = { serverWrote, connectionClosed };
LowResolutionStopwatch stopwatch = new LowResolutionStopwatch();
while (bytesLeft == 0)
{
stopwatch.Start();
int index = WaitHandle.WaitAny(waitHandles, timeLeft);
stopwatch.Stop();
if (index == WaitHandle.WaitTimeout)
throw new TimeoutException("Timeout when reading from shared memory");
if (waitHandles[index] == connectionClosed)
throw new MySqlException("Connection to server lost",true, null);
if (readTimeout != System.Threading.Timeout.Infinite)
{
timeLeft = readTimeout - (int)stopwatch.ElapsedMilliseconds;
if (timeLeft < 0)
throw new TimeoutException("Timeout when reading from shared memory");
}
bytesLeft = Marshal.ReadInt32(data.View);
position = 4;
}
int len = Math.Min(count, bytesLeft);
long baseMem = data.View.ToInt64() + position;
for (int i = 0; i < len; i++, position++)
buffer[offset + i] = Marshal.ReadByte((IntPtr)(baseMem + i));
bytesLeft -= len;
if (bytesLeft == 0)
clientRead.Set();
return len;
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException("SharedMemoryStream does not support seeking");
}
public override void Write(byte[] buffer, int offset, int count)
{
int leftToDo = count;
int buffPos = offset;
WaitHandle[] waitHandles = { serverRead, connectionClosed };
LowResolutionStopwatch stopwatch = new LowResolutionStopwatch();
int timeLeft = writeTimeout;
while (leftToDo > 0)
{
stopwatch.Start();
int index = WaitHandle.WaitAny(waitHandles, timeLeft);
stopwatch.Stop();
if (waitHandles[index] == connectionClosed)
throw new MySqlException("Connection to server lost",true, null);
if (index == WaitHandle.WaitTimeout)
throw new TimeoutException("Timeout when reading from shared memory");
if (writeTimeout != System.Threading.Timeout.Infinite)
{
timeLeft = writeTimeout - (int)stopwatch.ElapsedMilliseconds;
if (timeLeft < 0)
throw new TimeoutException("Timeout when writing to shared memory");
}
int bytesToDo = Math.Min(leftToDo, BUFFERLENGTH);
long baseMem = data.View.ToInt64() + 4;
Marshal.WriteInt32(data.View, bytesToDo);
Marshal.Copy(buffer, buffPos, (IntPtr)baseMem, bytesToDo);
buffPos += bytesToDo;
leftToDo -= bytesToDo;
if (!clientWrote.Set())
throw new MySqlException("Writing to shared memory failed");
}
}
public override void SetLength(long value)
{
throw new NotSupportedException("SharedMemoryStream does not support seeking");
}
public override bool CanTimeout
{
get
{
return true;
}
}
public override int ReadTimeout
{
get
{
return readTimeout;
}
set
{
readTimeout = value;
}
}
public override int WriteTimeout
{
get
{
return writeTimeout;
}
set
{
writeTimeout = value;
}
}
}
#endif
}

@ -0,0 +1,142 @@
// Copyright (c) 2004-2007 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;
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)
{
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];
NativeMethods.connect(socket.Handle, buff, addr.Size);
int wsaerror = NativeMethods.WSAGetLastError();
if (wsaerror != 10035)
{
// this is probably an IPV6 address
if (wsaerror == 10047)
return false;
throw new SocketException(wsaerror);
}
// 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;
}
}
}

@ -0,0 +1,264 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Reflection;
using System.Diagnostics;
using MySql.Data.MySqlClient.Properties;
using System.Runtime.InteropServices;
namespace MySql.Data.Common
{
/// <summary>
/// Summary description for StreamCreator.
/// </summary>
internal class StreamCreator
{
string hostList;
uint port;
string pipeName;
uint timeOut;
uint keepalive;
public StreamCreator(string hosts, uint port, string pipeName, uint keepalive)
{
hostList = hosts;
if (hostList == null || hostList.Length == 0)
hostList = "localhost";
this.port = port;
this.pipeName = pipeName;
this.keepalive = keepalive;
}
public Stream GetStream(uint timeout)
{
timeOut = timeout;
if (hostList.StartsWith("/", StringComparison.OrdinalIgnoreCase))
return CreateSocketStream(null, true);
string[] dnsHosts = hostList.Split('&');
Random random = new Random((int)DateTime.Now.Ticks);
int index = random.Next(dnsHosts.Length);
int pos = 0;
bool usePipe = (pipeName != null && pipeName.Length != 0);
Stream stream = null;
while (pos < dnsHosts.Length)
{
try
{
if (usePipe)
{
#if !CF
stream = NamedPipeStream.Create(pipeName, dnsHosts[index], timeout);
#endif
}
else
{
IPHostEntry ipHE = GetHostEntry(dnsHosts[index]);
foreach (IPAddress address in ipHE.AddressList)
{
// MySQL doesn't currently support IPv6 addresses
if (address.AddressFamily == AddressFamily.InterNetworkV6)
continue;
stream = CreateSocketStream(address, false);
if (stream != null) break;
}
}
if (stream != null)
break;
index++;
if (index == dnsHosts.Length)
index = 0;
pos++;
}
catch (Exception)
{
// if on last host then throw
if (pos >= dnsHosts.Length - 1) throw;
// else continue
}
}
return stream;
}
private IPHostEntry ParseIPAddress(string hostname)
{
IPHostEntry ipHE = null;
#if !CF
IPAddress addr;
if (IPAddress.TryParse(hostname, out addr))
{
ipHE = new IPHostEntry();
ipHE.AddressList = new IPAddress[1];
ipHE.AddressList[0] = addr;
}
#endif
return ipHE;
}
#if CF
IPHostEntry GetDnsHostEntry(string hostname)
{
return Dns.GetHostEntry(hostname);
}
#else
IPHostEntry GetDnsHostEntry(string hostname)
{
LowResolutionStopwatch stopwatch = new LowResolutionStopwatch();
try
{
stopwatch.Start();
return Dns.GetHostEntry(hostname);
}
catch (SocketException ex)
{
string message = String.Format(Resources.GetHostEntryFailed,
stopwatch.Elapsed, hostname, ex.SocketErrorCode,
ex.ErrorCode, ex.NativeErrorCode);
throw new Exception(message, ex);
}
finally
{
stopwatch.Stop();
}
}
#endif
private IPHostEntry GetHostEntry(string hostname)
{
IPHostEntry ipHE = ParseIPAddress(hostname);
if (ipHE != null) return ipHE;
return GetDnsHostEntry(hostname);
}
#if !CF
private static EndPoint CreateUnixEndPoint(string host)
{
// first we need to load the Mono.posix assembly
Assembly a = Assembly.Load("Mono.Posix");
// 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;
}
#endif
private Stream CreateSocketStream(IPAddress ip, bool unix)
{
EndPoint endPoint;
#if !CF
if (!Platform.IsWindows() && unix)
endPoint = CreateUnixEndPoint(hostList);
else
#endif
endPoint = new IPEndPoint(ip, (int)port);
Socket socket = unix ?
new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP) :
new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
if (keepalive > 0)
{
SetKeepAlive(socket, keepalive);
}
IAsyncResult ias = socket.BeginConnect(endPoint, null, null);
if (!ias.AsyncWaitHandle.WaitOne((int)timeOut * 1000, false))
{
socket.Close();
return null;
}
try
{
socket.EndConnect(ias);
}
catch (Exception)
{
socket.Close();
throw;
}
MyNetworkStream stream = new MyNetworkStream(socket, true);
GC.SuppressFinalize(socket);
GC.SuppressFinalize(stream);
return stream;
}
/// <summary>
/// Set keepalive + timeout on socket.
/// </summary>
/// <param name="s">socket</param>
/// <param name="time">keepalive timeout, in seconds</param>
private static void SetKeepAlive(Socket s, uint time)
{
#if !CF
uint on = 1;
uint interval = 1000; // default interval = 1 sec
uint timeMilliseconds;
if (time > UInt32.MaxValue / 1000)
timeMilliseconds = UInt32.MaxValue;
else
timeMilliseconds = time * 1000;
// Use Socket.IOControl to implement equivalent of
// WSAIoctl with SOL_KEEPALIVE_VALS
// the native structure passed to WSAIoctl is
//struct tcp_keepalive {
// ULONG onoff;
// ULONG keepalivetime;
// ULONG keepaliveinterval;
//};
// marshal the equivalent of the native structure into a byte array
byte[] inOptionValues = new byte[12];
BitConverter.GetBytes(on).CopyTo(inOptionValues, 0);
BitConverter.GetBytes(time).CopyTo(inOptionValues, 4);
BitConverter.GetBytes(interval).CopyTo(inOptionValues, 8);
try
{
// call WSAIoctl via IOControl
s.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null);
return;
}
catch (NotImplementedException)
{
// Mono throws not implemented currently
}
#endif
// Fallback if Socket.IOControl is not available ( Compact Framework )
// or not implemented ( Mono ). Keepalive option will still be set, but
// with timeout is kept default.
s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
}
}
}

@ -0,0 +1,100 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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 MySql.Data.MySqlClient;
using MySql.Data.MySqlClient.Properties;
namespace MySql.Data.Common
{
/// <summary>
/// Summary description for Version.
/// </summary>
internal struct DBVersion
{
private int major;
private int minor;
private int build;
private string srcString;
public DBVersion( string s, int major, int minor, int build)
{
this.major = major;
this.minor = minor;
this.build = build;
srcString = s;
}
public int Major
{
get { return major; }
}
public int Minor
{
get { return minor; }
}
public int Build
{
get { return build; }
}
public static DBVersion Parse( string versionString )
{
int start = 0;
int index = versionString.IndexOf('.', start);
if (index == -1)
throw new MySqlException(Resources.BadVersionFormat);
string val = versionString.Substring(start, index-start).Trim();
int major = Convert.ToInt32(val, System.Globalization.NumberFormatInfo.InvariantInfo);
start = index+1;
index = versionString.IndexOf('.', start);
if (index == -1)
throw new MySqlException(Resources.BadVersionFormat);
val = versionString.Substring(start, index-start).Trim();
int minor = Convert.ToInt32(val, System.Globalization.NumberFormatInfo.InvariantInfo);
start = index+1;
int i = start;
while (i < versionString.Length && Char.IsDigit(versionString, i))
i++;
val = versionString.Substring(start, i-start).Trim();
int build = Convert.ToInt32(val, System.Globalization.NumberFormatInfo.InvariantInfo);
return new DBVersion(versionString, major, minor, build);
}
public bool isAtLeast(int majorNum, int minorNum, int buildNum)
{
if (major > majorNum) return true;
if (major == majorNum && minor > minorNum) return true;
if (major == majorNum && minor == minorNum && build >= buildNum) return true;
return false;
}
public override string ToString()
{
return srcString;
}
}
}

@ -0,0 +1,309 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Data.Common;
using System.ComponentModel;
using System.Collections.Generic;
namespace MySql.Data.MySqlClient
{
/// <include file='docs/MySqlDataAdapter.xml' path='docs/class/*'/>
#if !CF
[System.Drawing.ToolboxBitmap( typeof(MySqlDataAdapter), "MySqlClient.resources.dataadapter.bmp")]
[System.ComponentModel.DesignerCategory("Code")]
[Designer("MySql.Data.MySqlClient.Design.MySqlDataAdapterDesigner,MySqlClient.Design")]
#endif
public sealed class MySqlDataAdapter : DbDataAdapter, IDbDataAdapter, IDataAdapter, ICloneable
{
private bool loadingDefaults;
private int updateBatchSize;
List<IDbCommand> commandBatch;
/// <summary>
/// Occurs during Update before a command is executed against the data source. The attempt to update is made, so the event fires.
/// </summary>
public event MySqlRowUpdatingEventHandler RowUpdating;
/// <summary>
/// Occurs during Update after a command is executed against the data source. The attempt to update is made, so the event fires.
/// </summary>
public event MySqlRowUpdatedEventHandler RowUpdated;
/// <include file='docs/MySqlDataAdapter.xml' path='docs/Ctor/*'/>
public MySqlDataAdapter()
{
loadingDefaults = true;
updateBatchSize = 1;
}
/// <include file='docs/MySqlDataAdapter.xml' path='docs/Ctor1/*'/>
public MySqlDataAdapter(MySqlCommand selectCommand) : this()
{
SelectCommand = selectCommand;
}
/// <include file='docs/MySqlDataAdapter.xml' path='docs/Ctor2/*'/>
public MySqlDataAdapter(string selectCommandText, MySqlConnection connection) : this()
{
SelectCommand = new MySqlCommand(selectCommandText, connection);
}
/// <include file='docs/MySqlDataAdapter.xml' path='docs/Ctor3/*'/>
public MySqlDataAdapter(string selectCommandText, string selectConnString) : this()
{
SelectCommand = new MySqlCommand(selectCommandText,
new MySqlConnection(selectConnString) );
}
#region Properties
/// <include file='docs/MySqlDataAdapter.xml' path='docs/DeleteCommand/*'/>
#if !CF
[Description("Used during Update for deleted rows in Dataset.")]
#endif
public new MySqlCommand DeleteCommand
{
get { return (MySqlCommand)base.DeleteCommand; }
set { base.DeleteCommand = value; }
}
/// <include file='docs/MySqlDataAdapter.xml' path='docs/InsertCommand/*'/>
#if !CF
[Description("Used during Update for new rows in Dataset.")]
#endif
public new MySqlCommand InsertCommand
{
get { return (MySqlCommand)base.InsertCommand; }
set { base.InsertCommand = value; }
}
/// <include file='docs/MySqlDataAdapter.xml' path='docs/SelectCommand/*'/>
#if !CF
[Description("Used during Fill/FillSchema")]
[Category("Fill")]
#endif
public new MySqlCommand SelectCommand
{
get { return (MySqlCommand)base.SelectCommand; }
set { base.SelectCommand = value; }
}
/// <include file='docs/MySqlDataAdapter.xml' path='docs/UpdateCommand/*'/>
#if !CF
[Description("Used during Update for modified rows in Dataset.")]
#endif
public new MySqlCommand UpdateCommand
{
get { return (MySqlCommand)base.UpdateCommand; }
set { base.UpdateCommand = value; }
}
internal bool LoadDefaults
{
get { return loadingDefaults; }
set { loadingDefaults = value; }
}
#endregion
#region Batching Support
public override int UpdateBatchSize
{
get { return updateBatchSize; }
set { updateBatchSize = value; }
}
protected override void InitializeBatching()
{
commandBatch = new List<IDbCommand>();
}
protected override int AddToBatch(IDbCommand command)
{
// the first time each command is asked to be batched, we ask
// that command to prepare its batchable command text. We only want
// to do this one time for each command
MySqlCommand commandToBatch = (MySqlCommand)command;
if (commandToBatch.BatchableCommandText == null)
commandToBatch.GetCommandTextForBatching();
IDbCommand cloneCommand = (IDbCommand)((ICloneable)command).Clone();
commandBatch.Add(cloneCommand);
return commandBatch.Count - 1;
}
protected override int ExecuteBatch()
{
int recordsAffected = 0;
int index = 0;
while (index < commandBatch.Count)
{
MySqlCommand cmd = (MySqlCommand)commandBatch[index++];
for (int index2 = index; index2 < commandBatch.Count; index2++,index++)
{
MySqlCommand cmd2 = (MySqlCommand)commandBatch[index2];
if (cmd2.BatchableCommandText == null ||
cmd2.CommandText != cmd.CommandText) break;
cmd.AddToBatch(cmd2);
}
recordsAffected += cmd.ExecuteNonQuery();
}
return recordsAffected;
}
protected override void ClearBatch()
{
if (commandBatch.Count > 0)
{
MySqlCommand cmd = (MySqlCommand)commandBatch[0];
if (cmd.Batch != null)
cmd.Batch.Clear();
}
commandBatch.Clear();
}
protected override void TerminateBatching()
{
ClearBatch();
commandBatch = null;
}
protected override IDataParameter GetBatchedParameter(int commandIdentifier, int parameterIndex)
{
return (IDataParameter)commandBatch[commandIdentifier].Parameters[parameterIndex];
}
#endregion
/// <summary>
/// Overridden. See <see cref="DbDataAdapter.CreateRowUpdatedEvent"/>.
/// </summary>
/// <param name="dataRow"></param>
/// <param name="command"></param>
/// <param name="statementType"></param>
/// <param name="tableMapping"></param>
/// <returns></returns>
override protected RowUpdatedEventArgs CreateRowUpdatedEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
{
return new MySqlRowUpdatedEventArgs(dataRow, command, statementType, tableMapping);
}
/// <summary>
/// Overridden. See <see cref="DbDataAdapter.CreateRowUpdatingEvent"/>.
/// </summary>
/// <param name="dataRow"></param>
/// <param name="command"></param>
/// <param name="statementType"></param>
/// <param name="tableMapping"></param>
/// <returns></returns>
override protected RowUpdatingEventArgs CreateRowUpdatingEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
{
return new MySqlRowUpdatingEventArgs(dataRow, command, statementType, tableMapping);
}
/// <summary>
/// Overridden. Raises the RowUpdating event.
/// </summary>
/// <param name="value">A MySqlRowUpdatingEventArgs that contains the event data.</param>
override protected void OnRowUpdating(RowUpdatingEventArgs value)
{
if (RowUpdating != null)
RowUpdating(this, (value as MySqlRowUpdatingEventArgs));
}
/// <summary>
/// Overridden. Raises the RowUpdated event.
/// </summary>
/// <param name="value">A MySqlRowUpdatedEventArgs that contains the event data. </param>
override protected void OnRowUpdated(RowUpdatedEventArgs value)
{
if (RowUpdated != null)
RowUpdated(this, (value as MySqlRowUpdatedEventArgs));
}
}
/// <summary>
/// Represents the method that will handle the <see cref="MySqlDataAdapter.RowUpdating"/> event of a <see cref="MySqlDataAdapter"/>.
/// </summary>
public delegate void MySqlRowUpdatingEventHandler(object sender, MySqlRowUpdatingEventArgs e);
/// <summary>
/// Represents the method that will handle the <see cref="MySqlDataAdapter.RowUpdated"/> event of a <see cref="MySqlDataAdapter"/>.
/// </summary>
public delegate void MySqlRowUpdatedEventHandler(object sender, MySqlRowUpdatedEventArgs e);
/// <summary>
/// Provides data for the RowUpdating event. This class cannot be inherited.
/// </summary>
public sealed class MySqlRowUpdatingEventArgs : RowUpdatingEventArgs
{
/// <summary>
/// Initializes a new instance of the MySqlRowUpdatingEventArgs class.
/// </summary>
/// <param name="row">The <see cref="DataRow"/> to
/// <see cref="DbDataAdapter.Update(DataSet)"/>.</param>
/// <param name="command">The <see cref="IDbCommand"/> to execute during <see cref="DbDataAdapter.Update(DataSet)"/>.</param>
/// <param name="statementType">One of the <see cref="StatementType"/> values that specifies the type of query executed.</param>
/// <param name="tableMapping">The <see cref="DataTableMapping"/> sent through an <see cref="DbDataAdapter.Update(DataSet)"/>.</param>
public MySqlRowUpdatingEventArgs(DataRow row, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
: base(row, command, statementType, tableMapping)
{
}
/// <summary>
/// Gets or sets the MySqlCommand to execute when performing the Update.
/// </summary>
new public MySqlCommand Command
{
get { return (MySqlCommand)base.Command; }
set { base.Command = value; }
}
}
/// <summary>
/// Provides data for the RowUpdated event. This class cannot be inherited.
/// </summary>
public sealed class MySqlRowUpdatedEventArgs : RowUpdatedEventArgs
{
/// <summary>
/// Initializes a new instance of the MySqlRowUpdatedEventArgs class.
/// </summary>
/// <param name="row">The <see cref="DataRow"/> sent through an <see cref="DbDataAdapter.Update(DataSet)"/>.</param>
/// <param name="command">The <see cref="IDbCommand"/> executed when <see cref="DbDataAdapter.Update(DataSet)"/> is called.</param>
/// <param name="statementType">One of the <see cref="StatementType"/> values that specifies the type of query executed.</param>
/// <param name="tableMapping">The <see cref="DataTableMapping"/> sent through an <see cref="DbDataAdapter.Update(DataSet)"/>.</param>
public MySqlRowUpdatedEventArgs(DataRow row, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
: base(row, command, statementType, tableMapping)
{
}
/// <summary>
/// Gets or sets the MySqlCommand executed when Update is called.
/// </summary>
new public MySqlCommand Command
{
get { return (MySqlCommand)base.Command; }
}
}
}

@ -0,0 +1,924 @@
// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// 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.Data.Common;
using System.Collections;
using MySql.Data.Types;
using System.Data.SqlTypes;
using System.Collections.Generic;
using System.Globalization;
using MySql.Data.MySqlClient.Properties;
namespace MySql.Data.MySqlClient
{
/// <include file='docs/MySqlDataReader.xml' path='docs/ClassSummary/*'/>
public sealed class MySqlDataReader : DbDataReader, IDataReader, IDataRecord
{
// The DataReader should always be open when returned to the user.
private bool isOpen = true;
private CommandBehavior commandBehavior;
private MySqlCommand command;
internal long affectedRows;
internal Driver driver;
private PreparableStatement statement;
private ResultSet resultSet;
/*
* Keep track of the connection in order to implement the
* CommandBehavior.CloseConnection flag. A null reference means
* normal behavior (do not automatically close).
*/
private MySqlConnection connection;
/*
* Because the user should not be able to directly create a
* DataReader object, the constructors are
* marked as internal.
*/
internal MySqlDataReader(MySqlCommand cmd, PreparableStatement statement, CommandBehavior behavior)
{
this.command = cmd;
connection = (MySqlConnection)command.Connection;
commandBehavior = behavior;
driver = connection.driver;
affectedRows = -1;
this.statement = statement;
}
#region Properties
internal PreparableStatement Statement
{
get { return statement; }
}
internal MySqlCommand Command
{
get { return command; }
}
internal ResultSet ResultSet
{
get { return resultSet; }
}
/// <summary>
/// Gets a value indicating the depth of nesting for the current row. This method is not
/// supported currently and always returns 0.
/// </summary>
public override int Depth
{
get { return 0; }
}
/// <summary>
/// Gets the number of columns in the current row.
/// </summary>
public override int FieldCount
{
get { return resultSet == null ? 0 : resultSet.Size; }
}
/// <summary>
/// Gets a value indicating whether the MySqlDataReader contains one or more rows.
/// </summary>
public override bool HasRows
{
get { return resultSet == null ? false : resultSet.HasRows; }
}
/// <summary>
/// Gets a value indicating whether the data reader is closed.
/// </summary>
public override bool IsClosed
{
get { return !isOpen; }
}
/// <summary>
/// Gets the number of rows changed, inserted, or deleted by execution of the SQL statement.
/// </summary>
public override int RecordsAffected
{
// 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 (int)affectedRows; }
}
/// <summary>
/// Overloaded. Gets the value of a column in its native format.
/// In C#, this property is the indexer for the MySqlDataReader class.
/// </summary>
public override object this[int i]
{
get { return GetValue(i); }
}
/// <summary>
/// Gets the value of a column in its native format.
/// [C#] In C#, this property is the indexer for the MySqlDataReader class.
/// </summary>
public override object this[String name]
{
// Look up the ordinal and return
// the value at that position.
get { return this[GetOrdinal(name)]; }
}
#endregion
/// <summary>
/// Closes the MySqlDataReader object.
/// </summary>
public override void Close()
{
if (!isOpen) return;
bool shouldCloseConnection = (commandBehavior & CommandBehavior.CloseConnection) != 0;
commandBehavior = CommandBehavior.Default;
// clear all remaining resultsets
try
{
while (NextResult()) { }
}
catch (MySqlException ex)
{
if (ex.Number != 1317)
throw;
}
connection.Reader = null;
// 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(this);
if (shouldCloseConnection)
connection.Close();
command = null;
connection = null;
isOpen = false;
}
#region TypeSafe Accessors
/// <summary>
/// Gets the value of the specified column as a Boolean.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public bool GetBoolean(string name)
{
return GetBoolean(GetOrdinal(name));
}
/// <summary>
/// Gets the value of the specified column as a Boolean.
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public override bool GetBoolean(int i)
{
return Convert.ToBoolean(GetValue(i));
}
/// <summary>
/// Gets the value of the specified column as a byte.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public byte GetByte(string name)
{
return GetByte(GetOrdinal(name));
}
/// <summary>
/// Gets the value of the specified column as a byte.
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public override byte GetByte(int i)
{
IMySqlValue v = GetFieldValue(i, false);
if (v is MySqlUByte)
return ((MySqlUByte)v).Value;
else
return (byte)((MySqlByte)v).Value;
}
/// <summary>
/// Gets the value of the specified column as a sbyte.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public sbyte GetSByte(string name)
{
return GetSByte(GetOrdinal(name));
}
/// <summary>
/// Gets the value of the specified column as a sbyte.
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public sbyte GetSByte(int i)
{
IMySqlValue v = GetFieldValue(i, false);
if (v is MySqlByte)
return ((MySqlByte)v).Value;
else
return (sbyte)((MySqlByte)v).Value;
}
/// <summary>
/// Reads a stream of bytes from the specified column offset into the buffer an array starting at the given buffer offset.
/// </summary>
/// <param name="i">The zero-based column ordinal. </param>
/// <param name="fieldOffset">The index within the field from which to begin the read operation. </param>
/// <param name="buffer">The buffer into which to read the stream of bytes. </param>
/// <param name="bufferoffset">The index for buffer to begin the read operation. </param>
/// <param name="length">The maximum length to copy into the buffer. </param>
/// <returns>The actual number of bytes read.</returns>
/// <include file='docs/MySqlDataReader.xml' path='MyDocs/MyMembers[@name="GetBytes"]/*'/>
public override long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
{
if (i >= FieldCount)
throw new IndexOutOfRangeException();
IMySqlValue val = GetFieldValue(i, false);
if (!(val is MySqlBinary) && !(val is MySqlGuid))
throw new MySqlException("GetBytes can only be called on binary or guid columns");
byte[] bytes = null;
if (val is MySqlBinary)
bytes = ((MySqlBinary)val).Value;
else
bytes = ((MySqlGuid)val).Bytes;
if (buffer == null)
return bytes.Length;
if (bufferoffset >= buffer.Length || bufferoffset < 0)
throw new IndexOutOfRangeException("Buffer index must be a valid index in buffer");
if (buffer.Length < (bufferoffset + length))
throw new ArgumentException("Buffer is not large enough to hold the requested data");
if (fieldOffset < 0 ||
((ulong)fieldOffset >= (ulong)bytes.Length && (ulong)bytes.Length > 0))
throw new IndexOutOfRangeException("Data index must be a valid index in the field");
// adjust the length so we don't run off the end
if ((ulong)bytes.Length < (ulong)(fieldOffset + length))
{
length = (int)((ulong)bytes.Length - (ulong)fieldOffset);
}
Buffer.BlockCopy(bytes, (int)fieldOffset, buffer, (int)bufferoffset, (int)length);
return length;
}
private object ChangeType(IMySqlValue value, int fieldIndex, Type newType)
{
#if !CF
resultSet.Fields[fieldIndex].AddTypeConversion(newType);
#endif
return Convert.ChangeType(value.Value, newType, CultureInfo.InvariantCulture);
}
/// <summary>
/// Gets the value of the specified column as a single character.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public char GetChar(string name)
{
return GetChar(GetOrdinal(name));
}
/// <summary>
/// Gets the value of the specified column as a single character.
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public override char GetChar(int i)
{
string s = GetString(i);
return s[0];
}
/// <summary>
/// Reads a stream of characters from the specified column offset into the buffer as an array starting at the given buffer offset.
/// </summary>
/// <param name="i"></param>
/// <param name="fieldoffset"></param>
/// <param name="buffer"></param>
/// <param name="bufferoffset"></param>
/// <param name="length"></param>
/// <returns></returns>
public override long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
{
if (i >= FieldCount)
throw new IndexOutOfRangeException();
string valAsString = GetString(i);
if (buffer == null) return valAsString.Length;
if (bufferoffset >= buffer.Length || bufferoffset < 0)
throw new IndexOutOfRangeException("Buffer index must be a valid index in buffer");
if (buffer.Length < (bufferoffset + length))
throw new ArgumentException("Buffer is not large enough to hold the requested data");
if (fieldoffset < 0 || fieldoffset >= valAsString.Length)
throw new IndexOutOfRangeException("Field offset must be a valid index in the field");
if (valAsString.Length < length)
length = valAsString.Length;
valAsString.CopyTo((int)fieldoffset, buffer, bufferoffset, length);
return length;
}
/// <summary>
/// Gets the name of the source data type.
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public override String GetDataTypeName(int i)
{
if (!isOpen) throw new Exception("No current query in data reader");
if (i >= FieldCount) throw new IndexOutOfRangeException();
// return the name of the type used on the backend
IMySqlValue v = resultSet.Values[i];
return v.MySqlTypeName;
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetMySqlDateTime/*'/>
public MySqlDateTime GetMySqlDateTime(string column)
{
return GetMySqlDateTime(GetOrdinal(column));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetMySqlDateTime/*'/>
public MySqlDateTime GetMySqlDateTime(int column)
{
return (MySqlDateTime)GetFieldValue(column, true);
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetDateTimeS/*'/>
public DateTime GetDateTime(string column)
{
return GetDateTime(GetOrdinal(column));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetDateTime/*'/>
public override DateTime GetDateTime(int i)
{
IMySqlValue val = GetFieldValue(i, true);
MySqlDateTime dt;
if (val is MySqlDateTime)
dt = (MySqlDateTime)val;
else
{
// we need to do this because functions like date_add return string
string s = GetString(i);
dt = MySqlDateTime.Parse(s);
}
if (connection.Settings.ConvertZeroDateTime && !dt.IsValidDateTime)
return DateTime.MinValue;
else
return dt.GetDateTime();
}
public MySqlDecimal GetMySqlDecimal(string column)
{
return GetMySqlDecimal(GetOrdinal(column));
}
public MySqlDecimal GetMySqlDecimal(int i)
{
return (MySqlDecimal)GetFieldValue(i, false);
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetDecimalS/*'/>
public Decimal GetDecimal(string column)
{
return GetDecimal(GetOrdinal(column));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetDecimal/*'/>
public override Decimal GetDecimal(int i)
{
IMySqlValue v = GetFieldValue(i, true);
if (v is MySqlDecimal)
return ((MySqlDecimal)v).Value;
return Convert.ToDecimal(v.Value);
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetDoubleS/*'/>
public double GetDouble(string column)
{
return GetDouble(GetOrdinal(column));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetDouble/*'/>
public override double GetDouble(int i)
{
IMySqlValue v = GetFieldValue(i, true);
if (v is MySqlDouble)
return ((MySqlDouble)v).Value;
return Convert.ToDouble(v.Value);
}
public Type GetFieldType(string column)
{
return GetFieldType(GetOrdinal(column));
}
/// <summary>
/// Gets the Type that is the data type of the object.
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public override Type GetFieldType(int i)
{
if (!isOpen) throw new Exception("No current query in data reader");
if (i >= FieldCount) throw new IndexOutOfRangeException();
// we have to use the values array directly because we can't go through
// GetValue
IMySqlValue v = resultSet.Values[i];
if (v is MySqlDateTime)
{
if (!connection.Settings.AllowZeroDateTime)
return typeof(DateTime);
return typeof(MySqlDateTime);
}
return v.SystemType;
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetFloatS/*'/>
public float GetFloat(string column)
{
return GetFloat(GetOrdinal(column));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetFloat/*'/>
public override float GetFloat(int i)
{
IMySqlValue v = GetFieldValue(i, true);
if (v is MySqlSingle)
return ((MySqlSingle)v).Value;
return Convert.ToSingle(v.Value);
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetGuidS/*'/>
public Guid GetGuid(string column)
{
return GetGuid(GetOrdinal(column));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetGuid/*'/>
public override Guid GetGuid(int i)
{
object v = GetValue(i);
if (v is Guid)
return (Guid)v;
if (v is string)
return new Guid(v as string);
if (v is byte[])
{
byte[] bytes = (byte[])v;
if (bytes.Length == 16)
return new Guid(bytes);
}
throw new MySqlException(Resources.ValueNotSupportedForGuid);
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetInt16S/*'/>
public Int16 GetInt16(string column)
{
return GetInt16(GetOrdinal(column));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetInt16/*'/>
public override Int16 GetInt16(int i)
{
IMySqlValue v = GetFieldValue(i, true);
if (v is MySqlInt16)
return ((MySqlInt16)v).Value;
return (short)ChangeType(v, i, typeof(short));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetInt32S/*'/>
public Int32 GetInt32(string column)
{
return GetInt32(GetOrdinal(column));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetInt32/*'/>
public override Int32 GetInt32(int i)
{
IMySqlValue v = GetFieldValue(i, true);
if (v is MySqlInt32)
return ((MySqlInt32)v).Value;
return (Int32)ChangeType(v, i, typeof(Int32));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetInt64S/*'/>
public Int64 GetInt64(string column)
{
return GetInt64(GetOrdinal(column));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetInt64/*'/>
public override Int64 GetInt64(int i)
{
IMySqlValue v = GetFieldValue(i, true);
if (v is MySqlInt64)
return ((MySqlInt64)v).Value;
return (Int64)ChangeType(v, i, typeof(Int64));
}
/// <summary>
/// Gets the name of the specified column.
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public override String GetName(int i)
{
if (!isOpen) throw new Exception("No current query in data reader");
if (i >= FieldCount) throw new IndexOutOfRangeException();
return resultSet.Fields[i].ColumnName;
}
/// <summary>
/// Gets the column ordinal, given the name of the column.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public override int GetOrdinal(string name)
{
if (!isOpen || resultSet == null)
throw new Exception("No current query in data reader");
return resultSet.GetOrdinal(name);
}
/// <summary>
/// Returns a DataTable that describes the column metadata of the MySqlDataReader.
/// </summary>
/// <returns></returns>
public override DataTable GetSchemaTable()
{
// Only Results from SQL SELECT Queries
// get a DataTable for schema of the result
// otherwise, DataTable is null reference
if (FieldCount == 0) return null;
DataTable dataTableSchema = new DataTable("SchemaTable");
dataTableSchema.Columns.Add("ColumnName", typeof(string));
dataTableSchema.Columns.Add("ColumnOrdinal", typeof(int));
dataTableSchema.Columns.Add("ColumnSize", typeof(int));
dataTableSchema.Columns.Add("NumericPrecision", typeof(int));
dataTableSchema.Columns.Add("NumericScale", typeof(int));
dataTableSchema.Columns.Add("IsUnique", typeof(bool));
dataTableSchema.Columns.Add("IsKey", typeof(bool));
DataColumn dc = dataTableSchema.Columns["IsKey"];
dc.AllowDBNull = true; // IsKey can have a DBNull
dataTableSchema.Columns.Add("BaseCatalogName", typeof(string));
dataTableSchema.Columns.Add("BaseColumnName", typeof(string));
dataTableSchema.Columns.Add("BaseSchemaName", typeof(string));
dataTableSchema.Columns.Add("BaseTableName", typeof(string));
dataTableSchema.Columns.Add("DataType", typeof(Type));
dataTableSchema.Columns.Add("AllowDBNull", typeof(bool));
dataTableSchema.Columns.Add("ProviderType", typeof(int));
dataTableSchema.Columns.Add("IsAliased", typeof(bool));
dataTableSchema.Columns.Add("IsExpression", typeof(bool));
dataTableSchema.Columns.Add("IsIdentity", typeof(bool));
dataTableSchema.Columns.Add("IsAutoIncrement", typeof(bool));
dataTableSchema.Columns.Add("IsRowVersion", typeof(bool));
dataTableSchema.Columns.Add("IsHidden", typeof(bool));
dataTableSchema.Columns.Add("IsLong", typeof(bool));
dataTableSchema.Columns.Add("IsReadOnly", typeof(bool));
int ord = 1;
for (int i = 0; i < FieldCount; i++)
{
MySqlField f = resultSet.Fields[i];
DataRow r = dataTableSchema.NewRow();
r["ColumnName"] = f.ColumnName;
r["ColumnOrdinal"] = ord++;
r["ColumnSize"] = f.IsTextField ? f.ColumnLength / f.MaxLength : f.ColumnLength;
int prec = f.Precision;
int pscale = f.Scale;
if (prec != -1)
r["NumericPrecision"] = (short)prec;
if (pscale != -1)
r["NumericScale"] = (short)pscale;
r["DataType"] = GetFieldType(i);
r["ProviderType"] = (int)f.Type;
r["IsLong"] = f.IsBlob && f.ColumnLength > 255;
r["AllowDBNull"] = f.AllowsNull;
r["IsReadOnly"] = false;
r["IsRowVersion"] = false;
r["IsUnique"] = f.IsUnique;
r["IsKey"] = f.IsPrimaryKey;
r["IsAutoIncrement"] = f.IsAutoIncrement;
r["BaseSchemaName"] = f.DatabaseName;
r["BaseCatalogName"] = null;
r["BaseTableName"] = f.RealTableName;
r["BaseColumnName"] = f.OriginalColumnName;
dataTableSchema.Rows.Add(r);
}
return dataTableSchema;
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetStringS/*'/>
public string GetString(string column)
{
return GetString(GetOrdinal(column));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetString/*'/>
public override String GetString(int i)
{
IMySqlValue val = GetFieldValue(i, true);
if (val is MySqlBinary)
{
byte[] v = ((MySqlBinary)val).Value;
return resultSet.Fields[i].Encoding.GetString(v, 0, v.Length);
}
return val.Value.ToString();
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetTimeSpan/*'/>
public TimeSpan GetTimeSpan(string column)
{
return GetTimeSpan(GetOrdinal(column));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetTimeSpan/*'/>
public TimeSpan GetTimeSpan(int column)
{
IMySqlValue val = GetFieldValue(column, true);
MySqlTimeSpan ts = (MySqlTimeSpan)val;
return ts.Value;
}
/// <summary>
/// Gets the value of the specified column in its native format.
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public override object GetValue(int i)
{
if (!isOpen) throw new Exception("No current query in data reader");
if (i >= FieldCount) throw new IndexOutOfRangeException();
IMySqlValue val = GetFieldValue(i, false);
if (val.IsNull)
return DBNull.Value;
// if the column is a date/time, then we return a MySqlDateTime
// so .ToString() will print '0000-00-00' correctly
if (val is MySqlDateTime)
{
MySqlDateTime dt = (MySqlDateTime)val;
if (!dt.IsValidDateTime && connection.Settings.ConvertZeroDateTime)
return DateTime.MinValue;
else if (connection.Settings.AllowZeroDateTime)
return val;
else
return dt.GetDateTime();
}
return val.Value;
}
/// <summary>
/// Gets all attribute columns in the collection for the current row.
/// </summary>
/// <param name="values"></param>
/// <returns></returns>
public override int GetValues(object[] values)
{
int numCols = Math.Min(values.Length, FieldCount);
for (int i = 0; i < numCols; i++)
values[i] = GetValue(i);
return numCols;
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt16/*'/>
public UInt16 GetUInt16(string column)
{
return GetUInt16(GetOrdinal(column));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt16/*'/>
public UInt16 GetUInt16(int column)
{
IMySqlValue v = GetFieldValue(column, true);
if (v is MySqlUInt16)
return ((MySqlUInt16)v).Value;
return (UInt16)ChangeType(v, column, typeof(UInt16));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt32/*'/>
public UInt32 GetUInt32(string column)
{
return GetUInt32(GetOrdinal(column));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt32/*'/>
public UInt32 GetUInt32(int column)
{
IMySqlValue v = GetFieldValue(column, true);
if (v is MySqlUInt32)
return ((MySqlUInt32)v).Value;
return (uint)ChangeType(v, column, typeof(UInt32));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt64/*'/>
public UInt64 GetUInt64(string column)
{
return GetUInt64(GetOrdinal(column));
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt64/*'/>
public UInt64 GetUInt64(int column)
{
IMySqlValue v = GetFieldValue(column, true);
if (v is MySqlUInt64)
return ((MySqlUInt64)v).Value;
return (UInt64)ChangeType(v, column, typeof(UInt64));
}
#endregion
IDataReader IDataRecord.GetData(int i)
{
return base.GetData(i);
}
/// <summary>
/// Gets a value indicating whether the column contains non-existent or missing values.
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public override bool IsDBNull(int i)
{
return DBNull.Value == GetValue(i);
}
/// <summary>
/// Advances the data reader to the next result, when reading the results of batch SQL statements.
/// </summary>
/// <returns></returns>
public override bool NextResult()
{
if (!isOpen)
throw new MySqlException(Resources.NextResultIsClosed);
// this will clear out any unread data
if (resultSet != null)
resultSet.Close();
// single result means we only return a single resultset. If we have already
// returned one, then we return false;
if (resultSet != null && (commandBehavior & CommandBehavior.SingleResult) != 0)
return false;
// next load up the next resultset if any
try
{
do
{
resultSet = null;
resultSet = driver.NextResult(Statement.StatementId);
if (resultSet == null) return false;
if (resultSet.IsOutputParameters) return false;
if (resultSet.Size == 0)
{
Command.lastInsertedId = resultSet.InsertedId;
if (affectedRows == -1)
affectedRows = resultSet.AffectedRows;
else
affectedRows += resultSet.AffectedRows;
}
} while (resultSet.Size == 0);
return true;
}
catch (MySqlException ex)
{
if (ex.IsFatal)
connection.Abort();
if (ex.Number == 0)
throw new MySqlException(Resources.FatalErrorReadingResult, ex);
throw;
}
}
/// <summary>
/// Advances the MySqlDataReader to the next record.
/// </summary>
/// <returns></returns>
public override bool Read()
{
if (!isOpen)
throw new MySqlException("Invalid attempt to Read when reader is closed.");
if (resultSet == null)
return false;
try
{
return resultSet.NextRow(commandBehavior);
}
catch (TimeoutException tex)
{
connection.HandleTimeout(tex);
return false; // unreached
}
catch (MySqlException ex)
{
if (ex.IsFatal)
connection.Abort();
// if we get a query interrupted then our resultset is done
if (ex.Number == 1317)
{
return false;
}
throw new MySqlException(Resources.FatalErrorDuringRead, ex);
}
}
private IMySqlValue GetFieldValue(int index, bool checkNull)
{
if (index < 0 || index >= FieldCount)
throw new ArgumentException(Resources.InvalidColumnOrdinal);
IMySqlValue v = resultSet[index];
if (checkNull && v.IsNull)
throw new SqlNullValueException();
return v;
}
#region IEnumerator
/// <summary>
/// Returns an <see cref="IEnumerator"/> that iterates through the <see cref="MySqlDataReader"/>.
/// </summary>
/// <returns></returns>
public override IEnumerator GetEnumerator()
{
return new DbEnumerator(this, (commandBehavior & CommandBehavior.CloseConnection) != 0);
}
#endregion
}
}

@ -0,0 +1,934 @@
<docs>
<ClassSummary>
<summary>Represents a SQL statement to execute against a MySQL database. This class cannot be inherited.</summary>
<remarks>
<B>MySqlCommand</B> features the following methods for executing commands at a MySQL database:
<list type="table">
<listheader>
<term>Item</term>
<term>Description</term>
</listheader>
<item>
<term>
<a href="MySql.Data.MySqlClient.MySqlCommand.ExecuteReader_overloads.html">ExecuteReader</a>
</term>
<description>Executes commands that return rows.</description>
</item>
<item>
<term>
<a href="MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery.html">ExecuteNonQuery</a>
</term>
<description>Executes commands such as SQL INSERT, DELETE, and UPDATE statements.</description>
</item>
<item>
<term>
<a href="MySql.Data.MySqlClient.MySqlCommand.ExecuteScalar.html">ExecuteScalar</a>
</term>
<description>Retrieves a single value (for example, an aggregate value) from a database.</description>
</item>
</list>
You can reset the <B>CommandText</B> property and reuse the <B>MySqlCommand</B>
object. However, you must close the <A
href="MySql.Data.MySqlClient.MySqlDataReader.html">MySqlDataReader</A>
before you can execute a new or previous command.
If a <A href="MySql.Data.MySqlClient.MySqlException.html">MySqlException</A> is
generated by the method executing a <B>MySqlCommand</B>, the <A
href="MySql.Data.MySqlClient.MySqlConnection.html">MySqlConnection</A>
remains open. It is the responsibility of the programmer to close the connection.
<note>
Using the '@' symbol for paramters is now the preferred approach although the old pattern of using
'?' is still supported. Please be aware though that using '@' can cause conflicts when user variables
are also used. To help with this situation please see the documentation on the 'allow user variables'
connection string option. The 'old syntax' connection string option has now been deprecated.
</note>
</remarks>
<example>
The following example creates a <A href="frlrfsystemdatasqlclientsqlcommandclasstopic.htm">MySqlCommand</A> and
a <B>MySqlConnection</B>. The <B>MySqlConnection</B> is opened and set as the <A
href="frlrfsystemdatasqlclientsqlcommandclassconnectiontopic.htm">Connection</A>
for the <B>MySqlCommand</B>. The example then calls <A
href="frlrfsystemdatasqlclientsqlcommandclassexecutenonquerytopic.htm">ExecuteNonQuery</A>,
and closes the connection. To accomplish this, the <B>ExecuteNonQuery</B> is
passed a connection string and a query string that is a SQL INSERT
statement.
<code lang="vbnet">
Public Sub InsertRow(myConnectionString As String)
&quot; If the connection string is null, use a default.
If myConnectionString = "" Then
myConnectionString = "Database=Test;Data Source=localhost;User Id=username;Password=pass"
End If
Dim myConnection As New MySqlConnection(myConnectionString)
Dim myInsertQuery As String = "INSERT INTO Orders (id, customerId, amount) Values(1001, 23, 30.66)"
Dim myCommand As New MySqlCommand(myInsertQuery)
myCommand.Connection = myConnection
myConnection.Open()
myCommand.ExecuteNonQuery()
myCommand.Connection.Close()
End Sub
</code>
<code lang="C#">
public void InsertRow(string myConnectionString)
{
// If the connection string is null, use a default.
if(myConnectionString == "")
{
myConnectionString = "Database=Test;Data Source=localhost;User Id=username;Password=pass";
}
MySqlConnection myConnection = new MySqlConnection(myConnectionString);
string myInsertQuery = "INSERT INTO Orders (id, customerId, amount) Values(1001, 23, 30.66)";
MySqlCommand myCommand = new MySqlCommand(myInsertQuery);
myCommand.Connection = myConnection;
myConnection.Open();
myCommand.ExecuteNonQuery();
myCommand.Connection.Close();
}
</code>
</example>
</ClassSummary>
<ctor1>
<overloads>
<summary>
Initializes a new instance of the MySqlCommand class.
</summary>
<example>
The following example creates a MySqlCommand and sets some of its properties.
<para></para>
<note>
This example shows how to use one of the overloaded
versions of the MySqlCommand constructor. For other examples that might be available,
see the individual overload topics.
</note>
<code lang="vbnet">
Public Sub CreateMySqlCommand()
Dim myConnection As New MySqlConnection _
("Persist Security Info=False;database=test;server=myServer")
myConnection.Open()
Dim myTrans As MySqlTransaction = myConnection.BeginTransaction()
Dim mySelectQuery As String = "SELECT * FROM MyTable"
Dim myCommand As New MySqlCommand(mySelectQuery, myConnection, myTrans)
myCommand.CommandTimeout = 20
End Sub
</code>
<code lang="C#">
public void CreateMySqlCommand()
{
MySqlConnection myConnection = new MySqlConnection("Persist Security Info=False;
database=test;server=myServer");
myConnection.Open();
MySqlTransaction myTrans = myConnection.BeginTransaction();
string mySelectQuery = "SELECT * FROM myTable";
MySqlCommand myCommand = new MySqlCommand(mySelectQuery, myConnection,myTrans);
myCommand.CommandTimeout = 20;
}
</code>
<code lang="C++">
public:
void CreateMySqlCommand()
{
MySqlConnection* myConnection = new MySqlConnection(S"Persist Security Info=False;
database=test;server=myServer");
myConnection->Open();
MySqlTransaction* myTrans = myConnection->BeginTransaction();
String* mySelectQuery = S"SELECT * FROM myTable";
MySqlCommand* myCommand = new MySqlCommand(mySelectQuery, myConnection, myTrans);
myCommand->CommandTimeout = 20;
};
</code>
</example>
</overloads>
<summary>
Initializes a new instance of the MySqlCommand class.
</summary>
<remarks>
The base constructor initializes all fields to their default values. The
following table shows initial property values for an instance of <see cref="MySqlCommand"/>.
<list type="table">
<listheader>
<term>Properties</term>
<term>Initial Value</term>
</listheader>
<item>
<term>
<see cref="CommandText"/>
</term>
<term>empty string ("")</term>
</item>
<item>
<term>
<see cref="CommandTimeout"/>
</term>
<term>0</term>
</item>
<item>
<term>
<see cref="CommandType"/>
</term>
<term>CommandType.Text</term>
</item>
<item>
<term>
<see cref="Connection"/>
</term>
<term>Null</term>
</item>
</list>
<para>
You can change the value for any of these properties through a separate call to
the property.
</para>
</remarks>
<example>
The following example creates a <see cref="MySqlCommand"/> and
sets some of its properties.
<code lang="vbnet">
Public Sub CreateMySqlCommand()
Dim myCommand As New MySqlCommand()
myCommand.CommandType = CommandType.Text
End Sub
</code>
<code lang="C#">
public void CreateMySqlCommand()
{
MySqlCommand myCommand = new MySqlCommand();
myCommand.CommandType = CommandType.Text;
}
</code>
</example>
</ctor1>
<ctor2>
<summary>
Initializes a new instance of the <see cref="MySqlCommand"/> class with the text of the query.
</summary>
<param name="cmdText">The text of the query.</param>
<remarks>
When an instance of <see cref="MySqlCommand"/> is created,
the following read/write properties are set to initial values.
<list type="table">
<listheader>
<term>Properties</term>
<term>Initial Value</term>
</listheader>
<item>
<term>
<see cref="CommandText"/>
</term>
<term>
<i>cmdText</i>
</term>
</item>
<item>
<term>
<see cref="CommandTimeout"/>
</term>
<term>0</term>
</item>
<item>
<term>
<see cref="CommandType"/>
</term>
<term>CommandType.Text</term>
</item>
<item>
<term>
<see cref="Connection"/>
</term>
<term>Null</term>
</item>
</list>
<para>
You can change the value for any of these properties through a separate call to
the property.
</para>
</remarks>
<example>
The following example creates a <see cref="MySqlCommand"/> and
sets some of its properties.
<code lang="vbnet">
Public Sub CreateMySqlCommand()
Dim sql as String = "SELECT * FROM mytable"
Dim myCommand As New MySqlCommand(sql)
myCommand.CommandType = CommandType.Text
End Sub
</code>
<code lang="C#">
public void CreateMySqlCommand()
{
string sql = "SELECT * FROM mytable";
MySqlCommand myCommand = new MySqlCommand(sql);
myCommand.CommandType = CommandType.Text;
}
</code>
</example>
</ctor2>
<ctor3>
<summary>
Initializes a new instance of the <see cref="MySqlCommand"/> class
with the text of the query and a <see cref="MySqlConnection"/>.
</summary>
<param name="cmdText">The text of the query.</param>
<param name="connection">
A <see cref="MySqlConnection"/> that represents the
connection to an instance of SQL Server.
</param>
<remarks>
When an instance of <see cref="MySqlCommand"/> is created,
the following read/write properties are set to initial values.
<list type="table">
<listheader>
<term>Properties</term>
<term>Initial Value</term>
</listheader>
<item>
<term>
<see cref="CommandText"/>
</term>
<term>
<i>cmdText</i>
</term>
</item>
<item>
<term>
<see cref="CommandTimeout"/>
</term>
<term>0</term>
</item>
<item>
<term>
<see cref="CommandType"/>
</term>
<term>CommandType.Text</term>
</item>
<item>
<term>
<see cref="Connection"/>
</term>
<term>
<i>connection</i>
</term>
</item>
</list>
<para>
You can change the value for any of these properties through a separate call to
the property.
</para>
</remarks>
<example>
The following example creates a <see cref="MySqlCommand"/> and
sets some of its properties.
<code lang="vbnet">
Public Sub CreateMySqlCommand()
Dim conn as new MySqlConnection("server=myServer")
Dim sql as String = "SELECT * FROM mytable"
Dim myCommand As New MySqlCommand(sql, conn)
myCommand.CommandType = CommandType.Text
End Sub
</code>
<code lang="C#">
public void CreateMySqlCommand()
{
MySqlConnection conn = new MySqlConnection("server=myserver")
string sql = "SELECT * FROM mytable";
MySqlCommand myCommand = new MySqlCommand(sql, conn);
myCommand.CommandType = CommandType.Text;
}
</code>
</example>
</ctor3>
<ctor4>
<summary>
Initializes a new instance of the <see cref="MySqlCommand"/> class
with the text of the query, a <see cref="MySqlConnection"/>, and the
<see cref="MySqlTransaction"/>.
</summary>
<param name="cmdText">The text of the query.</param>
<param name="connection">
A <see cref="MySqlConnection"/> that represents the
connection to an instance of SQL Server.
</param>
<param name="transaction">
The <see cref="MySqlTransaction"/> in which the <see cref="MySqlCommand"/> executes.
</param>
<remarks>
When an instance of <see cref="MySqlCommand"/> is created,
the following read/write properties are set to initial values.
<list type="table">
<listheader>
<term>Properties</term>
<term>Initial Value</term>
</listheader>
<item>
<term>
<see cref="CommandText"/>
</term>
<term>
<i>cmdText</i>
</term>
</item>
<item>
<term>
<see cref="CommandTimeout"/>
</term>
<term>0</term>
</item>
<item>
<term>
<see cref="CommandType"/>
</term>
<term>CommandType.Text</term>
</item>
<item>
<term>
<see cref="Connection"/>
</term>
<term>
<i>connection</i>
</term>
</item>
</list>
<para>
You can change the value for any of these properties through a separate call to
the property.
</para>
</remarks>
<example>
The following example creates a <see cref="MySqlCommand"/> and
sets some of its properties.
<code lang="vbnet">
Public Sub CreateMySqlCommand()
Dim conn as new MySqlConnection("server=myServer")
conn.Open();
Dim txn as MySqlTransaction = conn.BeginTransaction()
Dim sql as String = "SELECT * FROM mytable"
Dim myCommand As New MySqlCommand(sql, conn, txn)
myCommand.CommandType = CommandType.Text
End Sub
</code>
<code lang="C#">
public void CreateMySqlCommand()
{
MySqlConnection conn = new MySqlConnection("server=myserver")
conn.Open();
MySqlTransaction txn = conn.BeginTransaction();
string sql = "SELECT * FROM mytable";
MySqlCommand myCommand = new MySqlCommand(sql, conn, txn);
myCommand.CommandType = CommandType.Text;
}
</code>
</example>
</ctor4>
<ExecuteNonQuery>
<summary>
Executes a SQL statement against the connection and returns the number of rows affected.
</summary>
<returns>Number of rows affected</returns>
<remarks>
You can use ExecuteNonQuery to perform any type of database operation,
however any resultsets returned will not be available. Any output parameters
used in calling a stored procedure will be populated with data and can be
retrieved after execution is complete.
For UPDATE, INSERT, and DELETE statements, the return value is the number
of rows affected by the command. For all other types of statements, the return
value is -1.
</remarks>
<example>
The following example creates a MySqlCommand and then
executes it using ExecuteNonQuery. The example is passed a string that is a
SQL statement (such as UPDATE, INSERT, or DELETE) and a string to use to
connect to the data source.
<code lang="vbnet">
Public Sub CreateMySqlCommand(myExecuteQuery As String, myConnection As MySqlConnection)
Dim myCommand As New MySqlCommand(myExecuteQuery, myConnection)
myCommand.Connection.Open()
myCommand.ExecuteNonQuery()
myConnection.Close()
End Sub
</code>
<code lang="C#">
public void CreateMySqlCommand(string myExecuteQuery, MySqlConnection myConnection)
{
MySqlCommand myCommand = new MySqlCommand(myExecuteQuery, myConnection);
myCommand.Connection.Open();
myCommand.ExecuteNonQuery();
myConnection.Close();
}
</code>
</example>
</ExecuteNonQuery>
<ExecuteReader1>
<summary>
Sends the <see cref="CommandText"/> to the <see cref="MySqlConnection">Connection</see>,
and builds a <see cref="MySqlDataReader"/> using one of the <see cref="CommandBehavior"/> values.
</summary>
<param name="behavior">
One of the <see cref="CommandBehavior"/> values.
</param>
<remarks>
<para>
When the <see cref="CommandType"/> property is set to <B>StoredProcedure</B>,
the <see cref="CommandText"/> property should be set to the name of the stored
procedure. The command executes this stored procedure when you call
<B>ExecuteReader</B>.
</para>
<para>
The <see cref="MySqlDataReader"/> supports a special mode that enables large binary
values to be read efficiently. For more information, see the <B>SequentialAccess</B>
setting for <see cref="CommandBehavior"/>.
</para>
<para>
While the <see cref="MySqlDataReader"/> is in use, the associated
<see cref="MySqlConnection"/> is busy serving the <B>MySqlDataReader</B>.
While in this state, no other operations can be performed on the
<B>MySqlConnection</B> other than closing it. This is the case until the
<see cref="MySqlDataReader.Close"/> method of the <B>MySqlDataReader</B> is called.
If the <B>MySqlDataReader</B> is created with <B>CommandBehavior</B> set to
<B>CloseConnection</B>, closing the <B>MySqlDataReader</B> closes the connection
automatically.
</para>
<note>
When calling ExecuteReader with the SingleRow behavior, you should be aware that using a <i>limit</i>
clause in your SQL will cause all rows (up to the limit given) to be retrieved by the client. The
<see cref="MySqlDataReader.Read"/> method will still return false after the first row but pulling all rows of data
into the client will have a performance impact. If the <i>limit</i> clause is not necessary, it should
be avoided.
</note>
</remarks>
<returns>
A <see cref="MySqlDataReader"/> object.
</returns>
</ExecuteReader1>
<ExecuteReader>
<summary>
Sends the <see cref="CommandText"/> to the <see cref="MySqlConnection">Connection</see>
and builds a <see cref="MySqlDataReader"/>.
</summary>
<returns>
A <see cref="MySqlDataReader"/> object.
</returns>
<remarks>
<para>
When the <see cref="CommandType"/> property is set to <B>StoredProcedure</B>,
the <see cref="CommandText"/> property should be set to the name of the stored
procedure. The command executes this stored procedure when you call
<B>ExecuteReader</B>.
</para>
<para>
While the <see cref="MySqlDataReader"/> is in use, the associated
<see cref="MySqlConnection"/> is busy serving the <B>MySqlDataReader</B>.
While in this state, no other operations can be performed on the
<B>MySqlConnection</B> other than closing it. This is the case until the
<see cref="MySqlDataReader.Close"/> method of the <B>MySqlDataReader</B> is called.
</para>
</remarks>
<example>
The following example creates a <see cref="MySqlCommand"/>, then executes it by
passing a string that is a SQL SELECT statement, and a string to use to connect to the
data source.
<code lang="vbnet">
Public Sub CreateMySqlDataReader(mySelectQuery As String, myConnection As MySqlConnection)
Dim myCommand As New MySqlCommand(mySelectQuery, myConnection)
myConnection.Open()
Dim myReader As MySqlDataReader
myReader = myCommand.ExecuteReader()
Try
While myReader.Read()
Console.WriteLine(myReader.GetString(0))
End While
Finally
myReader.Close
myConnection.Close
End Try
End Sub
</code>
<code lang="C#">
public void CreateMySqlDataReader(string mySelectQuery, MySqlConnection myConnection)
{
MySqlCommand myCommand = new MySqlCommand(mySelectQuery, myConnection);
myConnection.Open();
MMySqlDataReader myReader;
myReader = myCommand.ExecuteReader();
try
{
while(myReader.Read())
{
Console.WriteLine(myReader.GetString(0));
}
}
finally
{
myReader.Close();
myConnection.Close();
}
}
</code>
</example>
</ExecuteReader>
<Prepare>
<summary>
Creates a prepared version of the command on an instance of MySQL Server.
</summary>
<remarks>
<para>
Prepared statements are only supported on MySQL version 4.1 and higher. Calling
prepare while connected to earlier versions of MySQL will succeed but will execute
the statement in the same way as unprepared.
</para>
</remarks>
<example>
The following example demonstrates the use of the <b>Prepare</b> method.
<code lang="VB.NET">
public sub PrepareExample()
Dim cmd as New MySqlCommand("INSERT INTO mytable VALUES (@val)", myConnection)
cmd.Parameters.Add( "@val", 10 )
cmd.Prepare()
cmd.ExecuteNonQuery()
cmd.Parameters(0).Value = 20
cmd.ExecuteNonQuery()
end sub
</code>
<code lang="C#">
private void PrepareExample()
{
MySqlCommand cmd = new MySqlCommand("INSERT INTO mytable VALUES (@val)", myConnection);
cmd.Parameters.Add( "@val", 10 );
cmd.Prepare();
cmd.ExecuteNonQuery();
cmd.Parameters[0].Value = 20;
cmd.ExecuteNonQuery();
}
</code>
</example>
</Prepare>
<ExecuteScalar>
<summary>
Executes the query, and returns the first column of the first row in the
result set returned by the query. Extra columns or rows are ignored.
</summary>
<returns>
The first column of the first row in the result set, or a null reference if the
result set is empty
</returns>
<remarks>
<para>
Use the <B>ExecuteScalar</B> method to retrieve a single value (for example,
an aggregate value) from a database. This requires less code than using the
<see cref="ExecuteReader()"/> method, and then performing the operations necessary
to generate the single value using the data returned by a <see cref="MySqlDataReader"/>
</para>
</remarks>
<example>
The following example creates a <see cref="MySqlCommand"/> and then
executes it using <B>ExecuteScalar</B>. The example is passed a string that is a
SQL statement that returns an aggregate result, and a string to use to
connect to the data source.
<code lang="vbnet">
Public Sub CreateMySqlCommand(myScalarQuery As String, myConnection As MySqlConnection)
Dim myCommand As New MySqlCommand(myScalarQuery, myConnection)
myCommand.Connection.Open()
myCommand.ExecuteScalar()
myConnection.Close()
End Sub
</code>
<code lang="C#">
public void CreateMySqlCommand(string myScalarQuery, MySqlConnection myConnection)
{
MySqlCommand myCommand = new MySqlCommand(myScalarQuery, myConnection);
myCommand.Connection.Open();
myCommand.ExecuteScalar();
myConnection.Close();
}
</code>
<code lang="C++">
public:
void CreateMySqlCommand(String* myScalarQuery, MySqlConnection* myConnection)
{
MySqlCommand* myCommand = new MySqlCommand(myScalarQuery, myConnection);
myCommand-&gt;Connection-&gt;Open();
myCommand-&gt;ExecuteScalar();
myConnection-&gt;Close();
}
</code>
</example>
</ExecuteScalar>
<CommandText>
<summary>
Gets or sets the SQL statement to execute at the data source.
</summary>
<value>
The SQL statement or stored procedure to execute. The default is an empty string.
</value>
<remarks>
<para>
When the <see cref="CommandType"/> property is set to <B>StoredProcedure</B>,
the <B>CommandText</B> property should be set to the name of the stored procedure.
The user may be required to use escape character syntax if the stored procedure name
contains any special characters. The command executes this stored procedure when
you call one of the Execute methods. Starting with Connector/Net 5.0, having both a stored function
and stored procedure with the same name in the same database is not supported. It is
suggested that you provide unqiue names for your stored routines.
</para>
</remarks>
<example>
The following example creates a <see cref="MySqlCommand"/> and sets some of its properties.
<code lang="vbnet">
Public Sub CreateMySqlCommand()
Dim myCommand As New MySqlCommand()
myCommand.CommandText = "SELECT * FROM Mytable ORDER BY id"
myCommand.CommandType = CommandType.Text
End Sub
</code>
<code lang="C#">
public void CreateMySqlCommand()
{
MySqlCommand myCommand = new MySqlCommand();
myCommand.CommandText = "SELECT * FROM mytable ORDER BY id";
myCommand.CommandType = CommandType.Text;
}
</code>
</example>
</CommandText>
<CommandTimeout>
<summary>
Gets or sets the wait time before terminating the attempt to execute a command
and generating an error.
</summary>
<value>
The time (in seconds) to wait for the command to execute. The default is 30
seconds.
</value>
<remarks>
CommandTimeout is dependent on the ability of MySQL to cancel an executing query.
Because of this, CommandTimeout is only supported when connected to MySQL
version 5.0.0 or higher.
</remarks>
</CommandTimeout>
<CommandType>
<summary>
Gets or sets a value indicating how the <see cref="CommandText"/> property is to be interpreted.
</summary>
<value>
One of the <see cref="System.Data.CommandType"/> values. The default is <B>Text</B>.
</value>
<remarks>
<para>
When you set the <B>CommandType</B> property to <B>StoredProcedure</B>, you
should set the <see cref="CommandText"/> property to the name of the stored
procedure. The command executes this stored procedure when you call one of the
Execute methods.
</para>
</remarks>
<example>
The following example creates a <see cref="MySqlCommand"/> and sets some of its properties.
<code lang="vbnet">
Public Sub CreateMySqlCommand()
Dim myCommand As New MySqlCommand()
myCommand.CommandType = CommandType.Text
End Sub
</code>
<code lang="C#">
public void CreateMySqlCommand()
{
MySqlCommand myCommand = new MySqlCommand();
myCommand.CommandType = CommandType.Text;
}
</code>
</example>
</CommandType>
<Connection>
<summary>
Gets or sets the <see cref="MySqlConnection"/> used by this instance of the
<see cref="MySqlCommand"/>.
</summary>
<value>
The connection to a data source. The default value is a null reference
(<B>Nothing</B> in Visual Basic).
</value>
<remarks>
<para>
If you set <B>Connection</B> while a transaction is in progress and the
<see cref="Transaction"/> property is not null, an <see cref="InvalidOperationException"/>
is generated. If the <B>Transaction</B> property is not null and the transaction
has already been committed or rolled back, <B>Transaction</B> is set to
null.
</para>
</remarks>
<example>
The following example creates a <see cref="MySqlCommand"/> and sets some of its properties.
<code lang="vbnet">
Public Sub CreateMySqlCommand()
Dim mySelectQuery As String = "SELECT * FROM mytable ORDER BY id"
Dim myConnectString As String = "Persist Security Info=False;database=test;server=myServer"
Dim myCommand As New MySqlCommand(mySelectQuery)
myCommand.Connection = New MySqlConnection(myConnectString)
myCommand.CommandType = CommandType.Text
End Sub
</code>
<code lang="C#">
public void CreateMySqlCommand()
{
string mySelectQuery = "SELECT * FROM mytable ORDER BY id";
string myConnectString = "Persist Security Info=False;database=test;server=myServer";
MySqlCommand myCommand = new MySqlCommand(mySelectQuery);
myCommand.Connection = new MySqlConnection(myConnectString);
myCommand.CommandType = CommandType.Text;
}
</code>
</example>
</Connection>
<IsPrepared>
</IsPrepared>
<LastInsertedId>
<summary>Provides the id of the last inserted row.</summary>
<value>
Id of the last inserted row. -1 if none exists.
</value>
<remarks>
An important point to remember is that this property can be used
in batch SQL scenarios but it's important to remember that it will
only reflect the insert id from the last insert statement in the batch.
This property can also be used when the batch includes select statements
and ExecuteReader is used. This property can be consulted during result set
processing.
</remarks>
</LastInsertedId>
<Parameters>
<summary>
Get the <see cref="MySqlParameterCollection"/>
</summary>
<value>
The parameters of the SQL statement or stored procedure. The default is
an empty collection.
</value>
<remarks>
Connector/Net does not support unnamed parameters. Every parameter added to the collection must
have an associated name.
</remarks>
<example>
The following example creates a <see cref="MySqlCommand"/> and displays its parameters.
To accomplish this, the method is passed a <see cref="MySqlConnection"/>, a query string
that is a SQL SELECT statement, and an array of <see cref="MySqlParameter"/> objects.
<code lang="vbnet">
Public Sub CreateMySqlCommand(myConnection As MySqlConnection, _
mySelectQuery As String, myParamArray() As MySqlParameter)
Dim myCommand As New MySqlCommand(mySelectQuery, myConnection)
myCommand.CommandText = "SELECT id, name FROM mytable WHERE age=@age"
myCommand.UpdatedRowSource = UpdateRowSource.Both
myCommand.Parameters.Add(myParamArray)
Dim j As Integer
For j = 0 To myCommand.Parameters.Count - 1
myCommand.Parameters.Add(myParamArray(j))
Next j
Dim myMessage As String = ""
Dim i As Integer
For i = 0 To myCommand.Parameters.Count - 1
myMessage += myCommand.Parameters(i).ToString() &amp; ControlChars.Cr
Next i
Console.WriteLine(myMessage)
End Sub
</code>
<code lang="C#">
public void CreateMySqlCommand(MySqlConnection myConnection, string mySelectQuery,
MySqlParameter[] myParamArray)
{
MySqlCommand myCommand = new MySqlCommand(mySelectQuery, myConnection);
myCommand.CommandText = "SELECT id, name FROM mytable WHERE age=@age";
myCommand.Parameters.Add(myParamArray);
for (int j=0; j&lt;myParamArray.Length; j++)
{
myCommand.Parameters.Add(myParamArray[j]) ;
}
string myMessage = "";
for (int i = 0; i &lt; myCommand.Parameters.Count; i++)
{
myMessage += myCommand.Parameters[i].ToString() + "\n";
}
MessageBox.Show(myMessage);
}
</code>
</example>
</Parameters>
<Transaction>
<summary>
Gets or sets the <see cref="MySqlTransaction"/> within which the <see cref="MySqlCommand"/> executes.
</summary>
<value>
The <see cref="MySqlTransaction"/>. The default value is a null reference (<B>Nothing</B> in Visual Basic).
</value>
<remarks>
You cannot set the <B>Transaction</B> property if it is already set to a
specific value, and the command is in the process of executing. If you set the
transaction property to a <see cref="MySqlTransaction"/> object that is not connected
to the same <see cref="MySqlConnection"/> as the <see cref="MySqlCommand"/> object,
an exception will be thrown the next time you attempt to execute a statement.
</remarks>
</Transaction>
<UpdatedRowSource>
<summary>
Gets or sets how command results are applied to the <see cref="DataRow"/>
when used by the <see cref="System.Data.Common.DbDataAdapter.Update"/> method
of the <see cref="System.Data.Common.DbDataAdapter"/>.
</summary>
<value>
One of the <see cref="UpdateRowSource"/> values.
</value>
<remarks>
<para>
The default <see cref="System.Data.UpdateRowSource"/> value is
<B>Both</B> unless the command is automatically generated (as in the case of the
<see cref="MySqlCommandBuilder"/>), in which case the default is <B>None</B>.
</para>
</remarks>
</UpdatedRowSource>
</docs>

@ -0,0 +1,321 @@
<docs>
<class>
<summary>
Automatically generates single-table commands used to reconcile changes made to a DataSet with the associated MySQL database. This class cannot be inherited.
</summary>
<remarks>
<para>
The <see cref="MySqlDataAdapter"/> does not automatically generate the SQL statements required to
reconcile changes made to a <see cref="System.Data.DataSet">DataSet</see> with the associated instance of MySQL.
However, you can create a <B>MySqlCommandBuilder</B> object to automatically generate SQL statements for
single-table updates if you set the <see cref="MySqlDataAdapter.SelectCommand">SelectCommand</see> property
of the <B>MySqlDataAdapter</B>. Then, any additional SQL statements that you do not set are generated by the
<B>MySqlCommandBuilder</B>.
</para>
<para>
The <B>MySqlCommandBuilder</B> registers itself as a listener for <see cref="MySqlDataAdapter.OnRowUpdating">RowUpdating</see>
events whenever you set the <see cref="DataAdapter"/> property. You can only associate one
<B>MySqlDataAdapter</B> or <B>MySqlCommandBuilder</B> object with each other at one time.
</para>
<para>
To generate INSERT, UPDATE, or DELETE statements, the <B>MySqlCommandBuilder</B> uses the
<B>SelectCommand</B> property to retrieve a required set of metadata automatically. If you change
the <B>SelectCommand</B> after the metadata has is retrieved (for example, after the first update), you
should call the <see cref="RefreshSchema"/> method to update the metadata.
</para>
<para>
The <B>SelectCommand</B> must also return at least one primary key or unique
column. If none are present, an <I>InvalidOperation</I> exception is generated,
and the commands are not generated.
</para>
<para>
The <B>MySqlCommandBuilder</B> also uses the <see cref="MySqlCommand.Connection">Connection</see>,
<see cref="MySqlCommand.CommandTimeout">CommandTimeout</see>, and <see cref="MySqlCommand.Transaction">Transaction</see>
properties referenced by the <B>SelectCommand</B>. The user should call
<B>RefreshSchema</B> if any of these properties are modified, or if the
<B>SelectCommand</B> itself is replaced. Otherwise the <see cref="MySqlDataAdapter.InsertCommand">InsertCommand</see>,
<see cref="MySqlDataAdapter.UpdateCommand">UpdateCommand</see>, and
<see cref="MySqlDataAdapter.DeleteCommand">DeleteCommand</see> properties retain
their previous values.
</para>
<para>
If you call <i>Dispose</i>, the <B>MySqlCommandBuilder</B> is disassociated
from the <B>MySqlDataAdapter</B>, and the generated commands are no longer used.
</para>
<note>
Caution must be used when using MySqlCOmmandBuilder on MySql 4.0 systems. With MySql 4.0,
database/schema information is not provided to the connector for a query. This means that
a query that pulls columns from two identically named tables in two or more different databases
will not cause an exception to be thrown but will not work correctly. Even more dangerous
is the situation where your select statement references database X but is executed in
database Y and both databases have tables with similar layouts. This situation can cause
unwanted changes or deletes.
This note does not apply to MySQL versions 4.1 and later.
</note>
</remarks>
<example>
The following example uses the <see cref="MySqlCommand"/>, along
<see cref="MySqlDataAdapter"/> and <see cref="MySqlConnection"/>, to
select rows from a data source. The example is passed an initialized
<see cref="System.Data.DataSet"/>, a connection string, a
query string that is a SQL SELECT statement, and a string that is the
name of the database table. The example then creates a <B>MySqlCommandBuilder</B>.
<code lang="vbnet">
Public Shared Function SelectRows(myConnection As String, mySelectQuery As String, myTableName As String) As DataSet
Dim myConn As New MySqlConnection(myConnection)
Dim myDataAdapter As New MySqlDataAdapter()
myDataAdapter.SelectCommand = New MySqlCommand(mySelectQuery, myConn)
Dim cb As SqlCommandBuilder = New MySqlCommandBuilder(myDataAdapter)
myConn.Open()
Dim ds As DataSet = New DataSet
myDataAdapter.Fill(ds, myTableName)
' Code to modify data in DataSet here
' Without the MySqlCommandBuilder this line would fail.
myDataAdapter.Update(ds, myTableName)
myConn.Close()
End Function 'SelectRows
</code>
<code lang="C#">
public static DataSet SelectRows(string myConnection, string mySelectQuery, string myTableName)
{
MySqlConnection myConn = new MySqlConnection(myConnection);
MySqlDataAdapter myDataAdapter = new MySqlDataAdapter();
myDataAdapter.SelectCommand = new MySqlCommand(mySelectQuery, myConn);
MySqlCommandBuilder cb = new MySqlCommandBuilder(myDataAdapter);
myConn.Open();
DataSet ds = new DataSet();
myDataAdapter.Fill(ds, myTableName);
//code to modify data in DataSet here
//Without the MySqlCommandBuilder this line would fail
myDataAdapter.Update(ds, myTableName);
myConn.Close();
return ds;
}
</code>
</example>
</class>
<Ctor>
<summary>
Initializes a new instance of the <see cref="MySqlCommandBuilder"/> class.
</summary>
</Ctor>
<Ctor2>
<summary>
Initializes a new instance of the <see cref="MySqlCommandBuilder"/> class
with the associated <see cref="MySqlDataAdapter"/> object.
</summary>
<param name="adapter">
The <see cref="MySqlDataAdapter"/> to use.
</param>
<remarks>
<para>
The <see cref="MySqlCommandBuilder"/> registers itself as a listener for
<see cref="MySqlDataAdapter.RowUpdating"/> events that are generated by the
<see cref="MySqlDataAdapter"/> specified in this property.
</para>
<para>
When you create a new instance <B>MySqlCommandBuilder</B>, any existing
<B>MySqlCommandBuilder</B> associated with this <B>MySqlDataAdapter</B>
is released.
</para>
</remarks>
</Ctor2>
<DataAdapter>
<summary>
Gets or sets a <see cref="MySqlDataAdapter"/> object for which SQL statements are automatically generated.
</summary>
<value>
A <see cref="MySqlDataAdapter"/> object.
</value>
<remarks>
<para>
The <see cref="MySqlCommandBuilder"/> registers itself as a listener for
<see cref="MySqlDataAdapter.RowUpdating"/> events that are generated by the
<see cref="MySqlDataAdapter"/> specified in this property.
</para>
<para>
When you create a new instance <B>MySqlCommandBuilder</B>, any existing
<B>MySqlCommandBuilder</B> associated with this <B>MySqlDataAdapter</B>
is released.
</para>
</remarks>
</DataAdapter>
<QuotePrefix>
<summary>
Gets or sets the beginning character or characters to use when specifying MySQL
database objects (for example, tables or columns) whose names contain
characters such as spaces or reserved tokens.
</summary>
<value>
The beginning character or characters to use. The default value is `.
</value>
<remarks>
Database objects in MySQL can contain special characters such as spaces that would
make normal SQL strings impossible to correctly parse. Use of the <b>QuotePrefix</b>
and the <see cref="QuoteSuffix"/> properties allows the <see cref="MySqlCommandBuilder"/>
to build SQL commands that handle this situation.
</remarks>
</QuotePrefix>
<QuoteSuffix>
<summary>
Gets or sets the beginning character or characters to use when specifying MySQL
database objects (for example, tables or columns) whose names contain
characters such as spaces or reserved tokens.
</summary>
<value>
The beginning character or characters to use. The default value is `.
</value>
<remarks>
Database objects in MySQL can contain special characters such as spaces that would
make normal SQL strings impossible to correctly parse. Use of the <see cref="QuotePrefix"/>
and the <b>QuoteSuffix</b> properties allows the <see cref="MySqlCommandBuilder"/>
to build SQL commands that handle this situation.
</remarks>
</QuoteSuffix>
<DeriveParameters>
<summary>
</summary>
<remarks>
</remarks>
</DeriveParameters>
<GetDeleteCommand>
<summary>
Gets the automatically generated <see cref="MySqlCommand"/> object
required to perform deletions on the database.
</summary>
<returns>
The <see cref="MySqlCommand"/> object generated to handle delete operations.
</returns>
<remarks>
<para>
An application can use the <B>GetDeleteCommand</B> method for informational
or troubleshooting purposes because it returns the <see cref="MySqlCommand"/>
object to be executed.
</para>
<para>
You can also use <B>GetDeleteCommand</B> as the basis of a modified command.
For example, you might call <B>GetDeleteCommand</B> and modify the
<see cref="MySqlCommand.CommandTimeout"/> value, and then explicitly set that on the
<see cref="MySqlDataAdapter"/>.
</para>
<para>
After the SQL statement is first generated, the application must explicitly
call <see cref="RefreshSchema"/> if it changes the statement in any way.
Otherwise, the <B>GetDeleteCommand</B> will be still be using information
from the previous statement, which might not be correct. The SQL statements
are first generated either when the application calls
<see cref="System.Data.Common.DataAdapter.Update"/> or <B>GetDeleteCommand</B>.
</para>
</remarks>
</GetDeleteCommand>
<GetInsertCommand>
<summary>
Gets the automatically generated <see cref="MySqlCommand"/> object
required to perform insertions on the database.
</summary>
<returns>
The <see cref="MySqlCommand"/> object generated to handle insert operations.
</returns>
<remarks>
<para>
An application can use the <B>GetInsertCommand</B> method for informational
or troubleshooting purposes because it returns the <see cref="MySqlCommand"/>
object to be executed.
</para>
<para>
You can also use the <B>GetInsertCommand</B> as the basis of a modified command.
For example, you might call <B>GetInsertCommand</B> and modify the
<see cref="MySqlCommand.CommandTimeout"/> value, and then explicitly set that on the
<see cref="MySqlDataAdapter"/>.
</para>
<para>
After the SQL statement is first generated, the application must explicitly
call <see cref="RefreshSchema"/> if it changes the statement in any way.
Otherwise, the <B>GetInsertCommand</B> will be still be using information
from the previous statement, which might not be correct. The SQL statements
are first generated either when the application calls
<see cref="System.Data.Common.DataAdapter.Update"/> or <B>GetInsertCommand</B>.
</para>
</remarks>
</GetInsertCommand>
<GetUpdateCommand>
<summary>
Gets the automatically generated <see cref="MySqlCommand"/> object
required to perform updates on the database.
</summary>
<returns>
The <see cref="MySqlCommand"/> object generated to handle update operations.
</returns>
<remarks>
<para>
An application can use the <B>GetUpdateCommand</B> method for informational
or troubleshooting purposes because it returns the <see cref="MySqlCommand"/>
object to be executed.
</para>
<para>
You can also use <B>GetUpdateCommand</B> as the basis of a modified command.
For example, you might call <B>GetUpdateCommand</B> and modify the
<see cref="MySqlCommand.CommandTimeout"/> value, and then explicitly set that on the
<see cref="MySqlDataAdapter"/>.
</para>
<para>
After the SQL statement is first generated, the application must explicitly
call <see cref="RefreshSchema"/> if it changes the statement in any way.
Otherwise, the <B>GetUpdateCommand</B> will be still be using information
from the previous statement, which might not be correct. The SQL statements
are first generated either when the application calls
<see cref="System.Data.Common.DataAdapter.Update"/> or <B>GetUpdateCommand</B>.
</para>
</remarks>
</GetUpdateCommand>
<RefreshSchema>
<summary>
Refreshes the database schema information used to generate INSERT, UPDATE, or
DELETE statements.
</summary>
<remarks>
<para>
An application should call <B>RefreshSchema</B> whenever the SELECT statement
associated with the <see cref="MySqlCommandBuilder"/> changes.
</para>
<para>
An application should call <B>RefreshSchema</B> whenever the
<see cref="MySqlDataAdapter.SelectCommand"/> value of the <see cref="MySqlDataAdapter"/> changes.
</para>
</remarks>
</RefreshSchema>
</docs>

@ -0,0 +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>
<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>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save