2019年03月

GoogleカレンダーAPIを使う

PowerShellで操作したかったが難しそうなのでとりあえずリファレンスを見ながらC#で

まずはクイックスタートガイドのサンプルを実行してみる。

公式サイトの.NetQuickStartから

https://developers.google.com/calendar/quickstart/dotnet

  1. カレンダーAPIを有効にする

    Enable~APIをクリック→DOWNLOAD CLIENT CONFIGRATION

    credentials.jsonファイルをダウンロード

  2. VisualStudioを起動。

    • 新しいC#プロジェクト(コンソールアプリ)を作成する。
    • パッケージマネージャーコンソールを起動する。
    • 00_nuget
    • Install-Package Google.Apis.Calendar.v3と入力、インストールが終わるのを待つ
  3. credentials.jsonをプロジェクトに追加する

    • ここでサンプルのサイトではソリューションエクスプローラーでドラグするように指示があるが、VS2017ではドラグではなくcredentials.jsonをコピー⇒貼り付けで追加を行う。
    • 01_credentials.json
    • エクスプローラー上のcredentials.jsonを選択、プロパティウィンドウの出力ディレクトリにコピー→常にコピーするに変更。
    • 02_出力ディレクトリ.json
    • クイックスタートページのソースコードと置き換える

      using Google.Apis.Auth.OAuth2;
      using Google.Apis.Calendar.v3;
      using Google.Apis.Calendar.v3.Data;
      using Google.Apis.Services;
      using Google.Apis.Util.Store;
      using System;
      using System.Collections.Generic;
      using System.IO;
      using System.Linq;
      using System.Text;
      using System.Threading;
      using System.Threading.Tasks;
      
      namespace CalendarQuickstart
      {
        class Program
        {
            // If modifying these scopes, delete your previously saved credentials
            // at ~/.credentials/calendar-dotnet-quickstart.json
            static string[] Scopes = { CalendarService.Scope.CalendarReadonly };
            static string ApplicationName = "Google Calendar API .NET Quickstart";
      
            static void Main(string[] args)
            {
                UserCredential credential;
      
                using (var stream =
                    new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
                {
                    // The file token.json stores the user's access and refresh tokens, and is created
                    // automatically when the authorization flow completes for the first time.
                    string credPath = "token.json";
                    credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                        GoogleClientSecrets.Load(stream).Secrets,
                        Scopes,
                        "user",
                        CancellationToken.None,
                        new FileDataStore(credPath, true)).Result;
                    Console.WriteLine("Credential file saved to: " + credPath);
                }
      
                // Create Google Calendar API service.
                var service = new CalendarService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = ApplicationName,
                });
      
                // Define parameters of request.
                EventsResource.ListRequest request = service.Events.List("primary");
                request.TimeMin = DateTime.Now;
                request.ShowDeleted = false;
                request.SingleEvents = true;
                request.MaxResults = 10;
                request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime;
      
                // List events.
                Events events = request.Execute();
                Console.WriteLine("Upcoming events:");
                if (events.Items != null && events.Items.Count > 0)
                {
                    foreach (var eventItem in events.Items)
                    {
                        string when = eventItem.Start.DateTime.ToString();
                        if (String.IsNullOrEmpty(when))
                        {
                            when = eventItem.Start.Date;
                        }
                        Console.WriteLine("{0} ({1})", eventItem.Summary, when);
                    }
                }
                else
                {
                    Console.WriteLine("No upcoming events found.");
                }
                Console.Read();
      
            }
        }
      }
      
  4. ビルドして実行する。 初回実行時にブラウザが起動してAPIの権限付与の確認ダイアログが表示されるので「許可」を選択する。

    直近の予定10件がコンソールに表示される。

予定の追加方法

https://developers.google.com/calendar/v3/reference/events/insert?hl=ja

現在の認証は参照しか許されていないため、認証情報の修正を行う。

  1. クイックスタートページのEnable~APIをクリックしてAPIConsoleのリンククリック。

  2. 03_APIConsole
  3. 左上の▼をクリック。

    03_APIConsole_02

    プロジェクトの選択ウィンドウが出現するので、「Quickstart」(サンプルの通りに作成している場合)をクリックする。

    左側の「認証情報」をクリックするとOAuth 2.0 クライアント IDの一覧が表示される。

  4. 「OAuth同意画面」をクリック

    「スコープを追加」をクリックして「../auth/calendar」にチェックを入れて「追加」をクリック、画面下の保存ボタンをクリック。

    03_APIConsole_03

    重要なスコープを追加したため、スコープの公開前に、同意画面で Google による確認が必要です。と表示される。

    03_APIConsole_04
  5. 一度スコープを変更して実行

    このままスケジュール作成のコードを記述しても403エラーになってしまうので、 最初にサンプルで実行したスケジュール取得ソースの

    static string[] Scopes = { CalendarService.Scope.CalendarReadonly };

    これを

    static string[] Scopes = { CalendarService.Scope.Calendar };

    に変更して、一度実行する。

    すると再度承認の確認画面がブラウザで起動するので、「許可」を選択しプログラムを完走させる。

    1. 最初のサンプルソースを以下に書き換える

      ※using ディレクティブ部分は同じなので省略

      namespace CalendarQuickstart
      {
        class Program
        {
            // If modifying these scopes, delete your previously saved credentials
            // at ~/.credentials/calendar-dotnet-quickstart.json
            //"CalendarReadonly"から"Calendar"に変更
            static string[] Scopes = { CalendarService.Scope.Calendar };
            static string ApplicationName = "Google Calendar API .NET Quickstart";
      
            static void Main(string[] args)
            {
                //追加する予定の中身
                Event newEvent = new Event()
                {
                    Summary = "Google I/O 2019",
                    Location = "800 Howard St., San Francisco, CA 94103",
                    Description = "A chance to hear more about Google's developer products.",
                    Start = new EventDateTime()
                    {
                        DateTime = DateTime.Parse("2019-04-01T09:00:00+09:00"),
                        TimeZone = "Asia/Tokyo",
                    },
                    End = new EventDateTime()
                    {
                        DateTime = DateTime.Parse("2019-04-01T17:00:00+09:00"),
                        TimeZone = "Asia/Tokyo",
                    },
                    Recurrence = new String[] { "RRULE:FREQ=DAILY;COUNT=2" },
                    Attendees = new EventAttendee[] {
                        new EventAttendee() { Email = "lpage@example.com" },
                        new EventAttendee() { Email = "sbrin@example.com" },
                    },
                    Reminders = new Event.RemindersData()
                    {
                        UseDefault = false,
                        Overrides = new EventReminder[] {
                            new EventReminder() { Method = "email", Minutes = 24 * 60 },
                            new EventReminder() { Method = "sms", Minutes = 10 },
                        }
                    }
                };
      
                UserCredential credential;
      
                using (var stream =
                    new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
                {
                    // The file token.json stores the user's access and refresh tokens, and is created
                    // automatically when the authorization flow completes for the first time.
                    string credPath = "token.json";
                    credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                        GoogleClientSecrets.Load(stream).Secrets,
                        Scopes,
                        "user",
                        CancellationToken.None,
                        new FileDataStore(credPath, true)).Result;
                    Console.WriteLine("Credential file saved to: " + credPath);
                }
      
                // Create Google Calendar API service.
                var service = new CalendarService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = ApplicationName,
                });
      
                // 予定を追加登録
                string calendarId = "primary";
                EventsResource.InsertRequest request = service.Events.Insert(newEvent, calendarId);
                Event createdEvent = request.Execute();
      
                Console.WriteLine("Event created: {0}", createdEvent.HtmlLink);
      
            }
        }
      }
      

認証情報の追加修正は Google Cloud Console経由からでも可能。

ナビゲーションメニューから「APIとサービス」-「認証情報」

PowerShellでタブ区切りテキストファイルを読み込み

タブ区切りテキストを読込

Import-Csv .\tsv.txt -Delimiter "`t"  -Encoding Default

上記を実行したら "Import-Csv : メンバー "0" は既に存在します。"とエラーになった。

ヘッダの無い(いきなりデータから始まる)ファイルの場合は-Headerオプションでヘッダを指定してやる。

Import-Csv .\tsv.txt -Delimiter "`t" -Header "col1","col2","col3"  -Encoding Default

※タブ区切りでもヘッダーはカンマで区切る。(`tだと区切れない)
 -Encoding Defaultはsjisファイルの場合。

指定条件で抽出

以下のようなタブ区切りテキストファイルから"板野郡"のみを抽出する例

霊山寺    徳島県    鳴門市
極楽寺    徳島県    鳴門市
金泉寺    徳島県    板野郡
大日寺    徳島県    板野郡
地蔵寺    徳島県    板野郡
安楽寺    徳島県    板野郡
十楽寺    徳島県    阿波市
熊谷寺    徳島県    阿波市
法輪寺    徳島県    阿波市
切幡寺    徳島県    阿波市
Import-Csv .\tsv.txt -Delimiter "`t" -Header "col1","col2","col3"  -Encoding Default | Where-Object col3 -eq "板野郡"

OracleLinux7.6にOracle12cR2をインストール

Oracle® Databaseインストレーション・ガイド 12cリリース1

Oracle VM VirtualBox を用いた Oracle Database 12c Release 1 環境の構築

Oracle Database 2日でデータベース管理者 12c リリース2 (12.2)

単一インスタンス・データベース インストレーション・ガイド

第6回 Oracleインストール支援ツールを使う

Oracle® Linux管理者ガイド, リリース7

準備

以下をダウンロードしておく

  • Oracle Database 12c Release 2
    • Linux x86-64

動作要件の確認とインストール支援パッケージをインストール

以下、rootでログインして作業を行う。

ハードウェア要件の確認

  • システムアーキテクチャ(x86_64)

    # uname -m

  • システムの実行レベルは3または5

    # runlevel

  • ディスプレイ解像度 1024 x 768以上必要

    # xdpyinfo | grep dimensions

  • 物理メモリ 2GB以上を推奨

    # grep MemTotal /proc/meminfo

  • スワップ領域

    物理メモリの容量 スワップ領域として必要な量
    1GB~2GB 物理メモリの1.5倍
    2GB~16GB 物理メモリと同量
    16GB以上 16GB

    以下のコマンドでスワップ領域を確認

    # grep SwapTotal /proc/meminfo

    • スワップファイルの拡張方法

      • ファイルを作成して追加する(↓の例では1GB追加 bs=1M count=1000でもよい)

        1. ファイルを作成
          # dd if=/dev/zero of=/swapfile bs=1024 count=1000000
        2. スワップ・ファイルとして初期化
          # mkswap /swapfile
        3. スワップを有効に
          # swapon /swapfile
        4. /etc/fstabにエントリを追加
          /swapfile swap swap defaults 0 0

        削除方法
        # swapoff /swap/swap1
        # rm /swap/swap1

    以下のコマンドでスワップ領域の空きを確認

    # free

  • 一時領域 /tmpに最低1GBの空きが必要
    # df -h /tmp

  • ディスクの空き容量  7.5GB以上
    # df -h

  • /dev/shm ファイルシステム
    データベース作成時、自動メモリ管理機能を利用する場合は、そのサイズよりも大きいサイズで/dev/shmがマウントされている必要がある。

    • # df -kで確認

    • 指定サイズでマウント(この例では1.5GB)
      # mount -t tmpfs shmfs -o size=1500m /dev/shm

      資料によってmount -t tmpfs tmpfsと記載されているものもあった。
      とりあえずOracle® Database管理者リファレンスに従った。

    • 再起動後も確実にマウントされるように/etc/fstabファイルに以下を追加する。

      tmpfs /dev/shm tmpfs size=1500m 0

  • インストール用(Oracleベース)ディレクトリの作成

    # mkdir -p /u01/app/oracle
    # chown oracle:oinstall /u01/app/oracle
    # chmod -R 775 /u01
    

    マニュアル通りに作成するとインベントリディレクトリの作成でエラー(所有者の問題で作成が出来ない)になるため以下も追加

     # mkdir -p /u01/app/oraInventory
     # chown oracle:oinstall /u01/app/oraInventory
     # chmod -R 775 /u01
    
  • ダウンロードしたzipファイルの解凍
    unzip -d <解凍先> <zipファイル>

Oracle Preinstallation RPMのインストール

インストール前の事前作業を自動化してくれるパッケージ

# LANG=C yum install oracle-database-server-12cR2-preinstall

実行するとユーザー「oracle」が作成される。

  • ユーザーoracleにパスワードを設定(とりあえずoracle)
    # passwd oracle

データベースインストール時はこのユーザーでログインして作業する。

  • リソース制限
    /etc/security/limits.conf ファイルに以下の記載を追加

    oracle soft nproc 2047
    oracle hard nproc 16384
    oracle soft nofile 1024
    oracle hard nofile 65536
    oracle soft stack 10240
    oracle hard stack 32768
    
  • SELinuxの無効化
    ↑で編集したリソース制限がSELinuxを無効化しないと反映しなかった。
    有効にしたまま反映させる方法が解らなっかった。
    この辺りにヒントがありそうだが、とりあえず無効化して進むことにした。

    /etc/selinux/configを開き
    SELINUX=enforcingSELINUX=disabledに書き換える。

Oracleデータベースのインストール

  • OSを再起動後、ユーザー「oracle」でログイン

  • ターミナルを開き解凍したインストールファイルからrunInstallerを実行
    /インストールファイルのディレクトリ/runInstaller
    ユニバーサルインストーラー(OUI)が起動する。

  • セキュリティアップデートを~のチェックを外し次へ
    メールアドレスに関する警告が出るが「はい」を選択
  • ora01
  • ソフトウェアのみインストーを選択し、次へ
  • ora02
  • 単一インスタンスデータベースを選択し、次へ
  • ora03
  • Enterprise Editionを選択し、次へ
  • ora04
  • Oracleベースが先に作成したディレクトリになっていることを確認し、次へ
  • ora05
  • インベントディレクトリはそのまま次へ
  • ora06
  • オペレーティング・システム・グループは変更せず次へ
  • ora07
  • 前提条件のチェックを通過するとサマリー画面が現れる。インストールをクリック
  • ora08
  • インストール中にスクリプトの実行を求められる。
    ターミナルを開き以下のコマンドでrootに切り替える。 ora09
    $su - rootコマンドでルートに切り替え後、OUIで指定されたスクリプトを実行。
    Tarace File Analyzerのインストールを確認されたが、デフォルトがnoだったのでそのままエンターキーを押してスクリプトの実行は終了。

  • ora10
  • ターミナルを閉じて、OUIのスクリプト実行画面でOK⇒インストール成功

環境変数の設定

  • ホームディレクトリの.bash_profileを編集(隠しファイルになっているのでエクスプローラからは隠しファイルを表示する設定でないと見えない)

    以下を追記

    export TMPDIR=$HOME/tmp
    export TEMP=$HOME/tmp
    export ORACLE_BASE=/u01/app/oracle
    export ORACLE_HOME=/u01/app/oracle/product/12.2.0/dbhome_1
    export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/jdk/bin:${PATH}
    export LD_LIBRARY_PATH=$ORACLE_HOME/lib
    export LANG=ja_JP.UTF-8
    export NLS_LANG=Japanese_Japan.AL32UTF8
    export ORACLE_SID=cdb
    

    再起動するか、$ source ~/.bash_profileで再読み込みする。

データベースの作成

  • DBCAの起動 $ dbca
  • データベースの選択、次へ
  • dbca01
  • 作成モードは拡張構成を選択し次へ
  • dbca02
  • デプロイタイプ
    • 単一インスタンス
    • 汎用又はトランザクション処理
  • dbca03
  • データベースの識別
    • グローバルデータベース、SID共にORCL(作成環境に合わせて適宜変更)
    • マルチテナント機能は不要だったのでコンテナ・ベースのチェックは外す。
      テナント機能の説明は以下
      徹底解説!Oracle Database 12cのすべて Vol.1
  • dbca04
  • 記憶オプション
    • 記憶属性に次を使用を選択
    • ファイルシステムを選択し、データベースファイル位置は変更しない。
  • dbca05
  • リカバリオプションは使用しない。
  • dbca06
  • ネットワーク構成
    • リスナーを作成「LISTENER」、ポートに「1521」
  • dbca07
  • Data Vault 構成オプションは使用しない。
  • dbca08
  • 構成オプション
    • メモリーは自動メモリー管理 (仮想OSでメモリの割り当てが少ないため初期値のままにした。)   
    • キャラクタセット
      • JA16SJISTILDで作成されたDBのダンプを入れてみたかったのでsjisを選択した。
    • 他の項目は変更しない。
  • dbca091
    dbca092
  • EMの構成は変更せずに次へ
  • dbca10
  • 全てのアカウントに同じパスワードを選択、任意のパスワードを入れ次へ
  • dbca11
  • データベースの作成にチェックを入れて次へ
  • dbca12
  • サマリー画面で終了をクリック
  • dbca13
  • 後は作成が終わるまで待つ

  • Flash Playerのインストール

    • エンタープライズマネージャーの利用に必要。https://localhost:5500/emからリンクをたどりadobeのダウンロードサイトへ
    • YUM(Linux)を選択し、今すぐダウンロード
    • adobe-release-x86_64-1.0-1noarch.rpmがダウンロードされる
    • rootでターミナルを開き、rpmファイルのあるディレクトリに移動後
      # yum localinstall adobe-release-x86_64-1.0-1.noarch.rpm 
      # yum update
      # yum list all | grep flash
      
      flash-plugin.x86_64が表示される。後は、↓のコマンドでプラグインをインストール
      # yum install flash-plugin
    • sysユーザーでログイン出来るか確認する

Oracle12c Linux環境下で、改行コードCRLFの扱い

先日OracleLinux環境に作成した12cR2(多分他のバージョンでも)のデータベースで UTL_FILEの動作でハマったのでメモ。

以下内容

windows sjis環境で作成したテキストファイルをUTL_FILE.GETLINEで1行読込を行う。
その際、改行コード"CRLF"の"CR"迄をデータとして取り扱ってしまい、意図した処理を行えなかった。

windows環境で構築したDBであれば、"CRLF"は改行として取り除いてくれていたため、気付くまでに時間がかかってしまった。

とりあえず、テキストファイルの改行を全て"LF"に置換することで、処理を完了することが出来た。

固定長の場合は、パラメータで読み込むバイト数を指定しておいた方が良いかもしれない。

Oracleの自動起動とポートの解放

OS起動/シャットダウン時にOracleも起動/シャットダウンする

Oracle Database管理者リファレンス

以下、Oracle Linux7.6 Oracle12cR2環境での設定例

  1. oratabファイルの編集
    /etc/oratab ファイルを開き中身を以下のように修正する。

    SID(環境変数に設定したSID):ORACLE_HOME(環境変数のオラクルホームディレクトリ):Y
    ORCL:/u01/app/oracle/product/12.2.0/dbhome_1:Y

  2. dboraファイルの作成
    /etc/init.dディレクトリに移動、「dbora」ファイルを作成し、以下のスクリプトを作成。
    <>内を実環境に合わせて修正。

     #! /bin/sh 
     # description: Oracle auto start-stop script.
     #
     # Set ORACLE_HOME to be equivalent to the $ORACLE_HOME
     # from which you wish to execute dbstart and dbshut;
     #
     # Set ORA_OWNER to the user id of the owner of the
     # Oracle database in ORACLE_HOME.
    
     ORA_HOME=<環境変数に記載したオラクルホームディレクトリ>
     ORA_OWNER=<データベースの所有者のユーザー名(oracle)>
    
     case "$1" in
     'start')
         # Start the Oracle databases:
         # The following command assumes that the oracle login
         # will not prompt the user for any values
         # Remove "&" if you don't want startup as a background process.
         su - $ORA_OWNER -c "$ORA_HOME/bin/dbstart $ORA_HOME" &
         touch /var/lock/subsys/dbora
         ;;
    
     'stop')
         # Stop the Oracle databases:
         # The following command assumes that the oracle login
         # will not prompt the user for any values
         su - $ORA_OWNER -c "$ORA_HOME/bin/dbshut $ORA_HOME" &
         rm -f /var/lock/subsys/dbora
         ;;
     esac
    

    dboraファイルのグループをOSDBAグループ(通常はdba)に変更し、その権限を750に設定。
    # chgrp dba dbora
    # chmod 750 dbora

  3. シンボリックリンクを作成

     # ln -s /etc/init.d/dbora /etc/rc.d/rc0.d/K01dbora
     # ln -s /etc/init.d/dbora /etc/rc.d/rc3.d/S99dbora
     # ln -s /etc/init.d/dbora /etc/rc.d/rc5.d/S99dbora
    

ネットワーク上の他のPCから接続できるよう、 1521ポートを開ける

# firewall-cmd --permanent --add-port=1521/tcp
# firewall-cmd --reload
# firewall-cmd --list-all