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())
94 using (IResultSet resultSet = stmt.ExecuteQuery(sql))
96 IRecord record = resultSet?.FirstOrDefault();
99 RecordChangedEventArgs ev = new RecordChangedEventArgs(operationType, db_name, table_name, record);
100 _recordChanged?.Invoke(this, ev);
105 internal IntPtr GetHandle()
110 public void Open(Uri uri)
115 if (uri.Scheme != "tdbc")
116 throw new ArgumentException("Wrong scheme:" + uri.Scheme);
118 if (uri.Host != "localhost")
119 throw new ArgumentException("Host should be 'localhost':" + uri.Host);
121 string query = uri.Query;
122 var queryDictionary = System.Web.HttpUtility.ParseQueryString(query);
123 int mode = (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_READWRITE |
124 (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_CREATE;
126 if (queryDictionary.Get("mode") == "ro")
128 mode = (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_READONLY;
130 else if (queryDictionary.Get("mode") == "rw")
132 mode = (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_READWRITE;
134 else if (queryDictionary.Get("mode") == "rwc")
136 mode = (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_READWRITE |
137 (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_CREATE;
139 else if (queryDictionary.Get("mode") == "memory")
141 mode = (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_MEMORY;
144 if (queryDictionary.Get("cache") == "shared")
146 mode |= (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_SHAREDCACHE;
148 else if (queryDictionary.Get("cache") == "private")
150 mode |= (int)Interop.Sqlite.OpenParameter.SQLITE_OPEN_PRIVATECACHE;
153 int ret = Interop.Sqlite.OpenV2(uri.LocalPath, out _db, mode, IntPtr.Zero);
154 if (ret != (int)Interop.Sqlite.ResultCode.SQLITE_OK)
155 throw new InvalidOperationException("code:" + ret);
157 Interop.Sqlite.UpdateHook(_db, UpdateHookCallback, IntPtr.Zero);
161 public IStatement CreateStatement()
164 throw new InvalidOperationException("Not opened");
166 return new Statement(this);
174 protected virtual void Dispose(bool disposing)
184 disposedValue = true;
190 Dispose(disposing: false);
193 public void Dispose()
195 Dispose(disposing: true);
196 GC.SuppressFinalize(this);