C# SQLite FTS5 Table and Triger creation - c#

I am creating a virtual table with sqlite fts5 and I am having the following error message: SQL Logic error no such module: FTS5. Below is my code:
Using Package manager in VS 2017 I have already download SQLite and SQLite FTS5.
private static void CreateReport()
{
try
{
using (SQLiteConnection sqliteConnection = new SQLiteConnection(DataSources.LocalConnectionString()))
{
sqliteConnection.Open();
sqliteConnection.EnableExtensions(true);
string commandText = "CREATE TABLE IF NOT EXISTS JReport(JRId INTEGER PRIMARY KEY, IDId INTEGER, CaseId INTEGER, BoxName TEXT, JRText TEXT, JRFormatted TEXT)";
string commandText1 = "CREATE VIRTUAL TABLE IF NOT EXISTS DReport USING FTS5(JRId, CaseId, BoxName, CONTENT = 'JReport', CONTENT_ROWID = 'JRId')";
string commandText2 = "CREATE TRIGGER DocRepo AFTER INSERT ON JReport BEGIN INSERT INTO DReport(RowId, JRId, CaseId, BoxName) VALUES(NEW.JRId, NEW.CaseId, NEW.BoxName) END";
using (SQLiteCommand sqliteCommand = new SQLiteCommand(commandText, sqliteConnection))
{
sqliteCommand.ExecuteNonQuery();
sqliteCommand.Dispose();
}
using (SQLiteCommand sqliteCommand = new SQLiteCommand(commandText1, sqliteConnection))
{
sqliteCommand.ExecuteNonQuery();
sqliteCommand.Dispose();
}
using (SQLiteCommand sqliteCommand = new SQLiteCommand(commandText2, sqliteConnection))
{
sqliteCommand.ExecuteNonQuery();
sqliteCommand.Dispose();
}
sqliteConnection.Close();
}
}
catch (Exception ex)
{
MessageBoxEx.Show("An error has occurred while creating the Report table, the original error is: " +
ex.Message, "Report", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

SQL Logic error no such module: FTS5.
Just like the error message says, your sqlite3 library doesn't have the FTS5 module. It probably wasn't configured to include it as a built in one when the library was built, as it's not enabled by default. It might have been made available as a dynamically loadable module by whoever did configure and build the library you're using. Or not.
Personally, I just always include a copy of sqlite3.c in any program I'm using that uses it to avoid relying on an external dependency and so you can make sure you're always using a version with all the features you want to use present. Dunno what you'd have to do in C# to use your own local instance, but I'm sure there's a way.
Instructions for building FTS5 into sqlite3 or as a loadable module.

Related

Connect Azure SQL Database to .NET Project

I have built a web api using dotnet and this is my first time using Azure (or any other cloud platform) to host web applications. I've used EntityFramework and MySQL database with to build my project.
I used DbConnectionString = "Server=localhost;Database=hms;Uid='{root-user}';Pwd={pw};" as the connection string of my SQL Database and now I'm wondering how can I connect it with the Azure SQL Database I have created. I added my IP address in firewall access in the Azure server and tried changing the connection string as DbConnectionString = "Server=server.database.windows.net:1433;Database=hms;Uid='{root-user}';Pwd={pw};" but it gives an error An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding 'EnableRetryOnFailure()' to the 'UseMySql' call. when I'm trying to update the database after adding migrations.
I'd like to know what I have done wrong or what else I need to do in order to get this running. tyia.
I have created an Azure SQL database with one table.
Table is having data as below
3.Created Console application using C#.
Added Package Microsoft.Data.SqlClient to the Project.
Added following code in Program.cs file,
[Taking reference from here](https://learn.microsoft.com/en-us/azure/azure-sql/database/connect-query-dotnet-visual-studio?view=azuresql), I created a replica of the program.cs file as shown:
using System;
using Microsoft.Data.SqlClient;
using System.Text;
namespace sqltest
{
class Program
{
static void Main(string[] args)
{
try
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder.DataSource = "yourservername.database.windows.net";
builder.UserID = "your_username";
builder.Password = "your_password";
builder.InitialCatalog = "your_database";
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
{
Console.WriteLine("\nQuery data example:");
Console.WriteLine("=========================================\n");
//String sql = "SELECT * FROM dbo.Persons";
String sql = "SELECT LastName, FirstName FROM dbo.Persons";
using (SqlCommand command = new SqlCommand(sql, connection))
{
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine("{0} {1}", reader.GetString(0), reader.GetString(1));
}
}
}
}
}
catch (SqlException e)
{
Console.WriteLine(e.ToString());
}
Console.ReadLine();
}
}
}
6.Using above code, I am connecting to Azure SQL and retrieving data from database.
Run the application and getting data from Azure Sql data base as shown below,
Reference links:
https://learn.microsoft.com/en-us/visualstudio/azure/azure-sql-database-add-connected-service?view=vs-2022

C# - SQLite throwing "database is not open" error when adding table

I'm writing an application using C# and System.Data.SQLite (the library from https://system.data.sqlite.org) and I feel like I'm beating my head against a wall. My unit tests on my larger chunks of code are randomly throwing exceptions, so in preparation for asking a question here, I started a new project with as small a chunk of code as I can. This chunk of code, which creates a new sqlite file and then adds a table to it, keeps throwing a Database is not open error whenever it attempts to add the table.
Looking at the similar questions on Stack Overflow, many of them are regarding using SQLite with Android, which is not the case here.
In my research, I've seen that I want to keep the connection open only for as long as I need it, but as you can see from the code sample, I'm using using to isolate the connection and command right next to each other, but I'm still having problems.
There's probably something obvious I'm doing wrong, but I'm at a loss to figure out what it is.
Thanks!
using System.Data.SQLite;
namespace SmallCode {
class Program {
private const string DB_NAME = "Test.sqlite";
private const string DB_CONN_STRING = "Data Source=" + DB_NAME + ";Version=3;";
static void Main(string[] args) {
Program p = new Program();
SQLiteConnection.CreateFile(DB_NAME);
using (SQLiteConnection c = new SQLiteConnection(DB_CONN_STRING)) {
string sqlCreateTableAccount = "CREATE TABLE ACCOUNT (ID INTEGER PRIMARY KEY, NAME TEXT NOT NULL);";
using (SQLiteCommand cmd = new SQLiteCommand(sqlCreateTableAccount, c)) {
// EXCEPTION THROWN ON NEXT LINE
cmd.ExecuteNonQuery();
}
}
}
}
}
You still need to .Open the connection...
using (SQLiteConnection c = new SQLiteConnection(DB_CONN_STRING)) {
c.Open(); //<------ ADD THIS LINE
string sqlCreateTableAccount = "CREATE TABLE ACCOUNT (ID INTEGER PRIMARY KEY, NAME TEXT NOT NULL);";
using (SQLiteCommand cmd = new SQLiteCommand(sqlCreateTableAccount, c)) {
// EXCEPTION THROWN ON NEXT LINE
cmd.ExecuteNonQuery();
}
}
Creating the connection with using doesn't automatically open the connection, it just creates it. You don't need to explicitly .Close() it at the end though, it will be closed when the using disposes it.

Install database script in C #

We created a C # program with entity framework
Now I'm having trouble making the setup, because if this program is installed on another system it will be difficult to miss the database.
This program automatically installs sql server engine. Now my problem is the installation of the database.
I would like a code to check when installing whether or not there is a database on the engine, if not, install a script file that our database is installed on.
Sounds like you want a Database Initialization Stategy and I'd recommend this one to meet your requirements:
CreateDatabaseIfNotExists: This is default initializer. As the name suggests, it will create the database if none exists as per the configuration. However, if you change the model class and then run the application with this initializer, then it will throw an exception.
The page I linked also includes an example of how to implement the strategy:
public class SchoolDBContext: DbContext
{
public SchoolDBContext(): base("SchoolDBConnectionString")
{
Database.SetInitializer<SchoolDBContext>(new CreateDatabaseIfNotExists<SchoolDBContext>());
//Database.SetInitializer<SchoolDBContext>(new DropCreateDatabaseIfModelChanges<SchoolDBContext>());
//Database.SetInitializer<SchoolDBContext>(new DropCreateDatabaseAlways<SchoolDBContext>());
//Database.SetInitializer<SchoolDBContext>(new SchoolDBInitializer());
}
public DbSet<Student> Students { get; set; }
public DbSet<Standard> Standards { get; set; }
}
If you are using code first migrations, you could generate the requiered sql-scripts. I believe you already have the scripts to run, so that won't be a problem.
If Initializers won't do the trick, You could take a look at custom actions.
You can then run a program with the permissions of the system/user running the setup to check of if the database (or server) exists. And if not create it.
Assuming you are creating a msi setup take a look here.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa368066(v=vs.85).aspx
I used sp_attach_db for attach database.
But he tells me that Attach the database successfully
But something is not attached to SQL Server
When I run two runs, the program says that The database is available
or
(Database 'TellDB' already exists. Choose a different database name.
Changed database context to 'master'.)
try
{
SqlConnection con = new SqlConnection();
con.ConnectionString = #"Data Source=(LocalDB)\MSSQLLocalDB;Initial Catalog=master;Integrated Security=True;";
con.Open();
string str = "USE master;" +
"EXEC sp_attach_db #dbname = N'TellDB' , " +
" #filename1 = N'" + System.Environment.CurrentDirectory + "\\Data\\TellDB.mdf'," +
"#filename2 = N'" + System.Environment.CurrentDirectory + "\\Data\\TellDB_log.ldf'";
SqlCommand cmd = new SqlCommand(str, con);
cmd.ExecuteNonQuery();
con.Close();
MessageBox.Show("Attach the database successfully");
}
catch (Exception x)
{
if (x.Message.IndexOf("already exists") >= 0)
MessageBox.Show("The database is available");
else
MessageBox.Show(x.Message);
}

Programmatically create sqlite db if it doesn't exist?

I am trying to create an sqlite db programmatically if it doesn't exist. I have written the following code but I am getting an exception at the last line.
if (!System.IO.File.Exists("C:\\Users\\abc\\Desktop\\1\\synccc.sqlite"))
{
Console.WriteLine("Just entered to create Sync DB");
SQLiteConnection.CreateFile("C:\\Users\\abc\\Desktop\\1\\synccc.sqlite");
string sql = "create table highscores (name varchar(20), score int)";
SQLiteCommand command = new SQLiteCommand(sql, sqlite2);
command.ExecuteNonQuery();
}
sqlite2 = new SQLiteConnection("Data Source=C:\\Users\\abc\\Desktop\\1\\synccc.sqlite");
I get the exception at the line command.ExecuteNonQuery(); The exception is Invalid operation exception was unhandled. Is there any other way to add an sqlite file to your project? Can I do it manually? If not then how can I solve the above issue?
To execute any kind of data definition command on the database you need an open connection to pass the command. In your code you create the connection AFTER the execution of the query.
Of course, after that creation, you need to open the connection
if (!System.IO.File.Exists(#"C:\Users\abc\Desktop\1\synccc.sqlite"))
{
Console.WriteLine("Just entered to create Sync DB");
SQLiteConnection.CreateFile(#"C:\Users\abc\Desktop\1\synccc.sqlite");
using(var sqlite2 = new SQLiteConnection(#"Data Source=C:\Users\abc\Desktop\1\synccc.sqlite"))
{
sqlite2.Open();
string sql = "create table highscores (name varchar(20), score int)";
SQLiteCommand command = new SQLiteCommand(sql, sqlite2);
command.ExecuteNonQuery();
}
}
However, if you use the version 3 of the provider, you don't have to check for the existence of the file. Just opening the connection will create the file if it doesn't exists.

Insert byte[] to blob column in Informix DB using c#

Just like these links
Link 1
Link 2
Link 3
Link 4
Am also unable to insert only byte[] related operations on my informix database. I tried many ways and gone through IBM site. but no where its explained "how to use byte[] to insert into blob column using c#".
"LINK 4" is very helpful. but am facing problem with this code.
Error: The %0 enumeration value, %1, is invalid.
At line: blob.Open(IfxSmartLOBOpenMode.ReadWrite);
if i use cmd.Parameters.Add(new IfxParameter()).Value = byteuploaded`;
Here is my code snippet.
protected void uploadfile_Click(object sender, EventArgs e)
{
string extension;
// checks if file exists
if (!_imageUpload.HasFile)
{
_resultLbl.Text = "Please, Select a File!";
return;
}
// checks file extension
extension = System.IO.Path.GetExtension(_imageUpload.FileName).ToLower();
if (!extension.Equals(".jpg") && !extension.Equals(".jpeg") && !extension.Equals(".png"))
{
_resultLbl.Text = "Only image files (.JPGs and .PNGs) are allowed.";
return;
}
try
{
// ========= This is not working ==============
string sqlQuery = "insert into db95:TestBlobUpload (id ,fileblob) values('2', 'two');";
// ========= This is working properly ==============
//string sqlQuery = "insert into db95:TestBlobUpload (id ,filetext) values('4',?);";
string connString = "Database=db95;Host=172.16.XX.XX;Server=vsXXXX;Service=88;Protocol=onsoctcp;UID=ed;Password=ca94;";
using (this.connection = new IfxConnection(connString))
{
this.connection.Open();
using (this.cmd = new IfxCommand(sqlQuery, this.connection))
{
// Start a local transaction
this.trans = this.connection.BeginTransaction(IsolationLevel.Unspecified);
// Assign transaction object for a pending local transaction
this.cmd.Transaction = trans;
try
{
IfxBlob byteuploaded = new IfxBlob(this.connection);
byteuploaded.Read(_imageUpload.FileBytes);
// ========= BOTH OF THESE are not working ==============
//cmd.Parameters.Add(new IfxParameter()).Value = data;// System.Text.Encoding.UTF8.GetString(data);
cmd.Parameters.Add(new IfxParameter()).Value = byteuploaded;// _imageUpload.FileBytes;
int res = cmd.ExecuteNonQuery();
// commiting the transaction
this.cmd.Transaction.Commit();
}
catch
{
//this.cmd.Transaction.Rollback();
}
}
this.connection.Close();
}
}
catch (Exception)
{
}
}
am using this dll as a reference and using IBM.Data.Informix;
particularly am unable to add byte[] to blob columns. All other insert/update/delete operations i can do.
Any help?
I even upgraded to ibm_data_server_driver_package_win64_v10.1.exe & clientsdk.4.10.FC1DE.WIN.exe
But am facing problems with dll compatibility. unable to load'XX.XX.dll" exception is comin.
I even tried to execute the insert query using
INSERT INTO db95#vsXXXX:testblobupload (fileblob)
VALUES (db95#vsXXXX:FILETOBLOB('C:\tmp\Untitled.png', 'client'));
and facing error as
ERROR: Smart-large-object error.
Error Code: -9810.
Smart Large Objects: No sbspace number specified.
This is not your c# app. It's the Informix environment needs to be setup for large smart objects. I think it basically specifies space to use on server. I don't know anything else. If you return the isam error code it would be this
-12053 Smart Large Objects: No sbspace number specified.
No default sbspace was f ound, and the caller has not specified an sbspace
to use.
Either specify the smart-large-object space name in the
smart-large-object function call or set the SBSPACENAME onconfig
file parameter to the name of a valid smart-large-object space.
We can include blob fields in specific sbspace using the PUT IN clause.
If we use connection.GetIfxBlob() without specifying the table name and column name, the blob field will be included in the default sbspace set in the onconfig SBSPACENAME, and if not set will give the error SQLERR-9810 ISAM ERR-12053.
I guess, that the best way of save Informix Blob is using this function :
string insertSql = string.Format("insert into \"{0}\" (sbfotoint,NmArqBlob) values (?,?);", this.table);
using (var command = new IfxCommand(insertSql, this.connection))
{
this.connection.Open();
SetRole();
command.CommandType = System.Data.CommandType.Text;
command.Parameters.Add(new IfxParameter()).Value = CreateIfxBlob(entidade.SBlob);
command.Parameters.Add(new IfxParameter()).Value = entidade.NomeArquivo;
command.ExecuteNonQuery();
this.connection.Close();
}
private IfxBlob CreateIfxBlob(byte[] data)
{
IfxBlob blob = connection.GetIfxBlob(this.table, "sbfotoint");
blob.Open(IfxSmartLOBOpenMode.ReadWrite);
blob.Write(data);
blob.Close();
return blob;
}

Categories