SQLiteのデータをコマンドラインから操作してみる

# はじめに
前回はASP.NET MVC 5実践プログラミングをベースに、.NET Core 3.0を学習する方法を書いてみましたが、今回はSQLiteのデータをコマンドラインから操作してみます。
https://qiita.com/namikitakeo/items/c01055d934364fa55d34?fbclid=IwAR0PPa1ryY8mUHvhe8I8x78iw3sonaQ2xguigvXSPNiTSnLEUKXYU9LQzhw

# 実行環境
下記バージョンで動作確認しています。
- Windows 10
- .NET Core 3.0

<pre>
$ dotnet --version
3.0.100
</pre>

# 学習方針
コマンドプロンプトから実行する事で、Mac、Linuxにおいてもそのままできると思います。

<pre>
$ mkdir dbtool
$ cd dbtool
$ dotnet new console
</pre>

まずは実行してみます。

<pre>
$ dotnet run
Hello World!

</pre>

必要なパッケージをインストールします。
<pre>
$ dotnet add package System.Data.SQLite.Core
</pre>

以下のモデルを操作します。
http://www.wings.msn.to/index.php/-/A-03/978-4-7980-4179-7/

```C#:Models/Member.cs
using System;
using System.ComponentModel;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;

namespace MvcBasic.Models
{
  public class MvcBasicContext : DbContext
  {
//        public MvcBasicContext (DbContextOptions options) : base(options) {}
        public DbSet<Member> Members { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder options)
            => options.UseSqlite("Data Source=members.db");
  }
  public class Member
  {
    public int Id { get; set; }

    [DisplayName("氏名")]
    public string Name { get; set; }

    [DisplayName("メールアドレス")]
    public string Email { get; set; }

    [DisplayName("生年月日")]
    public DateTime Birth { get; set; }

    [DisplayName("既婚")]
    public bool Married { get; set; }

    [DisplayName("自己紹介")]
    public string Memo { get; set; }
  }
}
```

カレントディレクトリのデータベースを対象にコーディングしています。

<pre>
OnConfiguring(DbContextOptionsBuilder options)
            => options.UseSqlite("Data Source=members.db");
</pre>

以下のような使い方を想定しています。

<pre>
$ dbtool

Usage: dbtool -options [file path]

options
    -e          export user from SQLite
    -i          import user to SQLite
    -d          delete user from SQLite
    -v          display version
    -h          display help message

$ dbtool -v

SQLite module: version 201910

$ dbtool -e users.txt

$ type users.txt
Id      Name    Email   Birth   Married Memo
1       テスト太郎              2001-01-01 01:01:01     1       テスト1
2       テスト次郎              2002-02-02 02:02:02     0       テスト2
</pre>

```C#:Program.cs
using System;
using System.IO;
using System.Text;
using System.Data.SQLite;

namespace dbtool
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length<1 || args.Length>2) {
                help();
                return;
            }
            if (args.Length==1) {
                switch(args[0])
                {
                    case "-v": version();break;
                    default: help();break;
                }
                return;
           }
           switch(args[0])
           {
                case "-i": import(args[1]);break;
                case "-e": export(args[1]);break;
                case "-d": delete(args[1]);break;
                default: help();break;
           }
           return;
        }
        static void import(string param)
        {
            string sqlcmd;
            var sqlConnectionSb = new SQLiteConnectionStringBuilder { DataSource = "members.db" };
            using (var cn = new SQLiteConnection(sqlConnectionSb.ToString()))
            {
                cn.Open();
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                using (StreamReader sr = new StreamReader(new FileStream(@param, FileMode.Open), Encoding.GetEncoding("shift_jis")))
                {
                    while(sr.Peek() >0){
                        String line = sr.ReadLine();
                        string[] values =  line.Split('\t');
                        if (values[0]=="Id") {
                            continue;
                        } else {
                            sqlcmd = "REPLACE INTO members (Id, Name, Email, Birth, Married, Memo) VALUES (" + values[0]+",'"+values[1]+"','"+values[2]+"','"+values[3]+"','"+values[4]+"','"+values[5]+"')";
                        }
                        using (SQLiteTransaction trans = cn.BeginTransaction())
                        {
                            SQLiteCommand cmd = cn.CreateCommand();
                            cmd.CommandText = sqlcmd;
                            cmd.ExecuteNonQuery();
                            trans.Commit();
                        }
                    }
                }
                cn.Close();
            }
            return;
        }
        static void export(string param)
        {
            var sqlConnectionSb = new SQLiteConnectionStringBuilder { DataSource = "members.db" };
            using (var cn = new SQLiteConnection(sqlConnectionSb.ToString()))
            {
                cn.Open();
                using (var cmd = new SQLiteCommand(cn))
                {
                    cmd.CommandText = "SELECT * FROM members";
                    using (SQLiteDataReader reader = cmd.ExecuteReader())
                    {
                        string message = "Id\tName\tEmail\tBirth\tMarried\tMemo\r\n";
                        while (reader.Read())
                        {
                            message += reader["Id"].ToString() + "\t" + reader["Name"].ToString() + "\t" + reader["Email"].ToString() + "\t" + reader["Birth"].ToString() + "\t" + reader["Married"].ToString() + "\t" + reader["Memo"].ToString() + "\r\n";
                        }
                        Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                        File.WriteAllText(@param, message, Encoding.GetEncoding("shift_jis"));
                    }
                }
                cn.Close();
            }
            return;
        }
        static void delete(string param)
        {
            var sqlConnectionSb = new SQLiteConnectionStringBuilder { DataSource = "members.db" };
            using (var cn = new SQLiteConnection(sqlConnectionSb.ToString()))
            {
                cn.Open();
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                using (StreamReader sr = new StreamReader(new FileStream(@param, FileMode.Open), Encoding.GetEncoding("shift_jis")))
                {
                    while(sr.Peek() >0){
                        string sqlcmd = "DELETE FROM MEMBERS WHERE Id = " + sr.ReadLine();
                        using (SQLiteTransaction trans = cn.BeginTransaction())
                        {
                            SQLiteCommand cmd = cn.CreateCommand();
                            cmd.CommandText = sqlcmd;
                            cmd.ExecuteNonQuery();
                            trans.Commit();
                        }
                    }
                }
                cn.Close();
            }
            return;
        }
        static void version()
        {
            Console.WriteLine("\nSQLite module: version 201910\n");
            return;
        }
        static void help()
        {

            Console.WriteLine("\nUsage: dbtool -options [file path]\n");

            Console.WriteLine("options");
            Console.WriteLine("    -e          export user from SQLite");
            Console.WriteLine("    -i          import user to SQLite");
            Console.WriteLine("    -d          delete user from SQLite");
            Console.WriteLine("    -v          display version");
            Console.WriteLine("    -h          display help message");
            return;
        }
    }
}
```