/********************************************************
* ADO.NET 2.0 Data Provider for SQLite Version 3.X
* Written by Robert Simpson (robert@blackcastlesoft.com)
*
* Released to the public domain, use at your own risk!
********************************************************/
namespace Mono.Data.Sqlite
{
using System;
using System.Data;
using System.Data.Common;
using System.Collections.Generic;
using System.Globalization;
using System.ComponentModel;
using System.Reflection;
///
/// SQLite implementation of DbParameterCollection.
///
#if !PLATFORM_COMPACTFRAMEWORK
[Editor("Microsoft.VSDesigner.Data.Design.DBParametersEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), ListBindable(false)]
#endif
public sealed class SqliteParameterCollection : DbParameterCollection
{
///
/// The underlying command to which this collection belongs
///
private SqliteCommand _command;
///
/// The internal array of parameters in this collection
///
private List _parameterList;
///
/// Determines whether or not all parameters have been bound to their statement(s)
///
private bool _unboundFlag;
///
/// Initializes the collection
///
/// The command to which the collection belongs
internal SqliteParameterCollection(SqliteCommand cmd)
{
_command = cmd;
_parameterList = new List();
_unboundFlag = true;
}
///
/// Returns true
///
public override bool IsSynchronized
{
get { return true; }
}
///
/// Returns false
///
public override bool IsFixedSize
{
get { return false; }
}
///
/// Returns false
///
public override bool IsReadOnly
{
get { return false; }
}
///
/// Returns null
///
public override object SyncRoot
{
get { return null; }
}
///
/// Retrieves an enumerator for the collection
///
/// An enumerator for the underlying array
public override System.Collections.IEnumerator GetEnumerator()
{
return _parameterList.GetEnumerator();
}
///
/// Adds a parameter to the collection
///
/// The parameter name
/// The data type
/// The size of the value
/// The source column
/// A SqliteParameter object
public SqliteParameter Add(string parameterName, DbType parameterType, int parameterSize, string sourceColumn)
{
SqliteParameter param = new SqliteParameter(parameterName, parameterType, parameterSize, sourceColumn);
Add(param);
return param;
}
///
/// Adds a parameter to the collection
///
/// The parameter name
/// The data type
/// The size of the value
/// A SqliteParameter object
public SqliteParameter Add(string parameterName, DbType parameterType, int parameterSize)
{
SqliteParameter param = new SqliteParameter(parameterName, parameterType, parameterSize);
Add(param);
return param;
}
///
/// Adds a parameter to the collection
///
/// The parameter name
/// The data type
/// A SqliteParameter object
public SqliteParameter Add(string parameterName, DbType parameterType)
{
SqliteParameter param = new SqliteParameter(parameterName, parameterType);
Add(param);
return param;
}
///
/// Adds a parameter to the collection
///
/// The parameter to add
/// A zero-based index of where the parameter is located in the array
public int Add(SqliteParameter parameter)
{
int n = -1;
if (String.IsNullOrEmpty(parameter.ParameterName) == false)
{
n = IndexOf(parameter.ParameterName);
}
if (n == -1)
{
n = _parameterList.Count;
_parameterList.Add((SqliteParameter)parameter);
}
SetParameter(n, parameter);
return n;
}
///
/// Adds a parameter to the collection
///
/// The parameter to add
/// A zero-based index of where the parameter is located in the array
#if !PLATFORM_COMPACTFRAMEWORK
[EditorBrowsable(EditorBrowsableState.Never)]
#endif
public override int Add(object value)
{
return Add((SqliteParameter)value);
}
///
/// Adds a named/unnamed parameter and its value to the parameter collection.
///
/// Name of the parameter, or null to indicate an unnamed parameter
/// The initial value of the parameter
/// Returns the SqliteParameter object created during the call.
public SqliteParameter AddWithValue(string parameterName, object value)
{
SqliteParameter param = new SqliteParameter(parameterName, value);
Add(param);
return param;
}
///
/// Adds an array of parameters to the collection
///
/// The array of parameters to add
public void AddRange(SqliteParameter[] values)
{
int x = values.Length;
for (int n = 0; n < x; n++)
Add(values[n]);
}
///
/// Adds an array of parameters to the collection
///
/// The array of parameters to add
public override void AddRange(Array values)
{
int x = values.Length;
for (int n = 0; n < x; n++)
Add((SqliteParameter)(values.GetValue(n)));
}
///
/// Clears the array and resets the collection
///
public override void Clear()
{
_unboundFlag = true;
_parameterList.Clear();
}
///
/// Determines if the named parameter exists in the collection
///
/// The name of the parameter to check
/// True if the parameter is in the collection
public override bool Contains(string parameterName)
{
return (IndexOf(parameterName) != -1);
}
///
/// Determines if the parameter exists in the collection
///
/// The SqliteParameter to check
/// True if the parameter is in the collection
public override bool Contains(object value)
{
return _parameterList.Contains((SqliteParameter)value);
}
///
/// Not implemented
///
///
///
public override void CopyTo(Array array, int index)
{
throw new NotImplementedException();
}
///
/// Returns a count of parameters in the collection
///
public override int Count
{
get { return _parameterList.Count; }
}
///
/// Overloaded to specialize the return value of the default indexer
///
/// Name of the parameter to get/set
/// The specified named SQLite parameter
public new SqliteParameter this[string parameterName]
{
get
{
return (SqliteParameter)GetParameter(parameterName);
}
set
{
SetParameter(parameterName, value);
}
}
///
/// Overloaded to specialize the return value of the default indexer
///
/// The index of the parameter to get/set
/// The specified SQLite parameter
public new SqliteParameter this[int index]
{
get
{
return (SqliteParameter)GetParameter(index);
}
set
{
SetParameter(index, value);
}
}
///
/// Retrieve a parameter by name from the collection
///
/// The name of the parameter to fetch
/// A DbParameter object
protected override DbParameter GetParameter(string parameterName)
{
return GetParameter(IndexOf(parameterName));
}
///
/// Retrieves a parameter by its index in the collection
///
/// The index of the parameter to retrieve
/// A DbParameter object
protected override DbParameter GetParameter(int index)
{
return _parameterList[index];
}
///
/// Returns the index of a parameter given its name
///
/// The name of the parameter to find
/// -1 if not found, otherwise a zero-based index of the parameter
public override int IndexOf(string parameterName)
{
int x = _parameterList.Count;
for (int n = 0; n < x; n++)
{
if (String.Compare(parameterName, _parameterList[n].ParameterName, true, CultureInfo.InvariantCulture) == 0)
return n;
}
return -1;
}
///
/// Returns the index of a parameter
///
/// The parameter to find
/// -1 if not found, otherwise a zero-based index of the parameter
public override int IndexOf(object value)
{
return _parameterList.IndexOf((SqliteParameter)value);
}
///
/// Inserts a parameter into the array at the specified location
///
/// The zero-based index to insert the parameter at
/// The parameter to insert
public override void Insert(int index, object value)
{
_unboundFlag = true;
_parameterList.Insert(index, (SqliteParameter)value);
}
///
/// Removes a parameter from the collection
///
/// The parameter to remove
public override void Remove(object value)
{
_unboundFlag = true;
_parameterList.Remove((SqliteParameter)value);
}
///
/// Removes a parameter from the collection given its name
///
/// The name of the parameter to remove
public override void RemoveAt(string parameterName)
{
RemoveAt(IndexOf(parameterName));
}
///
/// Removes a parameter from the collection given its index
///
/// The zero-based parameter index to remove
public override void RemoveAt(int index)
{
_unboundFlag = true;
_parameterList.RemoveAt(index);
}
///
/// Re-assign the named parameter to a new parameter object
///
/// The name of the parameter to replace
/// The new parameter
protected override void SetParameter(string parameterName, DbParameter value)
{
SetParameter(IndexOf(parameterName), value);
}
///
/// Re-assign a parameter at the specified index
///
/// The zero-based index of the parameter to replace
/// The new parameter
protected override void SetParameter(int index, DbParameter value)
{
_unboundFlag = true;
_parameterList[index] = (SqliteParameter)value;
}
///
/// Un-binds all parameters from their statements
///
internal void Unbind()
{
_unboundFlag = true;
}
///
/// This function attempts to map all parameters in the collection to all statements in a Command.
/// Since named parameters may span multiple statements, this function makes sure all statements are bound
/// to the same named parameter. Unnamed parameters are bound in sequence.
///
internal void MapParameters(SqliteStatement activeStatement)
{
if (_unboundFlag == false || _parameterList.Count == 0 || _command._statementList == null) return;
int nUnnamed = 0;
string s;
int n;
int y = -1;
SqliteStatement stmt;
foreach(SqliteParameter p in _parameterList)
{
y ++;
s = p.ParameterName;
if (s == null)
{
s = String.Format(CultureInfo.InvariantCulture, ";{0}", nUnnamed);
nUnnamed++;
}
int x;
bool isMapped = false;
if (activeStatement == null)
x = _command._statementList.Count;
else
x = 1;
stmt = activeStatement;
for (n = 0; n < x; n++)
{
isMapped = false;
if (stmt == null) stmt = _command._statementList[n];
if (stmt._paramNames != null)
{
if (stmt.MapParameter(s, p) == true)
isMapped = true;
}
stmt = null;
}
// If the parameter has a name, but the SQL statement uses unnamed references, this can happen -- attempt to map
// the parameter by its index in the collection
if (isMapped == false)
{
s = String.Format(CultureInfo.InvariantCulture, ";{0}", y);
stmt = activeStatement;
for (n = 0; n < x; n++)
{
if (stmt == null) stmt = _command._statementList[n];
if (stmt._paramNames != null)
{
if (stmt.MapParameter(s, p) == true)
isMapped = true;
}
stmt = null;
}
}
}
if (activeStatement == null) _unboundFlag = false;
}
}
}