2025-06-04 23:10:11 +09:00
//
// Copyright (c) 2009-2012 Krueger Systems, Inc.
//
// 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.
//
2025-06-06 02:17:54 +09:00
#nullable enable
2025-06-04 23:10:11 +09:00
#if WINDOWS_PHONE & & ! USE_WP8_NATIVE_SQLITE
#define USE_CSHARP_SQLITE
#endif
2025-06-06 02:17:54 +09:00
2025-06-04 23:10:11 +09:00
using System ;
using System.Diagnostics ;
using System.Runtime.InteropServices ;
using System.Collections.Generic ;
using System.Reflection ;
using System.Linq ;
using System.Linq.Expressions ;
using System.Threading ;
#if USE_CSHARP_SQLITE
using Sqlite3 = Community . CsharpSqlite . Sqlite3 ;
using Sqlite3DatabaseHandle = Community . CsharpSqlite . Sqlite3 . sqlite3 ;
using Sqlite3Statement = Community . CsharpSqlite . Sqlite3 . Vdbe ;
#elif USE_WP8_NATIVE_SQLITE
using Sqlite3 = Sqlite . Sqlite3 ;
using Sqlite3DatabaseHandle = Sqlite . Database ;
using Sqlite3Statement = Sqlite . Statement ;
#else
using Sqlite3DatabaseHandle = System . IntPtr ;
using Sqlite3Statement = System . IntPtr ;
#endif
/// <summary>
/// SQLite4Unity3d<33> <64> Unity ȯ<> 濡<EFBFBD> <E6BFA1> SQLite<74> <65> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> ְ<EFBFBD> <20> <> <EFBFBD> ִ<EFBFBD> <20> <> <EFBFBD> ̺귯<CCBA> <EAB7AF> <EFBFBD> Դϴ<D4B4> .
/// <20> <> Ŭ<> <C5AC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> SQLite <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
namespace SQLite4Unity3d
{
/// <summary>
/// SQLite <20> ۾<EFBFBD> <20> <> <20> <EFBFBD> <DFBB> ϴ<EFBFBD> <20> <> <EFBFBD> ܸ<EFBFBD> ó<> <C3B3> <EFBFBD> ϱ <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ŭ<> <C5AC> <EFBFBD> <EFBFBD> <EFBFBD> Դϴ<D4B4> .
/// </summary>
public class SQLiteException : Exception
{
public SQLite3 . Result Result { get ; private set ; }
protected SQLiteException ( SQLite3 . Result r , string message ) : base ( message )
{
Result = r ;
}
public static SQLiteException New ( SQLite3 . Result r , string message )
{
return new SQLiteException ( r , message ) ;
}
}
/// <summary>
/// NOT NULL <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <20> <EFBFBD> <DFBB> ϴ<EFBFBD> <20> <> <EFBFBD> ܸ<EFBFBD> ó<> <C3B3> <EFBFBD> ϱ <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ŭ<> <C5AC> <EFBFBD> <EFBFBD> <EFBFBD> Դϴ<D4B4> .
/// </summary>
public class NotNullConstraintViolationException : SQLiteException
{
public IEnumerable < TableMapping . Column > Columns { get ; protected set ; }
protected NotNullConstraintViolationException ( SQLite3 . Result r , string message )
: this ( r , message , null , null )
{
}
protected NotNullConstraintViolationException ( SQLite3 . Result r , string message , TableMapping mapping , object obj )
: base ( r , message )
{
if ( mapping ! = null & & obj ! = null )
{
this . Columns = from c in mapping . Columns
where c . IsNullable = = false & & c . GetValue ( obj ) = = null
select c ;
}
}
public static new NotNullConstraintViolationException New ( SQLite3 . Result r , string message )
{
return new NotNullConstraintViolationException ( r , message ) ;
}
public static NotNullConstraintViolationException New ( SQLite3 . Result r , string message , TableMapping mapping , object obj )
{
return new NotNullConstraintViolationException ( r , message , mapping , obj ) ;
}
public static NotNullConstraintViolationException New ( SQLiteException exception , TableMapping mapping , object obj )
{
return new NotNullConstraintViolationException ( exception . Result , exception . Message , mapping , obj ) ;
}
}
/// <summary>
/// SQLite <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ɼǵ<C9BC> <C7B5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
[Flags]
public enum SQLiteOpenFlags
{
ReadOnly = 1 , ReadWrite = 2 , Create = 4 ,
NoMutex = 0x8000 , FullMutex = 0x10000 ,
SharedCache = 0x20000 , PrivateCache = 0x40000 ,
ProtectionComplete = 0x00100000 ,
ProtectionCompleteUnlessOpen = 0x00200000 ,
ProtectionCompleteUntilFirstUserAuthentication = 0x00300000 ,
ProtectionNone = 0x00400000
}
/// <summary>
/// <20> <> <EFBFBD> ̺<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ǵ<EFBFBD> <20> ÷<EFBFBD> <C3B7> <EFBFBD> <EFBFBD> Դϴ<D4B4> .
/// </summary>
[Flags]
public enum CreateFlags
{
None = 0 ,
ImplicitPK = 1 , // create a primary key for field called 'Id' (Orm.ImplicitPkName)
ImplicitIndex = 2 , // create an index for fields ending in 'Id' (Orm.ImplicitIndexSuffix)
AllImplicit = 3 , // do both above
AutoIncPK = 4 // force PK field to be auto inc
}
/// <summary>
/// SQLite <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ÿ<EFBFBD> <C5B8> <EFBFBD> ϴ<EFBFBD> .
/// </summary>
public partial class SQLiteConnection : IDisposable
{
private bool _open ;
private TimeSpan _busyTimeout ;
private Dictionary < string , TableMapping > _mappings = null ;
private Dictionary < string , TableMapping > _tables = null ;
private System . Diagnostics . Stopwatch _sw ;
private TimeSpan _elapsed = default ( TimeSpan ) ;
private int _transactionDepth = 0 ;
private Random _rand = new Random ( ) ;
public Sqlite3DatabaseHandle Handle { get ; private set ; }
internal static readonly Sqlite3DatabaseHandle NullHandle = default ( Sqlite3DatabaseHandle ) ;
public string DatabasePath { get ; private set ; }
// <20> <> <EFBFBD> <EFBFBD> ȭ <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Դϴ<D4B4> .
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ջ<EFBFBD> <D5BB> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϱ <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> Ͽ<EFBFBD> *<2A> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> * <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ؾ<EFBFBD> <20> մϴ<D5B4> .
// <20> ̸<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> Ͽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> ȭ <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϱ <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ű<> <C5B0> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ̰<EFBFBD> , <20> <> <EFBFBD> <EFBFBD> lock() <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> Դϴ<D4B4> .
//
// <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> :
// - <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ͻ<EFBFBD> <CFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ڵ<EFBFBD> <DAB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̷<EFBFBD> <CCB7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> .
// - <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ¸ <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϱ <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> α <CEB1> <D7B7> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <20> ֽ<EFBFBD> <D6BD> ϴ<EFBFBD> :
// - RunInTransaction(Action)<29> <> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ߿<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <20> <> <EFBFBD> ϴ<DEB4> (<28> <> <EFBFBD> <EFBFBD> /<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> ).
// - RunInDatabaseLock(Action)<29> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> (<28> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ).
private static Dictionary < string , object > syncObjects = new Dictionary < string , object > ( ) ;
#region debug tracing
public bool Trace { get ; set ; }
public bool TimeExecution { get ; set ; }
public delegate void TraceHandler ( string message ) ;
public event TraceHandler TraceEvent ;
internal void InvokeTrace ( string message )
{
if ( TraceEvent ! = null )
{
TraceEvent ( message ) ;
}
}
public delegate void TimeExecutionHandler ( TimeSpan executionTime , TimeSpan totalExecutionTime ) ;
public event TimeExecutionHandler TimeExecutionEvent ;
internal void InvokeTimeExecution ( TimeSpan executionTime , TimeSpan totalExecutionTime )
{
if ( TimeExecutionEvent ! = null )
{
TimeExecutionEvent ( executionTime , totalExecutionTime ) ;
}
}
#endregion
public bool StoreDateTimeAsTicks { get ; private set ; }
/// <summary>
/// <20> <> <EFBFBD> ο <EFBFBD> SQLiteConnection<6F> <6E> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> SQLite <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <20> <> <EFBFBD> ϴ<EFBFBD> .
/// </summary>
/// <param name="databasePath">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> θ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </param>
/// <param name="storeDateTimeAsTicks">
/// DateTime <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> ƽ (true) <20> Ǵ<EFBFBD> <20> <> <EFBFBD> ڿ<EFBFBD> (false)<29> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ݵ<EFBFBD> <DDB5> <EFBFBD> true<75> <65> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . false<73> <65> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȣ ȯ<C8A3> <C8AF> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> Դϴ<D4B4> .
/// true<75> <65> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϸ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ũ<> <C5A9> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ǹ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> .
/// </param>
/// <example>
/// <code>
/// // <20> ⺻ <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// var db = new SQLiteConnection(Application.persistentDataPath + "/myDatabase.db", true);
///
/// // <20> <> <EFBFBD> ̺<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// db.CreateTable<Person>();
2025-06-04 23:10:11 +09:00
/// </code>
/// </example>
public SQLiteConnection ( string databasePath , bool storeDateTimeAsTicks = false )
: this ( databasePath , SQLiteOpenFlags . ReadWrite | SQLiteOpenFlags . Create , storeDateTimeAsTicks )
{
}
/// <summary>
/// <20> <> <EFBFBD> ο <EFBFBD> SQLiteConnection<6F> <6E> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> SQLite <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <20> <> <EFBFBD> ϴ<EFBFBD> .
/// </summary>
/// <param name="databasePath">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> θ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </param>
/// <param name="openFlags">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> <20> ÷<EFBFBD> <C3B7> <EFBFBD> <EFBFBD> Դϴ<D4B4> .
/// </param>
/// <param name="storeDateTimeAsTicks">
/// DateTime <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> ƽ (true) <20> Ǵ<EFBFBD> <20> <> <EFBFBD> ڿ<EFBFBD> (false)<29> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ݵ<EFBFBD> <DDB5> <EFBFBD> true<75> <65> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . false<73> <65> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȣ ȯ<C8A3> <C8AF> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> Դϴ<D4B4> .
/// true<75> <65> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϸ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ũ<> <C5A9> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ǹ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> .
/// </param>
/// <example>
/// <code>
/// // <20> б <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// var dbReadOnly = new SQLiteConnection(
/// Application.persistentDataPath + "/myDatabase.db",
/// SQLiteOpenFlags.ReadOnly,
/// true);
/// </code>
/// </example>
public SQLiteConnection ( string databasePath , SQLiteOpenFlags openFlags , bool storeDateTimeAsTicks = false )
{
if ( string . IsNullOrEmpty ( databasePath ) )
throw new ArgumentException ( "Must be specified" , "databasePath" ) ;
DatabasePath = databasePath ;
mayCreateSyncObject ( databasePath ) ;
#if NETFX_CORE
SQLite3 . SetDirectory ( /*temp directory type*/ 2 , Windows . Storage . ApplicationData . Current . TemporaryFolder . Path ) ;
#endif
Sqlite3DatabaseHandle handle ;
#if SILVERLIGHT | | USE_CSHARP_SQLITE
var r = SQLite3 . Open ( databasePath , out handle , ( int ) openFlags , IntPtr . Zero ) ;
#else
// open using the byte[]
// in the case where the path may include Unicode
// force open to using UTF-8 using sqlite3_open_v2
var databasePathAsBytes = GetNullTerminatedUtf8 ( DatabasePath ) ;
var r = SQLite3 . Open ( databasePathAsBytes , out handle , ( int ) openFlags , IntPtr . Zero ) ;
#endif
Handle = handle ;
if ( r ! = SQLite3 . Result . OK )
{
throw SQLiteException . New ( r , String . Format ( "Could not open database file: {0} ({1})" , DatabasePath , r ) ) ;
}
_open = true ;
StoreDateTimeAsTicks = storeDateTimeAsTicks ;
BusyTimeout = TimeSpan . FromSeconds ( 0.1 ) ;
}
static SQLiteConnection ( )
{
if ( _preserveDuringLinkMagic )
{
var ti = new ColumnInfo ( ) ;
ti . Name = "magic" ;
}
}
/// <summary>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> ο <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> ȭ <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> (<28> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> ).
/// </summary>
/// <param name="databasePath"><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> </param>
void mayCreateSyncObject ( string databasePath )
{
if ( ! syncObjects . ContainsKey ( databasePath ) )
{
syncObjects [ databasePath ] = new object ( ) ;
}
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> ϱ <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> ȭ <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ɴϴ<C9B4> .
/// </summary>
/// <value><3E> <> <EFBFBD> <EFBFBD> ȭ <20> <> ü.</value>
public object SyncObject { get { return syncObjects [ DatabasePath ] ; } }
/// <summary>
/// Ȯ<> <C8AE> <20> <> <EFBFBD> <EFBFBD> <20> ε带 Ȱ<> <C8B0> ȭ <20> Ǵ<EFBFBD> <20> <> Ȱ<EFBFBD> <C8B0> ȭ<EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="onoff">1<> ̸<EFBFBD> Ȱ<> <C8B0> ȭ, 0<> ̸<EFBFBD> <20> <> Ȱ<EFBFBD> <C8B0> ȭ</param>
/// <example>
/// <code>
/// // SQLite Ȯ<> <C8AE> <20> <> <EFBFBD> <EFBFBD> Ȱ<> <C8B0> ȭ
/// db.EnableLoadExtension(1);
/// </code>
/// </example>
public void EnableLoadExtension ( int onoff )
{
SQLite3 . Result r = SQLite3 . EnableLoadExtension ( Handle , onoff ) ;
if ( r ! = SQLite3 . Result . OK )
{
string msg = SQLite3 . GetErrmsg ( Handle ) ;
throw SQLiteException . New ( r , msg ) ;
}
}
/// <summary>
/// <20> <> <EFBFBD> ڿ<EFBFBD> <DABF> <EFBFBD> UTF-8<> <38> <20> <> <EFBFBD> ڵ<EFBFBD> <DAB5> ϰ<EFBFBD> NULL <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> ߰<EFBFBD> <DFB0> մϴ<D5B4> .
/// </summary>
/// <param name="s"><3E> <> <EFBFBD> ڵ<EFBFBD> <DAB5> <EFBFBD> <20> <> <EFBFBD> ڿ<EFBFBD> </param>
/// <returns>NULL <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> UTF-8 <20> <> <EFBFBD> <EFBFBD> Ʈ <20> 迭</returns>
static byte [ ] GetNullTerminatedUtf8 ( string s )
{
var utf8Length = System . Text . Encoding . UTF8 . GetByteCount ( s ) ;
var bytes = new byte [ utf8Length + 1 ] ;
utf8Length = System . Text . Encoding . UTF8 . GetBytes ( s , 0 , s . Length , bytes , 0 ) ;
return bytes ;
}
/// <summary>
/// MonoTouch <20> <> Ŀ<EFBFBD> <C4BF> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ʱ⸦ <20> ٶ<EFBFBD> <D9B6> <EFBFBD> <20> ڵ带 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ˴ ϴ<CBB4> .
/// </summary>
#pragma warning disable 649
static bool _preserveDuringLinkMagic ;
#pragma warning restore 649
/// <summary>
/// <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ð<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ڵ鷯<DAB5> <E9B7AF> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> ڵ鷯<DAB5> <E9B7AF> <see cref="BusyTimeout"/><3E> <> <20> <> <20> ð<EFBFBD> <C3B0> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> <EFBFBD> <20> ð<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.BusyTimeout = TimeSpan.FromSeconds(5);
/// </code>
/// </example>
public TimeSpan BusyTimeout
{
get { return _busyTimeout ; }
set
{
_busyTimeout = value ;
if ( Handle ! = NullHandle )
{
SQLite3 . BusyTimeout ( Handle , ( int ) _busyTimeout . TotalMilliseconds ) ;
}
}
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> Ÿ<> Կ<EFBFBD> <D4BF> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> մϴ<D5B4> .
/// </summary>
public IEnumerable < TableMapping > TableMappings
{
get
{
return _tables ! = null ? _tables . Values : Enumerable . Empty < TableMapping > ( ) ;
}
}
/// <summary>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> Ÿ<> Կ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ڵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ˻<EFBFBD> <CBBB> մϴ<D5B4> .
/// </summary>
/// <param name="type">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> Ǵ<EFBFBD> Ÿ<> <C5B8> <EFBFBD> Դϴ<D4B4> .
/// </param>
/// <param name="createFlags">
/// <20> <> <EFBFBD> <EFBFBD> <20> <> Ģ<EFBFBD> <C4A2> <20> <> <EFBFBD> <EFBFBD> <20> Ͻ<EFBFBD> <CFBD> <EFBFBD> PK<50> <4B> <20> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ÷<EFBFBD> <C3B7> <EFBFBD>
/// </param>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> Ű<EFBFBD> <C5B0> <EFBFBD> <EFBFBD> <20> <> Ÿ<EFBFBD> <C5B8> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <EFBFBD> <DEBC> 带 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </returns>
/// <example>
/// <code>
/// // Person Ŭ<> <C5AC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// var mapping = db.GetMapping(typeof(Person));
///
/// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <20> ̸<EFBFBD> Ȯ<> <C8AE>
/// Console.WriteLine("<22> <> <EFBFBD> ̺<EFBFBD> <20> ̸<EFBFBD> : " + mapping.TableName);
/// </code>
/// </example>
public TableMapping GetMapping ( Type type , CreateFlags createFlags = CreateFlags . None )
{
if ( _mappings = = null )
{
_mappings = new Dictionary < string , TableMapping > ( ) ;
}
TableMapping map ;
if ( ! _mappings . TryGetValue ( type . FullName , out map ) )
{
map = new TableMapping ( type , createFlags ) ;
_mappings [ type . FullName ] = map ;
}
return map ;
}
/// <summary>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> Ÿ<> Կ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ڵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ˻<EFBFBD> <CBBB> մϴ<D5B4> .
/// </summary>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> Ű<EFBFBD> <C5B0> <EFBFBD> <EFBFBD> <20> <> Ÿ<EFBFBD> <C5B8> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <EFBFBD> <DEBC> 带 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> <EFBFBD> Ÿ<> <C5B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// var mapping = db.GetMapping<Person>();
2025-06-04 23:10:11 +09:00
/// </code>
/// </example>
public TableMapping GetMapping < T > ( )
{
return GetMapping ( typeof ( T ) ) ;
}
private struct IndexedColumn
{
public int Order ;
public string ColumnName ;
}
private struct IndexInfo
{
public string IndexName ;
public string TableName ;
public bool Unique ;
public List < IndexedColumn > Columns ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> "drop table" <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> . <20> <> <20> ۾<EFBFBD> <DBBE> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> .
/// </summary>
/// <example>
/// <code>
/// // Person <20> <> <EFBFBD> ̺<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// db.DropTable<Person>();
2025-06-04 23:10:11 +09:00
/// </code>
/// </example>
public int DropTable < T > ( )
{
var map = GetMapping ( typeof ( T ) ) ;
var query = string . Format ( "drop table if exists \"{0}\"" , map . TableName ) ;
return Execute ( query ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> "create table if not exists" <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ÿ<> Կ<EFBFBD> <D4BF> <EFBFBD> <20> ڵ<EFBFBD> <DAB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ű<EFBFBD> <C5B0> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> ߿<EFBFBD> GetMapping<6E> <67> ȣ <> <C8A3> <EFBFBD> Ͽ<EFBFBD> <20> <> <20> <> Ű<EFBFBD> <C5B0> <EFBFBD> <EFBFBD> <20> <EFBFBD> <D7BC> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> ֽ<EFBFBD> <D6BD> ϴ<EFBFBD> .
/// </summary>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> Ű<EFBFBD> <C5B0> <EFBFBD> <EFBFBD> <20> ߰<EFBFBD> <DFB0> <EFBFBD> <20> <EFBFBD> <D7B8> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> մϴ<D5B4> .
/// </returns>
/// <example>
/// <code>
/// // Person Ŭ<> <C5AC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǥ<> <C7A5> <EFBFBD> ϴ<EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// db.CreateTable<Person>();
2025-06-04 23:10:11 +09:00
///
/// // <20> Ͻ<EFBFBD> <CFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ɼ<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// db.CreateTable<Person>(CreateFlags.ImplicitIndex);
2025-06-04 23:10:11 +09:00
/// </code>
/// </example>
public int CreateTable < T > ( CreateFlags createFlags = CreateFlags . None )
{
return CreateTable ( typeof ( T ) , createFlags ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> "create table if not exists" <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ÿ<> Կ<EFBFBD> <D4BF> <EFBFBD> <20> ڵ<EFBFBD> <DAB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ű<EFBFBD> <C5B0> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> ߿<EFBFBD> GetMapping<6E> <67> ȣ <> <C8A3> <EFBFBD> Ͽ<EFBFBD> <20> <> <20> <> Ű<EFBFBD> <C5B0> <EFBFBD> <EFBFBD> <20> <EFBFBD> <D7BC> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> ֽ<EFBFBD> <D6BD> ϴ<EFBFBD> .
/// </summary>
/// <param name="ty"><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> ݿ<EFBFBD> <DDBF> <EFBFBD> Ÿ<> <C5B8> <EFBFBD> Դϴ<D4B4> .</param>
/// <param name="createFlags"><3E> <> <EFBFBD> <EFBFBD> <20> <> Ģ<EFBFBD> <C4A2> <20> <> <EFBFBD> <EFBFBD> <20> Ͻ<EFBFBD> <CFBD> <EFBFBD> PK <20> <> <20> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ÷<EFBFBD> <C3B7> <EFBFBD> <EFBFBD> Դϴ<D4B4> .</param>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> Ű<EFBFBD> <C5B0> <EFBFBD> <EFBFBD> <20> ߰<EFBFBD> <DFB0> <EFBFBD> <20> <EFBFBD> <D7B8> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> մϴ<D5B4> .
/// </returns>
/// <example>
/// <code>
/// // Type <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.CreateTable(typeof(Person), CreateFlags.AutoIncPK);
/// </code>
/// </example>
public int CreateTable ( Type ty , CreateFlags createFlags = CreateFlags . None )
{
if ( _tables = = null )
{
_tables = new Dictionary < string , TableMapping > ( ) ;
}
TableMapping map ;
if ( ! _tables . TryGetValue ( ty . FullName , out map ) )
{
map = GetMapping ( ty , createFlags ) ;
_tables . Add ( ty . FullName , map ) ;
}
var query = "create table if not exists \"" + map . TableName + "\"(\n" ;
var decls = map . Columns . Select ( p = > Orm . SqlDecl ( p , StoreDateTimeAsTicks ) ) ;
var decl = string . Join ( ",\n" , decls . ToArray ( ) ) ;
query + = decl ;
query + = ")" ;
var count = Execute ( query ) ;
if ( count = = 0 )
{ //Possible bug: This always seems to return 0?
// Table already exists, migrate it
MigrateTable ( map ) ;
}
var indexes = new Dictionary < string , IndexInfo > ( ) ;
foreach ( var c in map . Columns )
{
foreach ( var i in c . Indices )
{
var iname = i . Name ? ? map . TableName + "_" + c . Name ;
IndexInfo iinfo ;
if ( ! indexes . TryGetValue ( iname , out iinfo ) )
{
iinfo = new IndexInfo
{
IndexName = iname ,
TableName = map . TableName ,
Unique = i . Unique ,
Columns = new List < IndexedColumn > ( )
} ;
indexes . Add ( iname , iinfo ) ;
}
if ( i . Unique ! = iinfo . Unique )
throw new Exception ( "All the columns in an index must have the same value for their Unique property" ) ;
iinfo . Columns . Add ( new IndexedColumn
{
Order = i . Order ,
ColumnName = c . Name
} ) ;
}
}
foreach ( var indexName in indexes . Keys )
{
var index = indexes [ indexName ] ;
string [ ] columnNames = new string [ index . Columns . Count ] ;
if ( index . Columns . Count = = 1 )
{
columnNames [ 0 ] = index . Columns [ 0 ] . ColumnName ;
}
else
{
index . Columns . Sort ( ( lhs , rhs ) = > {
return lhs . Order - rhs . Order ;
} ) ;
for ( int i = 0 , end = index . Columns . Count ; i < end ; + + i )
{
columnNames [ i ] = index . Columns [ i ] . ColumnName ;
}
}
count + = CreateIndex ( indexName , index . TableName , columnNames , index . Unique ) ;
}
return count ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="indexName"><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̸<EFBFBD> </param>
/// <param name="tableName"><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <20> ̸<EFBFBD> </param>
/// <param name="columnNames"><3E> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> ̸<EFBFBD> <20> 迭</param>
/// <param name="unique"><3E> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ؾ<EFBFBD> <20> ϴ<EFBFBD> <CFB4> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> </param>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.CreateIndex("personNameIndex", "Person", new[] { "FirstName", "LastName" }, true);
/// </code>
/// </example>
public int CreateIndex ( string indexName , string tableName , string [ ] columnNames , bool unique = false )
{
const string sqlFormat = "create {2} index if not exists \"{3}\" on \"{0}\"(\"{1}\")" ;
var sql = String . Format ( sqlFormat , tableName , string . Join ( "\", \"" , columnNames ) , unique ? "unique" : "" , indexName ) ;
return Execute ( sql ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="indexName"><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̸<EFBFBD> </param>
/// <param name="tableName"><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <20> ̸<EFBFBD> </param>
/// <param name="columnName"><3E> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> ̸<EFBFBD> </param>
/// <param name="unique"><3E> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ؾ<EFBFBD> <20> ϴ<EFBFBD> <CFB4> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> </param>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.CreateIndex("emailIndex", "Person", "Email", true);
/// </code>
/// </example>
public int CreateIndex ( string indexName , string tableName , string columnName , bool unique = false )
{
return CreateIndex ( indexName , tableName , new string [ ] { columnName } , unique ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="tableName"><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <20> ̸<EFBFBD> </param>
/// <param name="columnName"><3E> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> ̸<EFBFBD> </param>
/// <param name="unique"><3E> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ؾ<EFBFBD> <20> ϴ<EFBFBD> <CFB4> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> </param>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <20> ̸<EFBFBD> <CCB8> <EFBFBD> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <20> ̸<EFBFBD> <20> ڵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.CreateIndex("Person", "Age", false);
/// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <20> ̸<EFBFBD> <CCB8> <EFBFBD> "Person_Age"
/// </code>
/// </example>
public int CreateIndex ( string tableName , string columnName , bool unique = false )
{
return CreateIndex ( tableName + "_" + columnName , tableName , columnName , unique ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="tableName"><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <20> ̸<EFBFBD> </param>
/// <param name="columnNames"><3E> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> ̸<EFBFBD> <20> 迭</param>
/// <param name="unique"><3E> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ؾ<EFBFBD> <20> ϴ<EFBFBD> <CFB4> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> </param>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <20> ̸<EFBFBD> <CCB8> <EFBFBD> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <20> ̸<EFBFBD> <20> ڵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.CreateIndex("Person", new[] { "FirstName", "LastName" }, true);
/// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <20> ̸<EFBFBD> <CCB8> <EFBFBD> "Person_FirstName_LastName"
/// </code>
/// </example>
public int CreateIndex ( string tableName , string [ ] columnNames , bool unique = false )
{
return CreateIndex ( tableName + "_" + string . Join ( "_" , columnNames ) , tableName , columnNames , unique ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
2025-06-10 01:09:36 +09:00
/// <20> <> <EFBFBD> <EFBFBD> : CreateIndex<Client>(c => c.Name);
2025-06-04 23:10:11 +09:00
/// </summary>
/// <typeparam name="T"><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> ݿ<EFBFBD> <DDBF> <EFBFBD> Ÿ<> <C5B8> .</typeparam>
/// <param name="property"><3E> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ӽ<EFBFBD> </param>
/// <param name="unique"><3E> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ؾ<EFBFBD> <20> ϴ<EFBFBD> <CFB4> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> </param>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// db.CreateIndex<Person>(p => p.Email, true);
2025-06-04 23:10:11 +09:00
/// </code>
/// </example>
public void CreateIndex < T > ( Expression < Func < T , object > > property , bool unique = false )
{
MemberExpression mx ;
if ( property . Body . NodeType = = ExpressionType . Convert )
{
mx = ( ( UnaryExpression ) property . Body ) . Operand as MemberExpression ;
}
else
{
mx = ( property . Body as MemberExpression ) ;
}
var propertyInfo = mx . Member as PropertyInfo ;
if ( propertyInfo = = null )
{
throw new ArgumentException ( "The lambda expression 'property' should point to a valid Property" ) ;
}
var propName = propertyInfo . Name ;
var map = GetMapping < T > ( ) ;
var colName = map . FindColumnWithPropertyName ( propName ) . Name ;
CreateIndex ( map . TableName , colName , unique ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> Ŭ<> <C5AC> <EFBFBD> <EFBFBD> <EFBFBD> Դϴ<D4B4> .
/// </summary>
public class ColumnInfo
{
// public int cid { get; set; }
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <20> ̸<EFBFBD> <CCB8> Դϴ<D4B4> .
/// </summary>
[Column("name")]
public string Name { get ; set ; }
// [Column ("type")]
// public string ColumnType { get; set; }
/// <summary>
/// NULL <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> θ<EFBFBD> <20> <> Ÿ<EFBFBD> <C5B8> <EFBFBD> ϴ<EFBFBD> . 0<> ̸<EFBFBD> NULL <20> <> <EFBFBD> <EFBFBD> , 1<> ̸<EFBFBD> NOT NULL<4C> Դϴ<D4B4> .
/// </summary>
public int notnull { get ; set ; }
// public string dflt_value { get; set; }
// public int pk { get; set; }
public override string ToString ( )
{
return Name ;
}
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ɴϴ<C9B4> .
/// </summary>
/// <param name="tableName"><3E> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> ̸<EFBFBD> </param>
/// <returns><3E> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> </returns>
/// <example>
/// <code>
/// // Person <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// var columns = db.GetTableInfo("Person");
/// foreach (var column in columns) {
/// Console.WriteLine("<22> <> <20> ̸<EFBFBD> : " + column.Name);
/// }
/// </code>
/// </example>
public List < ColumnInfo > GetTableInfo ( string tableName )
{
var query = "pragma table_info(\"" + tableName + "\")" ;
return Query < ColumnInfo > ( query ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ε<EFBFBD> <20> <> ü <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ġ<EFBFBD> ϵ<EFBFBD> <CFB5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> ο <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> ߰<EFBFBD> <DFB0> մϴ<D5B4> .
/// </summary>
/// <param name="map"><3E> <> <EFBFBD> ̺<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> </param>
void MigrateTable ( TableMapping map )
{
var existingCols = GetTableInfo ( map . TableName ) ;
var toBeAdded = new List < TableMapping . Column > ( ) ;
foreach ( var p in map . Columns )
{
var found = false ;
foreach ( var c in existingCols )
{
found = ( string . Compare ( p . Name , c . Name , StringComparison . OrdinalIgnoreCase ) = = 0 ) ;
if ( found )
break ;
}
if ( ! found )
{
toBeAdded . Add ( p ) ;
}
}
foreach ( var p in toBeAdded )
{
var addCol = "alter table \"" + map . TableName + "\" add column " + Orm . SqlDecl ( p , StoreDateTimeAsTicks ) ;
Execute ( addCol ) ;
}
}
/// <summary>
/// <20> <> <EFBFBD> ο <EFBFBD> SQLiteCommand<6E> <64> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> . <20> <> <EFBFBD> <EFBFBD> Ŭ<> <C5AC> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> ֽ<EFBFBD> <D6BD> ϴ<EFBFBD> .
/// </summary>
/// <seealso cref="SQLiteCommand.OnInstanceCreated"/>
protected virtual SQLiteCommand NewCommand ( )
{
return new SQLiteCommand ( this ) ;
}
/// <summary>
/// <20> μ<EFBFBD> <CEBC> <EFBFBD> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ؽ<EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> SQLiteCommand<6E> <64> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <20> ؽ<EFBFBD> Ʈ<EFBFBD> <C6AE> <EFBFBD> <EFBFBD> <20> <> <20> μ<EFBFBD> <CEBC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> '?' <20> <> <20> <> ġ<EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="cmdText">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̽<EFBFBD> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> SQL.
/// </param>
/// <param name="args">
/// <20> <> <EFBFBD> <EFBFBD> <20> ؽ<EFBFBD> Ʈ<EFBFBD> <C6AE> <EFBFBD> <EFBFBD> '?'<27> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> ϴ<EFBFBD> <20> μ<EFBFBD> .
/// </param>
/// <returns>
/// <see cref="SQLiteCommand"/> <20> <> ü
/// </returns>
/// <example>
/// <code>
/// // <20> Ķ<EFBFBD> <C4B6> <EFBFBD> <EFBFBD> Ͱ<EFBFBD> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// var cmd = db.CreateCommand("SELECT * FROM Person WHERE Id = ?", 1);
2025-06-10 01:09:36 +09:00
/// var person = cmd.ExecuteQuery<Person>().FirstOrDefault();
2025-06-04 23:10:11 +09:00
/// </code>
/// </example>
public SQLiteCommand CreateCommand ( string cmdText , params object [ ] ps )
{
if ( ! _open )
throw SQLiteException . New ( SQLite3 . Result . Error , "Cannot create commands from unopened database" ) ;
var cmd = NewCommand ( ) ;
cmd . CommandText = cmdText ;
foreach ( var o in ps )
{
cmd . Bind ( o ) ;
}
return cmd ;
}
/// <summary>
/// <20> μ<EFBFBD> <CEBC> <EFBFBD> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ؽ<EFBFBD> Ʈ(SQL)<29> <> SQLiteCommand<6E> <64> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <20> ؽ<EFBFBD> Ʈ<EFBFBD> <C6AE> <EFBFBD> <EFBFBD> <20> <> <20> μ<EFBFBD> <CEBC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> '?'<27> <> <20> <> ġ<EFBFBD> <C4A1> <20> <> <EFBFBD> <EFBFBD> <20> ش<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> <C8AF> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> Query <20> <> <EFBFBD> <EFBFBD> <20> <> <20> <EFBFBD> <DEBC> 带 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϼ<EFBFBD> <CFBC> <EFBFBD> .
/// <20> ̷<EFBFBD> <CCB7> <EFBFBD> <20> <> <EFBFBD> 쿡<EFBFBD> <ECBFA1> INSERT, UPDATE <20> <> DELETE<54> <45> <20> <> <EFBFBD> Ե˴ ϴ<CBB4> .
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Trace <20> Ǵ<EFBFBD> TimeExecution <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϸ<EFBFBD> <CFB8> <EFBFBD> <20> <> <20> ֽ<EFBFBD> <D6BD> ϴ<EFBFBD> .
/// </summary>
/// <param name="query">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̽<EFBFBD> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> SQL.
/// </param>
/// <param name="args">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> '?'<27> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> ϴ<EFBFBD> <20> μ<EFBFBD> .
/// </param>
/// <returns>
/// <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> .
/// </returns>
/// <example>
/// <code>
/// // SQL <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// int rowsAffected = db.Execute("UPDATE Person SET Name = ? WHERE Id = ?", "ȫ<> 浿", 1);
/// Console.WriteLine($"<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <20> <> : {rowsAffected}");
/// </code>
/// </example>
public int Execute ( string query , params object [ ] args )
{
var cmd = CreateCommand ( query , args ) ;
if ( TimeExecution )
{
if ( _sw = = null )
{
_sw = new Stopwatch ( ) ;
}
_sw . Reset ( ) ;
_sw . Start ( ) ;
}
var r = cmd . ExecuteNonQuery ( ) ;
if ( TimeExecution )
{
_sw . Stop ( ) ;
_elapsed + = _sw . Elapsed ;
this . InvokeTimeExecution ( _sw . Elapsed , _elapsed ) ;
}
return r ;
}
/// <summary>
/// SQL <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> Į<EFBFBD> <C4AE> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> մϴ<D5B4> .
/// </summary>
/// <typeparam name="T"><3E> <> ȯ<EFBFBD> Ǵ<EFBFBD> <20> <> Į<EFBFBD> <C4AE> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ÿ<> <C5B8> </typeparam>
/// <param name="query"><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> SQL <20> <> <EFBFBD> <EFBFBD> </param>
/// <param name="args"><3E> <> <EFBFBD> <EFBFBD> <20> Ķ<EFBFBD> <C4B6> <EFBFBD> <EFBFBD> <EFBFBD> </param>
/// <returns><3E> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ù <20> <> ° <20> <> , ù <20> <> ° <20> <> <20> <> </returns>
/// <example>
/// <code>
/// // <20> <> Į<EFBFBD> <C4AE> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// int count = db.ExecuteScalar<int>("SELECT COUNT(*) FROM Person");
/// string name = db.ExecuteScalar<string>("SELECT Name FROM Person WHERE Id = ?", 1);
2025-06-04 23:10:11 +09:00
/// </code>
/// </example>
public T ExecuteScalar < T > ( string query , params object [ ] args )
{
var cmd = CreateCommand ( query , args ) ;
if ( TimeExecution )
{
if ( _sw = = null )
{
_sw = new Stopwatch ( ) ;
}
_sw . Reset ( ) ;
_sw . Start ( ) ;
}
var r = cmd . ExecuteScalar < T > ( ) ;
if ( TimeExecution )
{
_sw . Stop ( ) ;
_elapsed + = _sw . Elapsed ;
this . InvokeTimeExecution ( _sw . Elapsed , _elapsed ) ;
}
return r ;
}
/// <summary>
/// <20> μ<EFBFBD> <CEBC> <EFBFBD> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ؽ<EFBFBD> Ʈ(SQL)<29> <> SQLiteCommand<6E> <64> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <20> ؽ<EFBFBD> Ʈ<EFBFBD> <C6AE> <EFBFBD> <EFBFBD> <20> <> <20> μ<EFBFBD> <CEBC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> '?'<27> <> <20> <> ġ<EFBFBD> <C4A1> <20> <> <EFBFBD> <EFBFBD> <20> ش<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ÿ<> Կ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ڵ<EFBFBD> <DAB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="query">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̽<EFBFBD> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> SQL.
/// </param>
/// <param name="args">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> '?'<27> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> ϴ<EFBFBD> <20> μ<EFBFBD> .
/// </param>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> <C8AF> <20> <> <20> <20> <> <EFBFBD> <EFBFBD> <20> ϳ <EFBFBD> <CFB3> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> .
/// </returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> ǿ<EFBFBD> <20> ´ <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Person <20> <> ü <20> <> ȸ
2025-06-10 01:09:36 +09:00
/// var adults = db.Query<Person>("SELECT * FROM Person WHERE Age >= ?", 18);
2025-06-04 23:10:11 +09:00
/// foreach (var person in adults) {
/// Console.WriteLine($"<22> <> <EFBFBD> <EFBFBD> : {person.Name}, {person.Age}<7D> <> ");
/// }
/// </code>
/// </example>
public List < T > Query < T > ( string query , params object [ ] args ) where T : new ( )
{
var cmd = CreateCommand ( query , args ) ;
return cmd . ExecuteQuery < T > ( ) ;
}
/// <summary>
/// <20> μ<EFBFBD> <CEBC> <EFBFBD> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ؽ<EFBFBD> Ʈ(SQL)<29> <> SQLiteCommand<6E> <64> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <20> ؽ<EFBFBD> Ʈ<EFBFBD> <C6AE> <EFBFBD> <EFBFBD> <20> <> <20> μ<EFBFBD> <CEBC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> '?'<27> <> <20> <> ġ<EFBFBD> <C4A1> <20> <> <EFBFBD> <EFBFBD> <20> ش<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ÿ<> Կ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ڵ<EFBFBD> <DAB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="query">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̽<EFBFBD> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> SQL.
/// </param>
/// <param name="args">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> '?'<27> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> ϴ<EFBFBD> <20> μ<EFBFBD> .
/// </param>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> <C8AF> <20> <> <20> <20> <> <EFBFBD> <EFBFBD> <20> ϳ <EFBFBD> <CFB3> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> .
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ڴ<EFBFBD> MoveNext<78> <74> ȣ <> <C8A3> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> sqlite3_step<65> <70> ȣ <> <C8A3> <EFBFBD> Ϲ Ƿ<CFB9> ,
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> մϴ<D5B4> .
/// </returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> 뷮 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> ó<> <C3B3>
2025-06-10 01:09:36 +09:00
/// var query = db.DeferredQuery<Person>("SELECT * FROM Person");
2025-06-04 23:10:11 +09:00
/// using (var enumerator = query.GetEnumerator()) {
/// while (enumerator.MoveNext()) {
/// var person = enumerator.Current;
/// ProcessPerson(person);
/// }
/// }
/// </code>
/// </example>
public IEnumerable < T > DeferredQuery < T > ( string query , params object [ ] args ) where T : new ( )
{
var cmd = CreateCommand ( query , args ) ;
return cmd . ExecuteDeferredQuery < T > ( ) ;
}
/// <summary>
/// <20> μ<EFBFBD> <CEBC> <EFBFBD> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ؽ<EFBFBD> Ʈ(SQL)<29> <> SQLiteCommand<6E> <64> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <20> ؽ<EFBFBD> Ʈ<EFBFBD> <C6AE> <EFBFBD> <EFBFBD> <20> <> <20> μ<EFBFBD> <CEBC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> '?'<27> <> <20> <> ġ<EFBFBD> <C4A1> <20> <> <EFBFBD> <EFBFBD> <20> ش<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> մϴ<D5B4> .
/// <20> <> <20> Լ<EFBFBD> <D4BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> (introspection)<29> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϱ <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// <20> <> <EFBFBD> ̺귯<CCBA> <EAB7AF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ˴ ϴ<CBB4> . <20> Ϲ <EFBFBD> <CFB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ʽ <EFBFBD> <CABD> ϴ<EFBFBD> .
/// </summary>
/// <param name="map">
/// <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> ȯ<EFBFBD> ϴ<EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <see cref="TableMapping"/>.
/// </param>
/// <param name="query">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̽<EFBFBD> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> SQL.
/// </param>
/// <param name="args">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> '?'<27> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> ϴ<EFBFBD> <20> μ<EFBFBD> .
/// </param>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> <C8AF> <20> <> <20> <20> <> <EFBFBD> <EFBFBD> <20> ϳ <EFBFBD> <CFB3> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> .
/// </returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// var map = db.GetMapping(typeof(Person));
/// var results = db.Query(map, "SELECT * FROM Person WHERE Id = ?", 1);
/// if (results.Count > 0) {
/// var person = results[0] as Person;
/// }
/// </code>
/// </example>
public List < object > Query ( TableMapping map , string query , params object [ ] args )
{
var cmd = CreateCommand ( query , args ) ;
return cmd . ExecuteQuery < object > ( map ) ;
}
/// <summary>
/// <20> μ<EFBFBD> <CEBC> <EFBFBD> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ؽ<EFBFBD> Ʈ(SQL)<29> <> SQLiteCommand<6E> <64> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <20> ؽ<EFBFBD> Ʈ<EFBFBD> <C6AE> <EFBFBD> <EFBFBD> <20> <> <20> μ<EFBFBD> <CEBC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> '?'<27> <> <20> <> ġ<EFBFBD> <C4A1> <20> <> <EFBFBD> <EFBFBD> <20> ش<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> մϴ<D5B4> .
/// <20> <> <20> Լ<EFBFBD> <D4BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> (introspection)<29> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϱ <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// <20> <> <EFBFBD> ̺귯<CCBA> <EAB7AF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ˴ ϴ<CBB4> . <20> Ϲ <EFBFBD> <CFB9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ʽ <EFBFBD> <CABD> ϴ<EFBFBD> .
/// </summary>
/// <param name="map">
/// <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> ȯ<EFBFBD> ϴ<EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <see cref="TableMapping"/>.
/// </param>
/// <param name="query">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̽<EFBFBD> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> SQL.
/// </param>
/// <param name="args">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> '?'<27> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> ϴ<EFBFBD> <20> μ<EFBFBD> .
/// </param>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> <C8AF> <20> <> <20> <20> <> <EFBFBD> <EFBFBD> <20> ϳ <EFBFBD> <CFB3> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> .
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ڴ<EFBFBD> MoveNext<78> <74> ȣ <> <C8A3> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> sqlite3_step<65> <70> ȣ <> <C8A3> <EFBFBD> Ϲ Ƿ<CFB9> ,
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> մϴ<D5B4> .
/// </returns>
public IEnumerable < object > DeferredQuery ( TableMapping map , string query , params object [ ] args )
{
var cmd = CreateCommand ( query , args ) ;
return cmd . ExecuteDeferredQuery < object > ( map ) ;
}
/// <summary>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> Ÿ<> <C5B8> <EFBFBD> <EFBFBD> <20> <> Ÿ<EFBFBD> <C5B8> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ̽<EFBFBD> <CCBD> <EFBFBD> <20> <> ȯ<EFBFBD> մϴ<D5B4> .
/// </summary>
/// <returns>
/// Where, OrderBy, Take <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ƽ <EFBFBD> <C6BC> SQL<51> <4C> <20> <> ȯ<EFBFBD> <C8AF> <20> <> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü.
/// </returns>
/// <example>
/// <code>
/// // LINQ<4E> <51> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϱ <EFBFBD>
2025-06-10 01:09:36 +09:00
/// var query = db.Table<Person>()
2025-06-04 23:10:11 +09:00
/// .Where(p => p.Age > 18)
/// .OrderBy(p => p.Name);
///
/// foreach(var adult in query) {
/// Console.WriteLine($"<22> <> <EFBFBD> <EFBFBD> : {adult.Name}, {adult.Age}<7D> <> ");
/// }
/// </code>
/// </example>
public TableQuery < T > Table < T > ( ) where T : new ( )
{
return new TableQuery < T > ( this ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> <20> ˻<EFBFBD> <CBBB> մϴ<D5B4> .
/// <20> <> <20> <EFBFBD> <DEBC> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ÿ<> Կ<EFBFBD> (PrimaryKeyAttribute<74> <65> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> )
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> PrimaryKey<65> <79> <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> մϴ<D5B4> .
/// </summary>
/// <param name="pk">
/// <20> ⺻ Ű.
/// </param>
/// <returns>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> <> <EFBFBD> <EFBFBD> <20> <> ü.
/// <20> <> ü<EFBFBD> <C3BC> ã<> <C3A3> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> not found <20> <> <EFBFBD> ܸ<EFBFBD> <20> <EFBFBD> <DFBB> <EFBFBD> ŵ<EFBFBD> ϴ<EFBFBD> .
/// </returns>
/// <example>
/// <code>
/// // <20> ⺻ Ű<> <C5B0> Person <20> <> ü <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// try {
2025-06-10 01:09:36 +09:00
/// var person = db.Get<Person>(1);
2025-06-04 23:10:11 +09:00
/// Console.WriteLine($"<22> ̸<EFBFBD> : {person.Name}");
/// } catch (Exception) {
/// Console.WriteLine("<22> ش<EFBFBD> ID<49> <44> Person<6F> <6E> ã<> <C3A3> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ");
/// }
/// </code>
/// </example>
public T Get < T > ( object pk ) where T : new ( )
{
var map = GetMapping ( typeof ( T ) ) ;
return Query < T > ( map . GetByPrimaryKeySql , pk ) . First ( ) ;
}
/// <summary>
/// <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ǽİ<C7BD> <20> <> ġ<EFBFBD> ϴ<EFBFBD> ù <20> <> ° <20> <> ü<EFBFBD> <C3BC> <20> ˻<EFBFBD> <CBBB> մϴ<D5B4> .
/// </summary>
/// <param name="predicate">
/// <20> <20> <> ü<EFBFBD> <C3BC> ã<> <C3A3> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> <20> <> <EFBFBD> ǽ<EFBFBD> .
/// </param>
/// <returns>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> <> <EFBFBD> ǽİ<C7BD> <20> <> ġ<EFBFBD> ϴ<EFBFBD> <20> <> ü.
/// <20> <> ü<EFBFBD> <C3BC> ã<> <C3A3> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> not found <20> <> <EFBFBD> ܸ<EFBFBD> <20> <EFBFBD> <DFBB> <EFBFBD> ŵ<EFBFBD> ϴ<EFBFBD> .
/// </returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> ǽ<EFBFBD> <C7BD> <EFBFBD> <EFBFBD> <EFBFBD> Person <20> <> ü <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// try {
2025-06-10 01:09:36 +09:00
/// var person = db.Get<Person>(p => p.Email == "test@example.com");
2025-06-04 23:10:11 +09:00
/// Console.WriteLine($"<22> ̸<EFBFBD> : {person.Name}");
/// } catch (Exception) {
/// Console.WriteLine("<22> <> <EFBFBD> ǿ<EFBFBD> <20> ´ <EFBFBD> Person<6F> <6E> ã<> <C3A3> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ");
/// }
/// </code>
/// </example>
public T Get < T > ( Expression < Func < T , bool > > predicate ) where T : new ( )
{
return Table < T > ( ) . Where ( predicate ) . First ( ) ;
}
/// <summary>
/// <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> ˻<EFBFBD> <CBBB> մϴ<D5B4> .
/// <20> <> <20> <EFBFBD> <DEBC> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ÿ<> Կ<EFBFBD> (PrimaryKeyAttribute<74> <65> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> )
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> PrimaryKey<65> <79> <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> մϴ<D5B4> .
/// </summary>
/// <param name="pk">
/// <20> ⺻ Ű.
/// </param>
/// <returns>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> <> <EFBFBD> <EFBFBD> <20> <> ü <20> Ǵ<EFBFBD>
/// <20> <> ü<EFBFBD> <C3BC> ã<> <C3A3> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> null.
/// </returns>
/// <example>
/// <code>
/// // <20> ⺻ Ű<> <C5B0> Person <20> <> ü ã<> <C3A3> (<28> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> null <20> <> ȯ)
2025-06-10 01:09:36 +09:00
/// var person = db.Find<Person>(1);
2025-06-04 23:10:11 +09:00
/// if (person != null) {
/// Console.WriteLine($"ã<> ҽ <EFBFBD> <D2BD> ϴ<EFBFBD> : {person.Name}");
/// } else {
/// Console.WriteLine("<22> ش<EFBFBD> ID<49> <44> Person<6F> <6E> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ");
/// }
/// </code>
/// </example>
public T Find < T > ( object pk ) where T : new ( )
{
var map = GetMapping ( typeof ( T ) ) ;
return Query < T > ( map . GetByPrimaryKeySql , pk ) . FirstOrDefault ( ) ;
}
/// <summary>
/// <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> ˻<EFBFBD> <CBBB> մϴ<D5B4> .
/// <20> <> <20> <EFBFBD> <DEBC> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ÿ<> Կ<EFBFBD> (PrimaryKeyAttribute<74> <65> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> )
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> PrimaryKey<65> <79> <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> մϴ<D5B4> .
/// </summary>
/// <param name="pk">
/// <20> ⺻ Ű.
/// </param>
/// <param name="map">
/// <20> <> ü Ÿ<> <C5B8> <EFBFBD> <EFBFBD> <20> ĺ<EFBFBD> <C4BA> ϴ<EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ǵ<EFBFBD> TableMapping.
/// </param>
/// <returns>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> <> <EFBFBD> <EFBFBD> <20> <> ü <20> Ǵ<EFBFBD>
/// <20> <> ü<EFBFBD> <C3BC> ã<> <C3A3> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> null.
/// </returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü ã<> <C3A3>
/// var map = db.GetMapping(typeof(Person));
/// var obj = db.Find(1, map);
/// if (obj != null) {
/// var person = obj as Person;
/// Console.WriteLine($"ã<> ҽ <EFBFBD> <D2BD> ϴ<EFBFBD> : {person.Name}");
/// }
/// </code>
/// </example>
public object Find ( object pk , TableMapping map )
{
return Query ( map , map . GetByPrimaryKeySql , pk ) . FirstOrDefault ( ) ;
}
/// <summary>
/// <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ǽİ<C7BD> <20> <> ġ<EFBFBD> ϴ<EFBFBD> ù <20> <> ° <20> <> ü<EFBFBD> <C3BC> <20> ˻<EFBFBD> <CBBB> մϴ<D5B4> .
/// </summary>
/// <param name="predicate">
/// <20> <20> <> ü<EFBFBD> <C3BC> ã<> <C3A3> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> <20> <> <EFBFBD> ǽ<EFBFBD> .
/// </param>
/// <returns>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> <> <EFBFBD> ǽİ<C7BD> <20> <> ġ<EFBFBD> ϴ<EFBFBD> <20> <> ü <20> Ǵ<EFBFBD>
/// <20> <> ü<EFBFBD> <C3BC> ã<> <C3A3> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> null.
/// </returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> ǽ<EFBFBD> <C7BD> <EFBFBD> <EFBFBD> <EFBFBD> Person <20> <> ü ã<> <C3A3> (<28> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> null <20> <> ȯ)
2025-06-10 01:09:36 +09:00
/// var person = db.Find<Person>(p => p.Email == "test@example.com");
2025-06-04 23:10:11 +09:00
/// if (person != null) {
/// Console.WriteLine($"ã<> ҽ <EFBFBD> <D2BD> ϴ<EFBFBD> : {person.Name}");
/// } else {
/// Console.WriteLine("<22> ش<EFBFBD> <20> ̸<EFBFBD> <CCB8> <EFBFBD> <EFBFBD> <EFBFBD> Person<6F> <6E> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ");
/// }
/// </code>
/// </example>
public T Find < T > ( Expression < Func < T , bool > > predicate ) where T : new ( )
{
return Table < T > ( ) . Where ( predicate ) . FirstOrDefault ( ) ;
}
/// <summary>
/// <see cref="BeginTransaction"/><3E> <> ȣ <> <C8A3> <EFBFBD> Ǿ<EFBFBD> <C7BE> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <see cref="Commit"/><3E> <> <20> <> <EFBFBD> ٸ<EFBFBD> <D9B8> <EFBFBD> <20> ִ<EFBFBD> <D6B4> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> .
/// </summary>
public bool IsInTransaction
{
get { return _transactionDepth > 0 ; }
}
/// <summary>
/// <20> <> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> . Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ϸ<EFBFBD> <CFB7> <EFBFBD> <see cref="Commit"/><3E> <> ȣ <> <C8A3> <EFBFBD> ϼ<EFBFBD> <CFBC> <EFBFBD> .
/// </summary>
/// <example cref="System.InvalidOperationException">Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̹<EFBFBD> <20> <> <EFBFBD> ۵ <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ܰ<EFBFBD> <20> <EFBFBD> <DFBB> մϴ<D5B4> .</example>
/// <example>
/// <code>
/// // Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// try {
/// db.BeginTransaction();
///
/// // <20> <> <EFBFBD> <EFBFBD> <20> ۾<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.Insert(new Person { Name = "ȫ<> 浿", Age = 30 });
/// db.Insert(new Person { Name = "<22> <> ö<EFBFBD> <C3B6> ", Age = 25 });
///
/// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ϸ<EFBFBD> <CFB7> Ǹ<EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<> <C4BF>
/// db.Commit();
/// } catch (Exception) {
/// // <20> <> <EFBFBD> <EFBFBD> <20> <EFBFBD> <DFBB> <EFBFBD> <20> ڵ<EFBFBD> <DAB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> ѹ<EFBFBD> <D1B9> ˴ ϴ<CBB4>
/// Console.WriteLine("Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> ");
/// }
/// </code>
/// </example>
public void BeginTransaction ( )
{
// BEGIN <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> , <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> 쿡<EFBFBD> <ECBFA1> <20> ۵ <EFBFBD> <DBB5> մϴ<D5B4> .
// BEGIN <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȣ <> <C8A3> <EFBFBD> <EFBFBD> <20> <> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> Բ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> 浹<EFBFBD> <E6B5B9> <20> <EFBFBD> <DFBB> ϴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <EFBFBD> <DFBB> <EFBFBD> <20> <> <20> ִ<EFBFBD> BeginTransaction ȣ <> <C8A3> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
if ( Interlocked . CompareExchange ( ref _transactionDepth , 1 , 0 ) = = 0 )
{
try
{
Execute ( "begin transaction" ) ;
}
catch ( Exception ex )
{
var sqlExp = ex as SQLiteException ;
if ( sqlExp ! = null )
{
// <20> Ʒ <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ؼ<EFBFBD> <D8BC> <EFBFBD> <20> <> <EFBFBD> ø<EFBFBD> <C3B8> <EFBFBD> <EFBFBD> ̼ǿ<CCBC> <C7BF> <EFBFBD> ROLLBACK <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> .
// TODO: <20> <> <20> ѹ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ġ<EFBFBD> <C4A1> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ǿ<EFBFBD> <C7BE> <EFBFBD> <20> մϴ<D5B4> .
switch ( sqlExp . Result )
{
case SQLite3 . Result . IOError :
case SQLite3 . Result . Full :
case SQLite3 . Result . Busy :
case SQLite3 . Result . NoMem :
case SQLite3 . Result . Interrupt :
RollbackTo ( null , true ) ;
break ;
}
}
else
{
// SaveTransactionPoint<6E> <74> <EFBFBD> <EFBFBD> catch <20> <> <EFBFBD> <EFBFBD> <20> ̹<EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE>
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> 쿡<EFBFBD> <ECBFA1> VolatileWrite<74> <65> <20> ƴ<EFBFBD> decrement<6E> <74> ȣ <> <C8A3> <EFBFBD> ϼ<EFBFBD> <CFBC> <EFBFBD> .
Interlocked . Decrement ( ref _transactionDepth ) ;
}
throw ;
}
}
else
{
// <20> ̹<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ִ<EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> ǿ<EFBFBD> BeginTransaction<6F> <6E> ȣ <> <C8A3> <EFBFBD> ϴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ȿ<EFBFBD> <C8BF> <EFBFBD> <EFBFBD> <20> ʽ <EFBFBD> <CABD> ϴ<EFBFBD> .
throw new InvalidOperationException ( "Cannot begin a transaction while already in a transaction." ) ;
}
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ÿ<> Ӷ<EFBFBD> <D3B6> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
///
/// <20> <> ȯ<EFBFBD> <C8AF> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ۾<EFBFBD> <DBBE> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ϸ<EFBFBD> <CFB7> <EFBFBD> <see cref="RollbackTo"/><3E> <> ȣ <> <C8A3> <EFBFBD> ϼ<EFBFBD> <CFBC> <EFBFBD> .
/// <20> <> ȯ<EFBFBD> <C8AF> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ۾<EFBFBD> <DBBE> <EFBFBD> Ȯ<> <C8AE> <EFBFBD> Ϸ<EFBFBD> <CFB7> <EFBFBD> <see cref="Release"/><3E> <> ȣ <> <C8A3> <EFBFBD> ϼ<EFBFBD> <CFBC> <EFBFBD> .
/// Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ȯ<> <C8AE> <EFBFBD> Ϸ<EFBFBD> <CFB7> <EFBFBD> <see cref="Commit"/><3E> <> ȣ <> <C8A3> <EFBFBD> ϼ<EFBFBD> <CFBC> <EFBFBD> .
/// </summary>
/// <returns><3E> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> ĺ<EFBFBD> <C4BA> ϴ<EFBFBD> <20> <> <EFBFBD> ڿ<EFBFBD> .</returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ó<> <C3B3>
/// db.BeginTransaction();
///
/// // ù <20> <> ° <20> ۾<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.Insert(new Person { Name = "ȫ<> 浿", Age = 30 });
///
/// // <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ <20> <> <EFBFBD> <EFBFBD>
/// string savepoint = db.SaveTransactionPoint();
///
/// try {
/// // <20> <> <20> <> ° <20> ۾<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.Insert(new Person { Name = "<22> <> ö<EFBFBD> <C3B6> ", Age = 25 });
///
/// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ <20> <> <EFBFBD> <EFBFBD> (Ȯ<> <C8AE> )
/// db.Release(savepoint);
/// } catch(Exception) {
/// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <EFBFBD> <DFBB> ϸ<EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> ѹ<EFBFBD>
/// db.RollbackTo(savepoint);
/// }
///
/// // Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ȯ<> <C8AE>
/// db.Commit();
/// </code>
/// </example>
public string SaveTransactionPoint ( )
{
int depth = Interlocked . Increment ( ref _transactionDepth ) - 1 ;
string retVal = "S" + _rand . Next ( short . MaxValue ) + "D" + depth ;
try
{
Execute ( "savepoint " + retVal ) ;
}
catch ( Exception ex )
{
var sqlExp = ex as SQLiteException ;
if ( sqlExp ! = null )
{
// It is recommended that applications respond to the errors listed below
// by explicitly issuing a ROLLBACK command.
// TODO: This rollback failsafe should be localized to all throw sites.
switch ( sqlExp . Result )
{
case SQLite3 . Result . IOError :
case SQLite3 . Result . Full :
case SQLite3 . Result . Busy :
case SQLite3 . Result . NoMem :
case SQLite3 . Result . Interrupt :
RollbackTo ( null , true ) ;
break ;
}
}
else
{
Interlocked . Decrement ( ref _transactionDepth ) ;
}
throw ;
}
return retVal ;
}
/// <summary>
/// <see cref="BeginTransaction"/> <20> Ǵ<EFBFBD> <see cref="SaveTransactionPoint"/><3E> <> <20> <> <EFBFBD> ۵ <EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ѹ<EFBFBD> <D1B9> մϴ<D5B4> .
/// </summary>
/// <example>
/// <code>
/// // Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <20> ѹ<EFBFBD>
/// try {
/// db.BeginTransaction();
/// db.Insert(new Person { Name = "ȫ<> 浿", Age = 30 });
///
/// // <20> <> <EFBFBD> <EFBFBD> <20> <EFBFBD> <DFBB> <EFBFBD> <20> <> <20> ִ<EFBFBD> <20> ۾<EFBFBD>
/// if (SomeConditionFails()) {
/// // Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ѹ<EFBFBD>
/// db.Rollback();
/// return;
/// }
///
/// // <20> <> <EFBFBD> <EFBFBD> <20> <> Ŀ<> <C4BF>
/// db.Commit();
/// } catch(Exception) {
/// // <20> <> <EFBFBD> <EFBFBD> <20> <EFBFBD> <20> <> <20> ѹ<EFBFBD>
/// db.Rollback();
/// }
/// </code>
/// </example>
public void Rollback ( )
{
RollbackTo ( null , false ) ;
}
/// <summary>
/// <see cref="BeginTransaction"/> <20> Ǵ<EFBFBD> SaveTransactionPoint<6E> <74> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> ѹ<EFBFBD> <D1B9> մϴ<D5B4> .
/// </summary>
/// <param name="savepoint"><see cref="SaveTransactionPoint"/><3E> <> <20> <> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> <C8AF> <20> ѹ<EFBFBD> <D1B9> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> ̸<EFBFBD> . savepoint<6E> <74> null<6C> ̰ų<CCB0> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <EFBFBD> <DEBC> <EFBFBD> <EFBFBD> <EFBFBD> <see cref="Rollback"/> ȣ <> <C8A3> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .</param>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> κ<EFBFBD> <20> ѹ<EFBFBD>
/// db.BeginTransaction();
///
/// // ù <20> <> ° <20> ۾<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.Insert(new Person { Name = "ȫ<> 浿", Age = 30 });
///
/// // <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ <20> <> <EFBFBD> <EFBFBD>
/// string savepoint = db.SaveTransactionPoint();
///
/// // <20> <> <20> <> ° <20> ۾<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.Insert(new Person { Name = "<22> <> ö<EFBFBD> <C3B6> ", Age = 25 });
///
/// // <20> <> <20> <> ° <20> ۾<EFBFBD> <DBBE> <EFBFBD> <20> ѹ<EFBFBD> (<28> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> ǵ<EFBFBD> <C7B5> <EFBFBD> <EFBFBD> <EFBFBD> )
/// db.RollbackTo(savepoint);
///
/// // ù <20> <> ° <20> ۾<EFBFBD> <DBBE> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ȿ<EFBFBD> ϸ<EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<> <C4BF>
/// db.Commit();
/// </code>
/// </example>
public void RollbackTo ( string savepoint )
{
RollbackTo ( savepoint , false ) ;
}
/// <summary>
/// <see cref="BeginTransaction"/><3E> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ۵ <EFBFBD> <20> ŷ<EFBFBD> <C5B7> <EFBFBD> <20> ѹ<EFBFBD> <D1B9> մϴ<D5B4> .
/// </summary>
/// <param name="noThrow"><3E> <> <EFBFBD> <EFBFBD> <20> <EFBFBD> <DFBB> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ϸ<EFBFBD> <CFB7> <EFBFBD> true, <20> <EFBFBD> <D7B7> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> false</param>
void RollbackTo ( string savepoint , bool noThrow )
{
// Rolling back without a TO clause rolls backs all transactions
// and leaves the transaction stack empty.
try
{
if ( String . IsNullOrEmpty ( savepoint ) )
{
if ( Interlocked . Exchange ( ref _transactionDepth , 0 ) > 0 )
{
Execute ( "rollback" ) ;
}
}
else
{
DoSavePointExecute ( savepoint , "rollback to " ) ;
}
}
catch ( SQLiteException )
{
if ( ! noThrow )
throw ;
}
// No need to rollback if there are no transactions open.
}
/// <summary>
/// <see cref="SaveTransactionPoint"/><3E> <> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> <C8AF> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϸ<EFBFBD> <20> ش<EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ߴ <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// <20> <> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ˴ ϴ<CBB4> .
/// <20> <EFBFBD> <D7B7> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> 쿡<EFBFBD> <ECBFA1> <see cref="Commit"/> ȣ <> <C8A3> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ·<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ˴ ϴ<CBB4> .
///
/// RELEASE <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> SAVEPOINT<4E> <54> <20> <> <EFBFBD> <EFBFBD> COMMIT<49> <54> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> .
/// </summary>
/// <param name="savepoint"><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> ̸<EFBFBD> . <20> <> <20> <> <EFBFBD> ڿ<EFBFBD> <DABF> <EFBFBD> <see cref="SaveTransactionPoint"/> ȣ <> <C8A3> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> մϴ<D5B4> .</param>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ <20> <> <EFBFBD> <EFBFBD> (Ȯ<> <C8AE> ) <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.BeginTransaction();
///
/// // <20> ۾<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.Insert(new Person { Name = "ȫ<> 浿", Age = 30 });
///
/// // <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ <20> <> <EFBFBD> <EFBFBD>
/// string savepoint1 = db.SaveTransactionPoint();
/// db.Insert(new Person { Name = "<22> <> ö<EFBFBD> <C3B6> ", Age = 25 });
///
/// // <20> ٸ<EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ <20> <> <EFBFBD> <EFBFBD>
/// string savepoint2 = db.SaveTransactionPoint();
/// db.Insert(new Person { Name = "<22> ̿<EFBFBD> <CCBF> <EFBFBD> ", Age = 35 });
///
/// // <20> <> <20> <> ° <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ȯ<> <C8AE>
/// db.Release(savepoint2);
///
/// // <20> <> <EFBFBD> <EFBFBD> ù <20> <> ° <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ȯ<> <C8AE>
/// db.Release(savepoint1);
///
/// // <20> <> ü Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<> <C4BF>
/// db.Commit();
/// </code>
/// </example>
public void Release ( string savepoint )
{
DoSavePointExecute ( savepoint , "release " ) ;
}
/// <summary>
/// <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="savepoint"><3E> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ <20> ĺ<EFBFBD> <C4BA> <EFBFBD> </param>
/// <param name="cmd"><3E> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> SQL <20> <> <EFBFBD> <EFBFBD> (rollback to <20> Ǵ<EFBFBD> release)</param>
/// <exception cref="ArgumentException"><3E> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> ȿ<EFBFBD> <C8BF> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <EFBFBD> </exception>
void DoSavePointExecute ( string savepoint , string cmd )
{
// Validate the savepoint
int firstLen = savepoint . IndexOf ( 'D' ) ;
if ( firstLen > = 2 & & savepoint . Length > firstLen + 1 )
{
int depth ;
if ( Int32 . TryParse ( savepoint . Substring ( firstLen + 1 ) , out depth ) )
{
// TODO: Mild race here, but inescapable without locking almost everywhere.
if ( 0 < = depth & & depth < _transactionDepth )
{
#if NETFX_CORE
Volatile . Write ( ref _transactionDepth , depth ) ;
#elif SILVERLIGHT
_transactionDepth = depth ;
#else
Thread . VolatileWrite ( ref _transactionDepth , depth ) ;
#endif
Execute ( cmd + savepoint ) ;
return ;
}
}
}
throw new ArgumentException ( "savePoint is not valid, and should be the result of a call to SaveTransactionPoint." , "savePoint" ) ;
}
/// <summary>
/// <see cref="BeginTransaction"/><3E> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ۵ <EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<> <C4BF> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <example>
/// <code>
/// // Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<> <C4BF> <20> <> <EFBFBD> <EFBFBD>
/// try {
/// db.BeginTransaction();
///
/// // <20> <> <EFBFBD> <EFBFBD> <20> ۾<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.Insert(new Person { Name = "ȫ<> 浿", Age = 30 });
/// db.Insert(new Person { Name = "<22> <> ö<EFBFBD> <C3B6> ", Age = 25 });
/// db.Insert(new Person { Name = "<22> ̿<EFBFBD> <CCBF> <EFBFBD> ", Age = 35 });
///
/// // <20> <> <EFBFBD> <EFBFBD> <20> ۾<EFBFBD> <DBBE> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ϸ<EFBFBD> <CFB7> Ǹ<EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<> <C4BF>
/// db.Commit();
/// } catch(Exception ex) {
/// // <20> <> <EFBFBD> <EFBFBD> <20> <EFBFBD> <20> <> <20> ѹ<EFBFBD>
/// db.Rollback();
/// Console.WriteLine("Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> : " + ex.Message);
/// }
/// </code>
/// </example>
public void Commit ( )
{
if ( Interlocked . Exchange ( ref _transactionDepth , 0 ) ! = 0 )
{
Execute ( "commit" ) ;
}
// Do nothing on a commit with no open transaction
}
/// <summary>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> <EFBFBD> <D7BC> <EFBFBD> SAVEPOINT<4E> <54> <20> <> <EFBFBD> μ<EFBFBD> (<28> <> ø<EFBFBD> <C3B8> <20> <> <20> ִ<EFBFBD> ) Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> ܰ<EFBFBD> <20> <EFBFBD> <DFBB> ϸ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> Ӹ<EFBFBD> <20> ƴ϶<C6B4> <20> <> ü Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ѹ<EFBFBD> <D1B9> ˴ ϴ<CBB4> .
/// <20> <EFBFBD> <DFBB> <EFBFBD> <20> <> <EFBFBD> ܴ<EFBFBD> <20> ٽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> .
/// </summary>
/// <param name="action">
/// Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <see cref="Action"/>. action<6F> <6E> <20> <> <EFBFBD> ῡ <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ۾<EFBFBD> <DBBE> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// <see cref="BeginTransaction"/> <20> Ǵ<EFBFBD> <see cref="Commit"/><3E> <> ȣ <> <C8A3> <EFBFBD> ؼ<EFBFBD> <D8BC> <EFBFBD> <20> <> <20> ˴ ϴ<CBB4> .
/// </param>
/// <example>
/// <code>
/// // RunInTransaction<6F> <6E> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ó<> <C3B3>
/// db.RunInTransaction(() => {
/// // <20> <> <EFBFBD> <EFBFBD> <20> ۾<EFBFBD> <DBBE> <EFBFBD> <20> ϳ <EFBFBD> <CFB3> <EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ˴ ϴ<CBB4> .
/// db.Insert(new Person { Name = "ȫ<> 浿", Age = 30 });
/// db.Insert(new Person { Name = "<22> <> ö<EFBFBD> <C3B6> ", Age = 25 });
/// db.Update(new Person { Id = 1, Name = "ȫ<> 浿", Age = 31 });
///
/// // <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ܰ<EFBFBD> <20> <EFBFBD> <DFBB> ϸ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ۾<EFBFBD> <DBBE> <EFBFBD> <20> ѹ<EFBFBD> <D1B9> ˴ ϴ<CBB4> .
/// });
///
/// // <20> <> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϸ<EFBFBD> Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ<> Ե<EFBFBD> <20> <> <EFBFBD> Դϴ<D4B4> .
/// </code>
/// </example>
public void RunInTransaction ( Action action )
{
try
{
lock ( syncObjects [ DatabasePath ] )
{
var savePoint = SaveTransactionPoint ( ) ;
action ( ) ;
Release ( savePoint ) ;
}
}
catch ( Exception )
{
Rollback ( ) ;
throw ;
}
}
/// <summary>
/// <20> ٸ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> 尡 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ϵ<EFBFBD> <CFB5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϸ鼭 <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> <EFBFBD> <D7BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="action">
/// <20> <> (lock) <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <see cref="Action"/>.
/// </param>
/// <example>
/// <code>
/// // RunInDatabaseLock<63> <6B> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.RunInDatabaseLock(() => {
/// // <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ۾<EFBFBD> <DBBE> <EFBFBD> <20> ٸ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> 忡<EFBFBD> <E5BFA1> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> .
2025-06-10 01:09:36 +09:00
/// var count = db.ExecuteScalar<int>("SELECT COUNT(*) FROM Person");
2025-06-04 23:10:11 +09:00
///
/// if (count > 0) {
2025-06-10 01:09:36 +09:00
/// var people = db.Query<Person>("SELECT * FROM Person");
2025-06-04 23:10:11 +09:00
/// foreach (var person in people) {
/// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ó<> <C3B3>
/// ProcessPerson(person);
/// }
/// }
/// });
/// </code>
/// </example>
public void RunInDatabaseLock ( Action action )
{
lock ( syncObjects [ DatabasePath ] )
{
action ( ) ;
}
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="objects">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <see cref="IEnumerable"/> <20> ÷<EFBFBD> <C3B7> <EFBFBD> .
/// </param>
/// <returns>
/// <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> ߰<EFBFBD> <DFB0> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> .
/// </returns>
/// <example>
/// <code>
/// // <20> <> ü <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// var people = new List<Person>
2025-06-04 23:10:11 +09:00
/// {
/// new Person { Name = "ȫ<> 浿", Age = 30 },
/// new Person { Name = "<22> <> ö<EFBFBD> <C3B6> ", Age = 25 },
/// new Person { Name = "<22> ̿<EFBFBD> <CCBF> <EFBFBD> ", Age = 35 }
/// };
///
/// // <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> ȯ
/// int count = db.InsertAll(people);
/// Console.WriteLine($"<22> <> <EFBFBD> Ե<EFBFBD> <20> <> <20> <> : {count}");
/// </code>
/// </example>
public int InsertAll ( System . Collections . IEnumerable objects )
{
var c = 0 ;
RunInTransaction ( ( ) = > {
foreach ( var r in objects )
{
c + = Insert ( r ) ;
}
} ) ;
return c ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="objects">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <EFBFBD> <EFBFBD> <see cref="IEnumerable"/> <20> ÷<EFBFBD> <C3B7> <EFBFBD> .
/// </param>
/// <param name="extra">
/// <20> <> <EFBFBD> ɿ<EFBFBD> <20> <> <EFBFBD> ԵǴ<D4B5> <20> <> <EFBFBD> ͷ<EFBFBD> SQL <20> ڵ<EFBFBD> <DAB5> Դϴ<D4B4> . INSERT {extra} INTO ...
/// </param>
/// <returns>
/// <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> ߰<EFBFBD> <DFB0> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> .
/// </returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> <EFBFBD> <20> <> ü <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> (<28> 浹 <20> <> <EFBFBD> <EFBFBD> <20> ɼ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> )
2025-06-10 01:09:36 +09:00
/// var people = new List<Person>
2025-06-04 23:10:11 +09:00
/// {
/// new Person { Id = 1, Name = "ȫ<> 浿", Age = 30 },
/// new Person { Id = 2, Name = "<22> <> ö<EFBFBD> <C3B6> ", Age = 25 },
/// new Person { Id = 3, Name = "<22> ̿<EFBFBD> <CCBF> <EFBFBD> ", Age = 35 }
/// };
///
/// // OR IGNORE <20> ɼ<EFBFBD> <C9BC> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> ߺ <EFBFBD> Ű <20> 浹 <20> <> <EFBFBD> <EFBFBD>
/// int count = db.InsertAll(people, "OR IGNORE");
/// Console.WriteLine($"<22> <> <EFBFBD> Ե<EFBFBD> <20> <> <20> <> : {count}");
/// </code>
/// </example>
public int InsertAll ( System . Collections . IEnumerable objects , string extra )
{
var c = 0 ;
RunInTransaction ( ( ) = > {
foreach ( var r in objects )
{
c + = Insert ( r , extra ) ;
}
} ) ;
return c ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="objects">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <EFBFBD> <EFBFBD> <see cref="IEnumerable"/> <20> ÷<EFBFBD> <C3B7> <EFBFBD> .
/// </param>
/// <param name="objType">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <EFBFBD> <EFBFBD> Ÿ<> <C5B8> .
/// </param>
/// <returns>
/// <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> ߰<EFBFBD> <DFB0> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> .
/// </returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> <EFBFBD> Ÿ<> <C5B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ü <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// var people = new List<object>
2025-06-04 23:10:11 +09:00
/// {
/// new Person { Name = "ȫ<> 浿", Age = 30 },
/// new Person { Name = "<22> <> ö<EFBFBD> <C3B6> ", Age = 25 }
/// };
///
/// // Ư<> <C6AF> Ÿ<> <C5B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// int count = db.InsertAll(people, typeof(Person));
/// Console.WriteLine($"<22> <> <EFBFBD> Ե<EFBFBD> <20> <> <20> <> : {count}");
/// </code>
/// </example>
public int InsertAll ( System . Collections . IEnumerable objects , Type objType )
{
var c = 0 ;
RunInTransaction ( ( ) = > {
foreach ( var r in objects )
{
c + = Insert ( r , objType ) ;
}
} ) ;
return c ;
}
/// <summary>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> , <20> ڵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> ִٸ<D6B4> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ɴϴ<C9B4> .
/// </summary>
/// <param name="obj">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü.
/// </param>
/// <returns>
/// <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> ߰<EFBFBD> <DFB0> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> .
/// </returns>
/// <example>
/// <code>
/// // Person <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// var person = new Person { Name = "ȫ<> 浿", Age = 30 };
///
/// // <20> <> ü <20> <> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> Ȯ<> <C8AE>
/// int rowsAffected = db.Insert(person);
///
/// // <20> ڵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> ID<49> <44> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <20> <> ID<49> <44> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/// Console.WriteLine($"<22> <> <EFBFBD> Ե<EFBFBD> ID: {person.Id}");
/// </code>
/// </example>
public int Insert ( object obj )
{
if ( obj = = null )
{
return 0 ;
}
return Insert ( obj , "" , obj . GetType ( ) ) ;
}
/// <summary>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> , <20> ڵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> ִٸ<D6B4> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ɴϴ<C9B4> .
/// UNIQUE <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <EFBFBD> <DFBB> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="obj">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü.
/// </param>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> .
/// </returns>
/// <example>
/// <code>
/// // <20> ߺ <EFBFBD> Ű<> <C5B0> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> Ͽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// var existingPerson = new Person { Id = 1, Name = "ȫ<> 浿", Age = 30 };
///
/// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Id<49> <64> <20> <> <20> <> ü <20> <> <EFBFBD> <EFBFBD> (<28> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> ü<EFBFBD> <C3BC> )
/// db.InsertOrReplace(new Person { Id = 1, Name = "ȫ<> 浿(<28> <> <EFBFBD> <EFBFBD> )", Age = 31 });
///
/// // <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> ü <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// var person = db.Get<Person>(1);
2025-06-04 23:10:11 +09:00
/// person.Age += 1;
/// db.InsertOrReplace(person);
/// </code>
/// </example>
public int InsertOrReplace ( object obj )
{
if ( obj = = null )
{
return 0 ;
}
return Insert ( obj , "OR REPLACE" , obj . GetType ( ) ) ;
}
/// <summary>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> ڵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> ִٸ<D6B4> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ɴϴ<C9B4> .
/// </summary>
/// <param name="obj">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü.
/// </param>
/// <param name="extra">
/// <20> <> <EFBFBD> ɿ<EFBFBD> <20> <> <EFBFBD> ԵǴ<D4B5> <20> <> <EFBFBD> ͷ<EFBFBD> SQL <20> ڵ<EFBFBD> <DAB5> Դϴ<D4B4> . INSERT {extra} INTO ...
/// </param>
/// <param name="objType">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> Ÿ<> <C5B8> .
/// </param>
/// <returns>
/// <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> ߰<EFBFBD> <DFB0> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> .
/// </returns>
/// <example>
/// <code>
/// // Ư<> <C6AF> Ÿ<> <C5B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü <20> <> <EFBFBD> <EFBFBD>
/// object person = new Person { Name = "ȫ<> 浿", Age = 30 };
///
/// // OR IGNORE <20> ɼ<EFBFBD> <C9BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> 浹 <20> <> <20> <> <EFBFBD> <EFBFBD>
/// int count = db.Insert(person, "OR IGNORE", typeof(Person));
///
/// // <20> Ǵ<EFBFBD> <20> ٸ<EFBFBD> SQL <20> ɼ<EFBFBD> <20> ߰<EFBFBD>
/// db.Insert(person, "OR FAIL", typeof(Person));
/// </code>
/// </example>
public int Insert ( object obj , Type objType )
{
return Insert ( obj , "" , objType ) ;
}
/// <summary>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> ڵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> ִٸ<D6B4> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ɴϴ<C9B4> .
/// UNIQUE <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <EFBFBD> <DFBB> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> ü<EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="obj">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü.
/// </param>
/// <param name="objType">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> Ÿ<> <C5B8> .
/// </param>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> .
/// </returns>
/// <example>
/// <code>
/// // Ư<> <C6AF> Ÿ<> <C5B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü <20> <> <EFBFBD> <EFBFBD> <20> <> <20> <> ü
/// object person = new Person { Id = 1, Name = "ȫ<> 浿", Age = 30 };
///
/// // <20> <> ü <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// int count = db.InsertOrReplace(person, typeof(Person));
/// </code>
/// </example>
public int InsertOrReplace ( object obj , Type objType )
{
return Insert ( obj , "OR REPLACE" , objType ) ;
}
/// <summary>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> ڵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> ִٸ<D6B4> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ɴϴ<C9B4> .
/// </summary>
/// <param name="obj">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü.
/// </param>
/// <param name="extra">
/// <20> <> <EFBFBD> ɿ<EFBFBD> <20> <> <EFBFBD> ԵǴ<D4B5> <20> <> <EFBFBD> ͷ<EFBFBD> SQL <20> ڵ<EFBFBD> <DAB5> Դϴ<D4B4> . INSERT {extra} INTO ...
/// </param>
/// <returns>
/// <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> ߰<EFBFBD> <DFB0> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> .
/// </returns>
/// <example>
/// <code>
/// // <20> 浹 <20> <> <EFBFBD> <EFBFBD> <20> ɼ<EFBFBD> <C9BC> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü <20> <> <EFBFBD> <EFBFBD>
/// var person = new Person { Id = 1, Name = "ȫ<> 浿", Age = 30 };
///
/// // OR IGNORE <20> ɼ<EFBFBD> <C9BC> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> ߺ <EFBFBD> Ű <20> 浹 <20> <> <EFBFBD> <EFBFBD>
/// int count = db.Insert(person, "OR IGNORE");
/// Console.WriteLine($"<22> <> <EFBFBD> Ե<EFBFBD> <20> <> <20> <> : {count}");
/// </code>
/// </example>
public int Insert ( object obj , string extra )
{
if ( obj = = null )
{
return 0 ;
}
return Insert ( obj , extra , obj . GetType ( ) ) ;
}
/// <summary>
/// <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> ڵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> ִٸ<D6B4> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ɴϴ<C9B4> .
/// </summary>
/// <param name="obj">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü.
/// </param>
/// <param name="extra">
/// <20> <> <EFBFBD> ɿ<EFBFBD> <20> <> <EFBFBD> ԵǴ<D4B5> <20> <> <EFBFBD> ͷ<EFBFBD> SQL <20> ڵ<EFBFBD> <DAB5> Դϴ<D4B4> . INSERT {extra} INTO ...
/// </param>
/// <param name="objType">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> Ÿ<> <C5B8> .
/// </param>
/// <returns>
/// <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> ߰<EFBFBD> <DFB0> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> .
/// </returns>
/// <example>
/// <code>
/// // <20> پ<EFBFBD> <D9BE> <EFBFBD> <20> ɼ<EFBFBD> <C9BC> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü <20> <> <EFBFBD> <EFBFBD>
/// var person = new Person { Name = "ȫ<> 浿", Age = 30 };
///
/// // <20> ⺻ <20> <> <EFBFBD> <EFBFBD>
/// db.Insert(person);
///
/// // OR IGNORE <20> ɼ<EFBFBD> <C9BC> <EFBFBD> <EFBFBD> <EFBFBD> <20> 浹 <20> <> <20> <> <EFBFBD> <EFBFBD>
/// db.Insert(person, "OR IGNORE");
///
/// // Ư<> <C6AF> Ÿ<> <C5B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// db.Insert(person, "OR REPLACE", typeof(Person));
/// </code>
/// </example>
public int Insert ( object obj , string extra , Type objType )
{
if ( obj = = null | | objType = = null )
{
return 0 ;
}
var map = GetMapping ( objType ) ;
#if NETFX_CORE
if ( map . PK ! = null & & map . PK . IsAutoGuid )
{
// no GetProperty so search our way up the inheritance chain till we find it
PropertyInfo prop ;
while ( objType ! = null )
{
var info = objType . GetTypeInfo ( ) ;
prop = info . GetDeclaredProperty ( map . PK . PropertyName ) ;
if ( prop ! = null )
{
if ( prop . GetValue ( obj , null ) . Equals ( Guid . Empty ) )
{
prop . SetValue ( obj , Guid . NewGuid ( ) , null ) ;
}
break ;
}
objType = info . BaseType ;
}
}
#else
if ( map . PK ! = null & & map . PK . IsAutoGuid )
{
var prop = objType . GetProperty ( map . PK . PropertyName ) ;
if ( prop ! = null )
{
//if (prop.GetValue(obj, null).Equals(Guid.Empty)) {
if ( prop . GetGetMethod ( ) . Invoke ( obj , null ) . Equals ( Guid . Empty ) )
{
prop . SetValue ( obj , Guid . NewGuid ( ) , null ) ;
}
}
}
#endif
var replacing = string . Compare ( extra , "OR REPLACE" , StringComparison . OrdinalIgnoreCase ) = = 0 ;
var cols = replacing ? map . InsertOrReplaceColumns : map . InsertColumns ;
var vals = new object [ cols . Length ] ;
for ( var i = 0 ; i < vals . Length ; i + + )
{
vals [ i ] = cols [ i ] . GetValue ( obj ) ;
}
var insertCmd = map . GetInsertCommand ( this , extra ) ;
int count ;
try
{
count = insertCmd . ExecuteNonQuery ( vals ) ;
}
catch ( SQLiteException ex )
{
if ( SQLite3 . ExtendedErrCode ( this . Handle ) = = SQLite3 . ExtendedResult . ConstraintNotNull )
{
throw NotNullConstraintViolationException . New ( ex . Result , ex . Message , map , obj ) ;
}
throw ;
}
if ( map . HasAutoIncPK )
{
var id = SQLite3 . LastInsertRowid ( Handle ) ;
map . SetAutoIncPK ( obj , id ) ;
}
return count ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> մϴ<D5B4> .
/// <20> <> ü<EFBFBD> <C3BC> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> մϴ<D5B4> .
/// </summary>
/// <param name="obj">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> ü. PrimaryKeyAttribute<74> <65> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> մϴ<D5B4> .
/// </param>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <20> <> .
/// </returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü <20> ˻<EFBFBD>
2025-06-10 01:09:36 +09:00
/// var person = db.Get<Person>(1);
2025-06-04 23:10:11 +09:00
///
/// // <20> <> ü <20> Ӽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// person.Name = "ȫ<> 浿(<28> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> )";
/// person.Age = 31;
///
/// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ
/// int rowsAffected = db.Update(person);
/// Console.WriteLine($"<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <20> <> : {rowsAffected}");
/// </code>
/// </example>
public int Update ( object obj )
{
if ( obj = = null )
{
return 0 ;
}
return Update ( obj , obj . GetType ( ) ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> մϴ<D5B4> .
/// <20> <> ü<EFBFBD> <C3BC> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> մϴ<D5B4> .
/// </summary>
/// <param name="obj">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> ü. PrimaryKeyAttribute<74> <65> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> մϴ<D5B4> .
/// </param>
/// <param name="objType">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> ü<EFBFBD> <C3BC> Ÿ<> <C5B8> .
/// </param>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <20> <> .
/// </returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> <EFBFBD> Ÿ<> <C5B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ
/// object person = new Person { Id = 1, Name = "ȫ<> 浿(<28> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> )", Age = 31 };
///
/// // Ư<> <C6AF> Ÿ<> <C5B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ
/// int count = db.Update(person, typeof(Person));
/// Console.WriteLine($"<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <20> <> : {count}");
/// </code>
/// </example>
public int Update ( object obj , Type objType )
{
int rowsAffected = 0 ;
if ( obj = = null | | objType = = null )
{
return 0 ;
}
var map = GetMapping ( objType ) ;
var pk = map . PK ;
if ( pk = = null )
{
throw new NotSupportedException ( "Cannot update " + map . TableName + ": it has no PK" ) ;
}
var cols = from p in map . Columns
where p ! = pk
select p ;
var vals = from c in cols
select c . GetValue ( obj ) ;
var ps = new List < object > ( vals ) ;
ps . Add ( pk . GetValue ( obj ) ) ;
var q = string . Format ( "update \"{0}\" set {1} where {2} = ? " , map . TableName , string . Join ( "," , ( from c in cols
select "\"" + c . Name + "\" = ? " ) . ToArray ( ) ) , pk . Name ) ;
try
{
rowsAffected = Execute ( q , ps . ToArray ( ) ) ;
}
catch ( SQLiteException ex )
{
if ( ex . Result = = SQLite3 . Result . Constraint & & SQLite3 . ExtendedErrCode ( this . Handle ) = = SQLite3 . ExtendedResult . ConstraintNotNull )
{
throw NotNullConstraintViolationException . New ( ex , map , obj ) ;
}
throw ex ;
}
return rowsAffected ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="objects">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> ü<EFBFBD> <C3BC> <EFBFBD> <EFBFBD> <see cref="IEnumerable"/> <20> ÷<EFBFBD> <C3B7> <EFBFBD> .
/// </param>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> .
/// </returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> <EFBFBD> <20> <> ü <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ
2025-06-10 01:09:36 +09:00
/// var people = db.Query<Person>("SELECT * FROM Person WHERE Age < 30");
2025-06-04 23:10:11 +09:00
/// foreach (var person in people) {
/// person.Age++;
/// }
///
/// // <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ
/// int count = db.UpdateAll(people);
/// Console.WriteLine($"<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <20> <> : {count}");
/// </code>
/// </example>
public int UpdateAll ( System . Collections . IEnumerable objects )
{
var c = 0 ;
RunInTransaction ( ( ) = > {
foreach ( var r in objects )
{
c + = Update ( r ) ;
}
} ) ;
return c ;
}
/// <summary>
/// <20> ⺻ Ű<> <C5B0> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="objectToDelete">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü. PrimaryKeyAttribute<74> <65> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> ־<EFBFBD> <D6BE> <EFBFBD> <20> մϴ<D5B4> .
/// </param>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> .
/// </returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü <20> ˻<EFBFBD>
2025-06-10 01:09:36 +09:00
/// var person = db.Get<Person>(1);
2025-06-04 23:10:11 +09:00
///
/// // <20> <> ü <20> <> <EFBFBD> <EFBFBD>
/// int rowsAffected = db.Delete(person);
/// Console.WriteLine($"<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> : {rowsAffected}");
///
/// // <20> Ǵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> ID<49> <44> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// rowsAffected = db.Delete<Person>(2);
2025-06-04 23:10:11 +09:00
/// </code>
/// </example>
public int Delete ( object objectToDelete )
{
var map = GetMapping ( objectToDelete . GetType ( ) ) ;
var pk = map . PK ;
if ( pk = = null )
{
throw new NotSupportedException ( "Cannot delete " + map . TableName + ": it has no PK" ) ;
}
var q = string . Format ( "delete from \"{0}\" where \"{1}\" = ?" , map . TableName , pk . Name ) ;
return Execute ( q , pk . GetValue ( objectToDelete ) ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ⺻ Ű<> <C5B0> <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <param name="primaryKey">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> ⺻ Ű.
/// </param>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> .
/// </returns>
/// <typeparam name='T'>
/// <20> <> ü<EFBFBD> <C3BC> Ÿ<> <C5B8> .
/// </typeparam>
/// <example>
/// <code>
/// // <20> ⺻ Ű<> <C5B0> <20> <> <EFBFBD> <EFBFBD> <20> <> ü <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// int rowsDeleted = db.Delete<Person>(1);
2025-06-04 23:10:11 +09:00
/// Console.WriteLine($"ID<49> <44> 1<> <31> Person <20> <> ü {rowsDeleted}<7D> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ");
///
/// // <20> <> <EFBFBD> <EFBFBD> ID<49> <44> <20> <> <EFBFBD> ʷ<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// int[] idsToDelete = { 2, 3, 4 };
/// foreach (int id in idsToDelete) {
2025-06-10 01:09:36 +09:00
/// db.Delete<Person>(id);
2025-06-04 23:10:11 +09:00
/// }
/// </code>
/// </example>
public int Delete < T > ( object primaryKey )
{
var map = GetMapping ( typeof ( T ) ) ;
var pk = map . PK ;
if ( pk = = null )
{
throw new NotSupportedException ( "Cannot delete " + map . TableName + ": it has no PK" ) ;
}
var q = string . Format ( "delete from \"{0}\" where \"{1}\" = ?" , map . TableName , pk . Name ) ;
return Execute ( q , primaryKey ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> : <20> ݺ<EFBFBD> <DDBA> Ͽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڸ<EFBFBD> , <20> <> <20> ҵ<DEBC> <D2B5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// <20> <> <EFBFBD> <EFBFBD> <20> <> <20> ۾<EFBFBD> <DBBE> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ϸ<EFBFBD> <CFB7> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ´ <EFBFBD> <C2B4> <EFBFBD> Ȯ<> <C8AE> <EFBFBD> ϼ<EFBFBD> <CFBC> <EFBFBD> .
/// </summary>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> <20> <> .
/// </returns>
/// <typeparam name='T'>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü<EFBFBD> <C3BC> Ÿ<> <C5B8> .
/// </typeparam>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> (<28> <> <EFBFBD> <EFBFBD> <EFBFBD> ؼ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> )
/// db.BeginTransaction();
/// try {
/// // <20> <> <EFBFBD> <EFBFBD> <20> <> Ȯ<> <C8AE> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> ī<> <C4AB> Ʈ
2025-06-10 01:09:36 +09:00
/// int beforeCount = db.ExecuteScalar<int>("SELECT COUNT(*) FROM Person");
2025-06-04 23:10:11 +09:00
/// Console.WriteLine($"<22> <> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> : {beforeCount}");
///
/// // <20> <> <EFBFBD> <EFBFBD> Person <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// int deleted = db.DeleteAll<Person>();
2025-06-04 23:10:11 +09:00
///
/// Console.WriteLine($"<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> : {deleted}");
/// db.Commit();
/// } catch(Exception) {
/// db.Rollback();
/// Console.WriteLine("<22> <> <EFBFBD> <EFBFBD> <20> ۾<EFBFBD> <20> <> <EFBFBD> ҵ<EFBFBD> ");
/// }
/// </code>
/// </example>
public int DeleteAll < T > ( )
{
var map = GetMapping ( typeof ( T ) ) ;
var query = string . Format ( "delete from \"{0}\"" , map . TableName ) ;
return Execute ( query ) ;
}
~ SQLiteConnection ( )
{
Dispose ( false ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> ݽ<EFBFBD> <DDBD> ϴ<EFBFBD> .
/// </summary>
/// <example>
/// <code>
/// // using <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ڵ<EFBFBD> <20> <> <EFBFBD> ҽ <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// using (var db = new SQLiteConnection("database.db"))
/// {
/// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> ۾<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// var people = db.Query<Person>("SELECT * FROM Person");
2025-06-04 23:10:11 +09:00
///
/// // using <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ڵ<EFBFBD> <DAB5> <EFBFBD> <EFBFBD> <EFBFBD> db.Dispose() ȣ <> <C8A3> <EFBFBD> <EFBFBD>
/// }
///
/// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ҽ <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// var connection = new SQLiteConnection("database.db");
/// try
/// {
/// // <20> ۾<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// connection.CreateTable<Person>();
2025-06-04 23:10:11 +09:00
/// }
/// finally
/// {
/// connection.Dispose();
/// }
/// </code>
/// </example>
public void Dispose ( )
{
Dispose ( true ) ;
GC . SuppressFinalize ( this ) ;
}
protected virtual void Dispose ( bool disposing )
{
Close ( ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ݽ<EFBFBD> <DDBD> ϴ<EFBFBD> . <20> <> <20> ҵ<DEBC> <D2B5> <EFBFBD> Dispose<73> <65> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȣ <> <C8A3> <EFBFBD> ˴ ϴ<CBB4> .
/// </summary>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ݱ<EFBFBD>
/// db.Close();
///
/// // <20> Ǵ<EFBFBD> using <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> ڵ<EFBFBD> <DAB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> ݱ<EFBFBD>
/// using (var db = new SQLiteConnection("database.db")) {
/// // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <20> ۾<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// var count = db.ExecuteScalar<int>("SELECT COUNT(*) FROM Person");
2025-06-04 23:10:11 +09:00
/// Console.WriteLine($"Person <20> <> <EFBFBD> ̺<EFBFBD> <CCBA> <EFBFBD> <20> <> <20> <> : {count}");
///
/// // using <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ڵ<EFBFBD> <DAB5> <EFBFBD> <EFBFBD> <EFBFBD> db.Dispose()<29> <> ȣ <> <C8A3> <EFBFBD> Ǿ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
/// }
/// </code>
/// </example>
public void Close ( )
{
if ( _open & & Handle ! = NullHandle )
{
try
{
if ( _mappings ! = null )
{
foreach ( var sqlInsertCommand in _mappings . Values )
{
sqlInsertCommand . Dispose ( ) ;
}
}
var r = SQLite3 . Close ( Handle ) ;
if ( r ! = SQLite3 . Result . OK )
{
string msg = SQLite3 . GetErrmsg ( Handle ) ;
throw SQLiteException . New ( r , msg ) ;
}
}
finally
{
Handle = NullHandle ;
_open = false ;
}
}
}
}
/// <summary>
/// Represents a parsed connection string.
/// </summary>
class SQLiteConnectionString
{
public string ConnectionString { get ; private set ; }
public string DatabasePath { get ; private set ; }
public bool StoreDateTimeAsTicks { get ; private set ; }
#if NETFX_CORE
static readonly string MetroStyleDataPath = Windows . Storage . ApplicationData . Current . LocalFolder . Path ;
#endif
public SQLiteConnectionString ( string databasePath , bool storeDateTimeAsTicks )
{
ConnectionString = databasePath ;
StoreDateTimeAsTicks = storeDateTimeAsTicks ;
#if NETFX_CORE
DatabasePath = System . IO . Path . Combine ( MetroStyleDataPath , databasePath ) ;
#else
DatabasePath = databasePath ;
#endif
}
}
[AttributeUsage(AttributeTargets.Class)]
public class TableAttribute : Attribute
{
public string Name { get ; set ; }
public TableAttribute ( string name )
{
Name = name ;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class ColumnAttribute : Attribute
{
public string Name { get ; set ; }
public ColumnAttribute ( string name )
{
Name = name ;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class PrimaryKeyAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Property)]
public class AutoIncrementAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Property)]
public class IndexedAttribute : Attribute
{
public string Name { get ; set ; }
public int Order { get ; set ; }
public virtual bool Unique { get ; set ; }
public IndexedAttribute ( )
{
}
public IndexedAttribute ( string name , int order )
{
Name = name ;
Order = order ;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class IgnoreAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Property)]
public class UniqueAttribute : IndexedAttribute
{
public override bool Unique
{
get { return true ; }
set { /* throw? */ }
}
public UniqueAttribute ( ) : base ( )
{
}
public UniqueAttribute ( string name , int order ) : base ( name , order )
{
}
}
[AttributeUsage(AttributeTargets.Property)]
public class MaxLengthAttribute : Attribute
{
public int Value { get ; private set ; }
public MaxLengthAttribute ( int length )
{
Value = length ;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class CollationAttribute : Attribute
{
public string Value { get ; private set ; }
public CollationAttribute ( string collation )
{
Value = collation ;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class NotNullAttribute : Attribute
{
}
public class TableMapping
{
public Type MappedType { get ; private set ; }
public string TableName { get ; private set ; }
public Column [ ] Columns { get ; private set ; }
public Column PK { get ; private set ; }
public string GetByPrimaryKeySql { get ; private set ; }
Column _autoPk ;
Column [ ] _insertColumns ;
Column [ ] _insertOrReplaceColumns ;
public TableMapping ( Type type , CreateFlags createFlags = CreateFlags . None )
{
MappedType = type ;
#if NETFX_CORE
var tableAttr = ( TableAttribute ) System . Reflection . CustomAttributeExtensions
. GetCustomAttribute ( type . GetTypeInfo ( ) , typeof ( TableAttribute ) , true ) ;
#else
var tableAttr = ( TableAttribute ) type . GetCustomAttributes ( typeof ( TableAttribute ) , true ) . FirstOrDefault ( ) ;
#endif
TableName = tableAttr ! = null ? tableAttr . Name : MappedType . Name ;
#if ! NETFX_CORE
var props = MappedType . GetProperties ( BindingFlags . Public | BindingFlags . Instance | BindingFlags . SetProperty ) ;
#else
var props = from p in MappedType . GetRuntimeProperties ( )
where ( ( p . GetMethod ! = null & & p . GetMethod . IsPublic ) | | ( p . SetMethod ! = null & & p . SetMethod . IsPublic ) | | ( p . GetMethod ! = null & & p . GetMethod . IsStatic ) | | ( p . SetMethod ! = null & & p . SetMethod . IsStatic ) )
select p ;
#endif
var cols = new List < Column > ( ) ;
foreach ( var p in props )
{
#if ! NETFX_CORE
var ignore = p . GetCustomAttributes ( typeof ( IgnoreAttribute ) , true ) . Length > 0 ;
#else
var ignore = p . GetCustomAttributes ( typeof ( IgnoreAttribute ) , true ) . Count ( ) > 0 ;
#endif
if ( p . CanWrite & & ! ignore )
{
cols . Add ( new Column ( p , createFlags ) ) ;
}
}
Columns = cols . ToArray ( ) ;
foreach ( var c in Columns )
{
if ( c . IsAutoInc & & c . IsPK )
{
_autoPk = c ;
}
if ( c . IsPK )
{
PK = c ;
}
}
HasAutoIncPK = _autoPk ! = null ;
if ( PK ! = null )
{
GetByPrimaryKeySql = string . Format ( "select * from \"{0}\" where \"{1}\" = ?" , TableName , PK . Name ) ;
}
else
{
// People should not be calling Get/Find without a PK
GetByPrimaryKeySql = string . Format ( "select * from \"{0}\" limit 1" , TableName ) ;
}
}
public bool HasAutoIncPK { get ; private set ; }
public void SetAutoIncPK ( object obj , long id )
{
if ( _autoPk ! = null )
{
_autoPk . SetValue ( obj , Convert . ChangeType ( id , _autoPk . ColumnType , null ) ) ;
}
}
public Column [ ] InsertColumns
{
get
{
if ( _insertColumns = = null )
{
_insertColumns = Columns . Where ( c = > ! c . IsAutoInc ) . ToArray ( ) ;
}
return _insertColumns ;
}
}
public Column [ ] InsertOrReplaceColumns
{
get
{
if ( _insertOrReplaceColumns = = null )
{
_insertOrReplaceColumns = Columns . ToArray ( ) ;
}
return _insertOrReplaceColumns ;
}
}
public Column FindColumnWithPropertyName ( string propertyName )
{
var exact = Columns . FirstOrDefault ( c = > c . PropertyName = = propertyName ) ;
return exact ;
}
public Column FindColumn ( string columnName )
{
var exact = Columns . FirstOrDefault ( c = > c . Name = = columnName ) ;
return exact ;
}
PreparedSqlLiteInsertCommand _insertCommand ;
string _insertCommandExtra ;
public PreparedSqlLiteInsertCommand GetInsertCommand ( SQLiteConnection conn , string extra )
{
if ( _insertCommand = = null )
{
_insertCommand = CreateInsertCommand ( conn , extra ) ;
_insertCommandExtra = extra ;
}
else if ( _insertCommandExtra ! = extra )
{
_insertCommand . Dispose ( ) ;
_insertCommand = CreateInsertCommand ( conn , extra ) ;
_insertCommandExtra = extra ;
}
return _insertCommand ;
}
PreparedSqlLiteInsertCommand CreateInsertCommand ( SQLiteConnection conn , string extra )
{
var cols = InsertColumns ;
string insertSql ;
if ( ! cols . Any ( ) & & Columns . Count ( ) = = 1 & & Columns [ 0 ] . IsAutoInc )
{
insertSql = string . Format ( "insert {1} into \"{0}\" default values" , TableName , extra ) ;
}
else
{
var replacing = string . Compare ( extra , "OR REPLACE" , StringComparison . OrdinalIgnoreCase ) = = 0 ;
if ( replacing )
{
cols = InsertOrReplaceColumns ;
}
insertSql = string . Format ( "insert {3} into \"{0}\"({1}) values ({2})" , TableName ,
string . Join ( "," , ( from c in cols
select "\"" + c . Name + "\"" ) . ToArray ( ) ) ,
string . Join ( "," , ( from c in cols
select "?" ) . ToArray ( ) ) , extra ) ;
}
var insertCommand = new PreparedSqlLiteInsertCommand ( conn ) ;
insertCommand . CommandText = insertSql ;
return insertCommand ;
}
protected internal void Dispose ( )
{
if ( _insertCommand ! = null )
{
_insertCommand . Dispose ( ) ;
_insertCommand = null ;
}
}
public class Column
{
PropertyInfo _prop ;
public string Name { get ; private set ; }
public string PropertyName { get { return _prop . Name ; } }
public Type ColumnType { get ; private set ; }
public string Collation { get ; private set ; }
public bool IsAutoInc { get ; private set ; }
public bool IsAutoGuid { get ; private set ; }
public bool IsPK { get ; private set ; }
public IEnumerable < IndexedAttribute > Indices { get ; set ; }
public bool IsNullable { get ; private set ; }
public int? MaxStringLength { get ; private set ; }
public Column ( PropertyInfo prop , CreateFlags createFlags = CreateFlags . None )
{
var colAttr = ( ColumnAttribute ) prop . GetCustomAttributes ( typeof ( ColumnAttribute ) , true ) . FirstOrDefault ( ) ;
_prop = prop ;
Name = colAttr = = null ? prop . Name : colAttr . Name ;
//If this type is Nullable<T> then Nullable.GetUnderlyingType returns the T, otherwise it returns null, so get the actual type instead
ColumnType = Nullable . GetUnderlyingType ( prop . PropertyType ) ? ? prop . PropertyType ;
Collation = Orm . Collation ( prop ) ;
IsPK = Orm . IsPK ( prop ) | |
( ( ( createFlags & CreateFlags . ImplicitPK ) = = CreateFlags . ImplicitPK ) & &
string . Compare ( prop . Name , Orm . ImplicitPkName , StringComparison . OrdinalIgnoreCase ) = = 0 ) ;
var isAuto = Orm . IsAutoInc ( prop ) | | ( IsPK & & ( ( createFlags & CreateFlags . AutoIncPK ) = = CreateFlags . AutoIncPK ) ) ;
IsAutoGuid = isAuto & & ColumnType = = typeof ( Guid ) ;
IsAutoInc = isAuto & & ! IsAutoGuid ;
Indices = Orm . GetIndices ( prop ) ;
if ( ! Indices . Any ( )
& & ! IsPK
& & ( ( createFlags & CreateFlags . ImplicitIndex ) = = CreateFlags . ImplicitIndex )
& & Name . EndsWith ( Orm . ImplicitIndexSuffix , StringComparison . OrdinalIgnoreCase )
)
{
Indices = new IndexedAttribute [ ] { new IndexedAttribute ( ) } ;
}
IsNullable = ! ( IsPK | | Orm . IsMarkedNotNull ( prop ) ) ;
MaxStringLength = Orm . MaxStringLength ( prop ) ;
}
public void SetValue ( object obj , object val )
{
_prop . SetValue ( obj , val , null ) ;
}
public object GetValue ( object obj )
{
return _prop . GetGetMethod ( ) . Invoke ( obj , null ) ;
}
}
}
public static class Orm
{
public const int DefaultMaxStringLength = 140 ;
public const string ImplicitPkName = "Id" ;
public const string ImplicitIndexSuffix = "Id" ;
public static string SqlDecl ( TableMapping . Column p , bool storeDateTimeAsTicks )
{
string decl = "\"" + p . Name + "\" " + SqlType ( p , storeDateTimeAsTicks ) + " " ;
if ( p . IsPK )
{
decl + = "primary key " ;
}
if ( p . IsAutoInc )
{
decl + = "autoincrement " ;
}
if ( ! p . IsNullable )
{
decl + = "not null " ;
}
if ( ! string . IsNullOrEmpty ( p . Collation ) )
{
decl + = "collate " + p . Collation + " " ;
}
return decl ;
}
public static string SqlType ( TableMapping . Column p , bool storeDateTimeAsTicks )
{
var clrType = p . ColumnType ;
if ( clrType = = typeof ( Boolean ) | | clrType = = typeof ( Byte ) | | clrType = = typeof ( UInt16 ) | | clrType = = typeof ( SByte ) | | clrType = = typeof ( Int16 ) | | clrType = = typeof ( Int32 ) )
{
return "integer" ;
}
else if ( clrType = = typeof ( UInt32 ) | | clrType = = typeof ( Int64 ) )
{
return "bigint" ;
}
else if ( clrType = = typeof ( Single ) | | clrType = = typeof ( Double ) | | clrType = = typeof ( Decimal ) )
{
return "float" ;
}
else if ( clrType = = typeof ( String ) )
{
int? len = p . MaxStringLength ;
if ( len . HasValue )
return "varchar(" + len . Value + ")" ;
return "varchar" ;
}
else if ( clrType = = typeof ( TimeSpan ) )
{
return "bigint" ;
}
else if ( clrType = = typeof ( DateTime ) )
{
return storeDateTimeAsTicks ? "bigint" : "datetime" ;
}
else if ( clrType = = typeof ( DateTimeOffset ) )
{
return "bigint" ;
#if ! NETFX_CORE
}
else if ( clrType . IsEnum )
{
#else
} else if ( clrType . GetTypeInfo ( ) . IsEnum ) {
#endif
return "integer" ;
}
else if ( clrType = = typeof ( byte [ ] ) )
{
return "blob" ;
}
else if ( clrType = = typeof ( Guid ) )
{
return "varchar(36)" ;
}
else
{
throw new NotSupportedException ( "Don't know about " + clrType ) ;
}
}
public static bool IsPK ( MemberInfo p )
{
var attrs = p . GetCustomAttributes ( typeof ( PrimaryKeyAttribute ) , true ) ;
#if ! NETFX_CORE
return attrs . Length > 0 ;
#else
return attrs . Count ( ) > 0 ;
#endif
}
public static string Collation ( MemberInfo p )
{
var attrs = p . GetCustomAttributes ( typeof ( CollationAttribute ) , true ) ;
#if ! NETFX_CORE
if ( attrs . Length > 0 )
{
return ( ( CollationAttribute ) attrs [ 0 ] ) . Value ;
#else
if ( attrs . Count ( ) > 0 ) {
return ( ( CollationAttribute ) attrs . First ( ) ) . Value ;
#endif
}
else
{
return string . Empty ;
}
}
public static bool IsAutoInc ( MemberInfo p )
{
var attrs = p . GetCustomAttributes ( typeof ( AutoIncrementAttribute ) , true ) ;
#if ! NETFX_CORE
return attrs . Length > 0 ;
#else
return attrs . Count ( ) > 0 ;
#endif
}
public static IEnumerable < IndexedAttribute > GetIndices ( MemberInfo p )
{
var attrs = p . GetCustomAttributes ( typeof ( IndexedAttribute ) , true ) ;
return attrs . Cast < IndexedAttribute > ( ) ;
}
public static int? MaxStringLength ( PropertyInfo p )
{
var attrs = p . GetCustomAttributes ( typeof ( MaxLengthAttribute ) , true ) ;
#if ! NETFX_CORE
if ( attrs . Length > 0 )
return ( ( MaxLengthAttribute ) attrs [ 0 ] ) . Value ;
#else
if ( attrs . Count ( ) > 0 )
return ( ( MaxLengthAttribute ) attrs . First ( ) ) . Value ;
#endif
return null ;
}
public static bool IsMarkedNotNull ( MemberInfo p )
{
var attrs = p . GetCustomAttributes ( typeof ( NotNullAttribute ) , true ) ;
#if ! NETFX_CORE
return attrs . Length > 0 ;
#else
return attrs . Count ( ) > 0 ;
#endif
}
}
public partial class SQLiteCommand
{
SQLiteConnection _conn ;
private List < Binding > _bindings ;
public string CommandText { get ; set ; }
internal SQLiteCommand ( SQLiteConnection conn )
{
_conn = conn ;
_bindings = new List < Binding > ( ) ;
CommandText = "" ;
}
public int ExecuteNonQuery ( )
{
if ( _conn . Trace )
{
_conn . InvokeTrace ( "Executing: " + this ) ;
}
var r = SQLite3 . Result . OK ;
lock ( _conn . SyncObject )
{
var stmt = Prepare ( ) ;
r = SQLite3 . Step ( stmt ) ;
Finalize ( stmt ) ;
}
if ( r = = SQLite3 . Result . Done )
{
int rowsAffected = SQLite3 . Changes ( _conn . Handle ) ;
return rowsAffected ;
}
else if ( r = = SQLite3 . Result . Error )
{
string msg = SQLite3 . GetErrmsg ( _conn . Handle ) ;
throw SQLiteException . New ( r , msg ) ;
}
else if ( r = = SQLite3 . Result . Constraint )
{
if ( SQLite3 . ExtendedErrCode ( _conn . Handle ) = = SQLite3 . ExtendedResult . ConstraintNotNull )
{
throw NotNullConstraintViolationException . New ( r , SQLite3 . GetErrmsg ( _conn . Handle ) ) ;
}
}
throw SQLiteException . New ( r , r . ToString ( ) ) ;
}
public IEnumerable < T > ExecuteDeferredQuery < T > ( )
{
return ExecuteDeferredQuery < T > ( _conn . GetMapping ( typeof ( T ) ) ) ;
}
public List < T > ExecuteQuery < T > ( )
{
return ExecuteDeferredQuery < T > ( _conn . GetMapping ( typeof ( T ) ) ) . ToList ( ) ;
}
public List < T > ExecuteQuery < T > ( TableMapping map )
{
return ExecuteDeferredQuery < T > ( map ) . ToList ( ) ;
}
/// <summary>
/// Invoked every time an instance is loaded from the database.
/// </summary>
/// <param name='obj'>
/// The newly created object.
/// </param>
/// <remarks>
/// This can be overridden in combination with the <see cref="SQLiteConnection.NewCommand"/>
/// method to hook into the life-cycle of objects.
///
/// Type safety is not possible because MonoTouch does not support virtual generic methods.
/// </remarks>
protected virtual void OnInstanceCreated ( object obj )
{
// Can be overridden.
}
public IEnumerable < T > ExecuteDeferredQuery < T > ( TableMapping map )
{
if ( _conn . Trace )
{
_conn . InvokeTrace ( "Executing Query: " + this ) ;
}
lock ( _conn . SyncObject )
{
var stmt = Prepare ( ) ;
try
{
var cols = new TableMapping . Column [ SQLite3 . ColumnCount ( stmt ) ] ;
for ( int i = 0 ; i < cols . Length ; i + + )
{
var name = SQLite3 . ColumnName16 ( stmt , i ) ;
cols [ i ] = map . FindColumn ( name ) ;
}
while ( SQLite3 . Step ( stmt ) = = SQLite3 . Result . Row )
{
var obj = Activator . CreateInstance ( map . MappedType ) ;
for ( int i = 0 ; i < cols . Length ; i + + )
{
if ( cols [ i ] = = null )
continue ;
var colType = SQLite3 . ColumnType ( stmt , i ) ;
var val = ReadCol ( stmt , i , colType , cols [ i ] . ColumnType ) ;
cols [ i ] . SetValue ( obj , val ) ;
}
OnInstanceCreated ( obj ) ;
yield return ( T ) obj ;
}
}
finally
{
SQLite3 . Finalize ( stmt ) ;
}
}
}
public T ExecuteScalar < T > ( )
{
if ( _conn . Trace )
{
_conn . InvokeTrace ( "Executing Query: " + this ) ;
}
T val = default ( T ) ;
lock ( _conn . SyncObject )
{
var stmt = Prepare ( ) ;
try
{
var r = SQLite3 . Step ( stmt ) ;
if ( r = = SQLite3 . Result . Row )
{
var colType = SQLite3 . ColumnType ( stmt , 0 ) ;
val = ( T ) ReadCol ( stmt , 0 , colType , typeof ( T ) ) ;
}
else if ( r = = SQLite3 . Result . Done )
{
}
else
{
throw SQLiteException . New ( r , SQLite3 . GetErrmsg ( _conn . Handle ) ) ;
}
}
finally
{
Finalize ( stmt ) ;
}
}
return val ;
}
public void Bind ( string name , object val )
{
_bindings . Add ( new Binding
{
Name = name ,
Value = val
} ) ;
}
public void Bind ( object val )
{
Bind ( null , val ) ;
}
public override string ToString ( )
{
var parts = new string [ 1 + _bindings . Count ] ;
parts [ 0 ] = CommandText ;
var i = 1 ;
foreach ( var b in _bindings )
{
parts [ i ] = string . Format ( " {0}: {1}" , i - 1 , b . Value ) ;
i + + ;
}
return string . Join ( Environment . NewLine , parts ) ;
}
Sqlite3Statement Prepare ( )
{
var stmt = SQLite3 . Prepare2 ( _conn . Handle , CommandText ) ;
BindAll ( stmt ) ;
return stmt ;
}
void Finalize ( Sqlite3Statement stmt )
{
SQLite3 . Finalize ( stmt ) ;
}
void BindAll ( Sqlite3Statement stmt )
{
int nextIdx = 1 ;
foreach ( var b in _bindings )
{
if ( b . Name ! = null )
{
b . Index = SQLite3 . BindParameterIndex ( stmt , b . Name ) ;
}
else
{
b . Index = nextIdx + + ;
}
BindParameter ( stmt , b . Index , b . Value , _conn . StoreDateTimeAsTicks ) ;
}
}
internal static IntPtr NegativePointer = new IntPtr ( - 1 ) ;
internal static void BindParameter ( Sqlite3Statement stmt , int index , object value , bool storeDateTimeAsTicks )
{
if ( value = = null )
{
SQLite3 . BindNull ( stmt , index ) ;
}
else
{
if ( value is Int32 )
{
SQLite3 . BindInt ( stmt , index , ( int ) value ) ;
}
else if ( value is String )
{
SQLite3 . BindText ( stmt , index , ( string ) value , - 1 , NegativePointer ) ;
}
else if ( value is Byte | | value is UInt16 | | value is SByte | | value is Int16 )
{
SQLite3 . BindInt ( stmt , index , Convert . ToInt32 ( value ) ) ;
}
else if ( value is Boolean )
{
SQLite3 . BindInt ( stmt , index , ( bool ) value ? 1 : 0 ) ;
}
else if ( value is UInt32 | | value is Int64 )
{
SQLite3 . BindInt64 ( stmt , index , Convert . ToInt64 ( value ) ) ;
}
else if ( value is Single | | value is Double | | value is Decimal )
{
SQLite3 . BindDouble ( stmt , index , Convert . ToDouble ( value ) ) ;
}
else if ( value is TimeSpan )
{
SQLite3 . BindInt64 ( stmt , index , ( ( TimeSpan ) value ) . Ticks ) ;
}
else if ( value is DateTime )
{
if ( storeDateTimeAsTicks )
{
SQLite3 . BindInt64 ( stmt , index , ( ( DateTime ) value ) . Ticks ) ;
}
else
{
SQLite3 . BindText ( stmt , index , ( ( DateTime ) value ) . ToString ( "yyyy-MM-dd HH:mm:ss" ) , - 1 , NegativePointer ) ;
}
}
else if ( value is DateTimeOffset )
{
SQLite3 . BindInt64 ( stmt , index , ( ( DateTimeOffset ) value ) . UtcTicks ) ;
#if ! NETFX_CORE
}
else if ( value . GetType ( ) . IsEnum )
{
#else
} else if ( value . GetType ( ) . GetTypeInfo ( ) . IsEnum ) {
#endif
SQLite3 . BindInt ( stmt , index , Convert . ToInt32 ( value ) ) ;
}
else if ( value is byte [ ] )
{
SQLite3 . BindBlob ( stmt , index , ( byte [ ] ) value , ( ( byte [ ] ) value ) . Length , NegativePointer ) ;
}
else if ( value is Guid )
{
SQLite3 . BindText ( stmt , index , ( ( Guid ) value ) . ToString ( ) , 72 , NegativePointer ) ;
}
else
{
throw new NotSupportedException ( "Cannot store type: " + value . GetType ( ) ) ;
}
}
}
class Binding
{
public string Name { get ; set ; }
public object Value { get ; set ; }
public int Index { get ; set ; }
}
object ReadCol ( Sqlite3Statement stmt , int index , SQLite3 . ColType type , Type clrType )
{
if ( type = = SQLite3 . ColType . Null )
{
return null ;
}
else
{
if ( clrType = = typeof ( String ) )
{
return SQLite3 . ColumnString ( stmt , index ) ;
}
else if ( clrType = = typeof ( Int32 ) )
{
return ( int ) SQLite3 . ColumnInt ( stmt , index ) ;
}
else if ( clrType = = typeof ( Boolean ) )
{
return SQLite3 . ColumnInt ( stmt , index ) = = 1 ;
}
else if ( clrType = = typeof ( double ) )
{
return SQLite3 . ColumnDouble ( stmt , index ) ;
}
else if ( clrType = = typeof ( float ) )
{
return ( float ) SQLite3 . ColumnDouble ( stmt , index ) ;
}
else if ( clrType = = typeof ( TimeSpan ) )
{
return new TimeSpan ( SQLite3 . ColumnInt64 ( stmt , index ) ) ;
}
else if ( clrType = = typeof ( DateTime ) )
{
if ( _conn . StoreDateTimeAsTicks )
{
return new DateTime ( SQLite3 . ColumnInt64 ( stmt , index ) ) ;
}
else
{
var text = SQLite3 . ColumnString ( stmt , index ) ;
return DateTime . Parse ( text ) ;
}
}
else if ( clrType = = typeof ( DateTimeOffset ) )
{
return new DateTimeOffset ( SQLite3 . ColumnInt64 ( stmt , index ) , TimeSpan . Zero ) ;
#if ! NETFX_CORE
}
else if ( clrType . IsEnum )
{
#else
} else if ( clrType . GetTypeInfo ( ) . IsEnum ) {
#endif
return SQLite3 . ColumnInt ( stmt , index ) ;
}
else if ( clrType = = typeof ( Int64 ) )
{
return SQLite3 . ColumnInt64 ( stmt , index ) ;
}
else if ( clrType = = typeof ( UInt32 ) )
{
return ( uint ) SQLite3 . ColumnInt64 ( stmt , index ) ;
}
else if ( clrType = = typeof ( decimal ) )
{
return ( decimal ) SQLite3 . ColumnDouble ( stmt , index ) ;
}
else if ( clrType = = typeof ( Byte ) )
{
return ( byte ) SQLite3 . ColumnInt ( stmt , index ) ;
}
else if ( clrType = = typeof ( UInt16 ) )
{
return ( ushort ) SQLite3 . ColumnInt ( stmt , index ) ;
}
else if ( clrType = = typeof ( Int16 ) )
{
return ( short ) SQLite3 . ColumnInt ( stmt , index ) ;
}
else if ( clrType = = typeof ( sbyte ) )
{
return ( sbyte ) SQLite3 . ColumnInt ( stmt , index ) ;
}
else if ( clrType = = typeof ( byte [ ] ) )
{
return SQLite3 . ColumnByteArray ( stmt , index ) ;
}
else if ( clrType = = typeof ( Guid ) )
{
var text = SQLite3 . ColumnString ( stmt , index ) ;
return new Guid ( text ) ;
}
else
{
throw new NotSupportedException ( "Don't know how to read " + clrType ) ;
}
}
}
}
/// <summary>
/// Since the insert never changed, we only need to prepare once.
/// </summary>
public class PreparedSqlLiteInsertCommand : IDisposable
{
public bool Initialized { get ; set ; }
protected SQLiteConnection Connection { get ; set ; }
public string CommandText { get ; set ; }
protected Sqlite3Statement Statement { get ; set ; }
internal static readonly Sqlite3Statement NullStatement = default ( Sqlite3Statement ) ;
internal PreparedSqlLiteInsertCommand ( SQLiteConnection conn )
{
Connection = conn ;
}
public int ExecuteNonQuery ( object [ ] source )
{
if ( Connection . Trace )
{
Connection . InvokeTrace ( "Executing: " + CommandText ) ;
}
var r = SQLite3 . Result . OK ;
if ( ! Initialized )
{
Statement = Prepare ( ) ;
Initialized = true ;
}
//bind the values.
if ( source ! = null )
{
for ( int i = 0 ; i < source . Length ; i + + )
{
SQLiteCommand . BindParameter ( Statement , i + 1 , source [ i ] , Connection . StoreDateTimeAsTicks ) ;
}
}
r = SQLite3 . Step ( Statement ) ;
if ( r = = SQLite3 . Result . Done )
{
int rowsAffected = SQLite3 . Changes ( Connection . Handle ) ;
SQLite3 . Reset ( Statement ) ;
return rowsAffected ;
}
else if ( r = = SQLite3 . Result . Error )
{
string msg = SQLite3 . GetErrmsg ( Connection . Handle ) ;
SQLite3 . Reset ( Statement ) ;
throw SQLiteException . New ( r , msg ) ;
}
else if ( r = = SQLite3 . Result . Constraint & & SQLite3 . ExtendedErrCode ( Connection . Handle ) = = SQLite3 . ExtendedResult . ConstraintNotNull )
{
SQLite3 . Reset ( Statement ) ;
throw NotNullConstraintViolationException . New ( r , SQLite3 . GetErrmsg ( Connection . Handle ) ) ;
}
else
{
SQLite3 . Reset ( Statement ) ;
throw SQLiteException . New ( r , r . ToString ( ) ) ;
}
}
protected virtual Sqlite3Statement Prepare ( )
{
var stmt = SQLite3 . Prepare2 ( Connection . Handle , CommandText ) ;
return stmt ;
}
public void Dispose ( )
{
Dispose ( true ) ;
GC . SuppressFinalize ( this ) ;
}
private void Dispose ( bool disposing )
{
if ( Statement ! = NullStatement )
{
try
{
SQLite3 . Finalize ( Statement ) ;
}
finally
{
Statement = NullStatement ;
Connection = null ;
}
}
}
~ PreparedSqlLiteInsertCommand ( )
{
Dispose ( false ) ;
}
}
public abstract class BaseTableQuery
{
protected class Ordering
{
public string ColumnName { get ; set ; }
public bool Ascending { get ; set ; }
}
}
public class TableQuery < T > : BaseTableQuery , IEnumerable < T >
{
public SQLiteConnection Connection { get ; private set ; }
public TableMapping Table { get ; private set ; }
Expression _where ;
List < Ordering > _orderBys ;
int? _limit ;
int? _offset ;
BaseTableQuery _joinInner ;
Expression _joinInnerKeySelector ;
BaseTableQuery _joinOuter ;
Expression _joinOuterKeySelector ;
Expression _joinSelector ;
Expression _selector ;
TableQuery ( SQLiteConnection conn , TableMapping table )
{
Connection = conn ;
Table = table ;
}
public TableQuery ( SQLiteConnection conn )
{
Connection = conn ;
Table = Connection . GetMapping ( typeof ( T ) ) ;
}
public TableQuery < U > Clone < U > ( )
{
var q = new TableQuery < U > ( Connection , Table ) ;
q . _where = _where ;
q . _deferred = _deferred ;
if ( _orderBys ! = null )
{
q . _orderBys = new List < Ordering > ( _orderBys ) ;
}
q . _limit = _limit ;
q . _offset = _offset ;
q . _joinInner = _joinInner ;
q . _joinInnerKeySelector = _joinInnerKeySelector ;
q . _joinOuter = _joinOuter ;
q . _joinOuterKeySelector = _joinOuterKeySelector ;
q . _joinSelector = _joinSelector ;
q . _selector = _selector ;
return q ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ǽĿ<C7BD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <CDB8> մϴ<D5B4> .
/// </summary>
/// <param name="predExpr">
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <CDB8> ϴ<EFBFBD> <20> <> <EFBFBD> ǽ<EFBFBD> .
/// </param>
/// <returns>
/// <20> <> <EFBFBD> <EFBFBD> <CDB8> <EFBFBD> TableQuery <20> <> ü.
/// </returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> ǽ<EFBFBD> <C7BD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// var adults = db.Table<Person>()
2025-06-04 23:10:11 +09:00
/// .Where(p => p.Age >= 18);
///
/// // <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> ü<> ̴<EFBFBD>
2025-06-10 01:09:36 +09:00
/// var adultMales = db.Table<Person>()
2025-06-04 23:10:11 +09:00
/// .Where(p => p.Age >= 18)
/// .Where(p => p.Gender == "<22> <> <EFBFBD> <EFBFBD> ");
///
/// foreach (var person in adults) {
/// Console.WriteLine($"<22> <> <EFBFBD> <EFBFBD> : {person.Name}, {person.Age}<7D> <> ");
/// }
/// </code>
/// </example>
public TableQuery < T > Where ( Expression < Func < T , bool > > predExpr )
{
if ( predExpr . NodeType = = ExpressionType . Lambda )
{
var lambda = ( LambdaExpression ) predExpr ;
var pred = lambda . Body ;
var q = Clone < T > ( ) ;
q . AddWhere ( pred ) ;
return q ;
}
else
{
throw new NotSupportedException ( "Must be a predicate" ) ;
}
}
public TableQuery < T > Take ( int n )
{
var q = Clone < T > ( ) ;
q . _limit = n ;
return q ;
}
public TableQuery < T > Skip ( int n )
{
var q = Clone < T > ( ) ;
q . _offset = n ;
return q ;
}
public T ElementAt ( int index )
{
return Skip ( index ) . Take ( 1 ) . First ( ) ;
}
bool _deferred ;
public TableQuery < T > Deferred ( )
{
var q = Clone < T > ( ) ;
q . _deferred = true ;
return q ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <typeparam name="U"><3E> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> Ÿ<> <C5B8> </typeparam>
/// <param name="orderExpr"><3E> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> <20> <> </param>
/// <returns><3E> <> <EFBFBD> ĵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ü</returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> ̼<EFBFBD> <CCBC> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// var peopleByAge = db.Table<Person>().OrderBy(p => p.Age);
2025-06-04 23:10:11 +09:00
///
/// // <20> ̸<EFBFBD> <CCB8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// var peopleByName = db.Table<Person>().OrderBy(p => p.Name);
2025-06-04 23:10:11 +09:00
///
/// foreach (var person in peopleByAge) {
/// Console.WriteLine($"{person.Name}, {person.Age}<7D> <> ");
/// }
/// </code>
/// </example>
public TableQuery < T > OrderBy < U > ( Expression < Func < T , U > > orderExpr )
{
return AddOrderBy < U > ( orderExpr , true ) ;
}
/// <summary>
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̺<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> մϴ<D5B4> .
/// </summary>
/// <typeparam name="U"><3E> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> Ÿ<> <C5B8> </typeparam>
/// <param name="orderExpr"><3E> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> <20> <> </param>
/// <returns><3E> <> <EFBFBD> ĵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ü</returns>
/// <example>
/// <code>
/// // <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// var olderFirst = db.Table<Person>().OrderByDescending(p => p.Age);
2025-06-04 23:10:11 +09:00
///
/// // <20> ̸<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2025-06-10 01:09:36 +09:00
/// var reverseAlpha = db.Table<Person>().OrderByDescending(p => p.Name);
2025-06-04 23:10:11 +09:00
///
/// foreach (var person in olderFirst) {
/// Console.WriteLine($"{person.Name}, {person.Age}<7D> <> ");
/// }
/// </code>
/// </example>
public TableQuery < T > OrderByDescending < U > ( Expression < Func < T , U > > orderExpr )
{
return AddOrderBy < U > ( orderExpr , false ) ;
}
public TableQuery < T > ThenBy < U > ( Expression < Func < T , U > > orderExpr )
{
return AddOrderBy < U > ( orderExpr , true ) ;
}
public TableQuery < T > ThenByDescending < U > ( Expression < Func < T , U > > orderExpr )
{
return AddOrderBy < U > ( orderExpr , false ) ;
}
private TableQuery < T > AddOrderBy < U > ( Expression < Func < T , U > > orderExpr , bool asc )
{
if ( orderExpr . NodeType = = ExpressionType . Lambda )
{
var lambda = ( LambdaExpression ) orderExpr ;
MemberExpression mem = null ;
var unary = lambda . Body as UnaryExpression ;
if ( unary ! = null & & unary . NodeType = = ExpressionType . Convert )
{
mem = unary . Operand as MemberExpression ;
}
else
{
mem = lambda . Body as MemberExpression ;
}
if ( mem ! = null & & ( mem . Expression . NodeType = = ExpressionType . Parameter ) )
{
var q = Clone < T > ( ) ;
if ( q . _orderBys = = null )
{
q . _orderBys = new List < Ordering > ( ) ;
}
q . _orderBys . Add ( new Ordering
{
ColumnName = Table . FindColumnWithPropertyName ( mem . Member . Name ) . Name ,
Ascending = asc
} ) ;
return q ;
}
else
{
throw new NotSupportedException ( "Order By does not support: " + orderExpr ) ;
}
}
else
{
throw new NotSupportedException ( "Must be a predicate" ) ;
}
}
private void AddWhere ( Expression pred )
{
if ( _where = = null )
{
_where = pred ;
}
else
{
_where = Expression . AndAlso ( _where , pred ) ;
}
}
public TableQuery < TResult > Join < TInner , TKey , TResult > (
TableQuery < TInner > inner ,
Expression < Func < T , TKey > > outerKeySelector ,
Expression < Func < TInner , TKey > > innerKeySelector ,
Expression < Func < T , TInner , TResult > > resultSelector )
{
var q = new TableQuery < TResult > ( Connection , Connection . GetMapping ( typeof ( TResult ) ) )
{
_joinOuter = this ,
_joinOuterKeySelector = outerKeySelector ,
_joinInner = inner ,
_joinInnerKeySelector = innerKeySelector ,
_joinSelector = resultSelector ,
} ;
return q ;
}
public TableQuery < TResult > Select < TResult > ( Expression < Func < T , TResult > > selector )
{
var q = Clone < TResult > ( ) ;
q . _selector = selector ;
return q ;
}
private SQLiteCommand GenerateCommand ( string selectionList )
{
if ( _joinInner ! = null & & _joinOuter ! = null )
{
throw new NotSupportedException ( "Joins are not supported." ) ;
}
else
{
var cmdText = "select " + selectionList + " from \"" + Table . TableName + "\"" ;
var args = new List < object > ( ) ;
if ( _where ! = null )
{
var w = CompileExpr ( _where , args ) ;
cmdText + = " where " + w . CommandText ;
}
if ( ( _orderBys ! = null ) & & ( _orderBys . Count > 0 ) )
{
var t = string . Join ( ", " , _orderBys . Select ( o = > "\"" + o . ColumnName + "\"" + ( o . Ascending ? "" : " desc" ) ) . ToArray ( ) ) ;
cmdText + = " order by " + t ;
}
if ( _limit . HasValue )
{
cmdText + = " limit " + _limit . Value ;
}
if ( _offset . HasValue )
{
if ( ! _limit . HasValue )
{
cmdText + = " limit -1 " ;
}
cmdText + = " offset " + _offset . Value ;
}
return Connection . CreateCommand ( cmdText , args . ToArray ( ) ) ;
}
}
class CompileResult
{
public string CommandText { get ; set ; }
public object Value { get ; set ; }
}
private CompileResult CompileExpr ( Expression expr , List < object > queryArgs )
{
if ( expr = = null )
{
throw new NotSupportedException ( "Expression is NULL" ) ;
}
else if ( expr is BinaryExpression )
{
var bin = ( BinaryExpression ) expr ;
var leftr = CompileExpr ( bin . Left , queryArgs ) ;
var rightr = CompileExpr ( bin . Right , queryArgs ) ;
//If either side is a parameter and is null, then handle the other side specially (for "is null"/"is not null")
string text ;
if ( leftr . CommandText = = "?" & & leftr . Value = = null )
text = CompileNullBinaryExpression ( bin , rightr ) ;
else if ( rightr . CommandText = = "?" & & rightr . Value = = null )
text = CompileNullBinaryExpression ( bin , leftr ) ;
else
text = "(" + leftr . CommandText + " " + GetSqlName ( bin ) + " " + rightr . CommandText + ")" ;
return new CompileResult { CommandText = text } ;
}
else if ( expr . NodeType = = ExpressionType . Call )
{
var call = ( MethodCallExpression ) expr ;
var args = new CompileResult [ call . Arguments . Count ] ;
var obj = call . Object ! = null ? CompileExpr ( call . Object , queryArgs ) : null ;
for ( var i = 0 ; i < args . Length ; i + + )
{
args [ i ] = CompileExpr ( call . Arguments [ i ] , queryArgs ) ;
}
var sqlCall = "" ;
if ( call . Method . Name = = "Like" & & args . Length = = 2 )
{
sqlCall = "(" + args [ 0 ] . CommandText + " like " + args [ 1 ] . CommandText + ")" ;
}
else if ( call . Method . Name = = "Contains" & & args . Length = = 2 )
{
sqlCall = "(" + args [ 1 ] . CommandText + " in " + args [ 0 ] . CommandText + ")" ;
}
else if ( call . Method . Name = = "Contains" & & args . Length = = 1 )
{
if ( call . Object ! = null & & call . Object . Type = = typeof ( string ) )
{
sqlCall = "(" + obj . CommandText + " like ('%' || " + args [ 0 ] . CommandText + " || '%'))" ;
}
else
{
sqlCall = "(" + args [ 0 ] . CommandText + " in " + obj . CommandText + ")" ;
}
}
else if ( call . Method . Name = = "StartsWith" & & args . Length = = 1 )
{
sqlCall = "(" + obj . CommandText + " like (" + args [ 0 ] . CommandText + " || '%'))" ;
}
else if ( call . Method . Name = = "EndsWith" & & args . Length = = 1 )
{
sqlCall = "(" + obj . CommandText + " like ('%' || " + args [ 0 ] . CommandText + "))" ;
}
else if ( call . Method . Name = = "Equals" & & args . Length = = 1 )
{
sqlCall = "(" + obj . CommandText + " = (" + args [ 0 ] . CommandText + "))" ;
}
else if ( call . Method . Name = = "ToLower" )
{
sqlCall = "(lower(" + obj . CommandText + "))" ;
}
else if ( call . Method . Name = = "ToUpper" )
{
sqlCall = "(upper(" + obj . CommandText + "))" ;
}
else
{
sqlCall = call . Method . Name . ToLower ( ) + "(" + string . Join ( "," , args . Select ( a = > a . CommandText ) . ToArray ( ) ) + ")" ;
}
return new CompileResult { CommandText = sqlCall } ;
}
else if ( expr . NodeType = = ExpressionType . Constant )
{
var c = ( ConstantExpression ) expr ;
queryArgs . Add ( c . Value ) ;
return new CompileResult
{
CommandText = "?" ,
Value = c . Value
} ;
}
else if ( expr . NodeType = = ExpressionType . Convert )
{
var u = ( UnaryExpression ) expr ;
var ty = u . Type ;
var valr = CompileExpr ( u . Operand , queryArgs ) ;
return new CompileResult
{
CommandText = valr . CommandText ,
Value = valr . Value ! = null ? ConvertTo ( valr . Value , ty ) : null
} ;
}
else if ( expr . NodeType = = ExpressionType . Not )
{
var u = ( UnaryExpression ) expr ;
var ty = u . Type ;
var valr = CompileExpr ( u . Operand , queryArgs ) ;
return new CompileResult
{
CommandText = "NOT " + valr . CommandText ,
Value = valr . Value ! = null ? valr . Value : null
} ;
}
else if ( expr . NodeType = = ExpressionType . MemberAccess )
{
var mem = ( MemberExpression ) expr ;
if ( mem . Expression ! = null & & mem . Expression . NodeType = = ExpressionType . Parameter )
{
//
// This is a column of our table, output just the column name
// Need to translate it if that column name is mapped
//
var columnName = Table . FindColumnWithPropertyName ( mem . Member . Name ) . Name ;
return new CompileResult { CommandText = "\"" + columnName + "\"" } ;
}
else
{
object obj = null ;
if ( mem . Expression ! = null )
{
var r = CompileExpr ( mem . Expression , queryArgs ) ;
if ( r . Value = = null )
{
throw new NotSupportedException ( "Member access failed to compile expression" ) ;
}
if ( r . CommandText = = "?" )
{
queryArgs . RemoveAt ( queryArgs . Count - 1 ) ;
}
obj = r . Value ;
}
//
// Get the member value
//
object val = null ;
#if ! NETFX_CORE
if ( mem . Member . MemberType = = MemberTypes . Property )
{
#else
if ( mem . Member is PropertyInfo ) {
#endif
var m = ( PropertyInfo ) mem . Member ;
//val = m.GetValue (obj, null);
val = m . GetGetMethod ( ) . Invoke ( obj , null ) ;
#if ! NETFX_CORE
}
else if ( mem . Member . MemberType = = MemberTypes . Field )
{
#else
} else if ( mem . Member is FieldInfo ) {
#endif
#if SILVERLIGHT
val = Expression . Lambda ( expr ) . Compile ( ) . DynamicInvoke ( ) ;
#else
var m = ( FieldInfo ) mem . Member ;
val = m . GetValue ( obj ) ;
#endif
}
else
{
#if ! NETFX_CORE
throw new NotSupportedException ( "MemberExpr: " + mem . Member . MemberType ) ;
#else
throw new NotSupportedException ( "MemberExpr: " + mem . Member . DeclaringType ) ;
#endif
}
//
// Work special magic for enumerables
//
if ( val ! = null & & val is System . Collections . IEnumerable & & ! ( val is string ) & & ! ( val is System . Collections . Generic . IEnumerable < byte > ) )
{
var sb = new System . Text . StringBuilder ( ) ;
sb . Append ( "(" ) ;
var head = "" ;
foreach ( var a in ( System . Collections . IEnumerable ) val )
{
queryArgs . Add ( a ) ;
sb . Append ( head ) ;
sb . Append ( "?" ) ;
head = "," ;
}
sb . Append ( ")" ) ;
return new CompileResult
{
CommandText = sb . ToString ( ) ,
Value = val
} ;
}
else
{
queryArgs . Add ( val ) ;
return new CompileResult
{
CommandText = "?" ,
Value = val
} ;
}
}
}
throw new NotSupportedException ( "Cannot compile: " + expr . NodeType . ToString ( ) ) ;
}
static object ConvertTo ( object obj , Type t )
{
Type nut = Nullable . GetUnderlyingType ( t ) ;
if ( nut ! = null )
{
if ( obj = = null ) return null ;
return Convert . ChangeType ( obj , nut ) ;
}
else
{
return Convert . ChangeType ( obj , t ) ;
}
}
/// <summary>
/// Compiles a BinaryExpression where one of the parameters is null.
/// </summary>
/// <param name="parameter">The non-null parameter</param>
private string CompileNullBinaryExpression ( BinaryExpression expression , CompileResult parameter )
{
if ( expression . NodeType = = ExpressionType . Equal )
return "(" + parameter . CommandText + " is ?)" ;
else if ( expression . NodeType = = ExpressionType . NotEqual )
return "(" + parameter . CommandText + " is not ?)" ;
else
throw new NotSupportedException ( "Cannot compile Null-BinaryExpression with type " + expression . NodeType . ToString ( ) ) ;
}
string GetSqlName ( Expression expr )
{
var n = expr . NodeType ;
if ( n = = ExpressionType . GreaterThan )
return ">" ;
else if ( n = = ExpressionType . GreaterThanOrEqual )
{
return ">=" ;
}
else if ( n = = ExpressionType . LessThan )
{
return "<" ;
}
else if ( n = = ExpressionType . LessThanOrEqual )
{
return "<=" ;
}
else if ( n = = ExpressionType . And )
{
return "&" ;
}
else if ( n = = ExpressionType . AndAlso )
{
return "and" ;
}
else if ( n = = ExpressionType . Or )
{
return "|" ;
}
else if ( n = = ExpressionType . OrElse )
{
return "or" ;
}
else if ( n = = ExpressionType . Equal )
{
return "=" ;
}
else if ( n = = ExpressionType . NotEqual )
{
return "!=" ;
}
else
{
throw new NotSupportedException ( "Cannot get SQL for: " + n ) ;
}
}
public int Count ( )
{
return GenerateCommand ( "count(*)" ) . ExecuteScalar < int > ( ) ;
}
public int Count ( Expression < Func < T , bool > > predExpr )
{
return Where ( predExpr ) . Count ( ) ;
}
public IEnumerator < T > GetEnumerator ( )
{
if ( ! _deferred )
return GenerateCommand ( "*" ) . ExecuteQuery < T > ( ) . GetEnumerator ( ) ;
return GenerateCommand ( "*" ) . ExecuteDeferredQuery < T > ( ) . GetEnumerator ( ) ;
}
System . Collections . IEnumerator System . Collections . IEnumerable . GetEnumerator ( )
{
return GetEnumerator ( ) ;
}
public T First ( )
{
var query = Take ( 1 ) ;
return query . ToList < T > ( ) . First ( ) ;
}
public T FirstOrDefault ( )
{
var query = Take ( 1 ) ;
return query . ToList < T > ( ) . FirstOrDefault ( ) ;
}
}
public static class SQLite3
{
public enum Result : int
{
OK = 0 ,
Error = 1 ,
Internal = 2 ,
Perm = 3 ,
Abort = 4 ,
Busy = 5 ,
Locked = 6 ,
NoMem = 7 ,
ReadOnly = 8 ,
Interrupt = 9 ,
IOError = 10 ,
Corrupt = 11 ,
NotFound = 12 ,
Full = 13 ,
CannotOpen = 14 ,
LockErr = 15 ,
Empty = 16 ,
SchemaChngd = 17 ,
TooBig = 18 ,
Constraint = 19 ,
Mismatch = 20 ,
Misuse = 21 ,
NotImplementedLFS = 22 ,
AccessDenied = 23 ,
Format = 24 ,
Range = 25 ,
NonDBFile = 26 ,
Notice = 27 ,
Warning = 28 ,
Row = 100 ,
Done = 101
}
public enum ExtendedResult : int
{
IOErrorRead = ( Result . IOError | ( 1 < < 8 ) ) ,
IOErrorShortRead = ( Result . IOError | ( 2 < < 8 ) ) ,
IOErrorWrite = ( Result . IOError | ( 3 < < 8 ) ) ,
IOErrorFsync = ( Result . IOError | ( 4 < < 8 ) ) ,
IOErrorDirFSync = ( Result . IOError | ( 5 < < 8 ) ) ,
IOErrorTruncate = ( Result . IOError | ( 6 < < 8 ) ) ,
IOErrorFStat = ( Result . IOError | ( 7 < < 8 ) ) ,
IOErrorUnlock = ( Result . IOError | ( 8 < < 8 ) ) ,
IOErrorRdlock = ( Result . IOError | ( 9 < < 8 ) ) ,
IOErrorDelete = ( Result . IOError | ( 10 < < 8 ) ) ,
IOErrorBlocked = ( Result . IOError | ( 11 < < 8 ) ) ,
IOErrorNoMem = ( Result . IOError | ( 12 < < 8 ) ) ,
IOErrorAccess = ( Result . IOError | ( 13 < < 8 ) ) ,
IOErrorCheckReservedLock = ( Result . IOError | ( 14 < < 8 ) ) ,
IOErrorLock = ( Result . IOError | ( 15 < < 8 ) ) ,
IOErrorClose = ( Result . IOError | ( 16 < < 8 ) ) ,
IOErrorDirClose = ( Result . IOError | ( 17 < < 8 ) ) ,
IOErrorSHMOpen = ( Result . IOError | ( 18 < < 8 ) ) ,
IOErrorSHMSize = ( Result . IOError | ( 19 < < 8 ) ) ,
IOErrorSHMLock = ( Result . IOError | ( 20 < < 8 ) ) ,
IOErrorSHMMap = ( Result . IOError | ( 21 < < 8 ) ) ,
IOErrorSeek = ( Result . IOError | ( 22 < < 8 ) ) ,
IOErrorDeleteNoEnt = ( Result . IOError | ( 23 < < 8 ) ) ,
IOErrorMMap = ( Result . IOError | ( 24 < < 8 ) ) ,
LockedSharedcache = ( Result . Locked | ( 1 < < 8 ) ) ,
BusyRecovery = ( Result . Busy | ( 1 < < 8 ) ) ,
CannottOpenNoTempDir = ( Result . CannotOpen | ( 1 < < 8 ) ) ,
CannotOpenIsDir = ( Result . CannotOpen | ( 2 < < 8 ) ) ,
CannotOpenFullPath = ( Result . CannotOpen | ( 3 < < 8 ) ) ,
CorruptVTab = ( Result . Corrupt | ( 1 < < 8 ) ) ,
ReadonlyRecovery = ( Result . ReadOnly | ( 1 < < 8 ) ) ,
ReadonlyCannotLock = ( Result . ReadOnly | ( 2 < < 8 ) ) ,
ReadonlyRollback = ( Result . ReadOnly | ( 3 < < 8 ) ) ,
AbortRollback = ( Result . Abort | ( 2 < < 8 ) ) ,
ConstraintCheck = ( Result . Constraint | ( 1 < < 8 ) ) ,
ConstraintCommitHook = ( Result . Constraint | ( 2 < < 8 ) ) ,
ConstraintForeignKey = ( Result . Constraint | ( 3 < < 8 ) ) ,
ConstraintFunction = ( Result . Constraint | ( 4 < < 8 ) ) ,
ConstraintNotNull = ( Result . Constraint | ( 5 < < 8 ) ) ,
ConstraintPrimaryKey = ( Result . Constraint | ( 6 < < 8 ) ) ,
ConstraintTrigger = ( Result . Constraint | ( 7 < < 8 ) ) ,
ConstraintUnique = ( Result . Constraint | ( 8 < < 8 ) ) ,
ConstraintVTab = ( Result . Constraint | ( 9 < < 8 ) ) ,
NoticeRecoverWAL = ( Result . Notice | ( 1 < < 8 ) ) ,
NoticeRecoverRollback = ( Result . Notice | ( 2 < < 8 ) )
}
public enum ConfigOption : int
{
SingleThread = 1 ,
MultiThread = 2 ,
Serialized = 3
}
#if ! USE_CSHARP_SQLITE & & ! USE_WP8_NATIVE_SQLITE
[DllImport("sqlite3", EntryPoint = "sqlite3_open", CallingConvention = CallingConvention.Cdecl)]
public static extern Result Open ( [ MarshalAs ( UnmanagedType . LPStr ) ] string filename , out IntPtr db ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_open_v2", CallingConvention = CallingConvention.Cdecl)]
public static extern Result Open ( [ MarshalAs ( UnmanagedType . LPStr ) ] string filename , out IntPtr db , int flags , IntPtr zvfs ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_open_v2", CallingConvention = CallingConvention.Cdecl)]
public static extern Result Open ( byte [ ] filename , out IntPtr db , int flags , IntPtr zvfs ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_open16", CallingConvention = CallingConvention.Cdecl)]
public static extern Result Open16 ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string filename , out IntPtr db ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_enable_load_extension", CallingConvention = CallingConvention.Cdecl)]
public static extern Result EnableLoadExtension ( IntPtr db , int onoff ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_close", CallingConvention = CallingConvention.Cdecl)]
public static extern Result Close ( IntPtr db ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_initialize", CallingConvention = CallingConvention.Cdecl)]
public static extern Result Initialize ( ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_shutdown", CallingConvention = CallingConvention.Cdecl)]
public static extern Result Shutdown ( ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_config", CallingConvention = CallingConvention.Cdecl)]
public static extern Result Config ( ConfigOption option ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_win32_set_directory", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern int SetDirectory ( uint directoryType , string directoryPath ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_busy_timeout", CallingConvention = CallingConvention.Cdecl)]
public static extern Result BusyTimeout ( IntPtr db , int milliseconds ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_changes", CallingConvention = CallingConvention.Cdecl)]
public static extern int Changes ( IntPtr db ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_prepare_v2", CallingConvention = CallingConvention.Cdecl)]
public static extern Result Prepare2 ( IntPtr db , [ MarshalAs ( UnmanagedType . LPStr ) ] string sql , int numBytes , out IntPtr stmt , IntPtr pzTail ) ;
#if NETFX_CORE
[DllImport ("sqlite3", EntryPoint = "sqlite3_prepare_v2", CallingConvention = CallingConvention.Cdecl)]
public static extern Result Prepare2 ( IntPtr db , byte [ ] queryBytes , int numBytes , out IntPtr stmt , IntPtr pzTail ) ;
#endif
public static IntPtr Prepare2 ( IntPtr db , string query )
{
IntPtr stmt ;
#if NETFX_CORE
byte [ ] queryBytes = System . Text . UTF8Encoding . UTF8 . GetBytes ( query ) ;
var r = Prepare2 ( db , queryBytes , queryBytes . Length , out stmt , IntPtr . Zero ) ;
#else
var r = Prepare2 ( db , query , System . Text . UTF8Encoding . UTF8 . GetByteCount ( query ) , out stmt , IntPtr . Zero ) ;
#endif
if ( r ! = Result . OK )
{
throw SQLiteException . New ( r , GetErrmsg ( db ) ) ;
}
return stmt ;
}
[DllImport("sqlite3", EntryPoint = "sqlite3_step", CallingConvention = CallingConvention.Cdecl)]
public static extern Result Step ( IntPtr stmt ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_reset", CallingConvention = CallingConvention.Cdecl)]
public static extern Result Reset ( IntPtr stmt ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_finalize", CallingConvention = CallingConvention.Cdecl)]
public static extern Result Finalize ( IntPtr stmt ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_last_insert_rowid", CallingConvention = CallingConvention.Cdecl)]
public static extern long LastInsertRowid ( IntPtr db ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_errmsg16", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr Errmsg ( IntPtr db ) ;
public static string GetErrmsg ( IntPtr db )
{
return Marshal . PtrToStringUni ( Errmsg ( db ) ) ;
}
[DllImport("sqlite3", EntryPoint = "sqlite3_bind_parameter_index", CallingConvention = CallingConvention.Cdecl)]
public static extern int BindParameterIndex ( IntPtr stmt , [ MarshalAs ( UnmanagedType . LPStr ) ] string name ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_bind_null", CallingConvention = CallingConvention.Cdecl)]
public static extern int BindNull ( IntPtr stmt , int index ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_bind_int", CallingConvention = CallingConvention.Cdecl)]
public static extern int BindInt ( IntPtr stmt , int index , int val ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_bind_int64", CallingConvention = CallingConvention.Cdecl)]
public static extern int BindInt64 ( IntPtr stmt , int index , long val ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_bind_double", CallingConvention = CallingConvention.Cdecl)]
public static extern int BindDouble ( IntPtr stmt , int index , double val ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_bind_text16", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern int BindText ( IntPtr stmt , int index , [ MarshalAs ( UnmanagedType . LPWStr ) ] string val , int n , IntPtr free ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_bind_blob", CallingConvention = CallingConvention.Cdecl)]
public static extern int BindBlob ( IntPtr stmt , int index , byte [ ] val , int n , IntPtr free ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_column_count", CallingConvention = CallingConvention.Cdecl)]
public static extern int ColumnCount ( IntPtr stmt ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_column_name", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr ColumnName ( IntPtr stmt , int index ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_column_name16", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr ColumnName16Internal ( IntPtr stmt , int index ) ;
public static string ColumnName16 ( IntPtr stmt , int index )
{
return Marshal . PtrToStringUni ( ColumnName16Internal ( stmt , index ) ) ;
}
[DllImport("sqlite3", EntryPoint = "sqlite3_column_type", CallingConvention = CallingConvention.Cdecl)]
public static extern ColType ColumnType ( IntPtr stmt , int index ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_column_int", CallingConvention = CallingConvention.Cdecl)]
public static extern int ColumnInt ( IntPtr stmt , int index ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_column_int64", CallingConvention = CallingConvention.Cdecl)]
public static extern long ColumnInt64 ( IntPtr stmt , int index ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_column_double", CallingConvention = CallingConvention.Cdecl)]
public static extern double ColumnDouble ( IntPtr stmt , int index ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_column_text", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr ColumnText ( IntPtr stmt , int index ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_column_text16", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr ColumnText16 ( IntPtr stmt , int index ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_column_blob", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr ColumnBlob ( IntPtr stmt , int index ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_column_bytes", CallingConvention = CallingConvention.Cdecl)]
public static extern int ColumnBytes ( IntPtr stmt , int index ) ;
public static string ColumnString ( IntPtr stmt , int index )
{
return Marshal . PtrToStringUni ( SQLite3 . ColumnText16 ( stmt , index ) ) ;
}
public static byte [ ] ColumnByteArray ( IntPtr stmt , int index )
{
int length = ColumnBytes ( stmt , index ) ;
var result = new byte [ length ] ;
if ( length > 0 )
Marshal . Copy ( ColumnBlob ( stmt , index ) , result , 0 , length ) ;
return result ;
}
[DllImport("sqlite3", EntryPoint = "sqlite3_extended_errcode", CallingConvention = CallingConvention.Cdecl)]
public static extern ExtendedResult ExtendedErrCode ( IntPtr db ) ;
[DllImport("sqlite3", EntryPoint = "sqlite3_libversion_number", CallingConvention = CallingConvention.Cdecl)]
public static extern int LibVersionNumber ( ) ;
#else
public static Result Open ( string filename , out Sqlite3DatabaseHandle db )
{
return ( Result ) Sqlite3 . sqlite3_open ( filename , out db ) ;
}
public static Result Open ( string filename , out Sqlite3DatabaseHandle db , int flags , IntPtr zVfs )
{
#if USE_WP8_NATIVE_SQLITE
return ( Result ) Sqlite3 . sqlite3_open_v2 ( filename , out db , flags , "" ) ;
#else
return ( Result ) Sqlite3 . sqlite3_open_v2 ( filename , out db , flags , null ) ;
#endif
}
public static Result Close ( Sqlite3DatabaseHandle db )
{
return ( Result ) Sqlite3 . sqlite3_close ( db ) ;
}
public static Result BusyTimeout ( Sqlite3DatabaseHandle db , int milliseconds )
{
return ( Result ) Sqlite3 . sqlite3_busy_timeout ( db , milliseconds ) ;
}
public static int Changes ( Sqlite3DatabaseHandle db )
{
return Sqlite3 . sqlite3_changes ( db ) ;
}
public static Sqlite3Statement Prepare2 ( Sqlite3DatabaseHandle db , string query )
{
Sqlite3Statement stmt = default ( Sqlite3Statement ) ;
#if USE_WP8_NATIVE_SQLITE
var r = Sqlite3 . sqlite3_prepare_v2 ( db , query , out stmt ) ;
#else
stmt = new Sqlite3Statement ( ) ;
var r = Sqlite3 . sqlite3_prepare_v2 ( db , query , - 1 , ref stmt , 0 ) ;
#endif
if ( r ! = 0 )
{
throw SQLiteException . New ( ( Result ) r , GetErrmsg ( db ) ) ;
}
return stmt ;
}
public static Result Step ( Sqlite3Statement stmt )
{
return ( Result ) Sqlite3 . sqlite3_step ( stmt ) ;
}
public static Result Reset ( Sqlite3Statement stmt )
{
return ( Result ) Sqlite3 . sqlite3_reset ( stmt ) ;
}
public static Result Finalize ( Sqlite3Statement stmt )
{
return ( Result ) Sqlite3 . sqlite3_finalize ( stmt ) ;
}
public static long LastInsertRowid ( Sqlite3DatabaseHandle db )
{
return Sqlite3 . sqlite3_last_insert_rowid ( db ) ;
}
public static string GetErrmsg ( Sqlite3DatabaseHandle db )
{
return Sqlite3 . sqlite3_errmsg ( db ) ;
}
public static int BindParameterIndex ( Sqlite3Statement stmt , string name )
{
return Sqlite3 . sqlite3_bind_parameter_index ( stmt , name ) ;
}
public static int BindNull ( Sqlite3Statement stmt , int index )
{
return Sqlite3 . sqlite3_bind_null ( stmt , index ) ;
}
public static int BindInt ( Sqlite3Statement stmt , int index , int val )
{
return Sqlite3 . sqlite3_bind_int ( stmt , index , val ) ;
}
public static int BindInt64 ( Sqlite3Statement stmt , int index , long val )
{
return Sqlite3 . sqlite3_bind_int64 ( stmt , index , val ) ;
}
public static int BindDouble ( Sqlite3Statement stmt , int index , double val )
{
return Sqlite3 . sqlite3_bind_double ( stmt , index , val ) ;
}
public static int BindText ( Sqlite3Statement stmt , int index , string val , int n , IntPtr free )
{
#if USE_WP8_NATIVE_SQLITE
return Sqlite3 . sqlite3_bind_text ( stmt , index , val , n ) ;
#else
return Sqlite3 . sqlite3_bind_text ( stmt , index , val , n , null ) ;
#endif
}
public static int BindBlob ( Sqlite3Statement stmt , int index , byte [ ] val , int n , IntPtr free )
{
#if USE_WP8_NATIVE_SQLITE
return Sqlite3 . sqlite3_bind_blob ( stmt , index , val , n ) ;
#else
return Sqlite3 . sqlite3_bind_blob ( stmt , index , val , n , null ) ;
#endif
}
public static int ColumnCount ( Sqlite3Statement stmt )
{
return Sqlite3 . sqlite3_column_count ( stmt ) ;
}
public static string ColumnName ( Sqlite3Statement stmt , int index )
{
return Sqlite3 . sqlite3_column_name ( stmt , index ) ;
}
public static string ColumnName16 ( Sqlite3Statement stmt , int index )
{
return Sqlite3 . sqlite3_column_name ( stmt , index ) ;
}
public static ColType ColumnType ( Sqlite3Statement stmt , int index )
{
return ( ColType ) Sqlite3 . sqlite3_column_type ( stmt , index ) ;
}
public static int ColumnInt ( Sqlite3Statement stmt , int index )
{
return Sqlite3 . sqlite3_column_int ( stmt , index ) ;
}
public static long ColumnInt64 ( Sqlite3Statement stmt , int index )
{
return Sqlite3 . sqlite3_column_int64 ( stmt , index ) ;
}
public static double ColumnDouble ( Sqlite3Statement stmt , int index )
{
return Sqlite3 . sqlite3_column_double ( stmt , index ) ;
}
public static string ColumnText ( Sqlite3Statement stmt , int index )
{
return Sqlite3 . sqlite3_column_text ( stmt , index ) ;
}
public static string ColumnText16 ( Sqlite3Statement stmt , int index )
{
return Sqlite3 . sqlite3_column_text ( stmt , index ) ;
}
public static byte [ ] ColumnBlob ( Sqlite3Statement stmt , int index )
{
return Sqlite3 . sqlite3_column_blob ( stmt , index ) ;
}
public static int ColumnBytes ( Sqlite3Statement stmt , int index )
{
return Sqlite3 . sqlite3_column_bytes ( stmt , index ) ;
}
public static string ColumnString ( Sqlite3Statement stmt , int index )
{
return Sqlite3 . sqlite3_column_text ( stmt , index ) ;
}
public static byte [ ] ColumnByteArray ( Sqlite3Statement stmt , int index )
{
return ColumnBlob ( stmt , index ) ;
}
public static Result EnableLoadExtension ( Sqlite3DatabaseHandle db , int onoff )
{
return ( Result ) Sqlite3 . sqlite3_enable_load_extension ( db , onoff ) ;
}
public static ExtendedResult ExtendedErrCode ( Sqlite3DatabaseHandle db )
{
return ( ExtendedResult ) Sqlite3 . sqlite3_extended_errcode ( db ) ;
}
#endif
public enum ColType : int
{
Integer = 1 ,
Float = 2 ,
Text = 3 ,
Blob = 4 ,
Null = 5
}
}
}