SQLiteでテーブル存在有無を確認(Golang)

GolangでDBドライバー使ってコードからテーブルの存在有無を確認する方法です。SQLコマンド打てば簡単ですが、コードでチェックするというのはどうやるかしばらく悩みました。以下のstackoverflowから引用しました。

https://stackoverflow.com/questions/56915022/check-if-database-table-exists-using-golang

動作環境でimportしているライブラリ(DBアクセスで必要なのはsqlとsqlite3の2個)、go-sqlite3は使わないけどインポートだけはしないとコンパイルできません。

go-sqlite3のブランクインポートが必要な理由は、

https://maku77.github.io/p/kgzfwdt/

になります。

import (
	"bufio"
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	_ "github.com/mattn/go-sqlite3"
	"log"
	"os"
	"strconv"
	"time"

	"go.bug.st/serial"
	"go.bug.st/serial/enumerator"
)

以下がテーブル存在をチェックしているコードになりますが、dateはフィアル名の一部ですね。戻りのerrorコードがnilならテーブル存在、それ以外ならテーブルが存在しないことになります。

	// table exist check
	cmd := "select*from tbl" + date
	_, table_check := db.Query(cmd)			// checked by using return code

	if table_check != nil {

方法は別にSQLite限定ではなくて他のDBでも同じだろうと思います。

 

admin

ioutilもdeprecated(Golang)

タイトルの通りですが、1.20以降ではそうなります。実は1.16でそういう風に宣言されていたらしい。以下のリンクを参照、

bytes, err := ioutil.ReadFile("sample.json")

bytes, err := os.ReadFile("sample.json")

おそらくファイル全体を読み込むのは、メモリ効率が良くないし、Goの美学とも相入れないのでos.ReadFileを使えということなんだろうと思います。

https://future-architect.github.io/articles/20210210/

 

admin

M5StackC plusとGolangでシリアル通信する

M5StackC plusからのMyfareカードのUID情報をUSBシリアル使ってGoで受信してみます。

参考は、

https://zenn.dev/nnabeyang/articles/d54f18cc39dc4a654c7a

USBシリアルのVID/PIDをMacBook Airからシステム情報/USBで引くと、以下のように見える。USB経由でファイル(USBストレージ)とシリアルインターフェースが見えるようになっています。

0x403と0x6001を使うが、これでは該当するポートが見つからないと言われる。

VID/PIDを調べるために取得スクリプトを、

https://pkg.go.dev/go.bug.st/serial/enumerator

のexampleから引っ張ってくる。参考までにPortDetails構造体の中身見ると、型が数値ではなく文字列だから16進表記じゃだめです。まあ、元々が文字列じゃないか、

if port.IsUSB {
fmt.Printf("   USB ID     %s:%s\n", port.VID, port.PID)
fmt.Printf("   USB serial %s\n", port.SerialNumber)


-->
   USB ID     0403:6001
   USB serial AD5232ED16
type PortDetails struct {
	Name         string
	IsUSB        bool
	VID          string
	PID          string
	SerialNumber string

	// Product is an OS-dependent string that describes the serial port, it may
	// be not always available and it may be different across OS.
	Product string
}

VID/PIDの文字列をそのまま使って、

package main

import (
	"bufio"
	"errors"
	"fmt"
	"log"
	"os"

	"go.bug.st/serial"
	"go.bug.st/serial/enumerator"
)

func getPortName() (string, error) {
	ports, error := enumerator.GetDetailedPortsList()
	if error != nil {
		return "", error
	}
	for _, port := range ports {
		/*
			if port.IsUSB {
				fmt.Printf("   USB ID     %s:%s\n", port.VID, port.PID)
				fmt.Printf("   USB serial %s\n", port.SerialNumber)
		*/

		if port.IsUSB && port.VID == "0403" && port.PID == "6001" {
			return port.Name, nil
		}
	}
	return "", errors.New("M5Stack cplus is not conntected")
}

func main() {
	portName, err := getPortName()
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
	mode := &serial.Mode{
		BaudRate: 115200,
	}
	port, err := serial.Open(portName, mode)
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
	scanner := bufio.NewScanner(port)
	for scanner.Scan() {
		fmt.Println(scanner.Text())
	}
}

これでちゃんと読めた。

 

admin

M1 MacBook AirのUbuntu版数

Ubuntuの18.04系が5月にサポート終了するというニュース見て、今の版数を改めて確認。

Intel MacBookは20.04系(VMWare)で、

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.2 LTS
Release:	22.04
Codename:	jammy

M1 Mac(UTM)に入れたのは最新版の22.04、まあインストール時期からすれば当然ですが。

 

admin

 

MacBook Airのゴミ箱がワンクリックで消せない

まあMacOSではありがちな現象ではありますが、ゴミ箱がワンクリックで消せなくて、わざわざゴミ箱の中に入ってファイルを全選択して消去。

週一のリフレッシュブートで回復しているから、何らかのOS問題。回避が簡単な問題なら最近気にならなくなった。

 

admin

rand.Seed()はdeprecated(Go lang)

VScodeでGo 1.20以降の環境では、rand.Seed()は使うなというwarningが出ます。

代わりに推奨されているのは、rand.NewSource()になります。

	rand.Seed(time.Now().UnixNano())
	rand.NewSource(time.Now().UnixNano())

理由は以下のポップアップメッセージですが、a dependency changes how much it consumes from …..の意味は理解できません。最後の一行を読むと、他のパッケージからもglobal random resourceにアクセスがあると期待したシーケンスで出力されなくなると読めるのでリソース(global random resource)を共有時の問題のようで、他のパッケージからアクセスできないrand.NewSource()を使えということなのでしょう。

stackoverflowのQAを見るとこの件がアップされていますね。

https://stackoverflow.com/questions/75597325/rand-seedseed-is-deprecated-how-to-use-newrandnewseed

 

admin

 

ChatGPT

公開されてからいくつかの質問をしていますが、無回答というのはなくてとりあえずハズレでも良いから回答するという特性があります。

ネットの記事にあった、円周率は3.05以上であることを証明しなさいというのを入力すると、円周率は3.14…だから3.05以上だという無意味な回答が出てきます。

内接する正多角形で考えると正六角形で3以上、正八角形でおよそ3.06、正十二角形でおよそ3.1というのが最大平方根の計算だけで求まるからというのがおそらく正しい回答で今の設問ならば正八角形で回答すれば良い。

下の手書きの絵は正十二角形での計算過程ですが、角度が60/45/30度ならば最大でも平方根の計算だけで求まります。

多分人間の思考とは違うので、こういう問題は苦手だろうと思います、簡単なアルゴリズムのコード化などはそれらしい結果が出てくるので。

だんだん賢くはなるだろうけれども、少なくとも創造はできないだろうから人間の思考の補助としての使い道でしょう。

 

admin

 

 

 

struct{}とstruct{}{}(Golang)

struct{}は型(type)を表現しているし、struct{}{}はstruct{}のインスタンス、従って変数の宣言時には型表現としてのstruct{}を使い、変数への代入時には値(インスタンス)としてのstruct{}{}を使わないといけません。

var empt struct{} 
empv := struct{}{}

考えてみればそうですが、混乱しやすいかもしれない

 

admin

doneパターン(Golang)

Goでの特徴的な機能の一つであるgoルーチンですが、その終了判定あるいはチャネルの選択時の一つのパターンがdoneパターンと言われるもの。

コードのベースは以下からですが、

https://github.com/mushahiroyuki/lgo/blob/main/example/ch10/ex1009.go

実はチャネルサイズが10なので、以下のgoルーチンのループでは11以降はチャネルへの書き込みができないので待ちになります。実質はmainルーチンが終了するとgoルーチンも終了されるので処理上の問題はないのですが、

ここでgoルーチン側で終了待ちをするためのdoneパターンを導入してみます。

close(done)がgoルーチンへの終了シグナルになりますが、goルーチン側ではselect/caseを使っています。チャネルの処理が継続できる条件が複数あるときに、継続可能となった処理をselect/caseで選択して実行するものです。select/case文の特徴的なところは、複数の条件が成立しているときにはランダムで継続可能処理を選ぶことでswitch文のように上から順番のような優先順位はつけないということです。

func main() {
	ch := make(chan int)
	var result []int

	done := make(chan struct{})

	go func() {  // 処理してもらう数値をchに入れる
		for i := 0; i < 100; i++ {
			select {
			case <- done:
				fmt.Print(". ")
				return
			case ch <- i:
			}
		}
	}()
	
	result = processChannel(ch)
	close(done)
	
	time.Sleep(1000)
	fmt.Printf("result: %d\n", result)
}

このサンプルでは確実にdone処理を実行するためにmainルーチンで1000nsの待ち時間を入れています。

実行すると、例えば以下のようになります。

ゴルーチン 起動完了
process: 0 0 0
process: 9 81 0
process: 5 25 2
process: 6 36 2
process: 4 16 0
process: 7 49 1
process: 1 1 2
process: 8 64 2
process: 2 4 1
process: 3 9 1
. result: [0 81 16 9 4 49 64 25 1 36]

 

admin

 

Fusion 360(Apple silicon)

https://knowledge.autodesk.com/support/fusion-360/troubleshooting/caas/sfdcarticles/sfdcarticles/Is-Fusion-360-supported-on-Apple-M1-System-Architecture.html

という情報を見たので、ダウンロードして立ち上げてみて、最初の二回は反応なくなったけど、3度目からは立ち上がるようになった。Intel版でも割と起きる現象だから、Apple silicon限定というわけでもない。

ただしFinderのアプリケーションからは見えず、ユーザディレクトリのApplications配下で見えるからDockに配置。

作成したパーツはクラウドに保存されているから、インポートとかは不要。

アプリ情報見てみるとrosetta2モードで動作しています、ネーティブ対応は今年の夏頃と言っていますから。

Intel Mac必須だった障壁また一つ乗り越えたから、そろそろApple silicon統一でも環境としては問題ないかもしれない。新規プラットホーム投入でも、二年半経過すると概ねそんな感じになるんだね。

P.S. 2023/3/14

アプリ立ち上げ時間比較(Dockのアイコンクリックから立ち上がり画面までストップウォッチ計測)

・2029 Intel i7 16GB 一回目:60秒、二回目:40秒

・M1 MacBook Air 16GB 一回目:33秒、二回目:36秒

ほぼ同じぐらいかと思っていたけど、M1の方がRosetta2にも関わらず高速立ち上がりだからApple siliconって優秀。

 

admin