Skip to content

Commit dde35bf

Browse files
committed
update nuget package. change mysql driver to MySqlConnector
1 parent 1afd281 commit dde35bf

File tree

9 files changed

+95
-76
lines changed

9 files changed

+95
-76
lines changed

Banana.AutoCode/Banana.AutoCode.VS2022.csproj

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@
3939
<ItemGroup>
4040
<PackageReference Include="DockPanelSuite" Version="3.1.0" />
4141
<PackageReference Include="DockPanelSuite.ThemeVS2015" Version="3.1.0" />
42-
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.7.0-1.final" />
43-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0-1.final" />
44-
<PackageReference Include="MySql.Data" Version="8.0.33" />
45-
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="3.21.100" />
46-
<PackageReference Include="System.CodeDom" Version="7.0.0" />
47-
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" />
42+
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.8.0" />
43+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" />
44+
<PackageReference Include="MySqlConnector" Version="2.3.3" />
45+
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="3.21.120" />
46+
<PackageReference Include="System.CodeDom" Version="8.0.0" />
47+
<PackageReference Include="System.Configuration.ConfigurationManager" Version="8.0.0" />
4848
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
49-
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.117" />
49+
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.118" />
5050
</ItemGroup>
5151

5252
<ItemGroup>

Banana.AutoCode/Config/db.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
<add name="oracle"
66
connectionString="Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.170)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=test)));User ID=test;Password=test;POOLING=True;CONNECTION TIMEOUT=30;"
77
providerName="Oracle.ManagedDataAccess.Client"/>
8-
<add name="mysql" connectionString="Data Source=localhost;Database=test;User Id=test;Password=123456;" providerName="MySql.Data.MySqlClient"/>
8+
<add name="mysql" connectionString="Data Source=localhost;Database=test;User Id=test;Password=123456;" providerName="MySqlConnector"/>
99
</connectionStrings>

Banana.AutoCode/Core/CustomHost.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public IList<string> StandardAssemblyReferences
8888
typeof(System.Linq.Enumerable).Assembly.Location,
8989
typeof(System.Data.SQLite.SQLiteConnection).Assembly.Location,
9090
typeof(Oracle.ManagedDataAccess.Client.OracleDbType).Assembly.Location,
91-
typeof(MySql.Data.MySqlClient.MySqlDbType).Assembly.Location,
91+
typeof(MySqlConnector.MySqlDbType).Assembly.Location,
9292
typeof(CustomHost).Assembly.Location
9393
};
9494
}
@@ -109,7 +109,7 @@ public IList<string> StandardImports
109109
"System.Text",
110110
"System.Data",
111111
"System.Data.SQLite",
112-
"MySql.Data.MySqlClient",
112+
"MySqlConnector",
113113
"Oracle.ManagedDataAccess.Client",
114114
"Banana.AutoCode",
115115
"Banana.AutoCode.DbSchema",

Banana.AutoCode/DbSchema/DbSchemaFactory.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public static DbSchemaBase Create(ConnectionStringSettings connSetting)
2020
case "Oracle.ManagedDataAccess.Client":
2121
return new OracleSchema(connSetting.Name);
2222
case "MySql.Data.MySqlClient":
23+
case "MySqlConnector":
2324
return new MySqlSchema(connSetting.Name);
2425
default:
2526
return new SqlServerSchema(connSetting.Name);

Banana.AutoCode/Forms/DbConnBuilderPanel.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using Banana.AutoCode.Resources;
2-
using MySql.Data.MySqlClient;
2+
using MySqlConnector;
33
using Oracle.ManagedDataAccess.Client;
44
using System;
55
using System.Configuration;
@@ -183,6 +183,7 @@ private ViewModel SettingToModel(ConnectionStringSettings connSetting)
183183
case "Oracle.ManagedDataAccess.Client":
184184
return OracleToModel(connSetting);
185185
case "MySql.Data.MySqlClient":
186+
case "MySqlConnector":
186187
return MySqlToModel(connSetting);
187188
default:
188189
return null;
@@ -262,7 +263,7 @@ private ConnectionStringSettings BuildSettings()
262263
break;
263264
case MySql:
264265
settings.ConnectionString = GetMySqlConnectionString(model);
265-
settings.ProviderName = "MySql.Data.MySqlClient";
266+
settings.ProviderName = "MySqlConnector";
266267
break;
267268
case Oracle:
268269
settings.ConnectionString = GetOracleConnectionString(model);

Banana.AutoCode/Program.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using Banana.AutoCode.Core;
2-
using MySql.Data.MySqlClient;
2+
using MySqlConnector;
33
using Oracle.ManagedDataAccess.Client;
44
using System;
55
using System.Data.Common;
@@ -21,7 +21,8 @@ static Program()
2121
#endif
2222
#if NET
2323
DbProviderFactories.RegisterFactory("System.Data.SQLite", SQLiteFactory.Instance);
24-
DbProviderFactories.RegisterFactory("MySql.Data.MySqlClient", MySqlClientFactory.Instance);
24+
//DbProviderFactories.RegisterFactory("MySql.Data.MySqlClient", MySqlClientFactory.Instance);
25+
DbProviderFactories.RegisterFactory("MySqlConnector", MySqlConnectorFactory.Instance);
2526
DbProviderFactories.RegisterFactory("Oracle.ManagedDataAccess.Client", OracleClientFactory.Instance);
2627
DbProviderFactories.RegisterFactory("System.Data.SqlClient", SqlClientFactory.Instance);
2728
#endif

Banana.AutoCode/Templates/MySQL/DataProvider.tt

Lines changed: 76 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
// <date><#= DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") #></date>
3030
// <auto-generated>
3131
// This code was generated by AutoCode.exe
32-
// Template Version:20230227
32+
// Template Version:20231225
3333
//
3434
// Changes to this file may cause incorrect behavior and will be lost if
3535
// the code is regenerated.
@@ -45,7 +45,7 @@ namespace Banana.DataAccess.Base
4545
using System.Linq;
4646
using System.Text;
4747
using Banana.Entity;
48-
using MySql.Data.MySqlClient;
48+
using MySqlConnector;
4949

5050
/// <summary>
5151
/// <#= String.Format("Data access base class for {0}Entity", table.DisplayName) #>
@@ -111,60 +111,64 @@ WHERE <#= table.PrimaryKeyColumns.Select(m => String.Format("{0}=@{0}", m.Name))
111111

112112
public virtual Boolean Exists(<#= table.PrimaryKeyColumns.Select(m => String.Format("{0} {1}", m.TypeName, m.Name)).Aggregate((a, b) => a + ", " + b) #>)
113113
{
114-
var cmd = DatabaseObject.GetSqlStringCommand(Exists_<#= table.DisplayName #>_Sql);
114+
using(var cmd = DatabaseObject.GetSqlStringCommand(Exists_<#= table.DisplayName #>_Sql))
115+
{
115116
<#
116117
foreach(var col in table.PrimaryKeyColumns)
117118
{
118119
#>
119-
cmd.Parameters.Add(new MySqlParameter("<#= col.PascalCase #>", MySqlDbType.<#= MySqlTypeConverter.AsMySqlDbType(col.RawType).ToString() #>) { Value = <#= col.Name #>, Direction = ParameterDirection.Input });
120+
cmd.Parameters.Add(new MySqlParameter("<#= col.PascalCase #>", MySqlDbType.<#= MySqlTypeConverter.AsMySqlDbType(col.RawType).ToString() #>) { Value = <#= col.Name #>, Direction = ParameterDirection.Input });
120121
<#
121122
}
122123
#>
123-
var result = DataContextObject.ExecuteScalar(cmd);
124+
var result = DataContextObject.ExecuteScalar(cmd);
124125

125-
return Convert.ToInt32(result) > 0;
126+
return Convert.ToInt32(result) > 0;
127+
}
126128
}
127129

128130
public virtual <#= entClassName #> Get(<#= table.PrimaryKeyColumns.Select(m => String.Format("{0} {1}", m.TypeName, m.Name)).Aggregate((a, b) => a + ", " + b) #>)
129131
{
130132
<#= entClassName #> result = null;
131-
var cmd = DatabaseObject.GetSqlStringCommand(Get_<#= table.DisplayName #>_Sql);
132-
133+
using(var cmd = DatabaseObject.GetSqlStringCommand(Get_<#= table.DisplayName #>_Sql))
134+
{
133135
<#
134136
foreach(var col in table.PrimaryKeyColumns)
135137
{
136138
#>
137-
cmd.Parameters.Add(new MySqlParameter("<#= col.Name #>", MySqlDbType.<#= MySqlTypeConverter.AsMySqlDbType(col.RawType).ToString() #>) { Value = <#= col.Name #>, Direction = ParameterDirection.Input });
139+
cmd.Parameters.Add(new MySqlParameter("<#= col.Name #>", MySqlDbType.<#= MySqlTypeConverter.AsMySqlDbType(col.RawType).ToString() #>) { Value = <#= col.Name #>, Direction = ParameterDirection.Input });
138140
<#
139141
}
140142
#>
141-
using(var reader = DataContextObject.ExecuteReader(cmd))
142-
{
143-
if(reader.Read())
143+
using(var reader = DataContextObject.ExecuteReader(cmd))
144144
{
145-
result = Fill(reader);
145+
if(reader.Read())
146+
{
147+
result = Fill(reader);
148+
}
146149
}
147-
}
148150

149-
return result;
151+
return result;
152+
}
150153
}
151154

152155
public virtual List<<#= entClassName #>> FindAll(String whereClause)
153156
{
154157
var result = new List<<#= entClassName #>>();
155158
var sql = Find_<#= table.DisplayName #>_Sql + whereClause;
156-
var cmd = DatabaseObject.GetSqlStringCommand(sql);
157-
158-
using(var reader = DataContextObject.ExecuteReader(cmd))
159+
using(var cmd = DatabaseObject.GetSqlStringCommand(sql))
159160
{
160-
while(reader.Read())
161+
using(var reader = DataContextObject.ExecuteReader(cmd))
161162
{
162-
var ent = Fill(reader);
163-
result.Add(ent);
163+
while(reader.Read())
164+
{
165+
var ent = Fill(reader);
166+
result.Add(ent);
167+
}
164168
}
165-
}
166169

167-
return result;
170+
return result;
171+
}
168172
}
169173

170174
public virtual Int32 Add(<#= entClassName #> entity)
@@ -174,20 +178,21 @@ WHERE <#= table.PrimaryKeyColumns.Select(m => String.Format("{0}=@{0}", m.Name))
174178
{
175179
#>
176180
var isAutoGetNewId = entity.<#= pkCol.PascalCase #> == default(<#= pkTypeName #>);
177-
var cmd = DatabaseObject.GetSqlStringCommand(Insert_<#= table.DisplayName #>_Sql) as MySqlCommand;
178-
179-
var pkParam = new MySqlParameter("<#= pkCol.Name #>", MySqlDbType.<#= MySqlTypeConverter.AsMySqlDbType(pkCol.RawType).ToString() #>) { Value = entity.<#= pkCol.PascalCase #>, Direction = ParameterDirection.Input };
180-
cmd.Parameters.Add(pkParam);
181-
var nonKeyParams = BuildParametersForNonKey(entity);
182-
cmd.Parameters.AddRange(nonKeyParams);
183-
184-
var execResult = DataContextObject.ExecuteNonQuery(cmd);
185-
if(isAutoGetNewId && cmd.LastInsertedId > 0)
181+
using(var cmd = DatabaseObject.GetSqlStringCommand(Insert_<#= table.DisplayName #>_Sql) as MySqlCommand)
186182
{
187-
entity.<#= pkCol.PascalCase #> = (<#= pkTypeName #>)cmd.LastInsertedId;
188-
}
183+
var pkParam = new MySqlParameter("<#= pkCol.Name #>", MySqlDbType.<#= MySqlTypeConverter.AsMySqlDbType(pkCol.RawType).ToString() #>) { Value = entity.<#= pkCol.PascalCase #>, Direction = ParameterDirection.Input };
184+
cmd.Parameters.Add(pkParam);
185+
var nonKeyParams = BuildParametersForNonKey(entity);
186+
cmd.Parameters.AddRange(nonKeyParams);
187+
188+
var execResult = DataContextObject.ExecuteNonQuery(cmd);
189+
if(isAutoGetNewId && cmd.LastInsertedId > 0)
190+
{
191+
entity.<#= pkCol.PascalCase #> = (<#= pkTypeName #>)cmd.LastInsertedId;
192+
}
189193

190-
return execResult;
194+
return execResult;
195+
}
191196
<#
192197
}
193198
else
@@ -203,10 +208,12 @@ WHERE <#= table.PrimaryKeyColumns.Select(m => String.Format("{0}=@{0}", m.Name))
203208

204209
public virtual Int32 Add(DbParameter[] @parameters)
205210
{
206-
var cmd = DatabaseObject.GetSqlStringCommand(Insert_<#= table.DisplayName #>_Sql) as MySqlCommand;
207-
cmd.Parameters.AddRange(@parameters);
211+
using(var cmd = DatabaseObject.GetSqlStringCommand(Insert_<#= table.DisplayName #>_Sql) as MySqlCommand)
212+
{
213+
cmd.Parameters.AddRange(@parameters);
208214

209-
return DataContextObject.ExecuteNonQuery(cmd);
215+
return DataContextObject.ExecuteNonQuery(cmd);
216+
}
210217
}
211218

212219
public virtual Int32 Add(IEnumerable<<#= entClassName #>> list)
@@ -226,11 +233,13 @@ WHERE <#= table.PrimaryKeyColumns.Select(m => String.Format("{0}=@{0}", m.Name))
226233
index++;
227234
}
228235
var sql = InsertIntoClause + string.Join(",", valueClauses) + ";";
229-
var cmd = DatabaseObject.GetSqlStringCommand(sql) as MySqlCommand;
230-
var @parameters = BuildParameters(list);
231-
cmd.Parameters.AddRange(@parameters);
236+
using(var cmd = DatabaseObject.GetSqlStringCommand(sql) as MySqlCommand)
237+
{
238+
var @parameters = BuildParameters(list);
239+
cmd.Parameters.AddRange(@parameters);
232240

233-
return DataContextObject.ExecuteNonQuery(cmd);
241+
return DataContextObject.ExecuteNonQuery(cmd);
242+
}
234243
}
235244

236245
public virtual Int32 Update(<#= entClassName #> entity)
@@ -242,10 +251,12 @@ WHERE <#= table.PrimaryKeyColumns.Select(m => String.Format("{0}=@{0}", m.Name))
242251

243252
public virtual Int32 Update(DbParameter[] @parameters)
244253
{
245-
var cmd = DatabaseObject.GetSqlStringCommand(Update_<#= table.DisplayName #>_Sql) as MySqlCommand;
246-
cmd.Parameters.AddRange(@parameters);
254+
using(var cmd = DatabaseObject.GetSqlStringCommand(Update_<#= table.DisplayName #>_Sql) as MySqlCommand)
255+
{
256+
cmd.Parameters.AddRange(@parameters);
247257

248-
return DataContextObject.ExecuteNonQuery(cmd);
258+
return DataContextObject.ExecuteNonQuery(cmd);
259+
}
249260
}
250261

251262
public virtual Int32 Save(<#= entClassName #> entity)
@@ -268,10 +279,12 @@ WHERE <#= table.PrimaryKeyColumns.Select(m => String.Format("{0}=@{0}", m.Name))
268279

269280
public virtual Int32 Save(DbParameter[] @parameters)
270281
{
271-
var cmd = DatabaseObject.GetSqlStringCommand(Save_<#= table.DisplayName #>_Sql) as MySqlCommand;
272-
cmd.Parameters.AddRange(@parameters);
282+
using(var cmd = DatabaseObject.GetSqlStringCommand(Save_<#= table.DisplayName #>_Sql) as MySqlCommand)
283+
{
284+
cmd.Parameters.AddRange(@parameters);
273285

274-
return DataContextObject.ExecuteNonQuery(cmd);
286+
return DataContextObject.ExecuteNonQuery(cmd);
287+
}
275288
}
276289

277290
public virtual Int32 Delete(<#= entClassName #> entity)
@@ -283,26 +296,29 @@ WHERE <#= table.PrimaryKeyColumns.Select(m => String.Format("{0}=@{0}", m.Name))
283296

284297
public virtual Int32 Delete(<#= table.PrimaryKeyColumns.Select(m => String.Format("{0} {1}", m.TypeName, m.Name)).Aggregate((a, b) => a + ", " + b) #>)
285298
{
286-
var cmd = DatabaseObject.GetSqlStringCommand(Delete_<#= table.DisplayName #>_Sql);
287-
299+
using(var cmd = DatabaseObject.GetSqlStringCommand(Delete_<#= table.DisplayName #>_Sql))
300+
{
288301
<#
289302
foreach(var col in table.PrimaryKeyColumns)
290303
{
291304
#>
292-
cmd.Parameters.Add(new MySqlParameter("<#= col.Name #>", MySqlDbType.<#= MySqlTypeConverter.AsMySqlDbType(col.RawType).ToString() #>) { Value = <#= col.Name #>, Direction = ParameterDirection.Input });
305+
cmd.Parameters.Add(new MySqlParameter("<#= col.Name #>", MySqlDbType.<#= MySqlTypeConverter.AsMySqlDbType(col.RawType).ToString() #>) { Value = <#= col.Name #>, Direction = ParameterDirection.Input });
293306
<#
294307
}
295308
#>
296309

297-
return DataContextObject.ExecuteNonQuery(cmd);
310+
return DataContextObject.ExecuteNonQuery(cmd);
311+
}
298312
}
299313

300314
public virtual Int32 Delete(DbParameter[] @parameters)
301315
{
302-
var cmd = DatabaseObject.GetSqlStringCommand(Delete_<#= table.DisplayName #>_Sql) as MySqlCommand;
303-
cmd.Parameters.AddRange(@parameters);
316+
using(var cmd = DatabaseObject.GetSqlStringCommand(Delete_<#= table.DisplayName #>_Sql) as MySqlCommand)
317+
{
318+
cmd.Parameters.AddRange(@parameters);
304319

305-
return DataContextObject.ExecuteNonQuery(cmd);
320+
return DataContextObject.ExecuteNonQuery(cmd);
321+
}
306322
}
307323

308324
#region Build Parameters
@@ -319,7 +335,7 @@ WHERE <#= table.PrimaryKeyColumns.Select(m => String.Format("{0}=@{0}", m.Name))
319335
for (int i = 0; i < table.Columns.Count; i++)
320336
{
321337
var col = table.Columns[i];
322-
var paraDirection = col.IsPrimaryKey ? "ParameterDirection.InputOutput" : "ParameterDirection.Input";
338+
var paraDirection = col.IsPrimaryKey ? "ParameterDirection.Input" : "ParameterDirection.Input";
323339
#>
324340
@paramList[<#= i #>] = new MySqlParameter("<#= col.Name #>", MySqlDbType.<#= MySqlTypeConverter.AsMySqlDbType(col.RawType).ToString() #>) { Value = entity.<#= col.PascalCase #>, Direction = <#= paraDirection #> };
325341
<#
@@ -343,7 +359,7 @@ WHERE <#= table.PrimaryKeyColumns.Select(m => String.Format("{0}=@{0}", m.Name))
343359
<#
344360
foreach(var col in table.Columns)
345361
{
346-
var paraDirection = col.IsPrimaryKey ? "ParameterDirection.InputOutput" : "ParameterDirection.Input";
362+
var paraDirection = col.IsPrimaryKey ? "ParameterDirection.Input" : "ParameterDirection.Input";
347363
#>
348364
@paramList.Add(new MySqlParameter($"<#= col.Name #>_{index}", MySqlDbType.<#= MySqlTypeConverter.AsMySqlDbType(col.RawType).ToString() #>) { Value = entity.<#= col.PascalCase #>, Direction = <#= paraDirection #> });
349365
<#
@@ -363,7 +379,7 @@ WHERE <#= table.PrimaryKeyColumns.Select(m => String.Format("{0}=@{0}", m.Name))
363379
foreach(var col in table.PrimaryKeyColumns)
364380
{
365381
#>
366-
@paramList[<#= index++ #>] = new MySqlParameter("<#= col.Name #>", MySqlDbType.<#= MySqlTypeConverter.AsMySqlDbType(col.RawType).ToString() #>) { Value = entity.<#= col.PascalCase #>, Direction = ParameterDirection.InputOutput };
382+
@paramList[<#= index++ #>] = new MySqlParameter("<#= col.Name #>", MySqlDbType.<#= MySqlTypeConverter.AsMySqlDbType(col.RawType).ToString() #>) { Value = entity.<#= col.PascalCase #>, Direction = ParameterDirection.Input };
367383
<#
368384
}
369385
#>
@@ -385,7 +401,7 @@ WHERE <#= table.PrimaryKeyColumns.Select(m => String.Format("{0}=@{0}", m.Name))
385401
foreach(var col in table.PrimaryKeyColumns)
386402
{
387403
#>
388-
@paramList.Add(new MySqlParameter($"<#= col.Name #>_{index}", MySqlDbType.<#= MySqlTypeConverter.AsMySqlDbType(col.RawType).ToString() #>) { Value = entity.<#= col.PascalCase #>, Direction = ParameterDirection.InputOutput });
404+
@paramList.Add(new MySqlParameter($"<#= col.Name #>_{index}", MySqlDbType.<#= MySqlTypeConverter.AsMySqlDbType(col.RawType).ToString() #>) { Value = entity.<#= col.PascalCase #>, Direction = ParameterDirection.Input });
389405
<#
390406
}
391407
#>
@@ -501,7 +517,7 @@ using System.Linq;
501517
using System.Text;
502518
using Banana.DataAccess.Base;
503519
using Banana.Entity;
504-
using MySql.Data.MySqlClient;
520+
using MySqlConnector;
505521

506522
namespace Banana.DataAccess
507523
{

Banana.AutoCode/Templates/MySqlTypeConverter.ttinclude

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#><#@ import namespace="System.IO"
66
#><#@ import namespace="System.Text"
77
#><#@ import namespace="Microsoft.VisualStudio.TextTemplating"
8-
#><#@ import namespace="MySql.Data.MySqlClient"
8+
#><#@ import namespace="MySqlConnector"
99
#><#@ import namespace="Banana.AutoCode.DbSchema"
1010
#><#+
1111
public class MySqlTypeConverter

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@
1717
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
1818
</PropertyGroup>
1919
<ItemGroup>
20-
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All"/>
20+
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All"/>
2121
</ItemGroup>
2222
</Project>

0 commit comments

Comments
 (0)