--- /dev/null
+//\r
+// ParmUtil.cs - utility to bind variables in a SQL statement to parameters in C# code\r
+// This is in the PostgreSQL .NET Data provider in Mono\r
+//\r
+// Author: \r
+// Daniel Morgan <danmorg@sc.rr.com>\r
+//\r
+// (c)copyright 2002 Daniel Morgan\r
+//\r
+\r
+// comment DEBUG_ParmUtil for production, for debug messages, uncomment\r
+//#define DEBUG_ParmUtil\r
+\r
+using System;\r
+using System.Data;\r
+using System.Text;\r
+\r
+namespace System.Data.SqlClient {\r
+\r
+ enum PostgresBindVariableCharacter {\r
+ Semicolon,\r
+ At,\r
+ QuestionMark\r
+ }\r
+\r
+ public class ParmUtil {\r
+\r
+ private string sql = "";\r
+ private string resultSql = "";\r
+ private SqlParameterCollection parmsCollection = null;\r
+ \r
+ static private PostgresBindVariableCharacter PgbindChar = PostgresBindVariableCharacter.Semicolon;\r
+ static char bindChar;\r
+\r
+ // static constructor\r
+ static ParmUtil() {\r
+ switch(PgbindChar) {\r
+ case PostgresBindVariableCharacter.Semicolon:\r
+ bindChar = ':';\r
+ break;\r
+ case PostgresBindVariableCharacter.At:\r
+ bindChar = '@';\r
+ break;\r
+ case PostgresBindVariableCharacter.QuestionMark:\r
+ // this doesn't have named parameters,\r
+ // they must be in order\r
+ bindChar = '?';\r
+ break;\r
+ }\r
+ }\r
+ \r
+ public ParmUtil(string query, SqlParameterCollection parms) {\r
+ sql = query;\r
+ parmsCollection = parms;\r
+ }\r
+ \r
+ public string ResultSql {\r
+ get {\r
+ return resultSql;\r
+ }\r
+ }\r
+\r
+ // TODO: currently only works for input variables,\r
+ // need to do input/output, output, and return\r
+ public string ReplaceWithParms() {\r
+\r
+ StringBuilder result = new StringBuilder();\r
+ char[] chars = sql.ToCharArray();\r
+ bool bStringConstFound = false;\r
+\r
+ for(int i = 0; i < chars.Length; i++) {\r
+ if(chars[i] == '\'') {\r
+ if(bStringConstFound == true)\r
+ bStringConstFound = false;\r
+ else\r
+ bStringConstFound = true;\r
+\r
+ result.Append(chars[i]);\r
+ }\r
+ else if(chars[i] == bindChar && \r
+ bStringConstFound == false) {\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("Bind Variable character found...");\r
+#endif \r
+ StringBuilder parm = new StringBuilder();\r
+ i++;\r
+ while(i <= chars.Length) {\r
+ char ch;\r
+ if(i == chars.Length)\r
+ ch = ' '; // a space\r
+ else\r
+ ch = chars[i];\r
+\r
+#if DEBUG_ParmUtil \r
+ Console.WriteLine("Is char Letter or digit?");\r
+#endif \r
+ if(Char.IsLetterOrDigit(ch)) {\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("Char IS letter or digit. " + \r
+ "Now, append char to parm StringBuilder");\r
+#endif\r
+ parm.Append(ch);\r
+ }\r
+ else {\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("Char is NOT letter or char. " + \r
+ "thus we got rest of bind variable name. ");\r
+ \r
+ // replace bind variable placeholder \r
+ // with data value constant\r
+ Console.WriteLine("parm StringBuilder to string p...");\r
+#endif\r
+ string p = parm.ToString();\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("calling BindReplace...");\r
+#endif \r
+ bool found = BindReplace(result, p);\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine(" Found = " + found);\r
+#endif\r
+ if(found == true)\r
+ break;\r
+ else { \r
+ // *** Error Handling\r
+ Console.WriteLine("Error: parameter not found: " + p);\r
+ return "";\r
+ }\r
+ }\r
+ i++;\r
+ }\r
+ i--;\r
+ }\r
+ else \r
+ result.Append(chars[i]);\r
+ }\r
+ \r
+ resultSql = result.ToString();\r
+ return resultSql;\r
+ }\r
+\r
+ public bool BindReplace (StringBuilder result, string p) {\r
+ // bind variable\r
+ bool found = false;\r
+\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("Does the parmsCollection contain the parameter???: " + p);\r
+#endif\r
+ if(parmsCollection.Contains(p) == true) {\r
+ // parameter found\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("Parameter Found: " + p);\r
+#endif\r
+ SqlParameter prm = parmsCollection[p];\r
+\r
+#if DEBUG_ParmUtil \r
+ // DEBUG \r
+ Console.WriteLine(" Value: " + prm.Value);\r
+ Console.WriteLine(" Direction: " + prm.Direction);\r
+#endif\r
+ // convert object to string and place\r
+ // into SQL\r
+ if(prm.Direction == ParameterDirection.Input) {\r
+ string strObj = PostgresHelper.\r
+ ObjectToString(prm.DbType, \r
+ prm.Value);\r
+ result.Append(strObj);\r
+ }\r
+ else\r
+ result.Append(bindChar + p);\r
+\r
+ found = true;\r
+ }\r
+ return found;\r
+ }\r
+ }\r
+}\r
/// </summary>
// public sealed class SqlCommand : Component, IDbCommand, ICloneable
public sealed class SqlCommand : IDbCommand {
- // FIXME: Console.WriteLine() is used for debugging throughout
#region Fields
SqlParameterCollection();
// SqlDataReader state data for ExecuteReader()
- private SqlDataReader dataReader;
- private string[] queries;
+ private SqlDataReader dataReader = null;
+ private string[] queries = null;
private int currentQuery;
- CommandBehavior cmdBehavior;
+ private CommandBehavior cmdBehavior = CommandBehavior.Default;
+
+ private ParmUtil parmUtil = null;
#endregion // Fields
rowsAffected = int.Parse(rowsAffectedString);
PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
}
else {
String errorMessage;
errorMessage += " " + PostgresLibrary.\r
PQresultErrorMessage(pgResult);\r
- \r
+\r
+ PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
+\r
throw new SqlException(0, 0,
errorMessage, 0, "",
conn.DataSource, "SqlCommand", 0);\r
string statement = "";
StringBuilder td;
- // TODO: need to handle parameters
-
+#if DEBUG_SqlCommand
+ Console.WriteLine("---------[][] TweakQuery() [][]--------");
+ Console.WriteLine("CommandType: " + commandType + " CommandBehavior: " + cmdBehavior);
+ Console.WriteLine("SQL before command type: " + query);
+#endif
// finish building SQL based on CommandType
switch(commandType) {
case CommandType.Text:
"SELECT " + query + "()";
break;
case CommandType.TableDirect:
+ // NOTE: this is for the PostgreSQL provider
+ // and for OleDb, according to the docs,
+ // an exception is thrown if you try to use
+ // this with SqlCommand
string[] directTables = query.Split(
new Char[] {','});
td = new StringBuilder("SELECT * FROM ");
for(int tab = 0; tab < directTables.Length; tab++) {
- if(tab > 0 && tab < directTables.Length - 1)
+ if(tab > 0)
td.Append(',');
td.Append(directTables[tab]);
// FIXME: if multipe tables, how do we
statement = query;
break;
}
+#if DEBUG_SqlCommand
+ Console.WriteLine("SQL after command type: " + statement);
+#endif
+ // TODO: this parameters utility
+ // currently only support input variables
+ // need todo output, input/output, and return.
+#if DEBUG_SqlCommand
+ Console.WriteLine("using ParmUtil in TweakQuery()...");
+#endif
+ parmUtil = new ParmUtil(statement, parmCollection);
+#if DEBUG_SqlCommand
+ Console.WriteLine("ReplaceWithParms...");
+#endif
+
+ statement = parmUtil.ReplaceWithParms();
+
+#if DEBUG_SqlCommand
+ Console.WriteLine("SQL after ParmUtil: " + statement);
+#endif
return statement;
}
errorMessage += " " + PostgresLibrary.\r
PQresultErrorMessage(pgResult);\r
- \r
+\r
+ PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
+\r
throw new SqlException(0, 0,
errorMessage, 0, "",
conn.DataSource, "SqlCommand", 0);\r
// since SqlCommand has resources so SqlDataReader
// can do Read() and NextResult(), need to free
// those resources. Also, need to allow this SqlCommand
- // and this SqlConnection to things again.
+ // and this SqlConnection to do things again.
internal void CloseReader() {
conn.OpenReader = false;
dataReader = null;
errorMessage += " " + PostgresLibrary.\r
PQresultErrorMessage(pgResult);\r
- \r
+\r
+ PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
+\r
throw new SqlException(0, 0,
errorMessage, 0, "",
conn.DataSource, "SqlCommand", 0);\r
}
}
- SqlParameterCollection Parameters {
+ public SqlParameterCollection Parameters {
get {
return parmCollection;
}
using System.Text;
namespace System.Data.SqlClient {
- // using PGconn = IntPtr;
- // PGconn is native C library type in libpq for Postgres Connection
-
- // using PGressult = IntPtr;
- // PGresult is native C library type in libpq for Postgres Resultset
/// <summary>
/// Represents an open connection to a SQL data source
#region Constructors
- /*
- [MonoTODO]
- public SqlConnection ()
- {
- this.ConnectionString = null;
- this.ConnectionTimeout = 0;
- this.Database = null;
- this.State = 0;
- }
-
- [MonoTODO]
- public SqlConnection (string cs) : SqlConnection ()
- {
- this.ConnectionString = cs;
- }
-
- */
// A lot of the defaults were initialized in the Fields
[MonoTODO]
public SqlConnection () {
PQnfields(pgResult);
BuildTypes (pgResult, nRows, nFields);
+
+ // close result set
+ PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
}
else {
String errorMessage;
errorMessage += " " + PostgresLibrary.\r
PQresultErrorMessage(pgResult);\r
- \r
+\r
+ // close result set
+ PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
+\r
throw new SqlException(0, 0,
errorMessage, 0, "",
con.DataSource, "SqlConnection", 0);\r
}
- // close result set
- PostgresLibrary.PQclear (pgResult);
- pgResult = IntPtr.Zero;
}
}
// IDbDataParameter, IDataParameter, ICloneable
public sealed class SqlParameter : IDbDataParameter, IDataParameter
{
+ private string parmName;
+ private SqlDbType dbtype;
+ private DbType theDbType;
+ private object objValue;
+ private int size;
+ private string sourceColumn;
+ private ParameterDirection direction;
+ private bool isNullable;
+ private byte precision;
+ private byte scale;
+ private DataRowVersion sourceVersion;
+ private int offset;
+
[MonoTODO]
public SqlParameter () {
- // FIXME: do this
+
}
[MonoTODO]
public SqlParameter (string parameterName, object value) {
- // FIXME: do this
+ this.parmName = parameterName;
+ this.objValue = value;
}
[MonoTODO]
public SqlParameter(string parameterName, SqlDbType dbType) {
- // FIXME: do this
+ this.parmName = parameterName;
+ this.dbtype = dbType;
}
[MonoTODO]
public SqlParameter(string parameterName, SqlDbType dbType,
int size) {
- // FIXME: do this
+
+ this.parmName = parameterName;
+ this.dbtype = dbType;
+ this.size = size;
}
[MonoTODO]
public SqlParameter(string parameterName, SqlDbType dbType,
int size, string sourceColumn) {
- // FIXME: do this
+
+ this.parmName = parameterName;
+ this.dbtype = dbType;
+ this.size = size;
+ this.sourceColumn = sourceColumn;
}
[MonoTODO]
bool isNullable, byte precision,
byte scale, string sourceColumn,
DataRowVersion sourceVersion, object value) {
- // FIXME: do this
+
+ this.parmName = parameterName;
+ this.dbtype = dbType;
+ this.size = size;
+ this.sourceColumn = sourceColumn;
+ this.direction = direction;
+ this.isNullable = isNullable;
+ this.precision = precision;
+ this.scale = scale;
+ this.sourceVersion = sourceVersion;
+ this.objValue = value;
}
-
[MonoTODO]
public DbType DbType {
get {
- throw new NotImplementedException ();
+ return theDbType;
}
set {
- throw new NotImplementedException ();
+ theDbType = value;
}
}
[MonoTODO]
public ParameterDirection Direction {
get {
- throw new NotImplementedException ();
+ return direction;
}
set {
- throw new NotImplementedException ();
+ direction = value;
}
}
[MonoTODO]
public bool IsNullable {
get {
- throw new NotImplementedException ();
+ return isNullable;
}
}
[MonoTODO]
public int Offset {
get {
- throw new NotImplementedException ();
+ return offset;
}
set {
- throw new NotImplementedException ();
+ offset = value;
}
}
[MonoTODO]
public string ParameterName {
get {
- throw new NotImplementedException ();
+ return parmName;
}
set {
- throw new NotImplementedException ();
+ parmName = value;
}
}
[MonoTODO]
public string SourceColumn {
get {
- throw new NotImplementedException ();
+ return sourceColumn;
}
set {
- throw new NotImplementedException ();
+ sourceColumn = value;
}
}
[MonoTODO]
public DataRowVersion SourceVersion {
get {
- throw new NotImplementedException ();
+ return sourceVersion;
}
set {
- throw new NotImplementedException ();
+ sourceVersion = value;
}
}
[MonoTODO]
public SqlDbType SqlDbType {
get {
- throw new NotImplementedException ();
+ return dbtype;
}
set {
- throw new NotImplementedException ();
+ dbtype = value;
}
}
[MonoTODO]
public object Value {
get {
- throw new NotImplementedException ();
+ return objValue;
}
set {
- throw new NotImplementedException ();
+ objValue = value;
}
}
[MonoTODO]
public byte Precision {
get {
- throw new NotImplementedException ();
+ return precision;
}
set {
- throw new NotImplementedException ();
+ precision = value;
}
}
[MonoTODO]
public byte Scale {
get {
- throw new NotImplementedException ();
+ return scale;
}
set {
- throw new NotImplementedException ();
+ scale = value;
}
}
public int Size
{
get {
- throw new NotImplementedException ();
+ return size;
}
set {
- throw new NotImplementedException ();
+ size = value;
}
}
[MonoTODO]
public override string ToString() {
- throw new NotImplementedException ();
+ return parmName;
}
}
}
using System;
using System.ComponentModel;
using System.Data;
+using System.Data.Common;
using System.Collections;
namespace System.Data.SqlClient
// IDataParameterCollection, IList, ICollection, IEnumerable
public sealed class SqlParameterCollection : IDataParameterCollection
{
+ private ArrayList parameterList = new ArrayList();
+ private Hashtable parameterNames = new Hashtable();
+
+/*
[MonoTODO]
public void RemoveAt(string parameterName)
{
throw new NotImplementedException ();
}
+
[MonoTODO]
public bool Contains(string parameterName)
{
- throw new NotImplementedException ();
- }
-
- // [MonoTODO]
- public object this[string parameterName]
- {
- get { throw new NotImplementedException (); }
- set { throw new NotImplementedException (); }
+ return parameterNames.ContainsKey(parameterName);
}
+*/
[MonoTODO]
public IEnumerator GetEnumerator()
[MonoTODO]
public SqlParameter Add(SqlParameter value)
{
- throw new NotImplementedException ();
+ parameterList.Add(value);
+ parameterNames.Add(value.ParameterName, parameterList.Add(value));
+ return value;
}
[MonoTODO]
throw new NotImplementedException ();
}
-/*
+
[MonoTODO]
public bool Contains(string value)
{
- throw new NotImplementedException ();
+ return parameterNames.ContainsKey(value);
}
-
-*/
[MonoTODO]
public void CopyTo(Array array, int index)
{
throw new NotImplementedException ();
}
-/*
+
[MonoTODO]
public int IndexOf(string parameterName)
{
throw new NotImplementedException ();
}
-*/
+
[MonoTODO]
public void Insert(int index, object value)
{
{
throw new NotImplementedException ();
}
-/*
+
[MonoTODO]
public void RemoveAt(string parameterName)
{
throw new NotImplementedException ();
}
-*/
-/*
- [MonoTODO]
- [Serializable]
- [ClassInterface(ClassInterfaceType.AutoDual)]
- ~SqlParameterCollection();
-*/
-
+
[MonoTODO]
public int Count {
get {
- throw new NotImplementedException ();
+ return parameterList.Count;
}
}
- // [MonoTODO]
object IList.this[int index] {
- get {
- throw new NotImplementedException ();
- }
+ [MonoTODO]
+ get {
+ return (SqlParameter) this[index];
+ }
- set {
- throw new NotImplementedException ();
- }
+ [MonoTODO]
+ set {
+ this[index] = (SqlParameter) value;
+ }
}
- // [MonoTODO]
public SqlParameter this[int index] {
get {
- throw new NotImplementedException ();
+ return (SqlParameter) parameterList[index];
}
set {
- throw new NotImplementedException ();
+ parameterList[index] = (SqlParameter) value;
}
}
-/*
- [MonoTODO]
+
+ object IDataParameterCollection.this[string parameterName] {
+ [MonoTODO]
+ get {
+ return (SqlParameter) this[parameterName];
+ }
+
+ [MonoTODO]
+ set {
+ this[parameterName] = (SqlParameter) value;
+ }
+ }
+
public SqlParameter this[string parameterName] {
get {
- throw new NotImplementedException ();
+ if(parameterNames.ContainsKey(parameterName))
+ return (SqlParameter) parameterList[(int)parameterNames[parameterName]];
+ else
+ throw new IndexOutOfRangeException("The specified name does not exist: " + parameterName);
}
set {
- throw new NotImplementedException ();
+ if(parameterNames.ContainsKey(parameterName))
+ parameterList[(int)parameterNames[parameterName]] = (SqlParameter) value;
+ else
+ throw new IndexOutOfRangeException("The specified name does not exist: " + parameterName);
}
}
-*/
bool IList.IsFixedSize {
get {
throw new NotImplementedException ();
}
}
-
}
}
PGRES_FATAL_ERROR
}
- internal struct PostgresType {\r
- public int oid;\r
- public string typname;\r
- public DbType dbType;\r
- }\r
-
- sealed internal class PostgresHelper {
-
- // translates the PostgreSQL typname to System.Data.DbType
- public static DbType TypnameToSqlDbType(string typname) {\r
- DbType sqlType;\r
- \r
- // FIXME: use hashtable here?\r
-\r
- switch(typname) {\r
-\r
- case "abstime":\r
- sqlType = DbType.Int32;\r
- break;\r
-\r
- case "aclitem":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "bit":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "bool":\r
- sqlType = DbType.Boolean;\r
- break;\r
-\r
- case "box":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "bpchar":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "bytea":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "char":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "cidr":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "circle":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "date":\r
- sqlType = DbType.Date;\r
- break;\r
-\r
- case "float4":\r
- sqlType = DbType.Single;\r
- break;\r
-\r
- case "float8":\r
- sqlType = DbType.Double;\r
- break;\r
-\r
- case "inet":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "int2":\r
- sqlType = DbType.Int16;\r
- break;\r
-\r
- case "int4":\r
- sqlType = DbType.Int32;\r
- break;\r
-\r
- case "int8":\r
- sqlType = DbType.Int64;\r
- break;\r
-\r
- case "interval":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "line":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "lseg":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "macaddr":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "money":\r
- sqlType = DbType.Decimal;\r
- break;\r
-\r
- case "name":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "numeric":\r
- sqlType = DbType.Decimal;\r
- break;\r
-\r
- case "oid":\r
- sqlType = DbType.Int32;\r
- break;\r
-\r
- case "path":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "point":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "polygon":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "refcursor":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "reltime":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "text":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "time":\r
- sqlType = DbType.Time;\r
- break;\r
-\r
- case "timestamp":\r
- sqlType = DbType.DateTime;\r
- break;\r
-\r
- case "timestamptz":\r
- sqlType = DbType.DateTime;\r
- break;\r
-\r
- case "timetz":\r
- sqlType = DbType.DateTime;\r
- break;\r
-\r
- case "tinterval":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "varbit":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "varchar":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- default:\r
- sqlType = DbType.String;\r
- break;\r
- }\r
- return sqlType;\r
- }\r
- \r
- // Converts data value from database to .NET System type.\r
- public static object ConvertDbTypeToSystem (DbType typ, String value) {
- object obj = null;
-
- // FIXME: more types need
- // to be converted
- // from PostgreSQL oid type
- // to .NET System.<type>
-
- // FIXME: need to handle a NULL for each type
- // maybe setting obj to System.DBNull.Value ?
-
-
- if(value == null) {
- //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
- // typ + " value is null");
- return null;
- }
- else if(value.Equals("")) {
- //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
- // typ + " value is string empty");
- return null;
- }
-
- //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
- // typ + " value: " + value);
-
- // Date, Time, and DateTime
- // are parsed based on ISO format
- // "YYYY-MM-DD hh:mi:ss.ms"
-
- switch(typ) {
- case DbType.String:
- obj = String.Copy(value);
- break;
- case DbType.Boolean:
- obj = value.Equals("t");
- break;
- case DbType.Int16:\r
- obj = Int16.Parse(value);\r
- break;\r
- case DbType.Int32:\r
- obj = Int32.Parse(value);\r
- break;\r
- case DbType.Int64:\r
- obj = Int64.Parse(value);\r
- break;\r
- case DbType.Decimal:\r
- obj = Decimal.Parse(value);\r
- break;\r
- case DbType.Single:\r
- obj = Single.Parse(value);\r
- break;\r
- case DbType.Double:\r
- obj = Double.Parse(value);\r
- break;\r
- case DbType.Date:\r
- String[] sd = value.Split(new Char[] {'-'});\r
- obj = new DateTime(\r
- Int32.Parse(sd[0]), Int32.Parse(sd[1]), Int32.Parse(sd[2]),\r
- 0,0,0);\r
- break;\r
- case DbType.Time:\r
- String[] st = value.Split(new Char[] {':'});\r
- obj = new DateTime(0001,01,01,\r
- Int32.Parse(st[0]),Int32.Parse(st[1]),Int32.Parse(st[2]));\r
- break;\r
- case DbType.DateTime:\r
- Int32 YYYY,MM,DD,hh,mi,ss,ms;\r
- YYYY = Int32.Parse(value.Substring(0,4));\r
- MM = Int32.Parse(value.Substring(5,2));\r
- DD = Int32.Parse(value.Substring(8,2));\r
- hh = Int32.Parse(value.Substring(11,2));\r
- mi = Int32.Parse(value.Substring(14,2));\r
- ss = Int32.Parse(value.Substring(17,2));\r
- ms = Int32.Parse(value.Substring(20,2));\r
- obj = new DateTime(YYYY,MM,DD,hh,mi,ss,ms);\r
- break;\r
- default:\r
- obj = String.Copy(value);\r
- break;\r
- }
-
- return obj;
- }
-
- // Translates System.Data.DbType to System.Type
- public static Type DbTypeToSystemType (DbType dType) {
- // FIXME: more types need
- // to be mapped
- // from PostgreSQL oid type
- // to .NET System.<type>
-
- Type typ = null;
-
- switch(dType) {
- case DbType.String:
- typ = typeof(String);
- break;
- case DbType.Boolean:
- typ = typeof(Boolean);
- break;
- case DbType.Int16: \r
- typ = typeof(Int16);\r
- break;\r
- case DbType.Int32:\r
- typ = typeof(Int32);\r
- break;\r
- case DbType.Int64:\r
- typ = typeof(Int64);\r
- break;\r
- case DbType.Decimal:\r
- typ = typeof(Decimal);\r
- break;\r
- case DbType.Single:\r
- typ = typeof(Single);\r
- break;\r
- case DbType.Double:\r
- typ = typeof(Double);\r
- break;\r
- case DbType.Date:\r
- case DbType.Time:\r
- case DbType.DateTime:\r
- typ = typeof(DateTime);\r
- break;\r
- default:\r
- typ = typeof(String);\r
- break;\r
- }
- return typ;
- }
-
- // Find DbType for oid
- // which requires a look up of PostgresTypes
- // DbType <-> typname <-> oid
- public static string OidToTypname (int oid, ArrayList pgTypes) {
- // FIXME: more types need
- // to be mapped
- // from PostgreSQL oid type
- // to .NET System.<type>
-
- string typname = "text"; // default
- int i;
- for(i = 0; i < pgTypes.Count; i++) {
- PostgresType pt = (PostgresType) pgTypes[i];
- if(pt.oid == oid) {
- typname = pt.typname;
- break;
- }
- }
-
- return typname;
- }
-
- }
-
sealed internal class PostgresLibrary
{
#region PInvoke Functions
--- /dev/null
+//\r
+// PostgresTypes.cs - holding methods to convert \r
+// between PostgreSQL types and .NET types\r
+//\r
+// Author:\r
+// Daniel Morgan <danmorg@sc.rr.com>\r
+//\r
+// (c)copyright 2002 Daniel Morgan\r
+//\r
+\r
+// Note: this might become PostgresType and PostgresTypeCollection\r
+// also, the PostgresTypes that exist as an inner internal class\r
+// within SqlConnection maybe moved here in the future\r
+\r
+using System;\r
+using System.Collections;\r
+using System.Data;\r
+using System.Data.Common;\r
+using System.Data.SqlClient;\r
+using System.Text;\r
+\r
+namespace System.Data.SqlClient {\r
+\r
+ internal struct PostgresType {\r
+ public int oid;\r
+ public string typname;\r
+ public DbType dbType;\r
+ }\r
+
+ sealed internal class PostgresHelper {
+
+ // translates the PostgreSQL typname to System.Data.DbType
+ public static DbType TypnameToSqlDbType(string typname) {\r
+ DbType sqlType;\r
+ \r
+ // FIXME: use hashtable here?\r
+\r
+ switch(typname) {\r
+\r
+ case "abstime":\r
+ sqlType = DbType.Int32;\r
+ break;\r
+\r
+ case "aclitem":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "bit":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "bool":\r
+ sqlType = DbType.Boolean;\r
+ break;\r
+\r
+ case "box":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "bpchar":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "bytea":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "char":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "cidr":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "circle":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "date":\r
+ sqlType = DbType.Date;\r
+ break;\r
+\r
+ case "float4":\r
+ sqlType = DbType.Single;\r
+ break;\r
+\r
+ case "float8":\r
+ sqlType = DbType.Double;\r
+ break;\r
+\r
+ case "inet":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "int2":\r
+ sqlType = DbType.Int16;\r
+ break;\r
+\r
+ case "int4":\r
+ sqlType = DbType.Int32;\r
+ break;\r
+\r
+ case "int8":\r
+ sqlType = DbType.Int64;\r
+ break;\r
+\r
+ case "interval":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "line":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "lseg":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "macaddr":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "money":\r
+ sqlType = DbType.Decimal;\r
+ break;\r
+\r
+ case "name":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "numeric":\r
+ sqlType = DbType.Decimal;\r
+ break;\r
+\r
+ case "oid":\r
+ sqlType = DbType.Int32;\r
+ break;\r
+\r
+ case "path":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "point":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "polygon":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "refcursor":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "reltime":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "text":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "time":\r
+ sqlType = DbType.Time;\r
+ break;\r
+\r
+ case "timestamp":\r
+ sqlType = DbType.DateTime;\r
+ break;\r
+\r
+ case "timestamptz":\r
+ sqlType = DbType.DateTime;\r
+ break;\r
+\r
+ case "timetz":\r
+ sqlType = DbType.DateTime;\r
+ break;\r
+\r
+ case "tinterval":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "varbit":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "varchar":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ default:\r
+ sqlType = DbType.String;\r
+ break;\r
+ }\r
+ return sqlType;\r
+ }\r
+ \r
+ // Converts data value from database to .NET System type.\r
+ public static object ConvertDbTypeToSystem (DbType typ, String value) {
+ object obj = null;
+
+ // FIXME: more types need
+ // to be converted
+ // from PostgreSQL oid type
+ // to .NET System.<type>
+
+ // FIXME: need to handle a NULL for each type
+ // maybe setting obj to System.DBNull.Value ?
+
+
+ if(value == null) {
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value is null");
+ return null;
+ }
+ else if(value.Equals("")) {
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value is string empty");
+ return null;
+ }
+
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value: " + value);
+
+ // Date, Time, and DateTime
+ // are parsed based on ISO format
+ // "YYYY-MM-DD hh:mi:ss.ms"
+
+ switch(typ) {
+ case DbType.String:
+ obj = String.Copy(value);
+ break;
+ case DbType.Boolean:
+ obj = value.Equals("t");
+ break;
+ case DbType.Int16:\r
+ obj = Int16.Parse(value);\r
+ break;\r
+ case DbType.Int32:\r
+ obj = Int32.Parse(value);\r
+ break;\r
+ case DbType.Int64:\r
+ obj = Int64.Parse(value);\r
+ break;\r
+ case DbType.Decimal:\r
+ obj = Decimal.Parse(value);\r
+ break;\r
+ case DbType.Single:\r
+ obj = Single.Parse(value);\r
+ break;\r
+ case DbType.Double:\r
+ obj = Double.Parse(value);\r
+ break;\r
+ case DbType.Date:\r
+ String[] sd = value.Split(new Char[] {'-'});\r
+ obj = new DateTime(\r
+ Int32.Parse(sd[0]), Int32.Parse(sd[1]), Int32.Parse(sd[2]),\r
+ 0,0,0);\r
+ break;\r
+ case DbType.Time:\r
+ String[] st = value.Split(new Char[] {':'});\r
+ obj = new DateTime(0001,01,01,\r
+ Int32.Parse(st[0]),Int32.Parse(st[1]),Int32.Parse(st[2]));\r
+ break;\r
+ case DbType.DateTime:\r
+ Int32 YYYY,MM,DD,hh,mi,ss,ms;\r
+ YYYY = Int32.Parse(value.Substring(0,4));\r
+ MM = Int32.Parse(value.Substring(5,2));\r
+ DD = Int32.Parse(value.Substring(8,2));\r
+ hh = Int32.Parse(value.Substring(11,2));\r
+ mi = Int32.Parse(value.Substring(14,2));\r
+ ss = Int32.Parse(value.Substring(17,2));\r
+ ms = Int32.Parse(value.Substring(20,2));\r
+ obj = new DateTime(YYYY,MM,DD,hh,mi,ss,ms);\r
+ break;\r
+ default:\r
+ obj = String.Copy(value);\r
+ break;\r
+ }
+
+ return obj;
+ }
+
+ // Translates System.Data.DbType to System.Type
+ public static Type DbTypeToSystemType (DbType dType) {
+ // FIXME: more types need
+ // to be mapped
+ // from PostgreSQL oid type
+ // to .NET System.<type>
+
+ Type typ = null;
+
+ switch(dType) {
+ case DbType.String:
+ typ = typeof(String);
+ break;
+ case DbType.Boolean:
+ typ = typeof(Boolean);
+ break;
+ case DbType.Int16: \r
+ typ = typeof(Int16);\r
+ break;\r
+ case DbType.Int32:\r
+ typ = typeof(Int32);\r
+ break;\r
+ case DbType.Int64:\r
+ typ = typeof(Int64);\r
+ break;\r
+ case DbType.Decimal:\r
+ typ = typeof(Decimal);\r
+ break;\r
+ case DbType.Single:\r
+ typ = typeof(Single);\r
+ break;\r
+ case DbType.Double:\r
+ typ = typeof(Double);\r
+ break;\r
+ case DbType.Date:\r
+ case DbType.Time:\r
+ case DbType.DateTime:\r
+ typ = typeof(DateTime);\r
+ break;\r
+ default:\r
+ typ = typeof(String);\r
+ break;\r
+ }
+ return typ;
+ }
+
+ // Find DbType for oid
+ // which requires a look up of PostgresTypes
+ // DbType <-> typname <-> oid
+ public static string OidToTypname (int oid, ArrayList pgTypes) {
+ // FIXME: more types need
+ // to be mapped
+ // from PostgreSQL oid type
+ // to .NET System.<type>
+
+ string typname = "text"; // default
+ int i;
+ for(i = 0; i < pgTypes.Count; i++) {
+ PostgresType pt = (PostgresType) pgTypes[i];
+ if(pt.oid == oid) {
+ typname = pt.typname;
+ break;
+ }
+ }
+
+ return typname;
+ }
+
+ // Convert a .NET System value type (Int32, String, Boolean, etc)
+ // to a string that can be included within a SQL statement.
+ // This is to methods provides the parameters support
+ // for the PostgreSQL .NET Data provider
+ public static string ObjectToString(DbType dbtype, object obj) {\r
+ \r
+ // TODO: how do we handle a NULL?\r
+ //if(isNull == true)\r
+ // return "NULL";\r
+\r
+ string s;\r
+\r
+ // Date, Time, and DateTime are expressed in ISO format\r
+ // which is "YYYY-MM-DD hh:mm:ss.ms";\r
+ DateTime dt;\r
+ StringBuilder sb;\r
+\r
+ const string zero = "0";\r
+\r
+ switch(dbtype) {\r
+ case DbType.String:
+ s = "'" + obj + "'";
+ break;
+ case DbType.Boolean:
+ if((bool)obj == true)
+ s = "'t'";
+ else
+ s = "'f'";
+ break;
+ case DbType.Int16:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Int32:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Int64:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Decimal:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Single:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Double:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Date:\r
+ dt = (DateTime) obj;\r
+ sb = new StringBuilder();\r
+ sb.Append('\'');\r
+ // year\r
+ if(dt.Year < 10)\r
+ sb.Append("000" + dt.Year);\r
+ else if(dt.Year < 100)\r
+ sb.Append("00" + dt.Year);\r
+ else if(dt.Year < 1000)\r
+ sb.Append("0" + dt.Year);\r
+ else\r
+ sb.Append(dt.Year);\r
+ sb.Append("-");\r
+ // month\r
+ if(dt.Month < 10)\r
+ sb.Append(zero + dt.Month);\r
+ else\r
+ sb.Append(dt.Month);\r
+ sb.Append("-");\r
+ // day\r
+ if(dt.Day < 10)\r
+ sb.Append(zero + dt.Day);\r
+ else\r
+ sb.Append(dt.Day);\r
+ sb.Append('\'');\r
+ s = sb.ToString();\r
+ break;\r
+ case DbType.Time:\r
+ dt = (DateTime) obj;\r
+ sb = new StringBuilder();\r
+ sb.Append('\'');\r
+ // hour\r
+ if(dt.Hour < 10)\r
+ sb.Append(zero + dt.Hour);\r
+ else\r
+ sb.Append(dt.Hour);\r
+ sb.Append(":");\r
+ // minute\r
+ if(dt.Minute < 10)\r
+ sb.Append(zero + dt.Minute);\r
+ else\r
+ sb.Append(dt.Minute);\r
+ sb.Append(":");\r
+ // second\r
+ if(dt.Second < 10)\r
+ sb.Append(zero + dt.Second);\r
+ else\r
+ sb.Append(dt.Second);\r
+ sb.Append('\'');\r
+ s = sb.ToString();\r
+ break;\r
+ case DbType.DateTime:\r
+ dt = (DateTime) obj;\r
+ sb = new StringBuilder();\r
+ sb.Append('\'');\r
+ // year\r
+ if(dt.Year < 10)\r
+ sb.Append("000" + dt.Year);\r
+ else if(dt.Year < 100)\r
+ sb.Append("00" + dt.Year);\r
+ else if(dt.Year < 1000)\r
+ sb.Append("0" + dt.Year);\r
+ else\r
+ sb.Append(dt.Year);\r
+ sb.Append("-");\r
+ // month\r
+ if(dt.Month < 10)\r
+ sb.Append(zero + dt.Month);\r
+ else\r
+ sb.Append(dt.Month);\r
+ sb.Append("-");\r
+ // day\r
+ if(dt.Day < 10)\r
+ sb.Append(zero + dt.Day);\r
+ else\r
+ sb.Append(dt.Day);\r
+ sb.Append(" ");\r
+ // hour\r
+ if(dt.Hour < 10)\r
+ sb.Append(zero + dt.Hour);\r
+ else\r
+ sb.Append(dt.Hour);\r
+ sb.Append(":");\r
+ // minute\r
+ if(dt.Minute < 10)\r
+ sb.Append(zero + dt.Minute);\r
+ else\r
+ sb.Append(dt.Minute);\r
+ sb.Append(":");\r
+ // second\r
+ if(dt.Second < 10)\r
+ sb.Append(zero + dt.Second);\r
+ else\r
+ sb.Append(dt.Second);\r
+ sb.Append(".");\r
+ // millisecond\r
+ if(dt.Millisecond < 10)\r
+ sb.Append(zero + dt.Millisecond);\r
+ else\r
+ sb.Append(dt.Millisecond);\r
+ sb.Append('\'');\r
+ s = sb.ToString();\r
+ break;\r
+ default:\r
+ // default to DbType.String\r
+ s = "'" + obj + "'";\r
+ break;\r
+ }
+ return s;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+//\r
+// ParmUtil.cs - utility to bind variables in a SQL statement to parameters in C# code\r
+// This is in the PostgreSQL .NET Data provider in Mono\r
+//\r
+// Author: \r
+// Daniel Morgan <danmorg@sc.rr.com>\r
+//\r
+// (c)copyright 2002 Daniel Morgan\r
+//\r
+\r
+// comment DEBUG_ParmUtil for production, for debug messages, uncomment\r
+//#define DEBUG_ParmUtil\r
+\r
+using System;\r
+using System.Data;\r
+using System.Text;\r
+\r
+namespace System.Data.SqlClient {\r
+\r
+ enum PostgresBindVariableCharacter {\r
+ Semicolon,\r
+ At,\r
+ QuestionMark\r
+ }\r
+\r
+ public class ParmUtil {\r
+\r
+ private string sql = "";\r
+ private string resultSql = "";\r
+ private SqlParameterCollection parmsCollection = null;\r
+ \r
+ static private PostgresBindVariableCharacter PgbindChar = PostgresBindVariableCharacter.Semicolon;\r
+ static char bindChar;\r
+\r
+ // static constructor\r
+ static ParmUtil() {\r
+ switch(PgbindChar) {\r
+ case PostgresBindVariableCharacter.Semicolon:\r
+ bindChar = ':';\r
+ break;\r
+ case PostgresBindVariableCharacter.At:\r
+ bindChar = '@';\r
+ break;\r
+ case PostgresBindVariableCharacter.QuestionMark:\r
+ // this doesn't have named parameters,\r
+ // they must be in order\r
+ bindChar = '?';\r
+ break;\r
+ }\r
+ }\r
+ \r
+ public ParmUtil(string query, SqlParameterCollection parms) {\r
+ sql = query;\r
+ parmsCollection = parms;\r
+ }\r
+ \r
+ public string ResultSql {\r
+ get {\r
+ return resultSql;\r
+ }\r
+ }\r
+\r
+ // TODO: currently only works for input variables,\r
+ // need to do input/output, output, and return\r
+ public string ReplaceWithParms() {\r
+\r
+ StringBuilder result = new StringBuilder();\r
+ char[] chars = sql.ToCharArray();\r
+ bool bStringConstFound = false;\r
+\r
+ for(int i = 0; i < chars.Length; i++) {\r
+ if(chars[i] == '\'') {\r
+ if(bStringConstFound == true)\r
+ bStringConstFound = false;\r
+ else\r
+ bStringConstFound = true;\r
+\r
+ result.Append(chars[i]);\r
+ }\r
+ else if(chars[i] == bindChar && \r
+ bStringConstFound == false) {\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("Bind Variable character found...");\r
+#endif \r
+ StringBuilder parm = new StringBuilder();\r
+ i++;\r
+ while(i <= chars.Length) {\r
+ char ch;\r
+ if(i == chars.Length)\r
+ ch = ' '; // a space\r
+ else\r
+ ch = chars[i];\r
+\r
+#if DEBUG_ParmUtil \r
+ Console.WriteLine("Is char Letter or digit?");\r
+#endif \r
+ if(Char.IsLetterOrDigit(ch)) {\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("Char IS letter or digit. " + \r
+ "Now, append char to parm StringBuilder");\r
+#endif\r
+ parm.Append(ch);\r
+ }\r
+ else {\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("Char is NOT letter or char. " + \r
+ "thus we got rest of bind variable name. ");\r
+ \r
+ // replace bind variable placeholder \r
+ // with data value constant\r
+ Console.WriteLine("parm StringBuilder to string p...");\r
+#endif\r
+ string p = parm.ToString();\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("calling BindReplace...");\r
+#endif \r
+ bool found = BindReplace(result, p);\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine(" Found = " + found);\r
+#endif\r
+ if(found == true)\r
+ break;\r
+ else { \r
+ // *** Error Handling\r
+ Console.WriteLine("Error: parameter not found: " + p);\r
+ return "";\r
+ }\r
+ }\r
+ i++;\r
+ }\r
+ i--;\r
+ }\r
+ else \r
+ result.Append(chars[i]);\r
+ }\r
+ \r
+ resultSql = result.ToString();\r
+ return resultSql;\r
+ }\r
+\r
+ public bool BindReplace (StringBuilder result, string p) {\r
+ // bind variable\r
+ bool found = false;\r
+\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("Does the parmsCollection contain the parameter???: " + p);\r
+#endif\r
+ if(parmsCollection.Contains(p) == true) {\r
+ // parameter found\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("Parameter Found: " + p);\r
+#endif\r
+ SqlParameter prm = parmsCollection[p];\r
+\r
+#if DEBUG_ParmUtil \r
+ // DEBUG \r
+ Console.WriteLine(" Value: " + prm.Value);\r
+ Console.WriteLine(" Direction: " + prm.Direction);\r
+#endif\r
+ // convert object to string and place\r
+ // into SQL\r
+ if(prm.Direction == ParameterDirection.Input) {\r
+ string strObj = PostgresHelper.\r
+ ObjectToString(prm.DbType, \r
+ prm.Value);\r
+ result.Append(strObj);\r
+ }\r
+ else\r
+ result.Append(bindChar + p);\r
+\r
+ found = true;\r
+ }\r
+ return found;\r
+ }\r
+ }\r
+}\r
/// </summary>
// public sealed class SqlCommand : Component, IDbCommand, ICloneable
public sealed class SqlCommand : IDbCommand {
- // FIXME: Console.WriteLine() is used for debugging throughout
#region Fields
SqlParameterCollection();
// SqlDataReader state data for ExecuteReader()
- private SqlDataReader dataReader;
- private string[] queries;
+ private SqlDataReader dataReader = null;
+ private string[] queries = null;
private int currentQuery;
- CommandBehavior cmdBehavior;
+ private CommandBehavior cmdBehavior = CommandBehavior.Default;
+
+ private ParmUtil parmUtil = null;
#endregion // Fields
rowsAffected = int.Parse(rowsAffectedString);
PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
}
else {
String errorMessage;
errorMessage += " " + PostgresLibrary.\r
PQresultErrorMessage(pgResult);\r
- \r
+\r
+ PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
+\r
throw new SqlException(0, 0,
errorMessage, 0, "",
conn.DataSource, "SqlCommand", 0);\r
string statement = "";
StringBuilder td;
- // TODO: need to handle parameters
-
+#if DEBUG_SqlCommand
+ Console.WriteLine("---------[][] TweakQuery() [][]--------");
+ Console.WriteLine("CommandType: " + commandType + " CommandBehavior: " + cmdBehavior);
+ Console.WriteLine("SQL before command type: " + query);
+#endif
// finish building SQL based on CommandType
switch(commandType) {
case CommandType.Text:
"SELECT " + query + "()";
break;
case CommandType.TableDirect:
+ // NOTE: this is for the PostgreSQL provider
+ // and for OleDb, according to the docs,
+ // an exception is thrown if you try to use
+ // this with SqlCommand
string[] directTables = query.Split(
new Char[] {','});
td = new StringBuilder("SELECT * FROM ");
for(int tab = 0; tab < directTables.Length; tab++) {
- if(tab > 0 && tab < directTables.Length - 1)
+ if(tab > 0)
td.Append(',');
td.Append(directTables[tab]);
// FIXME: if multipe tables, how do we
statement = query;
break;
}
+#if DEBUG_SqlCommand
+ Console.WriteLine("SQL after command type: " + statement);
+#endif
+ // TODO: this parameters utility
+ // currently only support input variables
+ // need todo output, input/output, and return.
+#if DEBUG_SqlCommand
+ Console.WriteLine("using ParmUtil in TweakQuery()...");
+#endif
+ parmUtil = new ParmUtil(statement, parmCollection);
+#if DEBUG_SqlCommand
+ Console.WriteLine("ReplaceWithParms...");
+#endif
+
+ statement = parmUtil.ReplaceWithParms();
+
+#if DEBUG_SqlCommand
+ Console.WriteLine("SQL after ParmUtil: " + statement);
+#endif
return statement;
}
errorMessage += " " + PostgresLibrary.\r
PQresultErrorMessage(pgResult);\r
- \r
+\r
+ PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
+\r
throw new SqlException(0, 0,
errorMessage, 0, "",
conn.DataSource, "SqlCommand", 0);\r
// since SqlCommand has resources so SqlDataReader
// can do Read() and NextResult(), need to free
// those resources. Also, need to allow this SqlCommand
- // and this SqlConnection to things again.
+ // and this SqlConnection to do things again.
internal void CloseReader() {
conn.OpenReader = false;
dataReader = null;
errorMessage += " " + PostgresLibrary.\r
PQresultErrorMessage(pgResult);\r
- \r
+\r
+ PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
+\r
throw new SqlException(0, 0,
errorMessage, 0, "",
conn.DataSource, "SqlCommand", 0);\r
}
}
- SqlParameterCollection Parameters {
+ public SqlParameterCollection Parameters {
get {
return parmCollection;
}
using System.Text;
namespace System.Data.SqlClient {
- // using PGconn = IntPtr;
- // PGconn is native C library type in libpq for Postgres Connection
-
- // using PGressult = IntPtr;
- // PGresult is native C library type in libpq for Postgres Resultset
/// <summary>
/// Represents an open connection to a SQL data source
#region Constructors
- /*
- [MonoTODO]
- public SqlConnection ()
- {
- this.ConnectionString = null;
- this.ConnectionTimeout = 0;
- this.Database = null;
- this.State = 0;
- }
-
- [MonoTODO]
- public SqlConnection (string cs) : SqlConnection ()
- {
- this.ConnectionString = cs;
- }
-
- */
// A lot of the defaults were initialized in the Fields
[MonoTODO]
public SqlConnection () {
PQnfields(pgResult);
BuildTypes (pgResult, nRows, nFields);
+
+ // close result set
+ PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
}
else {
String errorMessage;
errorMessage += " " + PostgresLibrary.\r
PQresultErrorMessage(pgResult);\r
- \r
+\r
+ // close result set
+ PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
+\r
throw new SqlException(0, 0,
errorMessage, 0, "",
con.DataSource, "SqlConnection", 0);\r
}
- // close result set
- PostgresLibrary.PQclear (pgResult);
- pgResult = IntPtr.Zero;
}
}
// IDbDataParameter, IDataParameter, ICloneable
public sealed class SqlParameter : IDbDataParameter, IDataParameter
{
+ private string parmName;
+ private SqlDbType dbtype;
+ private DbType theDbType;
+ private object objValue;
+ private int size;
+ private string sourceColumn;
+ private ParameterDirection direction;
+ private bool isNullable;
+ private byte precision;
+ private byte scale;
+ private DataRowVersion sourceVersion;
+ private int offset;
+
[MonoTODO]
public SqlParameter () {
- // FIXME: do this
+
}
[MonoTODO]
public SqlParameter (string parameterName, object value) {
- // FIXME: do this
+ this.parmName = parameterName;
+ this.objValue = value;
}
[MonoTODO]
public SqlParameter(string parameterName, SqlDbType dbType) {
- // FIXME: do this
+ this.parmName = parameterName;
+ this.dbtype = dbType;
}
[MonoTODO]
public SqlParameter(string parameterName, SqlDbType dbType,
int size) {
- // FIXME: do this
+
+ this.parmName = parameterName;
+ this.dbtype = dbType;
+ this.size = size;
}
[MonoTODO]
public SqlParameter(string parameterName, SqlDbType dbType,
int size, string sourceColumn) {
- // FIXME: do this
+
+ this.parmName = parameterName;
+ this.dbtype = dbType;
+ this.size = size;
+ this.sourceColumn = sourceColumn;
}
[MonoTODO]
bool isNullable, byte precision,
byte scale, string sourceColumn,
DataRowVersion sourceVersion, object value) {
- // FIXME: do this
+
+ this.parmName = parameterName;
+ this.dbtype = dbType;
+ this.size = size;
+ this.sourceColumn = sourceColumn;
+ this.direction = direction;
+ this.isNullable = isNullable;
+ this.precision = precision;
+ this.scale = scale;
+ this.sourceVersion = sourceVersion;
+ this.objValue = value;
}
-
[MonoTODO]
public DbType DbType {
get {
- throw new NotImplementedException ();
+ return theDbType;
}
set {
- throw new NotImplementedException ();
+ theDbType = value;
}
}
[MonoTODO]
public ParameterDirection Direction {
get {
- throw new NotImplementedException ();
+ return direction;
}
set {
- throw new NotImplementedException ();
+ direction = value;
}
}
[MonoTODO]
public bool IsNullable {
get {
- throw new NotImplementedException ();
+ return isNullable;
}
}
[MonoTODO]
public int Offset {
get {
- throw new NotImplementedException ();
+ return offset;
}
set {
- throw new NotImplementedException ();
+ offset = value;
}
}
[MonoTODO]
public string ParameterName {
get {
- throw new NotImplementedException ();
+ return parmName;
}
set {
- throw new NotImplementedException ();
+ parmName = value;
}
}
[MonoTODO]
public string SourceColumn {
get {
- throw new NotImplementedException ();
+ return sourceColumn;
}
set {
- throw new NotImplementedException ();
+ sourceColumn = value;
}
}
[MonoTODO]
public DataRowVersion SourceVersion {
get {
- throw new NotImplementedException ();
+ return sourceVersion;
}
set {
- throw new NotImplementedException ();
+ sourceVersion = value;
}
}
[MonoTODO]
public SqlDbType SqlDbType {
get {
- throw new NotImplementedException ();
+ return dbtype;
}
set {
- throw new NotImplementedException ();
+ dbtype = value;
}
}
[MonoTODO]
public object Value {
get {
- throw new NotImplementedException ();
+ return objValue;
}
set {
- throw new NotImplementedException ();
+ objValue = value;
}
}
[MonoTODO]
public byte Precision {
get {
- throw new NotImplementedException ();
+ return precision;
}
set {
- throw new NotImplementedException ();
+ precision = value;
}
}
[MonoTODO]
public byte Scale {
get {
- throw new NotImplementedException ();
+ return scale;
}
set {
- throw new NotImplementedException ();
+ scale = value;
}
}
public int Size
{
get {
- throw new NotImplementedException ();
+ return size;
}
set {
- throw new NotImplementedException ();
+ size = value;
}
}
[MonoTODO]
public override string ToString() {
- throw new NotImplementedException ();
+ return parmName;
}
}
}
using System;
using System.ComponentModel;
using System.Data;
+using System.Data.Common;
using System.Collections;
namespace System.Data.SqlClient
// IDataParameterCollection, IList, ICollection, IEnumerable
public sealed class SqlParameterCollection : IDataParameterCollection
{
+ private ArrayList parameterList = new ArrayList();
+ private Hashtable parameterNames = new Hashtable();
+
+/*
[MonoTODO]
public void RemoveAt(string parameterName)
{
throw new NotImplementedException ();
}
+
[MonoTODO]
public bool Contains(string parameterName)
{
- throw new NotImplementedException ();
- }
-
- // [MonoTODO]
- public object this[string parameterName]
- {
- get { throw new NotImplementedException (); }
- set { throw new NotImplementedException (); }
+ return parameterNames.ContainsKey(parameterName);
}
+*/
[MonoTODO]
public IEnumerator GetEnumerator()
[MonoTODO]
public SqlParameter Add(SqlParameter value)
{
- throw new NotImplementedException ();
+ parameterList.Add(value);
+ parameterNames.Add(value.ParameterName, parameterList.Add(value));
+ return value;
}
[MonoTODO]
throw new NotImplementedException ();
}
-/*
+
[MonoTODO]
public bool Contains(string value)
{
- throw new NotImplementedException ();
+ return parameterNames.ContainsKey(value);
}
-
-*/
[MonoTODO]
public void CopyTo(Array array, int index)
{
throw new NotImplementedException ();
}
-/*
+
[MonoTODO]
public int IndexOf(string parameterName)
{
throw new NotImplementedException ();
}
-*/
+
[MonoTODO]
public void Insert(int index, object value)
{
{
throw new NotImplementedException ();
}
-/*
+
[MonoTODO]
public void RemoveAt(string parameterName)
{
throw new NotImplementedException ();
}
-*/
-/*
- [MonoTODO]
- [Serializable]
- [ClassInterface(ClassInterfaceType.AutoDual)]
- ~SqlParameterCollection();
-*/
-
+
[MonoTODO]
public int Count {
get {
- throw new NotImplementedException ();
+ return parameterList.Count;
}
}
- // [MonoTODO]
object IList.this[int index] {
- get {
- throw new NotImplementedException ();
- }
+ [MonoTODO]
+ get {
+ return (SqlParameter) this[index];
+ }
- set {
- throw new NotImplementedException ();
- }
+ [MonoTODO]
+ set {
+ this[index] = (SqlParameter) value;
+ }
}
- // [MonoTODO]
public SqlParameter this[int index] {
get {
- throw new NotImplementedException ();
+ return (SqlParameter) parameterList[index];
}
set {
- throw new NotImplementedException ();
+ parameterList[index] = (SqlParameter) value;
}
}
-/*
- [MonoTODO]
+
+ object IDataParameterCollection.this[string parameterName] {
+ [MonoTODO]
+ get {
+ return (SqlParameter) this[parameterName];
+ }
+
+ [MonoTODO]
+ set {
+ this[parameterName] = (SqlParameter) value;
+ }
+ }
+
public SqlParameter this[string parameterName] {
get {
- throw new NotImplementedException ();
+ if(parameterNames.ContainsKey(parameterName))
+ return (SqlParameter) parameterList[(int)parameterNames[parameterName]];
+ else
+ throw new IndexOutOfRangeException("The specified name does not exist: " + parameterName);
}
set {
- throw new NotImplementedException ();
+ if(parameterNames.ContainsKey(parameterName))
+ parameterList[(int)parameterNames[parameterName]] = (SqlParameter) value;
+ else
+ throw new IndexOutOfRangeException("The specified name does not exist: " + parameterName);
}
}
-*/
bool IList.IsFixedSize {
get {
throw new NotImplementedException ();
}
}
-
}
}
PGRES_FATAL_ERROR
}
- internal struct PostgresType {\r
- public int oid;\r
- public string typname;\r
- public DbType dbType;\r
- }\r
-
- sealed internal class PostgresHelper {
-
- // translates the PostgreSQL typname to System.Data.DbType
- public static DbType TypnameToSqlDbType(string typname) {\r
- DbType sqlType;\r
- \r
- // FIXME: use hashtable here?\r
-\r
- switch(typname) {\r
-\r
- case "abstime":\r
- sqlType = DbType.Int32;\r
- break;\r
-\r
- case "aclitem":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "bit":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "bool":\r
- sqlType = DbType.Boolean;\r
- break;\r
-\r
- case "box":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "bpchar":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "bytea":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "char":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "cidr":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "circle":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "date":\r
- sqlType = DbType.Date;\r
- break;\r
-\r
- case "float4":\r
- sqlType = DbType.Single;\r
- break;\r
-\r
- case "float8":\r
- sqlType = DbType.Double;\r
- break;\r
-\r
- case "inet":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "int2":\r
- sqlType = DbType.Int16;\r
- break;\r
-\r
- case "int4":\r
- sqlType = DbType.Int32;\r
- break;\r
-\r
- case "int8":\r
- sqlType = DbType.Int64;\r
- break;\r
-\r
- case "interval":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "line":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "lseg":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "macaddr":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "money":\r
- sqlType = DbType.Decimal;\r
- break;\r
-\r
- case "name":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "numeric":\r
- sqlType = DbType.Decimal;\r
- break;\r
-\r
- case "oid":\r
- sqlType = DbType.Int32;\r
- break;\r
-\r
- case "path":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "point":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "polygon":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "refcursor":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "reltime":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "text":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "time":\r
- sqlType = DbType.Time;\r
- break;\r
-\r
- case "timestamp":\r
- sqlType = DbType.DateTime;\r
- break;\r
-\r
- case "timestamptz":\r
- sqlType = DbType.DateTime;\r
- break;\r
-\r
- case "timetz":\r
- sqlType = DbType.DateTime;\r
- break;\r
-\r
- case "tinterval":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "varbit":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "varchar":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- default:\r
- sqlType = DbType.String;\r
- break;\r
- }\r
- return sqlType;\r
- }\r
- \r
- // Converts data value from database to .NET System type.\r
- public static object ConvertDbTypeToSystem (DbType typ, String value) {
- object obj = null;
-
- // FIXME: more types need
- // to be converted
- // from PostgreSQL oid type
- // to .NET System.<type>
-
- // FIXME: need to handle a NULL for each type
- // maybe setting obj to System.DBNull.Value ?
-
-
- if(value == null) {
- //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
- // typ + " value is null");
- return null;
- }
- else if(value.Equals("")) {
- //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
- // typ + " value is string empty");
- return null;
- }
-
- //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
- // typ + " value: " + value);
-
- // Date, Time, and DateTime
- // are parsed based on ISO format
- // "YYYY-MM-DD hh:mi:ss.ms"
-
- switch(typ) {
- case DbType.String:
- obj = String.Copy(value);
- break;
- case DbType.Boolean:
- obj = value.Equals("t");
- break;
- case DbType.Int16:\r
- obj = Int16.Parse(value);\r
- break;\r
- case DbType.Int32:\r
- obj = Int32.Parse(value);\r
- break;\r
- case DbType.Int64:\r
- obj = Int64.Parse(value);\r
- break;\r
- case DbType.Decimal:\r
- obj = Decimal.Parse(value);\r
- break;\r
- case DbType.Single:\r
- obj = Single.Parse(value);\r
- break;\r
- case DbType.Double:\r
- obj = Double.Parse(value);\r
- break;\r
- case DbType.Date:\r
- String[] sd = value.Split(new Char[] {'-'});\r
- obj = new DateTime(\r
- Int32.Parse(sd[0]), Int32.Parse(sd[1]), Int32.Parse(sd[2]),\r
- 0,0,0);\r
- break;\r
- case DbType.Time:\r
- String[] st = value.Split(new Char[] {':'});\r
- obj = new DateTime(0001,01,01,\r
- Int32.Parse(st[0]),Int32.Parse(st[1]),Int32.Parse(st[2]));\r
- break;\r
- case DbType.DateTime:\r
- Int32 YYYY,MM,DD,hh,mi,ss,ms;\r
- YYYY = Int32.Parse(value.Substring(0,4));\r
- MM = Int32.Parse(value.Substring(5,2));\r
- DD = Int32.Parse(value.Substring(8,2));\r
- hh = Int32.Parse(value.Substring(11,2));\r
- mi = Int32.Parse(value.Substring(14,2));\r
- ss = Int32.Parse(value.Substring(17,2));\r
- ms = Int32.Parse(value.Substring(20,2));\r
- obj = new DateTime(YYYY,MM,DD,hh,mi,ss,ms);\r
- break;\r
- default:\r
- obj = String.Copy(value);\r
- break;\r
- }
-
- return obj;
- }
-
- // Translates System.Data.DbType to System.Type
- public static Type DbTypeToSystemType (DbType dType) {
- // FIXME: more types need
- // to be mapped
- // from PostgreSQL oid type
- // to .NET System.<type>
-
- Type typ = null;
-
- switch(dType) {
- case DbType.String:
- typ = typeof(String);
- break;
- case DbType.Boolean:
- typ = typeof(Boolean);
- break;
- case DbType.Int16: \r
- typ = typeof(Int16);\r
- break;\r
- case DbType.Int32:\r
- typ = typeof(Int32);\r
- break;\r
- case DbType.Int64:\r
- typ = typeof(Int64);\r
- break;\r
- case DbType.Decimal:\r
- typ = typeof(Decimal);\r
- break;\r
- case DbType.Single:\r
- typ = typeof(Single);\r
- break;\r
- case DbType.Double:\r
- typ = typeof(Double);\r
- break;\r
- case DbType.Date:\r
- case DbType.Time:\r
- case DbType.DateTime:\r
- typ = typeof(DateTime);\r
- break;\r
- default:\r
- typ = typeof(String);\r
- break;\r
- }
- return typ;
- }
-
- // Find DbType for oid
- // which requires a look up of PostgresTypes
- // DbType <-> typname <-> oid
- public static string OidToTypname (int oid, ArrayList pgTypes) {
- // FIXME: more types need
- // to be mapped
- // from PostgreSQL oid type
- // to .NET System.<type>
-
- string typname = "text"; // default
- int i;
- for(i = 0; i < pgTypes.Count; i++) {
- PostgresType pt = (PostgresType) pgTypes[i];
- if(pt.oid == oid) {
- typname = pt.typname;
- break;
- }
- }
-
- return typname;
- }
-
- }
-
sealed internal class PostgresLibrary
{
#region PInvoke Functions
--- /dev/null
+//\r
+// PostgresTypes.cs - holding methods to convert \r
+// between PostgreSQL types and .NET types\r
+//\r
+// Author:\r
+// Daniel Morgan <danmorg@sc.rr.com>\r
+//\r
+// (c)copyright 2002 Daniel Morgan\r
+//\r
+\r
+// Note: this might become PostgresType and PostgresTypeCollection\r
+// also, the PostgresTypes that exist as an inner internal class\r
+// within SqlConnection maybe moved here in the future\r
+\r
+using System;\r
+using System.Collections;\r
+using System.Data;\r
+using System.Data.Common;\r
+using System.Data.SqlClient;\r
+using System.Text;\r
+\r
+namespace System.Data.SqlClient {\r
+\r
+ internal struct PostgresType {\r
+ public int oid;\r
+ public string typname;\r
+ public DbType dbType;\r
+ }\r
+
+ sealed internal class PostgresHelper {
+
+ // translates the PostgreSQL typname to System.Data.DbType
+ public static DbType TypnameToSqlDbType(string typname) {\r
+ DbType sqlType;\r
+ \r
+ // FIXME: use hashtable here?\r
+\r
+ switch(typname) {\r
+\r
+ case "abstime":\r
+ sqlType = DbType.Int32;\r
+ break;\r
+\r
+ case "aclitem":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "bit":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "bool":\r
+ sqlType = DbType.Boolean;\r
+ break;\r
+\r
+ case "box":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "bpchar":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "bytea":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "char":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "cidr":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "circle":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "date":\r
+ sqlType = DbType.Date;\r
+ break;\r
+\r
+ case "float4":\r
+ sqlType = DbType.Single;\r
+ break;\r
+\r
+ case "float8":\r
+ sqlType = DbType.Double;\r
+ break;\r
+\r
+ case "inet":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "int2":\r
+ sqlType = DbType.Int16;\r
+ break;\r
+\r
+ case "int4":\r
+ sqlType = DbType.Int32;\r
+ break;\r
+\r
+ case "int8":\r
+ sqlType = DbType.Int64;\r
+ break;\r
+\r
+ case "interval":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "line":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "lseg":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "macaddr":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "money":\r
+ sqlType = DbType.Decimal;\r
+ break;\r
+\r
+ case "name":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "numeric":\r
+ sqlType = DbType.Decimal;\r
+ break;\r
+\r
+ case "oid":\r
+ sqlType = DbType.Int32;\r
+ break;\r
+\r
+ case "path":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "point":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "polygon":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "refcursor":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "reltime":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "text":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "time":\r
+ sqlType = DbType.Time;\r
+ break;\r
+\r
+ case "timestamp":\r
+ sqlType = DbType.DateTime;\r
+ break;\r
+\r
+ case "timestamptz":\r
+ sqlType = DbType.DateTime;\r
+ break;\r
+\r
+ case "timetz":\r
+ sqlType = DbType.DateTime;\r
+ break;\r
+\r
+ case "tinterval":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "varbit":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "varchar":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ default:\r
+ sqlType = DbType.String;\r
+ break;\r
+ }\r
+ return sqlType;\r
+ }\r
+ \r
+ // Converts data value from database to .NET System type.\r
+ public static object ConvertDbTypeToSystem (DbType typ, String value) {
+ object obj = null;
+
+ // FIXME: more types need
+ // to be converted
+ // from PostgreSQL oid type
+ // to .NET System.<type>
+
+ // FIXME: need to handle a NULL for each type
+ // maybe setting obj to System.DBNull.Value ?
+
+
+ if(value == null) {
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value is null");
+ return null;
+ }
+ else if(value.Equals("")) {
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value is string empty");
+ return null;
+ }
+
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value: " + value);
+
+ // Date, Time, and DateTime
+ // are parsed based on ISO format
+ // "YYYY-MM-DD hh:mi:ss.ms"
+
+ switch(typ) {
+ case DbType.String:
+ obj = String.Copy(value);
+ break;
+ case DbType.Boolean:
+ obj = value.Equals("t");
+ break;
+ case DbType.Int16:\r
+ obj = Int16.Parse(value);\r
+ break;\r
+ case DbType.Int32:\r
+ obj = Int32.Parse(value);\r
+ break;\r
+ case DbType.Int64:\r
+ obj = Int64.Parse(value);\r
+ break;\r
+ case DbType.Decimal:\r
+ obj = Decimal.Parse(value);\r
+ break;\r
+ case DbType.Single:\r
+ obj = Single.Parse(value);\r
+ break;\r
+ case DbType.Double:\r
+ obj = Double.Parse(value);\r
+ break;\r
+ case DbType.Date:\r
+ String[] sd = value.Split(new Char[] {'-'});\r
+ obj = new DateTime(\r
+ Int32.Parse(sd[0]), Int32.Parse(sd[1]), Int32.Parse(sd[2]),\r
+ 0,0,0);\r
+ break;\r
+ case DbType.Time:\r
+ String[] st = value.Split(new Char[] {':'});\r
+ obj = new DateTime(0001,01,01,\r
+ Int32.Parse(st[0]),Int32.Parse(st[1]),Int32.Parse(st[2]));\r
+ break;\r
+ case DbType.DateTime:\r
+ Int32 YYYY,MM,DD,hh,mi,ss,ms;\r
+ YYYY = Int32.Parse(value.Substring(0,4));\r
+ MM = Int32.Parse(value.Substring(5,2));\r
+ DD = Int32.Parse(value.Substring(8,2));\r
+ hh = Int32.Parse(value.Substring(11,2));\r
+ mi = Int32.Parse(value.Substring(14,2));\r
+ ss = Int32.Parse(value.Substring(17,2));\r
+ ms = Int32.Parse(value.Substring(20,2));\r
+ obj = new DateTime(YYYY,MM,DD,hh,mi,ss,ms);\r
+ break;\r
+ default:\r
+ obj = String.Copy(value);\r
+ break;\r
+ }
+
+ return obj;
+ }
+
+ // Translates System.Data.DbType to System.Type
+ public static Type DbTypeToSystemType (DbType dType) {
+ // FIXME: more types need
+ // to be mapped
+ // from PostgreSQL oid type
+ // to .NET System.<type>
+
+ Type typ = null;
+
+ switch(dType) {
+ case DbType.String:
+ typ = typeof(String);
+ break;
+ case DbType.Boolean:
+ typ = typeof(Boolean);
+ break;
+ case DbType.Int16: \r
+ typ = typeof(Int16);\r
+ break;\r
+ case DbType.Int32:\r
+ typ = typeof(Int32);\r
+ break;\r
+ case DbType.Int64:\r
+ typ = typeof(Int64);\r
+ break;\r
+ case DbType.Decimal:\r
+ typ = typeof(Decimal);\r
+ break;\r
+ case DbType.Single:\r
+ typ = typeof(Single);\r
+ break;\r
+ case DbType.Double:\r
+ typ = typeof(Double);\r
+ break;\r
+ case DbType.Date:\r
+ case DbType.Time:\r
+ case DbType.DateTime:\r
+ typ = typeof(DateTime);\r
+ break;\r
+ default:\r
+ typ = typeof(String);\r
+ break;\r
+ }
+ return typ;
+ }
+
+ // Find DbType for oid
+ // which requires a look up of PostgresTypes
+ // DbType <-> typname <-> oid
+ public static string OidToTypname (int oid, ArrayList pgTypes) {
+ // FIXME: more types need
+ // to be mapped
+ // from PostgreSQL oid type
+ // to .NET System.<type>
+
+ string typname = "text"; // default
+ int i;
+ for(i = 0; i < pgTypes.Count; i++) {
+ PostgresType pt = (PostgresType) pgTypes[i];
+ if(pt.oid == oid) {
+ typname = pt.typname;
+ break;
+ }
+ }
+
+ return typname;
+ }
+
+ // Convert a .NET System value type (Int32, String, Boolean, etc)
+ // to a string that can be included within a SQL statement.
+ // This is to methods provides the parameters support
+ // for the PostgreSQL .NET Data provider
+ public static string ObjectToString(DbType dbtype, object obj) {\r
+ \r
+ // TODO: how do we handle a NULL?\r
+ //if(isNull == true)\r
+ // return "NULL";\r
+\r
+ string s;\r
+\r
+ // Date, Time, and DateTime are expressed in ISO format\r
+ // which is "YYYY-MM-DD hh:mm:ss.ms";\r
+ DateTime dt;\r
+ StringBuilder sb;\r
+\r
+ const string zero = "0";\r
+\r
+ switch(dbtype) {\r
+ case DbType.String:
+ s = "'" + obj + "'";
+ break;
+ case DbType.Boolean:
+ if((bool)obj == true)
+ s = "'t'";
+ else
+ s = "'f'";
+ break;
+ case DbType.Int16:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Int32:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Int64:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Decimal:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Single:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Double:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Date:\r
+ dt = (DateTime) obj;\r
+ sb = new StringBuilder();\r
+ sb.Append('\'');\r
+ // year\r
+ if(dt.Year < 10)\r
+ sb.Append("000" + dt.Year);\r
+ else if(dt.Year < 100)\r
+ sb.Append("00" + dt.Year);\r
+ else if(dt.Year < 1000)\r
+ sb.Append("0" + dt.Year);\r
+ else\r
+ sb.Append(dt.Year);\r
+ sb.Append("-");\r
+ // month\r
+ if(dt.Month < 10)\r
+ sb.Append(zero + dt.Month);\r
+ else\r
+ sb.Append(dt.Month);\r
+ sb.Append("-");\r
+ // day\r
+ if(dt.Day < 10)\r
+ sb.Append(zero + dt.Day);\r
+ else\r
+ sb.Append(dt.Day);\r
+ sb.Append('\'');\r
+ s = sb.ToString();\r
+ break;\r
+ case DbType.Time:\r
+ dt = (DateTime) obj;\r
+ sb = new StringBuilder();\r
+ sb.Append('\'');\r
+ // hour\r
+ if(dt.Hour < 10)\r
+ sb.Append(zero + dt.Hour);\r
+ else\r
+ sb.Append(dt.Hour);\r
+ sb.Append(":");\r
+ // minute\r
+ if(dt.Minute < 10)\r
+ sb.Append(zero + dt.Minute);\r
+ else\r
+ sb.Append(dt.Minute);\r
+ sb.Append(":");\r
+ // second\r
+ if(dt.Second < 10)\r
+ sb.Append(zero + dt.Second);\r
+ else\r
+ sb.Append(dt.Second);\r
+ sb.Append('\'');\r
+ s = sb.ToString();\r
+ break;\r
+ case DbType.DateTime:\r
+ dt = (DateTime) obj;\r
+ sb = new StringBuilder();\r
+ sb.Append('\'');\r
+ // year\r
+ if(dt.Year < 10)\r
+ sb.Append("000" + dt.Year);\r
+ else if(dt.Year < 100)\r
+ sb.Append("00" + dt.Year);\r
+ else if(dt.Year < 1000)\r
+ sb.Append("0" + dt.Year);\r
+ else\r
+ sb.Append(dt.Year);\r
+ sb.Append("-");\r
+ // month\r
+ if(dt.Month < 10)\r
+ sb.Append(zero + dt.Month);\r
+ else\r
+ sb.Append(dt.Month);\r
+ sb.Append("-");\r
+ // day\r
+ if(dt.Day < 10)\r
+ sb.Append(zero + dt.Day);\r
+ else\r
+ sb.Append(dt.Day);\r
+ sb.Append(" ");\r
+ // hour\r
+ if(dt.Hour < 10)\r
+ sb.Append(zero + dt.Hour);\r
+ else\r
+ sb.Append(dt.Hour);\r
+ sb.Append(":");\r
+ // minute\r
+ if(dt.Minute < 10)\r
+ sb.Append(zero + dt.Minute);\r
+ else\r
+ sb.Append(dt.Minute);\r
+ sb.Append(":");\r
+ // second\r
+ if(dt.Second < 10)\r
+ sb.Append(zero + dt.Second);\r
+ else\r
+ sb.Append(dt.Second);\r
+ sb.Append(".");\r
+ // millisecond\r
+ if(dt.Millisecond < 10)\r
+ sb.Append(zero + dt.Millisecond);\r
+ else\r
+ sb.Append(dt.Millisecond);\r
+ sb.Append('\'');\r
+ s = sb.ToString();\r
+ break;\r
+ default:\r
+ // default to DbType.String\r
+ s = "'" + obj + "'";\r
+ break;\r
+ }
+ return s;
+ }
+ }
+}
\ No newline at end of file
+2002-05-21 Daniel Morgan <danmorg@sc.rr.com>
+
+ * System.Data.SqlClient/ParmUtil.cs: added file - to
+ provide utility for conversion of input parameters
+
+ * System.Data.SqlClient/PostgresTypes.cs: added file -
+ moved the PostgreHelper class to here. May eventually
+ move the internal class PostgresTypes that's inside the
+ SqlConnection to here as well.
+ Handling of PostgreSQL <-> .NET types need to be though
+ out more. Also, the PostgreHelper has a method to convert
+ from .NET types to a string which can be put into used in
+ an SQL statement to execute against a PostgreSQL database.
+ This is the beginnings of parameters support. It currently
+ only supports input parameters. Still need to do output,
+ input/output, and return parameters.
+
+ * Test/TestSqlParameters.cs: new test to test the input
+ parameters in System.Data.SqlClient against a
+ PostgreSQL db.
+
+ * System.Data.SqlClient/PostgresLibrary.cs: moved
+ PostgresHelper class to file PostgresTypes.cs. Also
+ moved struct PostgresType there too.
+
+ * System.Data.SqlClient/SqlCommand.cs: added input
+ parameters support
+
+ * System.Data.SqlClient/SqlParameter.cs: got
+ SqlParameter to work
+
+ * System.Data.SqlClient/SqlParameterCollection.cs: got
+ SqlParameterCollection to work
+
+ * Test/System.Data_test.build: added files to exclude
+ from test build
+
+ * System.Data.SqlClient/SqlConnection.cs: release resources
+ no longer used
+
2002-05-18 Daniel Morgan <danmorg@sc.rr.com>
* System.Xml: added directory for classes with namespace
--- /dev/null
+//\r
+// ParmUtil.cs - utility to bind variables in a SQL statement to parameters in C# code\r
+// This is in the PostgreSQL .NET Data provider in Mono\r
+//\r
+// Author: \r
+// Daniel Morgan <danmorg@sc.rr.com>\r
+//\r
+// (c)copyright 2002 Daniel Morgan\r
+//\r
+\r
+// comment DEBUG_ParmUtil for production, for debug messages, uncomment\r
+//#define DEBUG_ParmUtil\r
+\r
+using System;\r
+using System.Data;\r
+using System.Text;\r
+\r
+namespace System.Data.SqlClient {\r
+\r
+ enum PostgresBindVariableCharacter {\r
+ Semicolon,\r
+ At,\r
+ QuestionMark\r
+ }\r
+\r
+ public class ParmUtil {\r
+\r
+ private string sql = "";\r
+ private string resultSql = "";\r
+ private SqlParameterCollection parmsCollection = null;\r
+ \r
+ static private PostgresBindVariableCharacter PgbindChar = PostgresBindVariableCharacter.Semicolon;\r
+ static char bindChar;\r
+\r
+ // static constructor\r
+ static ParmUtil() {\r
+ switch(PgbindChar) {\r
+ case PostgresBindVariableCharacter.Semicolon:\r
+ bindChar = ':';\r
+ break;\r
+ case PostgresBindVariableCharacter.At:\r
+ bindChar = '@';\r
+ break;\r
+ case PostgresBindVariableCharacter.QuestionMark:\r
+ // this doesn't have named parameters,\r
+ // they must be in order\r
+ bindChar = '?';\r
+ break;\r
+ }\r
+ }\r
+ \r
+ public ParmUtil(string query, SqlParameterCollection parms) {\r
+ sql = query;\r
+ parmsCollection = parms;\r
+ }\r
+ \r
+ public string ResultSql {\r
+ get {\r
+ return resultSql;\r
+ }\r
+ }\r
+\r
+ // TODO: currently only works for input variables,\r
+ // need to do input/output, output, and return\r
+ public string ReplaceWithParms() {\r
+\r
+ StringBuilder result = new StringBuilder();\r
+ char[] chars = sql.ToCharArray();\r
+ bool bStringConstFound = false;\r
+\r
+ for(int i = 0; i < chars.Length; i++) {\r
+ if(chars[i] == '\'') {\r
+ if(bStringConstFound == true)\r
+ bStringConstFound = false;\r
+ else\r
+ bStringConstFound = true;\r
+\r
+ result.Append(chars[i]);\r
+ }\r
+ else if(chars[i] == bindChar && \r
+ bStringConstFound == false) {\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("Bind Variable character found...");\r
+#endif \r
+ StringBuilder parm = new StringBuilder();\r
+ i++;\r
+ while(i <= chars.Length) {\r
+ char ch;\r
+ if(i == chars.Length)\r
+ ch = ' '; // a space\r
+ else\r
+ ch = chars[i];\r
+\r
+#if DEBUG_ParmUtil \r
+ Console.WriteLine("Is char Letter or digit?");\r
+#endif \r
+ if(Char.IsLetterOrDigit(ch)) {\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("Char IS letter or digit. " + \r
+ "Now, append char to parm StringBuilder");\r
+#endif\r
+ parm.Append(ch);\r
+ }\r
+ else {\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("Char is NOT letter or char. " + \r
+ "thus we got rest of bind variable name. ");\r
+ \r
+ // replace bind variable placeholder \r
+ // with data value constant\r
+ Console.WriteLine("parm StringBuilder to string p...");\r
+#endif\r
+ string p = parm.ToString();\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("calling BindReplace...");\r
+#endif \r
+ bool found = BindReplace(result, p);\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine(" Found = " + found);\r
+#endif\r
+ if(found == true)\r
+ break;\r
+ else { \r
+ // *** Error Handling\r
+ Console.WriteLine("Error: parameter not found: " + p);\r
+ return "";\r
+ }\r
+ }\r
+ i++;\r
+ }\r
+ i--;\r
+ }\r
+ else \r
+ result.Append(chars[i]);\r
+ }\r
+ \r
+ resultSql = result.ToString();\r
+ return resultSql;\r
+ }\r
+\r
+ public bool BindReplace (StringBuilder result, string p) {\r
+ // bind variable\r
+ bool found = false;\r
+\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("Does the parmsCollection contain the parameter???: " + p);\r
+#endif\r
+ if(parmsCollection.Contains(p) == true) {\r
+ // parameter found\r
+#if DEBUG_ParmUtil\r
+ Console.WriteLine("Parameter Found: " + p);\r
+#endif\r
+ SqlParameter prm = parmsCollection[p];\r
+\r
+#if DEBUG_ParmUtil \r
+ // DEBUG \r
+ Console.WriteLine(" Value: " + prm.Value);\r
+ Console.WriteLine(" Direction: " + prm.Direction);\r
+#endif\r
+ // convert object to string and place\r
+ // into SQL\r
+ if(prm.Direction == ParameterDirection.Input) {\r
+ string strObj = PostgresHelper.\r
+ ObjectToString(prm.DbType, \r
+ prm.Value);\r
+ result.Append(strObj);\r
+ }\r
+ else\r
+ result.Append(bindChar + p);\r
+\r
+ found = true;\r
+ }\r
+ return found;\r
+ }\r
+ }\r
+}\r
PGRES_FATAL_ERROR
}
- internal struct PostgresType {\r
- public int oid;\r
- public string typname;\r
- public DbType dbType;\r
- }\r
-
- sealed internal class PostgresHelper {
-
- // translates the PostgreSQL typname to System.Data.DbType
- public static DbType TypnameToSqlDbType(string typname) {\r
- DbType sqlType;\r
- \r
- // FIXME: use hashtable here?\r
-\r
- switch(typname) {\r
-\r
- case "abstime":\r
- sqlType = DbType.Int32;\r
- break;\r
-\r
- case "aclitem":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "bit":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "bool":\r
- sqlType = DbType.Boolean;\r
- break;\r
-\r
- case "box":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "bpchar":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "bytea":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "char":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "cidr":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "circle":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "date":\r
- sqlType = DbType.Date;\r
- break;\r
-\r
- case "float4":\r
- sqlType = DbType.Single;\r
- break;\r
-\r
- case "float8":\r
- sqlType = DbType.Double;\r
- break;\r
-\r
- case "inet":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "int2":\r
- sqlType = DbType.Int16;\r
- break;\r
-\r
- case "int4":\r
- sqlType = DbType.Int32;\r
- break;\r
-\r
- case "int8":\r
- sqlType = DbType.Int64;\r
- break;\r
-\r
- case "interval":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "line":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "lseg":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "macaddr":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "money":\r
- sqlType = DbType.Decimal;\r
- break;\r
-\r
- case "name":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "numeric":\r
- sqlType = DbType.Decimal;\r
- break;\r
-\r
- case "oid":\r
- sqlType = DbType.Int32;\r
- break;\r
-\r
- case "path":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "point":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "polygon":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "refcursor":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "reltime":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "text":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "time":\r
- sqlType = DbType.Time;\r
- break;\r
-\r
- case "timestamp":\r
- sqlType = DbType.DateTime;\r
- break;\r
-\r
- case "timestamptz":\r
- sqlType = DbType.DateTime;\r
- break;\r
-\r
- case "timetz":\r
- sqlType = DbType.DateTime;\r
- break;\r
-\r
- case "tinterval":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "varbit":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- case "varchar":\r
- sqlType = DbType.String;\r
- break;\r
-\r
- default:\r
- sqlType = DbType.String;\r
- break;\r
- }\r
- return sqlType;\r
- }\r
- \r
- // Converts data value from database to .NET System type.\r
- public static object ConvertDbTypeToSystem (DbType typ, String value) {
- object obj = null;
-
- // FIXME: more types need
- // to be converted
- // from PostgreSQL oid type
- // to .NET System.<type>
-
- // FIXME: need to handle a NULL for each type
- // maybe setting obj to System.DBNull.Value ?
-
-
- if(value == null) {
- //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
- // typ + " value is null");
- return null;
- }
- else if(value.Equals("")) {
- //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
- // typ + " value is string empty");
- return null;
- }
-
- //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
- // typ + " value: " + value);
-
- // Date, Time, and DateTime
- // are parsed based on ISO format
- // "YYYY-MM-DD hh:mi:ss.ms"
-
- switch(typ) {
- case DbType.String:
- obj = String.Copy(value);
- break;
- case DbType.Boolean:
- obj = value.Equals("t");
- break;
- case DbType.Int16:\r
- obj = Int16.Parse(value);\r
- break;\r
- case DbType.Int32:\r
- obj = Int32.Parse(value);\r
- break;\r
- case DbType.Int64:\r
- obj = Int64.Parse(value);\r
- break;\r
- case DbType.Decimal:\r
- obj = Decimal.Parse(value);\r
- break;\r
- case DbType.Single:\r
- obj = Single.Parse(value);\r
- break;\r
- case DbType.Double:\r
- obj = Double.Parse(value);\r
- break;\r
- case DbType.Date:\r
- String[] sd = value.Split(new Char[] {'-'});\r
- obj = new DateTime(\r
- Int32.Parse(sd[0]), Int32.Parse(sd[1]), Int32.Parse(sd[2]),\r
- 0,0,0);\r
- break;\r
- case DbType.Time:\r
- String[] st = value.Split(new Char[] {':'});\r
- obj = new DateTime(0001,01,01,\r
- Int32.Parse(st[0]),Int32.Parse(st[1]),Int32.Parse(st[2]));\r
- break;\r
- case DbType.DateTime:\r
- Int32 YYYY,MM,DD,hh,mi,ss,ms;\r
- YYYY = Int32.Parse(value.Substring(0,4));\r
- MM = Int32.Parse(value.Substring(5,2));\r
- DD = Int32.Parse(value.Substring(8,2));\r
- hh = Int32.Parse(value.Substring(11,2));\r
- mi = Int32.Parse(value.Substring(14,2));\r
- ss = Int32.Parse(value.Substring(17,2));\r
- ms = Int32.Parse(value.Substring(20,2));\r
- obj = new DateTime(YYYY,MM,DD,hh,mi,ss,ms);\r
- break;\r
- default:\r
- obj = String.Copy(value);\r
- break;\r
- }
-
- return obj;
- }
-
- // Translates System.Data.DbType to System.Type
- public static Type DbTypeToSystemType (DbType dType) {
- // FIXME: more types need
- // to be mapped
- // from PostgreSQL oid type
- // to .NET System.<type>
-
- Type typ = null;
-
- switch(dType) {
- case DbType.String:
- typ = typeof(String);
- break;
- case DbType.Boolean:
- typ = typeof(Boolean);
- break;
- case DbType.Int16: \r
- typ = typeof(Int16);\r
- break;\r
- case DbType.Int32:\r
- typ = typeof(Int32);\r
- break;\r
- case DbType.Int64:\r
- typ = typeof(Int64);\r
- break;\r
- case DbType.Decimal:\r
- typ = typeof(Decimal);\r
- break;\r
- case DbType.Single:\r
- typ = typeof(Single);\r
- break;\r
- case DbType.Double:\r
- typ = typeof(Double);\r
- break;\r
- case DbType.Date:\r
- case DbType.Time:\r
- case DbType.DateTime:\r
- typ = typeof(DateTime);\r
- break;\r
- default:\r
- typ = typeof(String);\r
- break;\r
- }
- return typ;
- }
-
- // Find DbType for oid
- // which requires a look up of PostgresTypes
- // DbType <-> typname <-> oid
- public static string OidToTypname (int oid, ArrayList pgTypes) {
- // FIXME: more types need
- // to be mapped
- // from PostgreSQL oid type
- // to .NET System.<type>
-
- string typname = "text"; // default
- int i;
- for(i = 0; i < pgTypes.Count; i++) {
- PostgresType pt = (PostgresType) pgTypes[i];
- if(pt.oid == oid) {
- typname = pt.typname;
- break;
- }
- }
-
- return typname;
- }
-
- }
-
sealed internal class PostgresLibrary
{
#region PInvoke Functions
--- /dev/null
+//\r
+// PostgresTypes.cs - holding methods to convert \r
+// between PostgreSQL types and .NET types\r
+//\r
+// Author:\r
+// Daniel Morgan <danmorg@sc.rr.com>\r
+//\r
+// (c)copyright 2002 Daniel Morgan\r
+//\r
+\r
+// Note: this might become PostgresType and PostgresTypeCollection\r
+// also, the PostgresTypes that exist as an inner internal class\r
+// within SqlConnection maybe moved here in the future\r
+\r
+using System;\r
+using System.Collections;\r
+using System.Data;\r
+using System.Data.Common;\r
+using System.Data.SqlClient;\r
+using System.Text;\r
+\r
+namespace System.Data.SqlClient {\r
+\r
+ internal struct PostgresType {\r
+ public int oid;\r
+ public string typname;\r
+ public DbType dbType;\r
+ }\r
+
+ sealed internal class PostgresHelper {
+
+ // translates the PostgreSQL typname to System.Data.DbType
+ public static DbType TypnameToSqlDbType(string typname) {\r
+ DbType sqlType;\r
+ \r
+ // FIXME: use hashtable here?\r
+\r
+ switch(typname) {\r
+\r
+ case "abstime":\r
+ sqlType = DbType.Int32;\r
+ break;\r
+\r
+ case "aclitem":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "bit":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "bool":\r
+ sqlType = DbType.Boolean;\r
+ break;\r
+\r
+ case "box":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "bpchar":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "bytea":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "char":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "cidr":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "circle":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "date":\r
+ sqlType = DbType.Date;\r
+ break;\r
+\r
+ case "float4":\r
+ sqlType = DbType.Single;\r
+ break;\r
+\r
+ case "float8":\r
+ sqlType = DbType.Double;\r
+ break;\r
+\r
+ case "inet":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "int2":\r
+ sqlType = DbType.Int16;\r
+ break;\r
+\r
+ case "int4":\r
+ sqlType = DbType.Int32;\r
+ break;\r
+\r
+ case "int8":\r
+ sqlType = DbType.Int64;\r
+ break;\r
+\r
+ case "interval":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "line":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "lseg":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "macaddr":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "money":\r
+ sqlType = DbType.Decimal;\r
+ break;\r
+\r
+ case "name":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "numeric":\r
+ sqlType = DbType.Decimal;\r
+ break;\r
+\r
+ case "oid":\r
+ sqlType = DbType.Int32;\r
+ break;\r
+\r
+ case "path":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "point":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "polygon":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "refcursor":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "reltime":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "text":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "time":\r
+ sqlType = DbType.Time;\r
+ break;\r
+\r
+ case "timestamp":\r
+ sqlType = DbType.DateTime;\r
+ break;\r
+\r
+ case "timestamptz":\r
+ sqlType = DbType.DateTime;\r
+ break;\r
+\r
+ case "timetz":\r
+ sqlType = DbType.DateTime;\r
+ break;\r
+\r
+ case "tinterval":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "varbit":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ case "varchar":\r
+ sqlType = DbType.String;\r
+ break;\r
+\r
+ default:\r
+ sqlType = DbType.String;\r
+ break;\r
+ }\r
+ return sqlType;\r
+ }\r
+ \r
+ // Converts data value from database to .NET System type.\r
+ public static object ConvertDbTypeToSystem (DbType typ, String value) {
+ object obj = null;
+
+ // FIXME: more types need
+ // to be converted
+ // from PostgreSQL oid type
+ // to .NET System.<type>
+
+ // FIXME: need to handle a NULL for each type
+ // maybe setting obj to System.DBNull.Value ?
+
+
+ if(value == null) {
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value is null");
+ return null;
+ }
+ else if(value.Equals("")) {
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value is string empty");
+ return null;
+ }
+
+ //Console.WriteLine("ConvertDbTypeToSystemDbType typ: " +
+ // typ + " value: " + value);
+
+ // Date, Time, and DateTime
+ // are parsed based on ISO format
+ // "YYYY-MM-DD hh:mi:ss.ms"
+
+ switch(typ) {
+ case DbType.String:
+ obj = String.Copy(value);
+ break;
+ case DbType.Boolean:
+ obj = value.Equals("t");
+ break;
+ case DbType.Int16:\r
+ obj = Int16.Parse(value);\r
+ break;\r
+ case DbType.Int32:\r
+ obj = Int32.Parse(value);\r
+ break;\r
+ case DbType.Int64:\r
+ obj = Int64.Parse(value);\r
+ break;\r
+ case DbType.Decimal:\r
+ obj = Decimal.Parse(value);\r
+ break;\r
+ case DbType.Single:\r
+ obj = Single.Parse(value);\r
+ break;\r
+ case DbType.Double:\r
+ obj = Double.Parse(value);\r
+ break;\r
+ case DbType.Date:\r
+ String[] sd = value.Split(new Char[] {'-'});\r
+ obj = new DateTime(\r
+ Int32.Parse(sd[0]), Int32.Parse(sd[1]), Int32.Parse(sd[2]),\r
+ 0,0,0);\r
+ break;\r
+ case DbType.Time:\r
+ String[] st = value.Split(new Char[] {':'});\r
+ obj = new DateTime(0001,01,01,\r
+ Int32.Parse(st[0]),Int32.Parse(st[1]),Int32.Parse(st[2]));\r
+ break;\r
+ case DbType.DateTime:\r
+ Int32 YYYY,MM,DD,hh,mi,ss,ms;\r
+ YYYY = Int32.Parse(value.Substring(0,4));\r
+ MM = Int32.Parse(value.Substring(5,2));\r
+ DD = Int32.Parse(value.Substring(8,2));\r
+ hh = Int32.Parse(value.Substring(11,2));\r
+ mi = Int32.Parse(value.Substring(14,2));\r
+ ss = Int32.Parse(value.Substring(17,2));\r
+ ms = Int32.Parse(value.Substring(20,2));\r
+ obj = new DateTime(YYYY,MM,DD,hh,mi,ss,ms);\r
+ break;\r
+ default:\r
+ obj = String.Copy(value);\r
+ break;\r
+ }
+
+ return obj;
+ }
+
+ // Translates System.Data.DbType to System.Type
+ public static Type DbTypeToSystemType (DbType dType) {
+ // FIXME: more types need
+ // to be mapped
+ // from PostgreSQL oid type
+ // to .NET System.<type>
+
+ Type typ = null;
+
+ switch(dType) {
+ case DbType.String:
+ typ = typeof(String);
+ break;
+ case DbType.Boolean:
+ typ = typeof(Boolean);
+ break;
+ case DbType.Int16: \r
+ typ = typeof(Int16);\r
+ break;\r
+ case DbType.Int32:\r
+ typ = typeof(Int32);\r
+ break;\r
+ case DbType.Int64:\r
+ typ = typeof(Int64);\r
+ break;\r
+ case DbType.Decimal:\r
+ typ = typeof(Decimal);\r
+ break;\r
+ case DbType.Single:\r
+ typ = typeof(Single);\r
+ break;\r
+ case DbType.Double:\r
+ typ = typeof(Double);\r
+ break;\r
+ case DbType.Date:\r
+ case DbType.Time:\r
+ case DbType.DateTime:\r
+ typ = typeof(DateTime);\r
+ break;\r
+ default:\r
+ typ = typeof(String);\r
+ break;\r
+ }
+ return typ;
+ }
+
+ // Find DbType for oid
+ // which requires a look up of PostgresTypes
+ // DbType <-> typname <-> oid
+ public static string OidToTypname (int oid, ArrayList pgTypes) {
+ // FIXME: more types need
+ // to be mapped
+ // from PostgreSQL oid type
+ // to .NET System.<type>
+
+ string typname = "text"; // default
+ int i;
+ for(i = 0; i < pgTypes.Count; i++) {
+ PostgresType pt = (PostgresType) pgTypes[i];
+ if(pt.oid == oid) {
+ typname = pt.typname;
+ break;
+ }
+ }
+
+ return typname;
+ }
+
+ // Convert a .NET System value type (Int32, String, Boolean, etc)
+ // to a string that can be included within a SQL statement.
+ // This is to methods provides the parameters support
+ // for the PostgreSQL .NET Data provider
+ public static string ObjectToString(DbType dbtype, object obj) {\r
+ \r
+ // TODO: how do we handle a NULL?\r
+ //if(isNull == true)\r
+ // return "NULL";\r
+\r
+ string s;\r
+\r
+ // Date, Time, and DateTime are expressed in ISO format\r
+ // which is "YYYY-MM-DD hh:mm:ss.ms";\r
+ DateTime dt;\r
+ StringBuilder sb;\r
+\r
+ const string zero = "0";\r
+\r
+ switch(dbtype) {\r
+ case DbType.String:
+ s = "'" + obj + "'";
+ break;
+ case DbType.Boolean:
+ if((bool)obj == true)
+ s = "'t'";
+ else
+ s = "'f'";
+ break;
+ case DbType.Int16:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Int32:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Int64:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Decimal:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Single:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Double:\r
+ s = obj.ToString();\r
+ break;\r
+ case DbType.Date:\r
+ dt = (DateTime) obj;\r
+ sb = new StringBuilder();\r
+ sb.Append('\'');\r
+ // year\r
+ if(dt.Year < 10)\r
+ sb.Append("000" + dt.Year);\r
+ else if(dt.Year < 100)\r
+ sb.Append("00" + dt.Year);\r
+ else if(dt.Year < 1000)\r
+ sb.Append("0" + dt.Year);\r
+ else\r
+ sb.Append(dt.Year);\r
+ sb.Append("-");\r
+ // month\r
+ if(dt.Month < 10)\r
+ sb.Append(zero + dt.Month);\r
+ else\r
+ sb.Append(dt.Month);\r
+ sb.Append("-");\r
+ // day\r
+ if(dt.Day < 10)\r
+ sb.Append(zero + dt.Day);\r
+ else\r
+ sb.Append(dt.Day);\r
+ sb.Append('\'');\r
+ s = sb.ToString();\r
+ break;\r
+ case DbType.Time:\r
+ dt = (DateTime) obj;\r
+ sb = new StringBuilder();\r
+ sb.Append('\'');\r
+ // hour\r
+ if(dt.Hour < 10)\r
+ sb.Append(zero + dt.Hour);\r
+ else\r
+ sb.Append(dt.Hour);\r
+ sb.Append(":");\r
+ // minute\r
+ if(dt.Minute < 10)\r
+ sb.Append(zero + dt.Minute);\r
+ else\r
+ sb.Append(dt.Minute);\r
+ sb.Append(":");\r
+ // second\r
+ if(dt.Second < 10)\r
+ sb.Append(zero + dt.Second);\r
+ else\r
+ sb.Append(dt.Second);\r
+ sb.Append('\'');\r
+ s = sb.ToString();\r
+ break;\r
+ case DbType.DateTime:\r
+ dt = (DateTime) obj;\r
+ sb = new StringBuilder();\r
+ sb.Append('\'');\r
+ // year\r
+ if(dt.Year < 10)\r
+ sb.Append("000" + dt.Year);\r
+ else if(dt.Year < 100)\r
+ sb.Append("00" + dt.Year);\r
+ else if(dt.Year < 1000)\r
+ sb.Append("0" + dt.Year);\r
+ else\r
+ sb.Append(dt.Year);\r
+ sb.Append("-");\r
+ // month\r
+ if(dt.Month < 10)\r
+ sb.Append(zero + dt.Month);\r
+ else\r
+ sb.Append(dt.Month);\r
+ sb.Append("-");\r
+ // day\r
+ if(dt.Day < 10)\r
+ sb.Append(zero + dt.Day);\r
+ else\r
+ sb.Append(dt.Day);\r
+ sb.Append(" ");\r
+ // hour\r
+ if(dt.Hour < 10)\r
+ sb.Append(zero + dt.Hour);\r
+ else\r
+ sb.Append(dt.Hour);\r
+ sb.Append(":");\r
+ // minute\r
+ if(dt.Minute < 10)\r
+ sb.Append(zero + dt.Minute);\r
+ else\r
+ sb.Append(dt.Minute);\r
+ sb.Append(":");\r
+ // second\r
+ if(dt.Second < 10)\r
+ sb.Append(zero + dt.Second);\r
+ else\r
+ sb.Append(dt.Second);\r
+ sb.Append(".");\r
+ // millisecond\r
+ if(dt.Millisecond < 10)\r
+ sb.Append(zero + dt.Millisecond);\r
+ else\r
+ sb.Append(dt.Millisecond);\r
+ sb.Append('\'');\r
+ s = sb.ToString();\r
+ break;\r
+ default:\r
+ // default to DbType.String\r
+ s = "'" + obj + "'";\r
+ break;\r
+ }
+ return s;
+ }
+ }
+}
\ No newline at end of file
/// </summary>
// public sealed class SqlCommand : Component, IDbCommand, ICloneable
public sealed class SqlCommand : IDbCommand {
- // FIXME: Console.WriteLine() is used for debugging throughout
#region Fields
SqlParameterCollection();
// SqlDataReader state data for ExecuteReader()
- private SqlDataReader dataReader;
- private string[] queries;
+ private SqlDataReader dataReader = null;
+ private string[] queries = null;
private int currentQuery;
- CommandBehavior cmdBehavior;
+ private CommandBehavior cmdBehavior = CommandBehavior.Default;
+
+ private ParmUtil parmUtil = null;
#endregion // Fields
rowsAffected = int.Parse(rowsAffectedString);
PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
}
else {
String errorMessage;
errorMessage += " " + PostgresLibrary.\r
PQresultErrorMessage(pgResult);\r
- \r
+\r
+ PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
+\r
throw new SqlException(0, 0,
errorMessage, 0, "",
conn.DataSource, "SqlCommand", 0);\r
string statement = "";
StringBuilder td;
- // TODO: need to handle parameters
-
+#if DEBUG_SqlCommand
+ Console.WriteLine("---------[][] TweakQuery() [][]--------");
+ Console.WriteLine("CommandType: " + commandType + " CommandBehavior: " + cmdBehavior);
+ Console.WriteLine("SQL before command type: " + query);
+#endif
// finish building SQL based on CommandType
switch(commandType) {
case CommandType.Text:
"SELECT " + query + "()";
break;
case CommandType.TableDirect:
+ // NOTE: this is for the PostgreSQL provider
+ // and for OleDb, according to the docs,
+ // an exception is thrown if you try to use
+ // this with SqlCommand
string[] directTables = query.Split(
new Char[] {','});
td = new StringBuilder("SELECT * FROM ");
for(int tab = 0; tab < directTables.Length; tab++) {
- if(tab > 0 && tab < directTables.Length - 1)
+ if(tab > 0)
td.Append(',');
td.Append(directTables[tab]);
// FIXME: if multipe tables, how do we
statement = query;
break;
}
+#if DEBUG_SqlCommand
+ Console.WriteLine("SQL after command type: " + statement);
+#endif
+ // TODO: this parameters utility
+ // currently only support input variables
+ // need todo output, input/output, and return.
+#if DEBUG_SqlCommand
+ Console.WriteLine("using ParmUtil in TweakQuery()...");
+#endif
+ parmUtil = new ParmUtil(statement, parmCollection);
+#if DEBUG_SqlCommand
+ Console.WriteLine("ReplaceWithParms...");
+#endif
+
+ statement = parmUtil.ReplaceWithParms();
+
+#if DEBUG_SqlCommand
+ Console.WriteLine("SQL after ParmUtil: " + statement);
+#endif
return statement;
}
errorMessage += " " + PostgresLibrary.\r
PQresultErrorMessage(pgResult);\r
- \r
+\r
+ PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
+\r
throw new SqlException(0, 0,
errorMessage, 0, "",
conn.DataSource, "SqlCommand", 0);\r
// since SqlCommand has resources so SqlDataReader
// can do Read() and NextResult(), need to free
// those resources. Also, need to allow this SqlCommand
- // and this SqlConnection to things again.
+ // and this SqlConnection to do things again.
internal void CloseReader() {
conn.OpenReader = false;
dataReader = null;
errorMessage += " " + PostgresLibrary.\r
PQresultErrorMessage(pgResult);\r
- \r
+\r
+ PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
+\r
throw new SqlException(0, 0,
errorMessage, 0, "",
conn.DataSource, "SqlCommand", 0);\r
}
}
- SqlParameterCollection Parameters {
+ public SqlParameterCollection Parameters {
get {
return parmCollection;
}
using System.Text;
namespace System.Data.SqlClient {
- // using PGconn = IntPtr;
- // PGconn is native C library type in libpq for Postgres Connection
-
- // using PGressult = IntPtr;
- // PGresult is native C library type in libpq for Postgres Resultset
/// <summary>
/// Represents an open connection to a SQL data source
#region Constructors
- /*
- [MonoTODO]
- public SqlConnection ()
- {
- this.ConnectionString = null;
- this.ConnectionTimeout = 0;
- this.Database = null;
- this.State = 0;
- }
-
- [MonoTODO]
- public SqlConnection (string cs) : SqlConnection ()
- {
- this.ConnectionString = cs;
- }
-
- */
// A lot of the defaults were initialized in the Fields
[MonoTODO]
public SqlConnection () {
PQnfields(pgResult);
BuildTypes (pgResult, nRows, nFields);
+
+ // close result set
+ PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
}
else {
String errorMessage;
errorMessage += " " + PostgresLibrary.\r
PQresultErrorMessage(pgResult);\r
- \r
+\r
+ // close result set
+ PostgresLibrary.PQclear (pgResult);
+ pgResult = IntPtr.Zero;
+\r
throw new SqlException(0, 0,
errorMessage, 0, "",
con.DataSource, "SqlConnection", 0);\r
}
- // close result set
- PostgresLibrary.PQclear (pgResult);
- pgResult = IntPtr.Zero;
}
}
// IDbDataParameter, IDataParameter, ICloneable
public sealed class SqlParameter : IDbDataParameter, IDataParameter
{
+ private string parmName;
+ private SqlDbType dbtype;
+ private DbType theDbType;
+ private object objValue;
+ private int size;
+ private string sourceColumn;
+ private ParameterDirection direction;
+ private bool isNullable;
+ private byte precision;
+ private byte scale;
+ private DataRowVersion sourceVersion;
+ private int offset;
+
[MonoTODO]
public SqlParameter () {
- // FIXME: do this
+
}
[MonoTODO]
public SqlParameter (string parameterName, object value) {
- // FIXME: do this
+ this.parmName = parameterName;
+ this.objValue = value;
}
[MonoTODO]
public SqlParameter(string parameterName, SqlDbType dbType) {
- // FIXME: do this
+ this.parmName = parameterName;
+ this.dbtype = dbType;
}
[MonoTODO]
public SqlParameter(string parameterName, SqlDbType dbType,
int size) {
- // FIXME: do this
+
+ this.parmName = parameterName;
+ this.dbtype = dbType;
+ this.size = size;
}
[MonoTODO]
public SqlParameter(string parameterName, SqlDbType dbType,
int size, string sourceColumn) {
- // FIXME: do this
+
+ this.parmName = parameterName;
+ this.dbtype = dbType;
+ this.size = size;
+ this.sourceColumn = sourceColumn;
}
[MonoTODO]
bool isNullable, byte precision,
byte scale, string sourceColumn,
DataRowVersion sourceVersion, object value) {
- // FIXME: do this
+
+ this.parmName = parameterName;
+ this.dbtype = dbType;
+ this.size = size;
+ this.sourceColumn = sourceColumn;
+ this.direction = direction;
+ this.isNullable = isNullable;
+ this.precision = precision;
+ this.scale = scale;
+ this.sourceVersion = sourceVersion;
+ this.objValue = value;
}
-
[MonoTODO]
public DbType DbType {
get {
- throw new NotImplementedException ();
+ return theDbType;
}
set {
- throw new NotImplementedException ();
+ theDbType = value;
}
}
[MonoTODO]
public ParameterDirection Direction {
get {
- throw new NotImplementedException ();
+ return direction;
}
set {
- throw new NotImplementedException ();
+ direction = value;
}
}
[MonoTODO]
public bool IsNullable {
get {
- throw new NotImplementedException ();
+ return isNullable;
}
}
[MonoTODO]
public int Offset {
get {
- throw new NotImplementedException ();
+ return offset;
}
set {
- throw new NotImplementedException ();
+ offset = value;
}
}
[MonoTODO]
public string ParameterName {
get {
- throw new NotImplementedException ();
+ return parmName;
}
set {
- throw new NotImplementedException ();
+ parmName = value;
}
}
[MonoTODO]
public string SourceColumn {
get {
- throw new NotImplementedException ();
+ return sourceColumn;
}
set {
- throw new NotImplementedException ();
+ sourceColumn = value;
}
}
[MonoTODO]
public DataRowVersion SourceVersion {
get {
- throw new NotImplementedException ();
+ return sourceVersion;
}
set {
- throw new NotImplementedException ();
+ sourceVersion = value;
}
}
[MonoTODO]
public SqlDbType SqlDbType {
get {
- throw new NotImplementedException ();
+ return dbtype;
}
set {
- throw new NotImplementedException ();
+ dbtype = value;
}
}
[MonoTODO]
public object Value {
get {
- throw new NotImplementedException ();
+ return objValue;
}
set {
- throw new NotImplementedException ();
+ objValue = value;
}
}
[MonoTODO]
public byte Precision {
get {
- throw new NotImplementedException ();
+ return precision;
}
set {
- throw new NotImplementedException ();
+ precision = value;
}
}
[MonoTODO]
public byte Scale {
get {
- throw new NotImplementedException ();
+ return scale;
}
set {
- throw new NotImplementedException ();
+ scale = value;
}
}
public int Size
{
get {
- throw new NotImplementedException ();
+ return size;
}
set {
- throw new NotImplementedException ();
+ size = value;
}
}
[MonoTODO]
public override string ToString() {
- throw new NotImplementedException ();
+ return parmName;
}
}
}
using System;
using System.ComponentModel;
using System.Data;
+using System.Data.Common;
using System.Collections;
namespace System.Data.SqlClient
// IDataParameterCollection, IList, ICollection, IEnumerable
public sealed class SqlParameterCollection : IDataParameterCollection
{
+ private ArrayList parameterList = new ArrayList();
+ private Hashtable parameterNames = new Hashtable();
+
+/*
[MonoTODO]
public void RemoveAt(string parameterName)
{
throw new NotImplementedException ();
}
+
[MonoTODO]
public bool Contains(string parameterName)
{
- throw new NotImplementedException ();
- }
-
- // [MonoTODO]
- public object this[string parameterName]
- {
- get { throw new NotImplementedException (); }
- set { throw new NotImplementedException (); }
+ return parameterNames.ContainsKey(parameterName);
}
+*/
[MonoTODO]
public IEnumerator GetEnumerator()
[MonoTODO]
public SqlParameter Add(SqlParameter value)
{
- throw new NotImplementedException ();
+ parameterList.Add(value);
+ parameterNames.Add(value.ParameterName, parameterList.Add(value));
+ return value;
}
[MonoTODO]
throw new NotImplementedException ();
}
-/*
+
[MonoTODO]
public bool Contains(string value)
{
- throw new NotImplementedException ();
+ return parameterNames.ContainsKey(value);
}
-
-*/
[MonoTODO]
public void CopyTo(Array array, int index)
{
throw new NotImplementedException ();
}
-/*
+
[MonoTODO]
public int IndexOf(string parameterName)
{
throw new NotImplementedException ();
}
-*/
+
[MonoTODO]
public void Insert(int index, object value)
{
{
throw new NotImplementedException ();
}
-/*
+
[MonoTODO]
public void RemoveAt(string parameterName)
{
throw new NotImplementedException ();
}
-*/
-/*
- [MonoTODO]
- [Serializable]
- [ClassInterface(ClassInterfaceType.AutoDual)]
- ~SqlParameterCollection();
-*/
-
+
[MonoTODO]
public int Count {
get {
- throw new NotImplementedException ();
+ return parameterList.Count;
}
}
- // [MonoTODO]
object IList.this[int index] {
- get {
- throw new NotImplementedException ();
- }
+ [MonoTODO]
+ get {
+ return (SqlParameter) this[index];
+ }
- set {
- throw new NotImplementedException ();
- }
+ [MonoTODO]
+ set {
+ this[index] = (SqlParameter) value;
+ }
}
- // [MonoTODO]
public SqlParameter this[int index] {
get {
- throw new NotImplementedException ();
+ return (SqlParameter) parameterList[index];
}
set {
- throw new NotImplementedException ();
+ parameterList[index] = (SqlParameter) value;
}
}
-/*
- [MonoTODO]
+
+ object IDataParameterCollection.this[string parameterName] {
+ [MonoTODO]
+ get {
+ return (SqlParameter) this[parameterName];
+ }
+
+ [MonoTODO]
+ set {
+ this[parameterName] = (SqlParameter) value;
+ }
+ }
+
public SqlParameter this[string parameterName] {
get {
- throw new NotImplementedException ();
+ if(parameterNames.ContainsKey(parameterName))
+ return (SqlParameter) parameterList[(int)parameterNames[parameterName]];
+ else
+ throw new IndexOutOfRangeException("The specified name does not exist: " + parameterName);
}
set {
- throw new NotImplementedException ();
+ if(parameterNames.ContainsKey(parameterName))
+ parameterList[(int)parameterNames[parameterName]] = (SqlParameter) value;
+ else
+ throw new IndexOutOfRangeException("The specified name does not exist: " + parameterName);
}
}
-*/
bool IList.IsFixedSize {
get {
throw new NotImplementedException ();
}
}
-
}
}
<excludes name="TestSqlException.cs"/>\r
<excludes name="TestSqlInsert.cs"/>\r
<excludes name="TestSqlIsolationLevel.cs"/>\r
+ <excludes name="TestSqlDataAdapter.cs"/>\r
<excludes name="PostgresTest.cs"/>\r
+ <excludes name="TestSqlParameters.cs"/>\r
\r
</sources>\r
<references basedir="..\..\..\nunit">\r
<excludes name="TestSqlInsert.cs"/>\r
<excludes name="TestSqlIsolationLevel.cs"/>\r
<excludes name="PostgresTest.cs"/>\r
-\r
+ <excludes name="TestSqlDataAdapter.cs"/>\r
+ <excludes name="TestSqlParameters.cs"/>\r
\r
</sources>\r
<references basedir="..\..\..\nunit">\r
--- /dev/null
+//\r
+// TestSqlParameters.cs - test parameters for the PostgreSQL .NET Data Provider in Mono\r
+// using *Parameter and *ParameterCollection\r
+//\r
+// Note: it currently only tests input parameters. Output is next on the list.\r
+// Then output/input and return parameters.\r
+//\r
+// Author: \r
+// Daniel Morgan <danmorg@sc.rr.com>\r
+//\r
+// (c)copyright 2002 Daniel Morgan\r
+//\r
+\r
+using System;\r
+using System.Collections;\r
+using System.Data;\r
+using System.Data.SqlClient;\r
+\r
+namespace TestSystemDataSqlClient {\r
+\r
+ public class TestParameters {\r
+ public static void Main() {\r
+ Console.WriteLine("** Start Test...");\r
+ \r
+ String connectionString = null;\r
+ connectionString =
+ "host=localhost;" +
+ "dbname=test;" +
+ "user=postgres";
+ \r
+ SqlConnection con;\r
+ Console.WriteLine("** Creating connection...");\r
+ con = new SqlConnection(connectionString);\r
+ Console.WriteLine("** opening connection...");\r
+ con.Open();\r
+ \r
+ string tableName = "pg_type";\r
+\r
+ string sql;\r
+ sql = "SELECT * FROM PG_TABLES WHERE TABLENAME = :inTableName";\r
+ \r
+ Console.WriteLine("** Creating command...");\r
+ SqlCommand cmd = new SqlCommand(sql, con);\r
+ \r
+ // add parameter for inTableName\r
+ Console.WriteLine("** Create parameter...");\r
+ SqlParameter parm = new SqlParameter("inTableName", SqlDbType.Text);\r
+ Console.WriteLine("** set dbtype of parameter to string");\r
+ parm.DbType = DbType.String;\r
+ Console.WriteLine("** set direction of parameter to input");\r
+ parm.Direction = ParameterDirection.Input;\r
+ Console.WriteLine("** set value to the tableName string...");\r
+ parm.Value = tableName;\r
+ \r
+ Console.WriteLine("** add parameter to parameters collection in the command...");\r
+ cmd.Parameters.Add(parm);\r
+ \r
+ SqlDataReader rdr;\r
+ Console.WriteLine("** ExecuteReader()...");\r
+ rdr = cmd.ExecuteReader();\r
+ Console.WriteLine("[][] And now we are going to our results [][]...");\r
+ int c;\r
+ int results = 0;\r
+ do {\r
+ results++;\r
+ Console.WriteLine("Result Set " + results + "...");\r
+\r
+ // get the DataTable that holds\r
+ // the schema\r
+ DataTable dt = rdr.GetSchemaTable();\r
+ \r
+ // number of columns in the table\r
+ Console.WriteLine(" Total Columns: " +\r
+ dt.Columns.Count);\r
+\r
+ // display the schema\r
+ for(c = 0; c < dt.Columns.Count; c++) {\r
+ Console.WriteLine(" Column Name: " + \r
+ dt.Columns[c].ColumnName);\r
+ Console.WriteLine(" MaxLength: " +\r
+ dt.Columns[c].MaxLength);\r
+ Console.WriteLine(" Type: " +\r
+ dt.Columns[c].DataType);\r
+ }\r
+ int nRows = 0;\r
+\r
+ // Read and display the rows\r
+ while(rdr.Read()) {\r
+ Console.WriteLine(" Row " + nRows + ": ");\r
+\r
+ for(c = 0; c < rdr.FieldCount; c++) {\r
+ if(rdr.IsDBNull(c) == true)\r
+ Console.WriteLine(" " + \r
+ rdr.GetName(c) + " is DBNull");\r
+ else\r
+ Console.WriteLine(" " + \r
+ rdr.GetName(c) + ": " +\r
+ rdr[c].ToString());\r
+ }\r
+ nRows++;\r
+ }\r
+ Console.WriteLine(" Total Rows: " + \r
+ nRows);\r
+ } while(rdr.NextResult());\r
+ Console.WriteLine("Total Result sets: " + results);\r
+\r
+ con.Close();\r
+ }\r
+ }\r
+}\r