#region MIT license
//
// MIT license
//
// Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Linq.Mapping;
using System.Reflection;
using DbLinq.Data.Linq;
using DbLinq.Data.Linq.SqlClient;
using DbLinq.Sqlite;
using DbLinq.Util;
using DbLinq.Vendor;
#if MONO_STRICT
using DataContext = System.Data.Linq.DataContext;
#else
using DataContext = DbLinq.Data.Linq.DataContext;
#endif
namespace DbLinq.Sqlite
{
///
/// SQLite - specific code.
///
[Vendor(typeof(SqliteProvider))]
#if !MONO_STRICT
public
#endif
class SqliteVendor : Vendor.Implementation.Vendor
{
public override string VendorName { get { return "SQLite"; } }
protected readonly SqliteSqlProvider sqlProvider = new SqliteSqlProvider();
public override ISqlProvider SqlProvider { get { return sqlProvider; } }
///
/// call SQLite stored proc or stored function,
/// optionally return DataSet, and collect return params.
///
public override System.Data.Linq.IExecuteResult ExecuteMethodCall(DataContext context, MethodInfo method
, params object[] inputValues)
{
if (method == null)
throw new ArgumentNullException("L56 Null 'method' parameter");
//check to make sure there is exactly one [FunctionEx]? that's below.
//FunctionAttribute functionAttrib = GetFunctionAttribute(method);
var functionAttrib = context.Mapping.GetFunction(method);
ParameterInfo[] paramInfos = method.GetParameters();
//int numRequiredParams = paramInfos.Count(p => p.IsIn || p.IsRetval);
//if (numRequiredParams != inputValues.Length)
// throw new ArgumentException("L161 Argument count mismatch");
string sp_name = functionAttrib.MappedName;
using (IDbCommand command = context.Connection.CreateCommand())
{
command.CommandText = sp_name;
//SQLiteCommand command = new SQLiteCommand("select hello0()");
int currInputIndex = 0;
List paramNames = new List();
for (int i = 0; i < paramInfos.Length; i++)
{
ParameterInfo paramInfo = paramInfos[i];
//TODO: check to make sure there is exactly one [Parameter]?
ParameterAttribute paramAttrib = paramInfo.GetCustomAttributes(false).OfType().Single();
string paramName = "?" + paramAttrib.Name; //eg. '?param1'
paramNames.Add(paramName);
System.Data.ParameterDirection direction = GetDirection(paramInfo, paramAttrib);
//SQLiteDbType dbType = SQLiteTypeConversions.ParseType(paramAttrib.DbType);
IDataParameter cmdParam = command.CreateParameter();
cmdParam.ParameterName = paramName;
//cmdParam.Direction = System.Data.ParameterDirection.Input;
if (direction == ParameterDirection.Input || direction == ParameterDirection.InputOutput)
{
object inputValue = inputValues[currInputIndex++];
cmdParam.Value = inputValue;
}
else
{
cmdParam.Value = null;
}
cmdParam.Direction = direction;
command.Parameters.Add(cmdParam);
}
if (!functionAttrib.IsComposable)
{
//procedures: under the hood, this seems to prepend 'CALL '
command.CommandType = System.Data.CommandType.StoredProcedure;
}
else
{
//functions: 'SELECT myFunction()' or 'SELECT hello(?s)'
string cmdText = "SELECT " + command.CommandText + "($args)";
cmdText = cmdText.Replace("$args", string.Join(",", paramNames.ToArray()));
command.CommandText = cmdText;
}
if (method.ReturnType == typeof(DataSet))
{
//unknown shape of resultset:
System.Data.DataSet dataSet = new DataSet();
IDbDataAdapter adapter = CreateDataAdapter(context);
adapter.SelectCommand = command;
adapter.Fill(dataSet);
List