アクトインディ開発者ブログ

子供とお出かけ情報「いこーよ」を運営する、アクトインディ株式会社の開発者ブログです

隙があればlispを詰め込んで行きたい (4)

隙があればlispを詰め込んで行きたい日々ですが、今回はWordPressのデータをいじる仕事です。
仕事の内容ですが、WordPressにはカスタムフィールドという便利機能があり、ここに入力したデータが便利にページに表示されます。
このカスタムフィールド内のHTMLを大量に変更することになりました。
具体的には、

select * from wp_postmeta where meta_key = 'こんにちは画像';

で目的の内容が取得できるので、このテキストの内容を置換して同じ場所に戻してやる、ということになります。
SQL文を書いて色々すれば良いのですが、CLSQLを使ってみることにしました。

(asdf:oos 'asdf:load-op :clsql)
(in-package :clsql-user)

(connect '("localhost" "db" "wp" "")
         :database-type :mysql)

(execute-command "set character_set_client='utf8'")
(execute-command "set character_set_connection='utf8'")
(execute-command "set character_set_results='utf8'"))

;; DBから読み出してSQLを出力
;; <a href=...>を<a target="_blank" href=...>に変更

(let ((ahref (ppcre:create-scanner "(<a)(\\s+)(href=.*)"))
      (window.open (ppcre:create-scanner "window.open")))
  (alexandria:with-output-to-file (out "/tmp/foo.txt")
    (do-query ((meta_id post_id meta_key meta_value)
               "select * from wp_postmeta where meta_key = 'こんにちは画像';")
      (cond ((ppcre:scan "window.open" meta_value)
             ;; 既にwindow.openで開くような指定があるばあいはスルー
             :nop)
            ('T (let ((new-val
                       (ppcre:regex-replace
                        ahref
                        meta_value
                        (lambda (match &rest registers)
                          (declare (ignore match))
                          (destructuring-bind (a b c) registers
                            (format nil
                                    "~a target=\"_blank\"~a~a"
                                    a
                                    b
                                    c)))
                        :simple-calls 'T)))
                  (format out
                          "update wp_postmeta set meta_value = '~A' where meta_key = 'こんにちは画像' and post_id = ~A;~%"
                          new-val
                          post_id)))))))

内容としては、

  • CLSQLを準備
  • MySQLに接続
  • 文字コードUTF-8に設定(任意)
  • select文を発行して結果をリストで受けとる
  • リストの内容から、目的の文を取り出しPPCRE(Common LispPerl正規表現互換パッケージ)で処理
  • ファイルにSQL文を書き出し

今回は目的のSQLサーバーに直接接続するのが面倒だったので、ファイルにSQL文を書き出しましたが、CLSQLで接続して変更ということも勿論できます。
また、”select〜”みたいなことになっていますが、(select […])のようにも書けるようです。
色々適当ですが、とりあえず目的は達成できました