Kotlinで指定のフォーマットの日時をStringで取得する拡張関数 #10

こんにちは hkrblog です.
ちょっと日が空いてしまった...
1週間に4回は更新したいところ...

最近個人的にサーバーサイドでKotlinを使っていて、便利で好きなのが拡張関数.
Kotlin + Spring Bootで開発しているのですが(近々こちらで記事にします...できれば明日....)
指定したフォーマットで日時をStringで返すLocalDataTimeの拡張関数が簡単で便利でした.

fun LocalDateTime.toStr(format: String): String{
    val dateTimeFormatter = DateTimeFormatter.ofPattern(format)
    return this.format(dateTimeFormatter)
}

これで指定したフォーマットの自身の文字列表現が得られます.
そのままですね....
また次回にお会いしましょう.

DbUnit AmbiguousTableNameExceptionが発生 #9

こんにちは hkrblog です.
DbUnit使用時にエンカウントしたAmbiguousTableNameExceptionを解決したので
それを記していきたいと思います.
若干日が経っちゃってちょい曖昧気味...

状況整理 / 原因

まず自分の場合は、SpringBoot, DBはPostgreSQLですね.
状況としては、
* データベース内に同名のテーブルが存在してる
(つまり別スキーマに同名のテーブルが存在している)

基本的にはこの状況だと思います.
自分の場合は厄介だったのが、VIEW(ビュー)を作成していたということですね.
これ全然関係なくて、DbUnitは普通にテーブルを探しに行くのでビューは関係なし.
初動でもしかしてビューか!?と疑ったので若干時間無駄にしました.
話を戻すと原因は上記の同名のテーブルが存在しているということ.
DbUnitは内部でテーブル名をマップ(確か)に詰めていくんだけれども、
そこで同名のテーブルがくるとAmbiguousTableNameExceptionを発生させる.
(だった気がした..)

なので、どのschemaのどのtableなのか?をハッキリさせれば良い.
で自分の場合はエラー表示されるテーブル名が大文字だったのも気になった.
これ関係あったんだかなかったんだか忘れちゃったんだけど、
小文字のはずのテーブル名が大文字で認識できるはずはないということでその辺も設定をしました.


実施した解決方法

1. Configuration
@Configuration
public class DbUnitConfig {

    @Value("${dbunit.schema.name}")
    private String schema;

    @Bean
    public DatabaseConfigBean dbUnitDatabaseConfig() {
        DatabaseConfigBean bean = new DatabaseConfigBean();
        bean.setQualifiedTableNames(true);
        bean.setCaseSensitiveTableNames(true);
        return bean;
    }

    @Bean
    public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection(
                     DataSource dataSource, DatabaseConfigBean dbUnitDatabaseConfig ) {
        DatabaseDataSourceConnectionFactoryBean bean = 
                     new DatabaseDataSourceConnectionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setDatabaseConfig(dbUnitDatabaseConfig);
        bean.setSchema(schema);
        return bean;
    }

}

設定クラスはこんな感じ.(インデントとかの関係で見づらくなってたらすみません)
DatabaseConfigBeanの登録で大文字小文字の区別したりという感じで、
DatabaseDataSourceConnectionFactoryBeanでスキーマ名をセットしてあげてます.

2. ファイル名

あとは読み込むCSVファイルの名前をスキーマ名.テーブル名.csvに変更する
テストデータを入力したcsvファイルの名前を例えば,
myschemaのmytableにデータを投入したいなら(myschemaは上のクラスでセットしたschema名)
名前は、myschema.mytable.csv にします.


あとは実際に実行してみてください.
できましたね? ...ね!?ね!?

PostgresはOK!!この勢いで
Oracleも余裕じゃ~(Oracleも使用している)と思ったらNoSuchTableExceptionが発生して
発狂しかけたので次回はDbUnitの NoSuchTableExceptionの解決記事にしようかなと思います.

もしかしたらKotlin記事になるかもです...

それではまた次回にお会いしましょう~~~~~.

SQLの基本構文(PostgreSQL) #8

こんにちは hkrblog です.
SQL構文簡単なのでも調べたりしがちなので、
良く使うものとか自分用にまとめます.

テーブル作成

create table テーブル名 (カラム名 データタイプ 制約, ... );


カラム追加

alter table テーブル名 add カラム名 データ型 制約, ... ;


カラム削除

alter table テーブル名 drop カラム名;


カラム制約の追加
大体これでイケるはず.

alter table テーブル名 alter カラム名 set 制約;
ex : alter table mytable alter weight set default 100;


カラム制約の削除

alter table テーブル名 alter カラム名 drop 制約;


テーブルのオーナーの変更

alter table テーブル名 owner to 新しいオーナー名;


テーブルを別スキーマ に移動

alter table テーブル名 set schema 新しいスキーマ 名;


テーブル名の変更

alter table テーブル名 rename to 新しいテーブル名;


カラム名の変更

alter table テーブル名 rename カラム名 to 新しいカラム名;


ユーザの一覧

# 1(パスワード隠れてる)
select * from pg_user;

# 2
select * from pg_shadow;


スキーマの作成

create schema スキーマ名;
# psqlの ¥dn でスキーマ一覧が確認できる


ロールの作成

create role ロール名 オプション;
ex : create role myrole createdb, createrole;


権限付与

grant 権限 on 対象 to ロール
ex : grant select, update, insert on mytable to myrole;


カレントスキーマ の確認 (デフォルトでは public がカレントスキーマ )

select current_schema();


スキーマ検索パスの確認

show search_path;


スキーマ検索パスの設定 (スキーマ名を省略したときに検索される)

set search_path to スキーマ名, ...;


ビューの作成

create view ビュー名 as クエリー;
ex : create view mytable as select * from mytable_1;


ではまた次回にお会いしましょう~~~~~~.
....多分DbUnitでエンカウントしたエラーについて記事書くと思います.

Pythonのデコレーターでメタプログラミング 【第3回】【動的に装飾】 #7

どうも hrkblog です.
久しぶりの更新になってしまった....
今回はデコレーターの最終回です.
デコレータで動的にデコレートしていきます.
早速コードを見ていきます..!!

# plus_arg() is injected into Foo
def plus_arg(self, a, b):
    return a + b


# minus_arg() is injected into Foo
def minus_arg(self, a, b):
    return a - b


def change_methods(new):
    if new.__name__ != '__new__':
        return new

    def __new__(cls, *args, **kws):
        # Add attributes
        cls.plus_arg = plus_arg
        cls.minus_arg = minus_arg

        # Delete attributes
        if hasattr(cls, 'say'):
            del cls.say
        return super(cls.__class__, cls).__new__(cls, *args, **kws)

    return __new__


class Foo(object):
    @change_methods
    def __new__():
        pass

    def say(self):
        print("Hi me:", self)


def main():
    foo = Foo()
    print('plus_arg : {}\nminus_arg : {}'.format(foo.plus_arg(1, 3), foo.minus_arg(1, 3)))

    try:
        print(foo.say())
    except AttributeError as ex:
        print('method say() has already been deleted.')
        print(ex)


if __name__ == '__main__':
    main()

まずは、mainから.

foo = Foo()
    print('plus_arg : {}\nminus_arg : {}'.format(foo.plus_arg(1, 3), foo.minus_arg(1, 3)))

    try:
        print(foo.say())
    except AttributeError as ex:
        print('method say() has already been deleted.')
        print(ex)

Fooのインスタンス生成 -> fooのplus_arg(1, 3)とfooのminus_arg(1, 3)を呼び出して
結果をそれぞれ出力してみてます.
そのあとfooのsay()メソッドを呼び出してプリントしてます.
そしてsay()がなければ'method say() has already been deleted'のメッセージをプリントすることにします.
ここだけだとなんのこっちゃて感じですね.

引数を足したり引いたりする単純なplus_arg()とminus_arg()が今回Fooに付け足すメソッドです.

# plus_arg() is injected into Foo
def plus_arg(self, a, b):
    return a + b


# minus_arg() is injected into Foo
def minus_arg(self, a, b):
    return a - b

クラスFooをみてみます.

class Foo:
    @change_methods
    def __new__():
        pass

    def say(self):
        print("Hi me:", self)

Fooは__new__にデコレーターをつけてます.
そして単純な出力をするメソッドsay()があります.
このいかにもな@change_methodsをみてみます.

def change_methods(new):
    if new.__name__ != '__new__':
        return new

    def __new__(cls, *args, **kws):
        # Add attributes
        cls.plus_arg = plus_arg
        cls.minus_arg = minus_arg

        # Delete attributes
        if hasattr(cls, 'say'):
            del cls.say
        return super(cls.__class__, cls).__new__(cls, *args, **kws)

    return __new__

普通のデコレーターですね.
引数の関数の名前が__new__ではないならそのままその返すようにしてます.
__new__だった場合は新しい__new__をあげるようにします.(new __new__じゃん...)
このnew __new__はクラスにplus_argとminus_argというattributeを付け足してます.
(__new__インスタンス生成時__init__の前に呼ばれます.)
そしてクラスにsayという属性があれば削除してしまいます.

実行結果は以下です.

plus_arg : 4
minus_arg : -2
method say() has already been deleted.
'Foo' object has no attribute 'say'

意外と簡単でしたね....?
いろんな使い道がありそうですが、
メタプログラミングってコードがカオスになりがちなんですよねw
(前に参画していた苦い記憶が蘇ってきたので今日はこの辺で......w)

今度はSpring Bootの記事でも書こうかなと思っていたり.....
Javaブロックチェーンの記事とかも書きたい.....

今回3部作にして思ったのは1回目を書くと続き書かなきゃ...となるんですが、
ちょっと日が経つと重荷になってじゃっかんめんどくさくなる...

なので次はその時書きたい記事にしたいと思います....
それではまた次回にお会いしましょう~~~~~~

Pythonのデコレーターでメタプログラミング 【第2回】【動的に装飾】 #6

どうも hkrblog です.
最近仕事が忙しく更新できませんでした....w(言い訳苦しい...)
今日は前回の続きの記事です.
まだメタプログラミングという感じはしないです.

デコレーターが関数の修飾(上書き)をすることができるなら、 デコレーター対象の関数の中身がない場合は関数自体を生やすことになるのではないか?
という発想ですね.
こう書くとちょっと馬鹿っぽいですねw

技術内容としては普通に デコレーターに引数を渡す というものです.
@デコレーターの関数シンタックスシュガーに引数を渡します.
コードを見ましょう...!!!

def argument_sayer(what):
    def _say(method):
        def _action(self, *args, **kws):
            print(what)
            return method(self, *args, **kws)

        return _action

    return _say


def create_pc(maker_name):
    class PC:
        @argument_sayer(maker_name)
        def display(self):
            pass

    return PC()


def main():
    pc1 = create_pc('DELL')
    pc2 = create_pc('ASUS')
    pc1.display()
    print('-------------')
    pc2.display()


if __name__ == '__main__':
    main()


"""
DELL
-------------
ASUS
"""

あ〜〜〜〜、、、これはメソッド生やしちゃってますねw
まず、メインなんですがcreate_pc('DELL')でPC作ってますね.
create_pc()はというと、シンプルに引数にメーカー名をとり、PCのインスタンスを作成する関数ですね.
pc1.display()で何かは分からないですが、PCインスタンスのdisplayメソッドを呼び出しましたね.
じゃあ、displayメソッドは何かというと、中身はないです....
しかし、デコレーターが付いてます.
このデコレーターは引数にメーカー名を取って、修飾します.
argument_sayer(what)こいつなんですが、何してるかというと、デコレーターの関数を作成してます.
なので_say()がデコレーターになります. で実際の処理の部分が_actionですね.
print(what)でメーカー名を出力する動きです.
PCクラスのdisplayメソッドは何もしないメソッドでしたが、無事デコレーターで処理を作成することができました.
パッっと見るとわからん...となるのですが、書いてみるとこんなものか.....という感じですね.

次回は最終回です!
また次回でお会いしましょう~~~

Pythonのデコレーターでメタプログラミング 【第1回】【動的に装飾】 #5

どうも hkrblog です.

昨日までの投稿内容がクソ雑魚wすぎたのか、あまりビューがないので
少しは誰かの役に立ちそうなPythonのデコレーターに関する記事を今日から3回に渡って書いていこうと思います.

デコレーターというと、メソッドに処理を加えるようなイメージがあると思います.
実際その解釈でOKだと思うんですが、
今シリーズの内容を超ざっくりいうと、メタプログラミングのような使い方もできます という記事です.

ただ、急に入ると変に難しく感じたりするので、第一回ではデコレーターのド基本の使い方を見ていこうと思います.
デコレーターなんて知ってるわ!!!!コラ!!!みたいな人はまずこの記事を見ないとは思うのですが、
第一回の対象読者ではないのでブラウザをそっと閉じてください...w
まずコードです.


def deco(func):
    def inner():
        print('before func')
        ret = func()
        print(ret + '!!!')
        print('after func')
    return inner


def sample():
    return 'Hello'


def main():
    # Original sample output
    print(sample())
    print('--------------')

    # Decorated sample output
    decorated = deco(sample)
    decorated()


if __name__ == '__main__':
    main()

仕事でpython使わなくなって久しいので、
デコレーターって実際どう書くんだったっけ?ってなって一旦これで思い出しましたw
危ない危ないw

まずmain()から見ていきます.
print(sample())sampleを呼び出し、出力してますね.
sample()はというとreturn 'Hello'するだけという簡単なメソッドです.

次が本題です.
doco(sample)sampleの関数オブジェクトを引数に、関数deco()を呼び出しました.
decoはというと、innerを返してます.(一旦funcは忘れて...)
innerは何かというと、内部関数innerの関数オブジェクトです.
で、その関数オブジェクトを変数decoratedにぶち込みます.
innerの関数オブジェクトなので、decorated()でinner()が呼ばれますね.
これでやっとsample()に話が戻ってきて、sampleはfuncなので、ret = func()ここで実行されました.

出力結果がこちらです.

Hello
--------------
before func
Hello!!!
after func

どうでしょうか、わかりましたでしょうか....?
ではまた次回#6、第2回 デコレーターでメソッドの中身を生やすでお会いしましょう.
さよなら~~~.

Pythonのメタプログラミング 入門 dynamically create class ! #4

どうも hkrblog です.

最近やたらと寒いですね.....

今日はpythonメタプログラミング入門と題して本当に触りの部分、
クラスを動的に作って、インスタンス生成して、メソッド呼び出すくらいのものです.
(やっぱりpythonだとコード短いし、パパパッて感じで書けてしまう感じがして
ブログとかに載せやすいからついついpython関連の記事になってしまう....w)
実際このコードは2, 3か月前に書いたものです...
まずはコードを載せてしまいます.

class Student:
    def __init__(self, student_id, name):
        self.student_id = student_id
        self.name = name

    def say_my_name(self):
        return "Hi I'm " + self.name


def student_init(self, student_id, name):
    self.student_id = student_id
    self.name = name


def say_my_name(self):
    return "Hi I'm " + self.name


def main():
    student_class = type('Student2', (), {'__init__': student_init,
                                          'say_my_name': say_my_name})
    student_a = Student(1, 'Alice')
    student_b = student_class(2, 'Mike')
    print(type(student_a), student_a.say_my_name())
    print(type(student_b), student_b.say_my_name())


if __name__ == '__main__':
    main()

type関数でクラスを作成します
main()のprint文print(type(student_a), student_a.say_my_name())でも使ってますが、普段良く使うあのtype関数です
type(classname, superclasses, attribute dict)こんな感じです.
つまり動的に作成したクラス名がStudent2です.(我ながらセンス0ですねw)

今回関数を定義してますが、ラムダが使えます.
'say_my_name': lambda self ~~~と書いてあげれば大丈夫です.

比較対象として、Studentクラスも作成してます.
実行結果は以下です.

<class '__main__.Student'> Hi I'm Alice
<class '__main__.Student2'> Hi I'm Mike

動的にStudent2クラスを作成して実行できました.

ではみなさん #5 でお会いしましょう.