月別アーカイブ: 2024年7月

A5:SQL Mk-2をH2につなげてみる

はい。タイトルの通りです。A5:SQL MK-2をH2につなげてみようというお話。
基本的な流れは
H2 Database Engine (H2DB) の環境構築
に詳しいので、補完する感じで。

ポートの話

H2をサーバモードで立ち上げると、TCPモード、PostgreSQLモード、Webモードの3つのモードがいっぺんに立ち上がるようです。TCPもーどはH2本来のモードかな?PostgreSQLモードはPostgreSQLのふりをするモード、Webモードはコンソール用のモードですね。
それぞれポートは
TCPモード:9092
PostgreSQLモード:5435
Webモード:8082
あたりを使うようです。今回のお話のメインはPostgreSQLモードなのですが、PostgreSQLのODBCドライバのインストール時に本体まで入れてしまうと、ポートがバッティングするんじゃないかな。本体の方は自動起動でサービスになっているので、起動しないようにしておいた方が無難だと思います。
コンピュータの管理→サービス→postgresql-x64-xxを手動にして停止させればよいかと。
もちろんPostgreSQLが必要な場合は起動しなければなりませんけれど。

ODBCドライバの話

A5:SQL MK-2はODBC経由で接続できるのですが、残念ながらJDBC経由では接続できなさそうです。Javaで作られていれば逆にJDBCではつながるけどODBCではつながらないとかになるので、どっちがいいのかよくわかりません。で、H2は専用のODBCドライバを作る代わりに、PostgreSQLのODBCドライバを借りるという手段を取りました。
これまた、いいんだか悪いんだか。
先に上げたページにもあるのですが最新版は接続エラーになります。なんかね、接続時の初期化コマンドにH2が知らないPostgreSQL独自の命令が入っているみたい。なので昔のドライバが必要なのですが、リンクが切れてます。
今はここらしいです。これもそのうちリンク切れるんだろうなぁ。メンテとか嫌だなぁ。
なので、リンクが切れていたら自分で探してみてください。
PostgreSQL ODBCドライバ psqlodbc_09_02_0100-x64.zip
あたりでググれば見つかるんじゃないかな。

接続ユーザのパスワード

ODBCの接続でユーザのパスワードがないと蹴られます。パスワードは必須みたいです。
これをなんとかする手は2つあって、一つはsaにパスワードを設定する。もう一つは新たにユーザーを作ってしまう。Webコンソールでは接続できている筈なので、そこからSQLを叩きましょう。各自調べてね♪

とか書いて終わろうかと思ったんですが、ケチ臭いのでSQLコマンドのイメージだけ書いておきます。
パスワードの追加:alter ユーザ名 set password ‘パスワード’
ユーザの作成:create user ユーザ名 identified by ‘パスワード’
こんな感じだった筈。TYPOがあったらゴメンナサイ。ついでなのでコマンドの詳細とか調べておくとよいよ。

以上、取り急ぎA5:SQL MK-2をH2につなげる、でした。

《2024/07/28 07:37:45》

BIOSと戯れてみる(3)

PCをレガシーブートさせてマシン語で遊んでみようというお話です。一応BIOSをメインにするつもりですが、どうなるかわかりません。
環境はAMD64+Windows11+VMware Workstation 17 Player+Debian 12.4です。

システム・タイマー・カウント・リード

BIOSの機能一覧とかは、例えばここなんかに詳しいんですけれど、色々と機能があって遊び甲斐がありそうです。文字の色を変えたりとか、ビデオモードを変えたりとか、目に見える形で遊べるものもたくさんあります。
とはいえ、そのあたりは皆さんの自由に任せるとして、今回はSystemTimerCountReadというBIOSコールを試してみようと思います。

このBIOSコールはとても単純な構造をしていて、引数とか全くなしで呼び出すだけです。
で、CF(キャリーフラグ)に成功か失敗か、ALにオーバーフローしたかしないか、CXとDXに起動してからのカウントが返ってきます。当然動かし続ければ32Bitだって超えちゃうんですが、そこはオーバーフローしたかどうかで大小判定するという仕様です。
見やすくするとこんな感じ。

CF:成功0
失敗 1
AH:0固定
AL:オーバーフローなし 0
  オーバーフロー   1
CX:タイマカウントの上位2バイト
DX:タイマカウントの下位2バイト

たったこれだけです。呼び出して帰ってきた値を参照するだけです。
さて、コードはどんな感じになるかな?
はい。ドン。

;>===========================
;>      BIOSで遊ぼっ!
;>===========================

section .data

    _c_seg          equ 0x07c0
    _c_ex_area_addr equ 0x200
    _c_seg          equ 0x07c0
    _c_ex_area_addr equ 0x200

section .text

boot:
    ; set segment register
    mov ax, _c_seg
    mov ds, ax

    ; disk read

    mov ax, _c_seg
    mov es, ax
    mov bx, _c_ex_area_addr

    mov ah, 0x02 ; Read Sectors From Drive
    mov dl, 0x80 ; Drive
    mov al, 0x20 ; Sectors To Read Count ;
    mov ch, 0x00 ; Cylinder
    mov cl, 0x02 ; Sector(starts from 1, not 0) ; set 2. becouse not need MBR
    mov dh, 0x00 ; Head

    int 0x13     ; Execute disk read

    ; ビデオモードの設定
    mov ah, 0x0
    mov al, 0x3    ; 16色テキスト、80x25
    int 0x10

    jmp main

;********************************
; ブートセクタ終端までゼロで埋める
;********************************

times 510-($-$$) db 0

;********************************
; ブートセクタシグネチャの書き込み
;********************************

db 0x55
db 0xAA

;>===========================
;> main
;>===========================

main:
    ; システムカウンタ
    ; BIOSコールの実行
    mov ah, 0x00
    int 0x01a

    ; 以下、結果の表示

    jnc ._cf_nomal
    ; キャリーが立っていた場合
    mov ah, 0x01
    mov [._cf], ah

._cf_nomal:
    mov [._of], al

    ; CFの表示
    mov ax, ._s_hdr_cf
    call disp_str
    mov al, [._cf]
    call disp_byte_hex
    call disp_nl

    ; over fllow の表示
    mov ax, ._s_hdr_of
    call disp_str
    mov al, [._of]
    call disp_byte_hex
    call disp_nl

    ; cxの表示
    mov ax, ._s_hdr_cx
    call disp_str
    mov ax, cx
    call disp_word_hex
    call disp_nl

    ; dxの表示	
    mov ax, ._s_hdr_dx
    call disp_str
    mov ax, dx
    call disp_word_hex
    call disp_nl
    call disp_nl

    ; 処理終了

    call _hlt

._cf: db 0x00
._of: db 0x00

._s_hdr_cf: db ' CF        : ', 0x00
._s_hdr_of: db ' over flow : ', 0x00
._s_hdr_cx: db ' cx        : ', 0x00
._s_hdr_dx: db ' dx        : ', 0x00
._s_crlf:       db 0x0d, 0x0a, 0x00

;>===========================
;>      サブルーチン
;>===========================
;********************************
; bin_nibble_hex
;       4bit整数を16進文字に変換する(下位4Bit)
;       0~15 -> '0'~'f'
; param  : al : 変換する数値
; return : bl : 変換された文字
;******************************
bin_nibble_hex:

        and al, 0x0f
        cmp al, 0x09
        ja .gt_9
        add al, 0x30
        jmp .cnv_end
.gt_9:
        add al, 0x37

.cnv_end:
        mov bl, al
        ret

;********************************
; bin_byte_hex
; param  : al : 変換したい数値
; return : bx : 変換した2文字の16進文字
;********************************
bin_byte_hex:
    push cx
    push dx

    mov cl, al
    sar al, 4
    and al, 0x0f
    mov ah, 0
    call bin_nibble_hex
    mov dh, bl

    mov al, cl
    and al, 0x0f
    mov ah, 0
    call bin_nibble_hex
    mov dl, bl

    mov bx, dx

    pop dx
    pop cx

    ret

;********************************
; disp_byte_hex
;      1バイトの数値を16進で表示する
; param  : al : 表示したい数値
;********************************
disp_byte_hex:
    push ax
    push bx

    call bin_byte_hex
    mov ah, 0x0e
    mov al, bh
    int 0x10
    mov al, bl
    int 0x10

    pop bx
    pop ax

    ret

;********************************
; disp_word_hex
;       2バイト(1ワード)のデータを表示する
; param : ax : 表示するword
;********************************
disp_word_hex:

    push ax
    push bx

    mov bx, ax
    mov al, bh
    call disp_byte_hex

    mov al, bl
    call disp_byte_hex

._end:

    pop bx
    pop ax

    ret

;********************************
; disp_str
;       display null-terminated string.
; param : ax : addr of mem where string is set.
;********************************
disp_str:

    push ax
    push si

    mov si, ax
    mov ah, 0x0E

._loop:
    lodsb
    or al, al
    jz ._loop_end
    int 0x10
    jmp ._loop

._loop_end:
    pop si
    pop ax

    ret

;****************************
; disp_nl
;   改行する
;****************************
disp_nl:

    push ax

    mov ax, _s_crlf
    call disp_str

    pop ax

    ret

;>****************************
;> hlt
;>****************************
_hlt:
    hlt
    jmp _hlt

;==============================================================
; ファイル長の調整
;==============================================================
_padding:
    times 0x100000-($-$$) db 0

PlayWithBIOS.3.1

なんと250行を超えてしまいました。実際の実行は61行目と62行目、この2行なんですが実行しただけでは何が起こったのかわからないので、結果を表示しています。その表示部分が200行とかあるわけです。いゃぁ、アセンブリ言語って楽しいですね♪
冗談はともかくとして、実行するとこんな感じになります。

ストップウォッチもどき

見出しでネタバレかもしれませんが、今回SystemTimerCountReadを題材に選んだのはこのためなんです。開始時のSystemTimerCountと終了時のSystemTimerCountをとれば、処理にどのくらいの時間がかかったかわかるじゃないですか。それで処理速度を比べてみたかったんですね。
なんの処理速度を比べたかったか。そうアレです。

cmp bx, 0 と
or bx, bx  の処理速度です。

果たして声を大にして叫ばなければいけないほど処理速度に差があるんでしょうか?
実際に試してみたかったんです。

cmp bx, 0 と or bx, bxの速度比較

さて速度比較なんですが生半可な回数だと繰り返しても一瞬で終わってしまうので、32Bit整数回以上回したいと思います。具体的には0x1000000000回繰り返してみます。
8086CPUでは整数の最大値が0xffffつまり65535でしかないので、16bitフルを2連にしてそれを16回繰り返します。変更点はこんな感じ。

;>=========================== ;> main ;>=========================== main: ; システムカウンタの取得と表示 call SystemCounter mov bx, 0xffff mov cx, 0xffff mov dx, 0x000f ._Loop1 ._loop2 ._loop3 dec bx cmp bx, 0 jne ._loop3 dec cx or cx, cx jne ._loop2 dec dx or dx, dx jne ._loop1 ; システムカウンタの取得と表示 call SystemCounter ; 処理終了 call _hlt

cmp bx, 0

さて、cmp bx, 0はこんな結果になりました。

開始が0x0003064Bで終了が0x00030916Cなので、0x2CBつまり715カウントかかったことになります。

or bx, bx

ではor bx,bxのほうはどうでしょうか。先ほどのソースの真ん中あたりかな?
cmp bx, 0をor bx, bxに変えて実行してみます。するとこんな結果になりました。



開始が0x00038561で終了が0x00038827ですから0x2C6ということで710カウントかかっています。

つまり?

cmpを使う場合とorを使う場合の比較ですが、見ての通りほとんど差がないという結果になりました。本来こういった速度比較をする場合、数十回とか数百回行って平均をとって比べるとかすべきですし、そもそもVMwareという仮想化ソフト上で動かしているわけですから実際のCPUとまるっきり一緒ということもないのかもしれません。
けれど、仮想環境で、なおかつ勉強や趣味のために動かしてている状況では、orを使おうがcmpを使おうがどっちでも構わないといえると思います。
少なくても、ですが、cmpを使っていて「そこはorを使うんだ。素人はこれだから…」とかしたり顔で言われる筋合いはないということです。(結局これが言いたかっただけ)

さて、ちょうどキリもいいので今回はここまでです。

《2024/07/06 12:45:23》

Spring Bootで遊ぶ

いまさらながらSpring Bootをお勉強しようかと思います。Eclipseで新しいワークスペースを立ててみたら、Spring入門コンテンツというものがあって、テーマごとにサンプルソースを通していろいろ勉強できるみたいです。公式の入門コンテンツ、一通りは目を通すべきでしょう。
と、思って中を覗いてみたら、どれが何だかさっぱりわからないという。
せめてWebサイトの名称とプロジェクトは対応とっりたいなぁ、ということで一覧表を作りました。

Spring入門コンテンツ一覧

項番Webサイト上の名称Project名PProjectの説明(冒頭のみ)
1REST API の作成REST ServiceRESTful Web サービスの構築
2@Scheduled アノテーションで定期実行Scheduling Tasksタスクのスケジュール 
3RestTemplate で REST API の利用Consuming RESTRESTful Web サービスの使用
4
Spring JDBC JdbcTemplate で SQL 発行Relational Data AccessSpring で JDBC を使用してリレーショナル・データにアクセス 
5ファイルのアップロードUploading Filesファイルのアップロード 
6LDAP でユーザー認証Authenticating LDAPLDAP でユーザー認証
7Redis でメッセージングMessaging RedisRedis でメッセージング
8RabbitMQ でメッセージングMessaging RabbitMQRabbitMQ でメッセージング
9Neo4j でデータアクセスAccessing Data Neo4jNeo4j でデータ・アクセス 
10Web 画面フォーム入力チェックValidating Form Inputフォーム入力の検証
11Spring Boot Actuator で監視機能を追加Validating Form InputSpring Boot Actuator で RESTful な Web サービスを構築 
12JMS でメッセージングMessaging JMSJMS でメッセージング 
13バッチサービスの作成Batch Processingバッチ・サービスの作成 
14Spring Boot ログイン画面Securing WebWeb アプリケーションのセキュリティー保護
15HATEOAS でハイパーメディア駆動 REST API の作成REST Hateoasハイパーメディア駆動 RESTful Web サービスの構築 
16Spring Integration システム接続Integrationデータの統合
17@Transactional アノテーションでトランザクション管理Managing Transactionsトランザクションの管理
18JPA でインメモリ H2 データアクセスAccessing Data JPAJPA でデータ・アクセス
19MongoDB でデータアクセスAccessing Data MongoDBMongoDB でデータ・アクセス
20Thymeleaf Web 画面の作成Serving Web ContentSpring MVC で Web コンテンツの提供
21@Async アノテーションで非同期メソッドの作成Async Method非同期メソッドの作成 
22Web 画面フォーム送信処理Handling Form Submissionフォーム送信処理
23Spring Boot アプリケーションの構築Spring BootSpring Boot でアプリケーションの構築 
24WebSocket でインタラクティブ Web アプリケーション作成Messaging Stomp WebSocketWebSocket を使用してインタラクティブな Web アプリケーションを構築 
25開発環境構築 Eclipse STS ダウンロードSTSSTS で入門ガイドを操作
26REST API で CORS を有効化REST Service CORSRESTful Web サービスのクロス・オリジン・リクエストを使用可能可
27SOAP Web サービスの使用Consuming Web ServiceSOAP Web サービスの使用 
28Spring Data REST API の自動生成 (JPA)Accessing Data RESTREST で JPA データ・アクセス
29Spring Data REST API の自動生成 (Neo4j)Accessing Neo4j Data RESTREST で Neo4j データ・アクセス 
30Spring Data REST API の自動生成 (MongoDB)Accessing MongoDB Data RESTREST で MongoDB データ・アクセス 
31Spring Data REST API の自動生成 (GemFire)Accessing Gemfire Data RESTREST を使用した Pivotal GemFire のデータへのアクセス
32Spring Integration システム接続(????)Producing Web ServiceSOAP Web サービスの生成
33Spring でデータキャッシングCachingSpring でデータ・キャッシング
36Docker で Spring BootSpring Boot DockerDocker で Spring Boot
36Docker で Spring BootTesting RestdocsDocker で Spring Boot 
37開発環境構築 IntelliJ IDEA ダウンロードIntelliJ IDEAIntelliJ IDEA で入門ガイドを操作
38Vaadin で CRUD UI を作成CRUD With VaadinVaadin で CRUD UI を作成 
40Netflix Eureka サービスディスカバリService Registration And Discoveryサービス登録およびディスカバリー
40Netflix Eureka サービスディスカバリSpring Data Reactive RedisRedis でリアクティブにデータ・アクセス
41Spring Cloud Config 集中構成Centralized Configuration集中構成
42MockMvc と @MockBean で Web レイヤーテストTesting WebWeb レイヤーのテスト
43JPA で MySQL データアクセスAccessing Data MySQLMySQL を使用したデータへのアクセス
44マルチモジュールプロジェクトの作成Multi Moduleマルチ・モジュール・プロジェクトの作成 
46Google Cloud Pub/Sub メッセージングMessaging Gcp PubsubGoogle Cloud Pub/Sub を使用したメッセージング
47WebFlux REST API と WebClientReactive REST Serviceリアクティブ RESTful Web サービスの構築
48Spring Cloud Contract サービス間テストContract REST消費者駆動の契約
49Vault へのアクセスAccessing VaultVault へのアクセス 
50Vault 構成Vault ConfigVault 構成
52Spring Boot アプリを Azure にデプロイSpring Boot For AzureSpring Boot アプリを Azure にデプロイ
53Spring Cloud Gateway の構築Spring Cloud LoadbalancerSpring Cloud LoadBalancer
55Spring Cloud StreamSpring Cloud StreamSpring Cloud Stream 
56Spring Cloud StreamSpring Cloud StreamSpring Cloud Stream 
57Spring Cloud Data FlowSpring Cloud DataflowSpring Cloud Data Flow 
58Spring Cloud TaskSpring Cloud TaskSpring Cloud Task
59Spring Boot KubernetesSpring Boot KubernetesSpring Boot Kubernetes
60R2DBC を使用したデータへのアクセスAccessing Data R2DBCR2DBC を使用したデータへのアクセス
61Spring Cloud サーキットブレーカーガイドCloud Circuit BreakerSpring Cloud サーキット・ブレーカー・ガイド
63Wavefront でメトリクス監視Tanzu ObservabilitySpring の可観測性 
65VSCode Java Spring Boot 開発環境構築Guides With VscodeBuilding a Guide with VS Code
66Cassandra を使用したデータへのアクセスAccessing Data Cassandra Accessing Data with Cassandra
67GraphQL サービスの構築Graphql ServerBuilding a GraphQL service

まとめ

とりあえずこれを頼りに必要そうなコンテンツで勉強してみようと思います。

《2024/04/03 6:51:30》