[記錄]PowerShell 初體驗

需求

  1. 將指定的Log記錄,匯入資料庫,產生row data
  2. 將row data 轉換成為需要的報表資料
  3. 產生報表

規劃

  1. powershell 讀取檔案
  2. powershell 連接資料庫
  3. powershell 執行SQL
  4. powershell 作BulkInsert
  5. powershell 寫入檔案

PowerShell

簡記要點

  • powershell 可以直接取用 .Net Framework 或 COM 元件
  • 宣告變用要用$字號
  • # 是註解

讀取檔案

1
2
3
4
5
6
#用New-Object 建立.Net StreamReader 物件
$reader = New-Object System.io.streamReader(get-item $filePath)
#使用`[]`建立靜態類別讀取檔案
$file = [System.IO.File]::ReadAllLines($filePath)
#直接使用Get-Content讀取文檔
$file = Get-Content "C:\filepath\file"

連線資料庫與執行語法

1
2
3
4
5
$connection = New-Object System.Data.SQLClient.SQLConnection
$connection.ConnectionString = "server='$server';database='$database';uid='$user'; pwd='$pwd';Integrated Security=False;"
$connection.Open()
# do something
$connection.Close()

BulkInsert

  • 從檔案建立DataTable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$table = New-Object System.Data.DataTable
#建立欄位
$col_title = New-Object system.Data.DataColumn "Title",([string])
$table.Columns.Add($col_title);
$col_content = New-Object system.Data.DataColumn "Content",([string])
$table.Columns.Add($col_content);
$col_author = New-Object system.Data.DataColumn "Author",([string])
$table.Columns.Add($col_author);
#建立資料
foreach($file in $files){
$dr = $table.NewRow();
$dr["Title"] = $file["title"]
$dr["Content"] = $file["content"]
$dr["Author"] = $file["author"]
}
#寫入資料表
$table.Rows.Add($dr);
  • 透過BulkCopy將DataTable寫入資料庫
1
2
3
4
5
$connection.Open()
$bulkCopy = New-Object (“Data.SqlClient.SqlBulkCopy”) -ArgumentList $connection
$bulkCopy.DestinationTableName = "tablename"
$bulkCopy.WriteToServer($datatable)
$connection.Close()

進度條

1
Write-Progress -Activity "BulkInsert" -Status "載入百分比: 100 %" -PercentComplete 100;

產生報表

1
$datatable | export-csv C:\Reports\20161026.csv -Encoding UTF8

參考

  1. https://msdn.microsoft.com/en-us/powershell
  2. https://msdn.microsoft.com/en-us/powershell/scripting/getting-started/cookbooks/using-static-classes-and-methods
  3. https://cmatskas.com/execute-sql-query-with-powershell/
  4. https://blogs.technet.microsoft.com/heyscriptingguy/

(fin)

[KATA]用 typescript 作一個簡易的 TodoList(二) - 用JQuery實作

設計理念

  1. 顯示/新增/刪除 TodoList
  2. TodoList 會是一堆todoItem的集合,所以要定義todoItem的形別
    • Content : todoItem 的內容
    • Status : todoItem 的狀態,完成(done)、未完成(undo) ,設計成列舉
  3. 主要的功能
    • 建立todoItem
    • 完成todoItem
    • 繪製todoList到前端的畫面上

自我分析

跟 UI 耦合太高,Render 應該與 TodoService 分離 ,
DOM 註冊事件相依在 Service 裡面要抽離也不好抽 。
沒有先寫測試 , 要想一想怎麼與 UI 層作隔離。

程式碼

建立 BaseService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class BaseService<T>{
constructor(private type: string) {}

List:Array<T> ;

Create(data: T) {
this.List.push(data);
}

Delete(data: T){
var index = this.List.indexOf(data);
this.List.splice(index,1) ;
}

Render(){

}
}

建立 todoItem interface

1
2
3
4
5
interface todoItem {
Content: string;
Status: todoStatus;
}

建立 todoItem Status 列舉

1
2
3
4
5
enum todoStatus{
undo,
done,
}

建立 TodoService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
class TodoService extends BaseService<todoItem>{
constructor(){
super("todoItem");
}

public Render() : void {
let doneHtml = '';
let undoHtml = '';

this.List.forEach((item)=>{
if(item.Status == todoStatus.done){
doneHtml += `<li>${item.Content}<button class="recover-item btn btn-default btn-xs pull-right"><span class="glyphicon glyphicon-share-alt"></span></button><button class="remove-item btn btn-default btn-xs pull-right"><span class="glyphicon glyphicon-remove"></span></button></li>`;
} else if (item.Status == todoStatus.undo){
undoHtml += `<li class="ui-state-default"><div class="checkbox"><label><input type="checkbox" value="" />${item.Content}</label></div></li>` ;
}
});
$("#done-items").html(doneHtml);
$('#sortable').html(undoHtml);
$('.add-todo').val('');
}

Delete(data: todoItem){
data.Status = todoStatus.done ;
}



Init(){
//// todoList in localStorage
var list = window.localStorage.getItem("todoList");
if(!list){
this.List = new Array<todoItem>();
}else{
this.List = JSON.parse(list);
}
window.onbeforeunload = (evt) => {
window.localStorage.setItem("todoList",JSON.stringify(this.List));
};

// mark task as done
$('.todolist').on('change','#sortable li input[type="checkbox"]',(evt)=>{
var self = evt.target;
var text = $(self).parent().text();
if($(self).prop('checked')){
var doneItem = this.List.filter((i)=>{return text == i.Content;})[0];
this.Delete(doneItem);
this.Render();
}
});

$('.add-todo').on('keypress',(evt) => {
evt.preventDefault
if (evt.which == 13) {
if($(evt.target).val() != ''){
var todo = $(evt.target).val();
this.Create( {
Content : $(evt.target).val() ,
Status : todoStatus.undo
});
this.Render();
}else{
// some validation
}
}
});

$('.todolist').on('click', '#done-items li button.recover-item',(evt)=>{
var text = $(evt.target).parent().parent().text();
var recoverItem = this.List.filter((i)=>{return text == i.Content;})[0];
recoverItem.Status = todoStatus.undo ;
this.Render();
});

$('.todolist').on('click','#done-items li button.remove-item' ,(evt)=>{
var text = $(evt.target).parent().parent().text();
var removeItem = this.List.filter((i)=>{return text == i.Content;})[0];
var index = this.List.indexOf(removeItem);
this.List.splice(index,1) ;
this.Render();
});

$('#checkAll').on('click',(evt)=>{
this.List.forEach((item)=>{
item.Status = todoStatus.done;
});
this.Render();
});

//// Render
this.Render();
}
}

使用建立好的 TodoService

1
2
3
var todoService = new TodoService();
todoService.Init();

(fin)

[KATA]用typescript作一個簡易的 TodoList(一) - 前置作業

目標

  1. 使用 typescript 開發
  2. 顯示/新增/刪除 TodoList

功能分析

  1. 只是練習,故不開發server side的程式
  2. 暫時存在 cookie 上
  3. 用 bootstrap 作簡單的樣式

實作記錄

UI : 使用 Bootstrap 沒有必要重新打造輪子,能用的就拿來用

  • 找到一個TodoList的樣版,內含 HTML 、 CSS 與 JS ,功能完整.
  • 取用樣版的HTML.
  • 引用 bootstrap 3.3.5 CDN上的 css .
  • 建立一個 todo.css 直接引用樣版的 css 並加入頁面參考.

開發環境

  1. 安裝 typescript
    npm install typescript --save
  2. 安裝 gulp
    npm install gulp
    npm install --global gulp
  3. 安裝 gulp-typescript
    npm install gulp-typescript
  4. 建立 gulpfile.js
1
2
3
4
5
6
7
var gulp = require('gulp');
var tsc = require('gulp-typescript');
gulp.task('default', function() {
return gulp.src('public/javascripts/**/*.ts')
.pipe(tsc())
.pipe(gulp.dest('public/javascripts/'));
});

Typescript

  1. 關於 typescript 的定義檔, 以前有 tsd 與 typings兩種管理工具,現在可以更簡便的合併到 npm 作管理 .

  2. 透過 TypeSearch 可以找到 bootstrap 的 typescript 定義檔.

  3. 執行 npm install --save @types/bootstrap 安裝 bootstrap (目前的版本是 Bootstrap 3.3.5) , 因為相依於 jquery 所以也會一併安裝

  4. 安裝 jquery-ui 的定義檔
    npm install --save @types/jqueryui

  5. 新增檔案 todo.ts ,將 樣版 的 javascript 複製貼上 .
    *註:因為 typescript 是 javascript 的 superset , 完全可以相容原生 javascript, 如果有任何錯誤, TypeScript將會提示你

  6. todo.ts 引用 jquery 、jquery-ui 與 bootstrap 的 typescript 定義檔.

    1
    2
    3
    /// <reference path="../../../node_modules/@types/jquery/index.d.ts"/>  
    /// <reference path="../../../node_modules/@types/bootstrap/index.d.ts"/>
    /// <reference path="../../../node_modules/@types/jqueryui/index.d.ts"/>
  7. 頁面載入對應的js檔,記得放置順序 jquery 要在最前面,並將放在<\body>之後

    1
    2
    3
    <script src="http://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script src="http://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
  8. 執行 gulp ,會產生todo.js

  9. 頁面載入js檔,記得要放在相依的js( jquery 、 bootstrap 、 jqueryui)之後.

1
<script type="text/javascript" src="/javascripts/kata/todo.js"></script>

截至目前為止,僅僅是在作複製樣版,同時一併處理一些基本 gulp 與 typescript 相關的配置
接下來才要開始寫 typescript

(待續)

參考

  1. 關於 TypeScript 2.0 之後的模組定義檔 ( Declaration Files ) ( *.d.ts )
  2. bootsnipp
  3. TYPESCRIPT + EXPRESS + NODE.JS

(fin)

[實作筆記] 怎麼建立一個網站?(三) - 簡單讓網站升級使用HTTP/2

應該知道的事

  • HTTP/1.1是目前被應用得最廣泛的通訊協定,也可以說是最成功的一個
    • HTTP/1.1 基於TCP,需要三方交握。
    • HTTP/1.1 本身存在得需多問題,安全性、效率等…。
  • HTTP/2 可以有效改善HTTP/1.1的缺點,而且可以向下相容
    • 主流的瀏覽器都開始支援了。
    • 只要設定好 Web Server,Client 端看使用的瀏覽器支不支援
  • 一流公司制定標準,二流作品牌,三流賣技術,四流作產品
    • HTTP/2 是源自 Google 的 SPDY。
    • Google下一代 QUIC 推動中。
  • HTTP/2 並不強制加密(HTTPS)
    • 在主流瀏覽器為了向下相容,保留了80 port的HTTP/1.1通訊協定,用443 port 實作HTTP/2。
    • 所以還是要走HTTPS,所以需要安全性憑証。
    • 安全性憑証要錢(現在也有免費的)。
    • cloudflare提供免費的安全性憑証。

前置作業

  1. 你要有cloudflare帳號。
  2. 看過我之網站的設定,簡單說就是一個github page 與 透過OpenShift 這個 PaaS服務建立的網站。

配置

  1. cloudflare 設定DNS,在指定的domain下,設定為「DNS and HTTP Proxy(CDN)」。
    設定為「DNS and HTTP Proxy(CDN)」
  2. 設定Page-Rules,這個是為了開啟SSL
    1. 設定SSLFlexible,輸入*.username.com/*
      這個時候你就可以瀏覽https://blog.username.com/,但同時也可以瀏覽http://blog.username.com/
      我希望HTTP能自動跳轉HTTPS,這部份如果是Node建立的網站,我可以用程式作轉導,
      但是如果是github page建立網站,就要再仰賴 cloudflare 了。
  3. 設定Page-Rules,這個是為了開啟SSL
    1. 設定ALWAYS USE HTTPS,輸入http://*.username.com/*
      設定為「DNS and HTTP Proxy(CDN)」

設定完大致如下,順利的話幾分鐘就生效了。
生效

這時候瀏覽 http://blog.username.com/ 就會轉導到 https://blog.username.com/ 了 。

檢驗

使用 support HTTP/2的瀏覽器,瀏覽網頁,觀察其 protocol 。
HTTP/2

系列文章

參考

(fin)

[工作筆記] 匯入文字資料到 MsSQL

前置作業

  1. 一個有權限寫入的 MsSQL Server 與 SSMS 管理工具
  2. 準備好你的檔案資料(Row Data)
  3. 這份記錄僅供參考(DB版本使用Microsoft SQL Server 2014)

步驟記錄

  1. 開啟 SSMS,連線測試 SQL Server
  2. 對測試資料庫右鍵>工作>匯入資料,開啟「SQL Server 匯入匯出精靈」
  3. 「開始畫面」> 下一步
  4. 「資料來源」選擇一般檔案來源,「檔案名稱」選取 Row Data 的檔案路徑
  5. 請依實際狀況選擇下列欄位
    • 「略過的標頭資料列數」: 預設為0,可透過設定此欄位略過 Row Data 內含註解,標頭等資料
    • 「第一個資料列的資料行名稱」:若Row Data第一行為標頭,請勾選此欄位
    • 左側選單選擇「資料行」>「資料列分隔符號」選擇「{CR}{LF}」、「資料行分隔符號」選擇「Tab鍵{t}」
  6. 左側選單選擇「預覽」確認匯入的資料無誤後,點擊下一步
  7. 「目的地」請選擇「SqlServer」,設定ConnectionString
    • Data Source=1.*..;Initial Catalog=TestDB;Persist Security Info=True;User ID=tester;Password=****;
  8. 「選取來源資料表和檢視畫面」確認無誤後,點擊下一步。
  9. 「檢閱資料類型對應畫面」請忽略資料類型的警告,點擊下一步。
  10. 「執行封裝畫面」勾選「立即執行」,點擊下一步。
  11. 「完成精靈畫面」點選完成。
  12. 執行時間長短,依Row Data大小而有所差異。

(fin)

[實作筆記] 怎麼建立一個網站?(二) - 簡單用github page 建立靜態網站

前置作業

  • 你要有一個 GitHub 帳號

建立github page

如果不排斥看原文,可以直接參考

  1. 建立一個 Repository , 並且命名為 username.github.io , 這裡的 username 請使用你的 GitHub 帳號的 username.

  2. clone username.github.io 到你的本機上.

    1
    git clone https://github.com/username/username.github.io
  3. 建立一個靜態網頁 index.html , 隨便打點什麼。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">
    <HTML>
    <HEAD>
    <TITLE>
    Hello world
    </TITLE>
    </HEAD>
    <BODY>
    <H1>Hello world</H1>
    <P>This is my github page</P>
    </BODY>
    </HTML>
  4. commit之後,push 到github上

    > git add --all
    > git commit -m "Initial commit"
    > git push -u origin master
  5. 瀏覽 http://username.github.io 即完成

使用自訂的 Domain

  1. 首先準備好一個domain ex: username.xyz
  2. 需要在根目錄底下,放入一個 CName file
    檔案的內容只需要你的domain即可
    ex:
    blog.username.xyz  
    username.xyz
    username.xyz
  3. 在Name Servers (例如cloudflare)上設定 CNAME 到github page,
    blog.username.xyz 綁定到 username.github.io
    ex:
TYPE NAME VALUE TTL
CName * username.xyz auto
CName blog username.github.io auto

更多請參考「購買網域到設定DNS」.

透過Hexo部署

Hexo基本概念可以參考官方中文文件 .

  1. 重點在於 _config.yml 的設定

    deploy:
      type: git
      repository: <https://github.com/username/username.github.io>
      branch: master
  2. 執行 hexo d 進行部署,這個動作會將hexo 建立出來的靜態網站(html+css+javascript+圖片等…)部署到github page上。

系列文章

(fin)

如何讓google analytics追踪你的Hexo Blog

前置作業

  1. 你要有google帳號,並申請好你的google_analytics ID
  2. 這個記錄僅針對Hexo預設的Theme有作用,未來有改Theme的話,可能會需要手動加入,再寫文章補上

開啟_config.yml

  1. 確定一下你是使用預設的theme landscape
    ## [Themes](https://hexo.io/themes/)
    theme: landscape
  2. 開啟 root/themes/landscape/_config.yml
  3. 找到以下的設定區段
    # Miscellaneous
    google_analytics:
  4. 填入步驟1. 中所取得 google_analytics ID
  5. 部署網站,完成!

(fin)

[實作筆記] 怎麼建立一個網站?(一) - 購買網域到設定DNS

前置作業

  1. 準備好你的google帳號。
  2. 可以連到美國的VPN。google domain beta 台灣尚未開放
  3. 準備一張信用卡,狠狠的刷下去(挑對domain其實很便宜啦)
  4. 你的網站,什麼語言都可以,靜態的網頁也可以。
    *這裡我事先準備好了兩個網站,
    分別是用github pagenodejsexpress,實作有機會再作記錄。

設定domain

  1. Github page 所建立的網站,會提供一組domain給你
    ex:myDomain.github.io

  2. OpenShift 建立的網站,一樣會提供一組domain給你
    ex:myDomain.rhcloud.com

  3. google domain 本身有提供 Name servers , 但是由於 typeA 的 Domain,
    必須指定公用ip(家中有裝 HiNet ADSL 可以申請一組);但實際上我的兩個網站,並不需要我準備實體 IP,
    只需要使用 type CName 將我的subdomain指向原本服務的domain即可。
    ex:

    • blog.myDomain.me → myDomain.github.io
    • www.myDomain.me → myDomain.rhcloud.com
  4. github page 要注意的事情,

你需要在你的github page 的repo root 加入一個名叫CName的檔案,
檔案的內容很簡單, 只需要你的domain即可
ex:
blog.myDomain.me
myDomain.me

Bare CName

大多數的時候, CName 的設定就夠了;不過對於我來說,
我會希望可以直接使用我的頂級domain,畢竟這樣網址可以更短一些,
myDomain.mewww.myDomain.me 更有感覺。

這裡受限於google 的 Name servers , 頂級domain 必為TypeA須綁定ip
這裡我們可以使用一個免費的服務cloudflare,來達成目的

  1. 註冊cloudflare

  2. 登入後add site,輸入你註冊的domain
    ex:myDomain

  3. cloudflare 會提供你至少兩組Name servers
    ex:
    carter.ns.cloudflare.com
    tina.ns.cloudflare.com

  4. 請先登入google domain beta設定Name servers到cloudflare

  5. 請依以下步驟設定

    • * → myDomain.me
    • blog.myDomain.me → myDomain.github.io
    • www.myDomain.me → myDomain.rhcloud.com
  6. 等待約數分鐘就ok啦

結語

前前後後查資料弄了一個禮拜,但是實際上設定大概1~2小時就搞定了。
對domain跟ip的相對關係與實務結合後更有體會了。

歡迎指教討論。

系列文章

(fin)

Please enable JavaScript to view the LikeCoin. :P