2 * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 using System.ComponentModel;
21 namespace Tizen.Data.Tdbc.Driver.Sqlite
23 [EditorBrowsable(EditorBrowsableState.Never)]
24 internal class Connection : IConnection
28 private bool disposedValue;
29 private readonly object _lock = new object();
30 private EventHandler<RecordChangedEventArgs> _recordChanged;
35 Interop.Sqlite.Init();
42 public event EventHandler<RecordChangedEventArgs> RecordChanged
48 _recordChanged += value;
56 _recordChanged -= value;
61 public void Open(String openString)
63 Open(new Uri(openString));
70 Interop.Sqlite.UpdateHook(_db, null, IntPtr.Zero);
71 Interop.Sqlite.Close(_db);
76 private void UpdateHookCallback(IntPtr data, int action, string db_name, string table_name, long rowid)
78 OperationType operationType = OperationType.None;
79 switch (((Interop.Sqlite.UpdateHookAction)action))
81 case Interop.Sqlite.UpdateHookAction.SQLITE_UPDATE:
82 operationType = OperationType.Update;
84 case Interop.Sqlite.UpdateHookAction.SQLITE_INSERT:
85 operationType = OperationType.Insert;
87 case Interop.Sqlite.UpdateHookAction.SQLITE_DELETE:
88 operationType = OperationType.Delete;
92 Sql sql = new Sql(string.Format("SELECT * from {0} WHERE rowid = {1}", table_name, rowid));
93 using (IStatement stmt = CreateStatement())
95 IRecord record = (operationType != OperationType.Delete ? stmt.ExecuteQuery(sql).FirstOrDefault() : null);
96 RecordChangedEventArgs ev = new RecordChangedEventArgs(operationType, db_name, table_name, record);
97 _recordChanged?.Invoke(this, ev);
101 internal IntPtr GetHandle()
106 public void Open(Uri uri)
111 if (uri.Scheme != "tdbc")
112 throw new ArgumentException("Wrong scheme:" + uri.Scheme);
114 if (uri.Host != "localhost")
115 throw new ArgumentException("Host should be 'localhost':" + uri.Host);
117 string query = uri.Query;
118 var queryDictionary = System.Web.HttpUtility.ParseQueryString(query);
119 int mode = (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_READWRITE |
120 (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_CREATE;
122 if (queryDictionary.Get("mode") == "ro")
124 mode = (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_READONLY;
126 else if (queryDictionary.Get("mode") == "rw")
128 mode = (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_READWRITE;
130 else if (queryDictionary.Get("mode") == "rwc")
132 mode = (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_READWRITE |
133 (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_CREATE;
135 else if (queryDictionary.Get("mode") == "memory")
137 mode = (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_MEMORY;
140 if (queryDictionary.Get("cache") == "shared")
142 mode |= (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_SHAREDCACHE;
144 else if (queryDictionary.Get("cache") == "private")
146 mode |= (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_PRIVATECACHE;
149 int ret = Interop.Sqlite.OpenV2(uri.LocalPath, out _db, mode, IntPtr.Zero);
150 if (ret != (int)Interop.Sqlite.ResultCode.SQLITE_OK)
151 throw new InvalidOperationException("code:" + ret);
153 Interop.Sqlite.UpdateHook(_db, UpdateHookCallback, IntPtr.Zero);
157 public IStatement CreateStatement()
160 throw new InvalidOperationException("Not opened");
162 return new Statement(this);
170 protected virtual void Dispose(bool disposing)
180 disposedValue = true;
186 Dispose(disposing: false);
189 public void Dispose()
191 Dispose(disposing: true);
192 GC.SuppressFinalize(this);