星期日, 12月 31, 2017

Extract binary data from MS SQL

在微軟範例 AdventureWorks,Production Schema 有個 Document 資料表,其中有一個欄位 Document 型態是 varbinary,儲存著 FileName 欄位所記載的檔案內容。藉由工具程式與適當的對話,可以取出內容復原:
  • bcp "SELECT Document FROM AdventureWorks.Production.Document WHERE FileName = 'Introduction 1.doc'" queryout /tmp/Introduction_1.doc -S localhost -U sa -P ...
  • Enter the file storage type of field Document [varbinary(max)]:
  • Enter prefix-length of field Document [8]: 0
  • Enter length of field Document [0]:
  • Enter field terminator [none]:
  • Do you want to save this format information in a file? [Y/n]
  • Host filename [bcp.fmt]:
雖然大多是預設值,唯一要特別注意的是 prefix-length,這裡有可能自作主張地把檔案前面多加了八位元組,讓 Word 開不起來或形成一堆亂碼的內容,因此必須輸入 0 覆蓋掉預設的 8 才能得到正常的檔案結果。在此之後,我們可以再利用 bcp.fmt:
  • bcp "SELECT Document FROM AdventureWorks.Production.Document WHERE FileName = 'Introduction 1.doc'" queryout /tmp/Introduction_1.doc -f bcp.fmt -S localhost -U sa -P ...
可惜的是除此之外,參數無法讓這段過程無需人工介入又産生正確的結果。另一個變通的做法:
  • bcp "SELECT Document FROM AdventureWorks.Production.Document WHERE FileName = 'Introduction 1.doc'" queryout /tmp/Introduction_1_with_prefix.doc -n -S localhost -U sa -P ...
  • tail --bytes=+9 /tmp/Introduction_1_with_prefix.doc > /tmp/Introduction_1.doc

星期二, 12月 26, 2017

JMeter JSR223 Pre / Post Processor

過去以為在 JMeter 裡會用 RegEx 處理動態 SessionId 就很高段了?這次遇到了些更有挑戰性的需求,不得不研究了一下何謂 JSR223?基本上就是一個在 Java 執行腳本程式語言的環境。結合 Groovy,能解決:
  • 取亂數
    • def uuid = UUID.randomUUID().toString();
    • vars.put("id", uuid);
  • 字串拆解、合併,Base64 編碼
    • char0 = (char)0
    • jid = vars.get("jid")
    • token = vars.get("token")
    • def(name, domain) = jid.split("@")
    • plain = jid + char0 + name + char0 + token
    • encoded = plain.bytes.encodeBase64().toString()
    • vars.put("encoded", encoded)

星期一, 12月 11, 2017

git sparse checkout

有時候我們只想拿 Git 上的一兩個檔案,但整個儲存庫很大,或歷史悠久,實在有點浪費。首先有個下指令 sparse checkout 指定要取的路徑,也可以搭配深度省略不需要的歷史:
  • git init <repository_name>
  • cd <repository_name>
  • git config core.sparseCheckout true
  • echo '/path/to/file1' > .git/info/sparse-checkout
  • echo '/path/to/files/*' >> .git/info/sparse-checkout
  • git remote add origin https://<repository_url>
  • git pull --depth 1 origin master
指令有點多,用 api 看有沒有好一點?以無需認證的 GitHub repository 為例:
  • curl -H 'Accept: application/vnd.github.v3.raw' -O -L https://api.github.com/repos/:owner/:repo/contents/:path
需認證的 GitLab 比較麻煩些:
  • curl -H 'PRIVATE-TOKEN: <token>' https://<git_host>/api/v4/projects/:id/repository/files/<url_encoded_file_path>/raw?ref=master -o output.ext
    • token 要取一個 scope 包含 api,尚在有效期限內的 personal access token
    • project id 可在專案的一般設定找到,通常是個數字
    • 以專案第一層 a 目錄下的 b.txt 為例,url_encoded_file_path 會是 a%2Fb.txt
    • master 是分支名,也可以是 tag 或 commit id
    • output.ext 是輸出檔名

星期一, 12月 04, 2017

GIT_ASKPASS timeout on Jenkins

有些 Jenkins Project 在運作一陣子之後,某天突然出現取不到 Git 原始碼(逾時)的問題,目前只找到兩個共同特徵:
  • using GIT_ASKPASS to set credentials
  • Jenkins node on Windows
在一些文章中提到,若在 Jenkins 使用帳密(非 ssh token)登入 Git,事實上只能由 GIT_ASKPASS 傳遞帳密,但這機制又不是那麼穩,有時會壞的。解法是:
  • Command Prompt (Admin) > git config --system --unset credential.helper