SqlFormatterException.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SQLFormatter
{
    class SqlFormatterException : Exception
    {
        /**
            * 例外のコンストラクタ
            */
        public SqlFormatterException()
            :base()
        {

        }

        /**
            * 例外のコンストラクタ
            * 
            * @param argMessage
            */
        public SqlFormatterException(String argMessage)
            :base(argMessage)
        {

        }
    }
}

SqlFormatter.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SQLFormatter
{
    class SqlFormatter
    {
        private SqlParser fParser = new SqlParser();

        private SqlRule fRule = null;

        /** 丸カッコが関数のものかどうかを覚える。 */
        private Stack functionBracket = new Stack();

        /**
         * SQL整形ツールのインスタンスを作成します。
         * 
         * @param argRule
         *            SQL変換ルール。
         */
        public SqlFormatter(SqlRule argRule)
        {
            fRule = argRule;
        }

        /**
         * 与えられたSQLを整形します。
         * 
         * 1.改行で終了するSQL文は、整形後も改行付きであるようにします。
         * 
         * @param argSql
         *            整形前のSQL文
         * @return 整形後のSQL文
         * @throws BlancoSqlFormatterException
         *             内部的に発生した例外は全てこのクラスになります。
         */
        public String format(String argSql)
    {
        functionBracket.Clear();
        try {
            bool isSqlEndsWithNewLine = false;
            if (argSql.EndsWith("\n")) {
                isSqlEndsWithNewLine = true;
            }

            //List<SqlToken> list = fParser.parse(argSql);

            //list = format(list);
            List<SqlToken> list = new List<SqlToken>();
            list.AddRange(format(fParser.parse(argSql)));

            // 変換結果を文字列に戻す。
            String after = "";
            for (int index = 0; index < list.Count(); index++) {
                SqlToken token = (SqlToken) list[index];
                after += token.getString();
            }

            if (isSqlEndsWithNewLine) {
                after += "\n";
            }

            //return after;
            return after.Replace("\n", "\r\n");
        } catch (Exception ex) {
            SqlFormatterException sqlException = new SqlFormatterException(ex.Message);
            //sqlException.initCause(ex);
            throw sqlException;
        }
    }

        /**
         * 字句の配列を、指定されたSQL書式規則に従って変換します。
         * 
         * @param argList
         *            変換前の字句の配列。ArrayList <Token>
         * @return 変換後の字句の配列。ArrayList <Token>
         */
        private List<SqlToken> format(List<SqlToken> argList)
        //private void format(List<SqlToken> argList)
        {

            // TODO:SQL整形のカスタマイズが必要な方は、ここから、あなたの行いたい書式に変換して下さい。
            // なるべくシンプルで明確な整形ルールにしてください。
            // また、誰も使わないような不必要な選択肢はやめましょう。

            // SQLの前後に空白があると削除する。
            SqlToken token = (SqlToken)argList[0];
            if (token.getType() == SqlTokenConstants.SPACE)
            {
                argList.RemoveAt(0);
            }

            token = (SqlToken)argList[argList.Count() - 1];
            if (token.getType() == SqlTokenConstants.SPACE)
            {
                argList.RemoveAt(argList.Count() - 1);
            }

            // SQLキーワードは大文字とする。or ...
            for (int index = 0; index < argList.Count(); index++)
            {
                token = (SqlToken)argList[index];
                if (token.getType() == SqlTokenConstants.KEYWORD)
                {
                    switch (fRule.keyword)
                    {
                        case SqlRule.KEYWORD_NONE:
                            break;
                        case SqlRule.KEYWORD_UPPER_CASE:
                            token.setString(token.getString().ToUpper());
                            break;
                        case SqlRule.KEYWORD_LOWER_CASE:
                            token.setString(token.getString().ToUpper());
                            break;
                    }
                }
            }

            // いったん、記号の前後の空白を除去する
            for (int index = argList.Count() - 1; index >= 1; index--)
            {
                token = (SqlToken)argList[index];
                SqlToken prevToken = (SqlToken)argList[index - 1];
                if (token.getType() == SqlTokenConstants.SPACE
                        && (prevToken.getType() == SqlTokenConstants.SYMBOL || prevToken
                                .getType() == SqlTokenConstants.COMMENT))
                {
                    argList.RemoveAt(index);
                }
                else if ((token.getType() == SqlTokenConstants.SYMBOL || token
                      .getType() == SqlTokenConstants.COMMENT)
                      && prevToken.getType() == SqlTokenConstants.SPACE)
                {
                    argList.RemoveAt(index - 1);
                }
                else if (token.getType() == SqlTokenConstants.SPACE)
                {
                    token.setString(" ");
                }
            }

            // 2つ並んだキーワードは1つのキーワードとみなす。(ex."INSERT INTO", "ORDER BY")
            // 近代の言語はキーワードが2つ並ぶことはない。古い言語では、自然言語(つまり人間の言語)に
            // 近づけるため、キーワードが2つ並ぶことがあった。しかし、近代では"ORDER_BY"、あるいは"OrderBy"
            // のように、可読性を損なうことなく、解析しやすい文法を採用している。
            for (int index = 0; index < argList.Count() - 2; index++)
            {
                SqlToken t0 = (SqlToken)argList[index];
                SqlToken t1 = (SqlToken)argList[index + 1];
                SqlToken t2 = (SqlToken)argList[index + 2];

                if (t0.getType() == SqlTokenConstants.KEYWORD
                        && t1.getType() == SqlTokenConstants.SPACE
                        && t2.getType() == SqlTokenConstants.KEYWORD)
                {
                    if (((string.Equals(t0.getString(), "ORDER", StringComparison.CurrentCultureIgnoreCase) ||
                        string.Equals(t0.getString(), "GROUP", StringComparison.CurrentCultureIgnoreCase)) &&
                        string.Equals(t2.getString(), "BY", StringComparison.CurrentCultureIgnoreCase)))
                    {
                        t0.setString(t0.getString() + " " + t2.getString());
                        argList.RemoveAt(index + 1);
                        argList.RemoveAt(index + 1);
                    }
                }

                // Oracle対応 begin 2007/10/24 A.Watanabe
                // Oracleの外部結合演算子"(+)"を1つの演算子とする。
                if (t0.getString().Equals("(") && t1.getString().Equals("+")
                        && t2.getString().Equals(")"))
                {
                    t0.setString("(+)");
                    argList.RemoveAt(index + 1);
                    argList.RemoveAt(index + 1);
                }
                // Oracle対応 end
            }

            // インデントを整える。
            int indent = 0;
            // 丸カッコのインデント位置を覚える。
            Stack bracketIndent = new Stack();
            SqlToken prev = new SqlToken(SqlTokenConstants.SPACE, " ");
            bool encounterBetween = false;
            for (int index = 0; index < argList.Count(); index++)
            {
                token = (SqlToken)argList[index];
                if (token.getType() == SqlTokenConstants.SYMBOL)
                {
                    // indentを1つ増やし、'('のあとで改行。
                    if (token.getString().Equals("("))
                    {
                        functionBracket.Push(fRule.isFunction(prev.getString()) ? true : false);
                        bracketIndent.Push(indent);
                        indent++;
                        index += insertReturnAndIndent(argList, index + 1, indent);
                    }
                    // indentを1つ増やし、')'の前と後ろで改行。
                    else if (token.getString().Equals(")"))
                    {
                        indent = ((int)bracketIndent.Pop());
                        index += insertReturnAndIndent(argList, index, indent);
                        functionBracket.Pop();
                    }
                    // ','の前で改行
                    else if (token.getString().Equals(","))
                    {
                        index += insertReturnAndIndent(argList, index, indent);
                    }
                    else if (token.getString().Equals(";"))
                    {
                        // 2005.07.26 Tosiki Iga とりあえずセミコロンでSQL文がつぶれないように改良
                        indent = 0;
                        index += insertReturnAndIndent(argList, index, indent);
                    }
                }
                else if (token.getType() == SqlTokenConstants.KEYWORD)
                {
                    // indentを2つ増やし、キーワードの後ろで改行
                    if (string.Compare(token.getString(), "DELETE", true) == 0 ||
                       string.Compare(token.getString(), "SELECT", true) == 0 ||
                       string.Compare(token.getString(), "UPDATE", true) == 0)
                    {
                        indent += 2;
                        index += insertReturnAndIndent(argList, index + 1, indent);
                    }
                    // indentを1つ増やし、キーワードの後ろで改行
                    if (string.Compare(token.getString(), "INSERT", true) == 0 ||
                       string.Compare(token.getString(), "INTO", true) == 0 ||
                       string.Compare(token.getString(), "CREATE", true) == 0 ||
                       string.Compare(token.getString(), "DROP", true) == 0 ||
                       string.Compare(token.getString(), "TRUNCATE", true) == 0 ||
                       string.Compare(token.getString(), "TABLE", true) == 0 ||
                       string.Compare(token.getString(), "CASE", true) == 0)
                    {
                        indent++;
                        index += insertReturnAndIndent(argList, index + 1, indent);
                    }
                    // キーワードの前でindentを1つ減らして改行、キーワードの後ろでindentを戻して改行。
                    if (string.Compare(token.getString(), "FROM", true) == 0 ||
                       string.Compare(token.getString(), "WHERE", true) == 0 ||
                       string.Compare(token.getString(), "SET", true) == 0 ||
                       string.Compare(token.getString(), "ORDER BY", true) == 0 ||
                       string.Compare(token.getString(), "GROUP BY", true) == 0 ||
                       string.Compare(token.getString(), "HAVING", true) == 0)
                    {
                        index += insertReturnAndIndent(argList, index, indent - 1);
                        index += insertReturnAndIndent(argList, index + 1, indent);
                    }
                    // キーワードの前でindentを1つ減らして改行、キーワードの後ろでindentを戻して改行。
                    if (string.Compare(token.getString(), "VALUES", true) == 0)
                    {
                        indent--;
                        index += insertReturnAndIndent(argList, index, indent);
                    }
                    // キーワードの前でindentを1つ減らして改行
                    if (string.Compare(token.getString(), "END", true) == 0)
                    {
                        indent--;
                        index += insertReturnAndIndent(argList, index, indent);
                    }
                    // キーワードの前で改行
                    if (string.Compare(token.getString(), "OR", true) == 0 ||
                       string.Compare(token.getString(), "THEN", true) == 0 ||
                       string.Compare(token.getString(), "ELSE", true) == 0)
                    {
                        index += insertReturnAndIndent(argList, index, indent);
                    }
                    // キーワードの前で改行
                    if (string.Compare(token.getString(), "ON", true) == 0 ||
                       string.Compare(token.getString(), "USING", true) == 0)
                    {
                        index += insertReturnAndIndent(argList, index, indent + 1);
                    }
                    // キーワードの前で改行。indentを強制的に0にする。
                    if (string.Compare(token.getString(), "UNION", true) == 0 ||
                       string.Compare(token.getString(), "INTERSECT", true) == 0 ||
                       string.Compare(token.getString(), "EXCEPT", true) == 0)
                    {
                        indent -= 2;
                        index += insertReturnAndIndent(argList, index, indent);
                        index += insertReturnAndIndent(argList, index + 1, indent);
                    }
                    if (string.Compare(token.getString(), "BETWEEN", true) == 0)
                    {
                        encounterBetween = true;
                    }
                    if (string.Compare(token.getString(), "AND", true) == 0)
                    {
                        // BETWEEN のあとのANDは改行しない。
                        if (!encounterBetween)
                        {
                            index += insertReturnAndIndent(argList, index, indent);
                        }
                        encounterBetween = false;
                    }
                }
                else if (token.getType() == SqlTokenConstants.COMMENT)
                {
                    if (token.getString().StartsWith("/*"))
                    {
                        // マルチラインコメントの後に改行を入れる。
                        index += insertReturnAndIndent(argList, index + 1, indent);
                    }
                }
                prev = token;
            }

            // 丸カッコで囲まれた (ひとつの項目)については特別扱いを行う。 @author tosiki iga
            for (int index = argList.Count() - 1; index >= 4; index--)
            {
                if (index >= argList.Count())
                {
                    continue;
                }

                SqlToken t0 = (SqlToken)argList[index];
                SqlToken t1 = (SqlToken)argList[index - 1];
                SqlToken t2 = (SqlToken)argList[index - 2];
                SqlToken t3 = (SqlToken)argList[index - 3];
                SqlToken t4 = (SqlToken)argList[index - 4];

                if (string.Compare(t4.getString(), "(", true) == 0 &&
                   string.Compare(t3.getString().Trim(), "", true) == 0 &&
                   string.Compare(t1.getString().Trim(), "", true) == 0 &&
                   string.Compare(t0.getString(), ")", true) == 0)
                {
                    t4.setString(t4.getString() + t2.getString() + t0.getString());
                    argList.RemoveAt(index);
                    argList.RemoveAt(index - 1);
                    argList.RemoveAt(index - 2);
                    argList.RemoveAt(index - 3);
                }
            }

            // 前後にスペースを入れる
            for (int index = 1; index < argList.Count(); index++)
            {
                prev = (SqlToken)argList[index - 1];
                token = (SqlToken)argList[index];

                if (prev.getType() != SqlTokenConstants.SPACE
                        && token.getType() != SqlTokenConstants.SPACE)
                {
                    // カンマの後にはスペース入れない
                    if (prev.getString().Equals(","))
                    {
                        continue;
                    }
                    // 関数名の後ろにはスペースは入れない
                    if (fRule.isFunction(prev.getString())
                            && token.getString().Equals("("))
                    {
                        continue;
                    }
                    argList.Insert(index, new SqlToken(SqlTokenConstants.SPACE, " "));
                }
            }

            return argList;
        }

        /**
         * 改行とインデントを挿入する.
         * 
         * @param argList
         * @param argIndex
         * @param argIndent
         * @return 空白を挿入した場合は1を、空白を置き換えた場合は0を返す。
         */
        private int insertReturnAndIndent(List<SqlToken> argList, int argIndex, int argIndent)
        {
            // 関数内では改行は挿入しない
            if (functionBracket.Contains(true))
                return 0;
            try
            {
                // 挿入する文字列を作成する。
                String s = "\n";
                // もし1つ前にシングルラインコメントがあるなら、改行は不要。
                SqlToken prevToken = (SqlToken)(argList[argIndex - 1]);
                if (prevToken.getType() == SqlTokenConstants.COMMENT && prevToken.getString().StartsWith("--"))
                {
                    s = "";
                }
                // インデントをつける。
                for (int index = 0; index < argIndent; index++)
                {
                    s += fRule.indentString;
                }

                // 前後にすでにスペースがあれば、それを置き換える。
                SqlToken token = (SqlToken)argList[argIndex];
                if (token.getType() == SqlTokenConstants.SPACE)
                {
                    token.setString(s);
                    return 0;
                }

                token = (SqlToken)argList[argIndex - 1];
                if (token.getType() == SqlTokenConstants.SPACE)
                {
                    token.setString(s);
                    return 0;
                }
                // 前後になければ、新たにスペースを追加する。
                argList.Insert(argIndex, new SqlToken(SqlTokenConstants.SPACE, s));
                return 1;
            }
            catch (IndexOutOfRangeException e)
            {
                // e.printStackTrace();
                return 0;
            }
        }

        //public static void main(String[] args)
        //{
        //    // ルールを設定する
        //    SqlRule rule = new SqlRule();
        //    rule.keyword = SqlRule.KEYWORD_UPPER_CASE;
        //    rule.indentString = "    ";
        //    String[] mySqlFuncs = {
        //        // getNumericFunctions
        //        "ABS", "ACOS", "ASIN", "ATAN", "ATAN2", "BIT_COUNT", "CEILING",
        //        "COS", "COT", "DEGREES", "EXP",
        //        "FLOOR",
        //        "LOG",
        //        "LOG10",
        //        "MAX",
        //        "MIN",
        //        "MOD",
        //        "PI",
        //        "POW",
        //        "POWER",
        //        "RADIANS",
        //        "RAND",
        //        "ROUND",
        //        "SIN",
        //        "SQRT",
        //        "TAN",
        //        "TRUNCATE",
        //        // getStringFunctions
        //        "ASCII", "BIN", "BIT_LENGTH", "CHAR", "CHARACTER_LENGTH",
        //        "CHAR_LENGTH", "CONCAT", "CONCAT_WS", "CONV", "ELT",
        //        "EXPORT_SET", "FIELD", "FIND_IN_SET", "HEX,INSERT", "INSTR",
        //        "LCASE", "LEFT", "LENGTH", "LOAD_FILE", "LOCATE", "LOCATE",
        //        "LOWER", "LPAD", "LTRIM", "MAKE_SET", "MATCH", "MID", "OCT",
        //        "OCTET_LENGTH", "ORD", "POSITION", "QUOTE", "REPEAT",
        //        "REPLACE", "REVERSE", "RIGHT", "RPAD", "RTRIM", "SOUNDEX",
        //        "SPACE", "STRCMP", "SUBSTRING",
        //        "SUBSTRING",
        //        "SUBSTRING",
        //        "SUBSTRING",
        //        "SUBSTRING_INDEX",
        //        "TRIM",
        //        "UCASE",
        //        "UPPER",
        //        // getSystemFunctions
        //        "DATABASE", "USER",
        //        "SYSTEM_USER",
        //        "SESSION_USER",
        //        "PASSWORD",
        //        "ENCRYPT",
        //        "LAST_INSERT_ID",
        //        "VERSION",
        //        // getTimeDateFunctions
        //        "DAYOFWEEK", "WEEKDAY", "DAYOFMONTH", "DAYOFYEAR", "MONTH",
        //        "DAYNAME", "MONTHNAME", "QUARTER", "WEEK", "YEAR", "HOUR",
        //        "MINUTE", "SECOND", "PERIOD_ADD", "PERIOD_DIFF", "TO_DAYS",
        //        "FROM_DAYS", "DATE_FORMAT", "TIME_FORMAT", "CURDATE",
        //        "CURRENT_DATE", "CURTIME", "CURRENT_TIME", "NOW", "SYSDATE",
        //        "CURRENT_TIMESTAMP", "UNIX_TIMESTAMP", "FROM_UNIXTIME",
        //        "SEC_TO_TIME", "TIME_TO_SEC" };
        //    rule.setFunctionNames(mySqlFuncs);
        //    SqlFormatter formatter = new SqlFormatter(rule);

        //    //// テストディレクトリ内のファイルを一括で変換する。
        //    //File[] files = new File("Test").listFiles();
        //    //for (int i = 0; i < files.length; i++) {
        //    //    System.out.println("-- " + files[i]);
        //    //    // ファイルのSQLを読み込む.
        //    //    final BufferedReader reader = new BufferedReader(new FileReader(
        //    //            files[i]));
        //    //    String before = "";
        //    //    while (reader.ready()) {
        //    //        String line = reader.readLine();
        //    //        if (line == null)
        //    //            break;
        //    //        before += line + "\n";
        //    //    }
        //    //    reader.close();

        //    //    // 整形
        //    //    System.out.println("[before]\n" + before);
        //    //    String after = formatter.format(before);
        //    //    System.out.println("[after]\n" + after);
        //    //}

        //    string before = "select hoge as aaa, hoge2 as bbb from dual";
        //    string after = formatter.format(before);
        //    Console.WriteLine(before);
        //    Console.WriteLine(after);
        //}
    }
}

SqlConstants.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SQLFormatter
{
    class SqlConstants
    {
            /**
             * ANSI SQL キーワード
             */
            public static readonly String[] SQL_RESERVED_WORDS = {
                    // ANSI SQL89
                    "ALL", "AND", "ANY", "AS", "ASC", "AUTHORIZATION", "AVG", "BEGIN",
                    "BETWEEN", "BY", "CHAR", "CHARACTER", "CHECK", "CLOSE", "COBOL",
                    "COMMIT", "CONTINUE", "COUNT", "CREATE", "CURRENT", "CURSOR",
                    "DEC", "DECIMAL", "DECLARE", "DEFAULT", "DELETE", "DESC",
                    "DISTINCT", "DOUBLE", "END", "ESCAPE", "EXEC", "EXISTS", "FETCH",
                    "FLOAT", "FOR", "FOREIGN", "FORTRAN", "FOUND", "FROM", "GO",
                    "GOTO", "GRANT", "GROUP", "HAVING", "IN", "INDICATOR", "INSERT",
                    "INT", "INTEGER", "INTO", "IS", "KEY", "LANGUAGE", "LIKE", "MAX",
                    "MIN", "MODULE", "NOT",
                    "NULL",
                    "NUMERIC",
                    "OF",
                    "ON",
                    "OPEN",
                    "OPTION",
                    "OR",
                    "ORDER",
                    "PASCAL",
                    "PLI",
                    "PRECISION",
                    "PRIMARY",
                    "PRIVILEGES",
                    "PROCEDURE",
                    "PUBLIC",
                    "REAL",
                    "REFERENCES",
                    "ROLLBACK",
                    "SCHEMA",
                    "SECTION",
                    "SELECT",
                    "SET",
                    "SMALLINT",
                    "SOME",
                    "SQL",
                    "SQLCODE",
                    "SQLERROR",
                    "SUM",
                    "TABLE",
                    "TO",
                    "UNION",
                    "UNIQUE",
                    "UPDATE",
                    "USER",
                    "VALUES",
                    "VIEW",
                    "WHENEVER",
                    "WHERE",
                    "WITH",
                    "WORK",
                    // ANSI SQL92
                    "ABSOLUTE", "ACTION", "ADD", "ALLOCATE", "ALTER", "ARE",
                    "ASSERTION", "AT", "BIT", "BIT_LENGTH", "BOTH", "CASCADE",
                    "CASCADED", "CASE", "CAST", "CATALOG", "CHAR_LENGTH",
                    "CHARACTER_LENGTH", "COALESCE", "COLLATE", "COLLATION", "COLUMN",
                    "CONNECT", "CONNECTION", "CONSTRAINT", "CONSTRAINTS", "CONVERT",
                    "CORRESPONDING", "CROSS", "CURRENT_DATE", "CURRENT_TIME",
                    "CURRENT_TIMESTAMP", "CURRENT_USER", "DATE", "DAY", "DEALLOATE",
                    "DEFERRABLE", "DEFERRED", "DESCRIBE", "DESCRIPTOR", "DIAGNOSTICS",
                    "DISCONNECT", "DOMAIN", "DROP", "ELSE", "END-EXEC", "EXCEPT",
                    "EXCEPTION", "EXECUTE", "EXTERNAL", "EXTRACT", "FALSE", "FIRST",
                    "FULL", "GET", "GLOBAL", "HOUR", "IDENTITY", "IMMEDIATE",
                    "INITIALLY", "INNER", "INPUT", "INSENSITIVE", "INTERSECT",
                    "INTERVAL", "ISOLATION", "JOIN", "LAST", "LEADING", "LEFT",
                    "LEVEL", "LOCAL", "LOWER", "MATCH", "MINUTE", "MONTH", "NAMES",
                    "NATIONAL", "NATURAL", "NCHAR", "NEXT", "NO", "NULLIF",
                    "OCTET_LENGTH", "ONLY", "OUTER", "OUTPUT", "OVERLAPS", "PAD",
                    "PARTIAL", "POSITION", "PREPARE", "PRESERVE", "PRIOR", "READ",
                    "RELATIVE", "RESTRICT", "REVOKE", "RIGHT", "ROWS", "SCROLL",
                    "SECOND", "SESSION", "SESSION_USER", "SIZE", "SPACE", "SQLSTATE",
                    "SUBSTRING", "SYSTEM_USER", "TEMPORARY", "THEN", "TIME",
                    "TIMESTAMP", "TIMEZONE_HOUR", "TIMEZONE_MINUTE", "TRAILING",
                    "TRANSACTION", "TRANSLATE", "TRANSLATION",
                    "TRIM",
                    "TRUE",
                    "UNKNOWN",
                    "UPPER",
                    "USAGE",
                    "USING",
                    "VALUE",
                    "VARCHAR",
                    "VARYING",
                    "WHEN",
                    "WRITE",
                    "YEAR",
                    "ZONE",
                    // ANSI SQL99
                    "ADMIN", "AFTER", "AGGREGATE", "ALIAS", "ARRAY", "BEFORE",
                    "BINARY", "BLOB", "BOOLEAN", "BREADTH", "CALL", "CLASS", "CLOB",
                    "COMPLETION", "CONDITION", "CONSTRUCTOR", "CUBE", "CURRENT_PATH",
                    "CURRENT_ROLE", "CYCLE", "DATA", "DEPTH", "DEREF", "DESTROY",
                    "DESTRUCTOR", "DETERMINISTIC", "DICTIONARY", "DO", "DYNAMIC",
                    "EACH", "ELSEIF", "EQUALS", "EVERY", "EXIT", "FREE", "FUNCTION",
                    "GENERAL", "GROUPING", "HANDLER", "HOST", "IF", "IGNORE",
                    "INITIALIZE", "INOUT", "ITERATE", "LARGE", "LATERAL", "LEAVE",
                    "LESS", "LIMIT", "LIST", "LOCALTIME", "LOCALTIMESTAMP", "LOCATOR",
                    "LONG", "LOOP", "MAP", "MODIFIES", "MODIFY", "NCLOB", "NEW",
                    "NONE", "NUMBER", "OBJECT", "OFF", "OLD", "OPERATION",
                    "ORDINALITY", "OUT", "PARAMETER", "PARAMETERS", "PATH", "POSTFIX",
                    "PREFIX", "PREORDER", "RAW", "READS", "RECURSIVE", "REDO",
                    // ANSI SQLではないのだが とても良く使われる構文
                    "TRUNCATE" };

            /**
             * キーワード. ANSI SQL89
             * 
             * Eclipseプラグイン側から利用されています。
             */
            public static readonly String[] SQL89_RESERVED_WORDS = { "ALL", "AND", "ANY",
                    "AS", "ASC", "AUTHORIZATION", "AVG", "BEGIN", "BETWEEN", "BY",
                    "CHAR", "CHARACTER", "CHECK", "CLOSE", "COBOL", "COMMIT",
                    "CONTINUE", "COUNT", "CREATE", "CURRENT", "CURSOR", "DEC",
                    "DECIMAL", "DECLARE", "DEFAULT", "DELETE", "DESC", "DISTINCT",
                    "DOUBLE", "END", "ESCAPE", "EXEC", "EXISTS", "FETCH", "FLOAT",
                    "FOR", "FOREIGN", "FORTRAN", "FOUND", "FROM", "GO", "GOTO",
                    "GRANT", "GROUP", "HAVING", "IN", "INDICATOR", "INSERT", "INT",
                    "INTEGER", "INTO", "IS", "KEY", "LANGUAGE", "LIKE", "MAX", "MIN",
                    "MODULE", "NOT", "NULL", "NUMERIC", "OF", "ON", "OPEN", "OPTION",
                    "OR", "ORDER", "PASCAL", "PLI", "PRECISION", "PRIMARY",
                    "PRIVILEGES", "PROCEDURE", "PUBLIC", "REAL", "REFERENCES",
                    "ROLLBACK", "SCHEMA", "SECTION", "SELECT", "SET", "SMALLINT",
                    "SOME", "SQL", "SQLCODE", "SQLERROR", "SUM", "TABLE", "TO",
                    "UNION", "UNIQUE", "UPDATE", "USER", "VALUES", "VIEW", "WHENEVER",
                    "WHERE", "WITH", "WORK" };

            /**
             * キーワード. ANSI SQL92
             * 
             * Eclipseプラグイン側から利用されています。
             */
            public static readonly String[] SQL92_RESERVED_WORDS = { "ABSOLUTE", "ACTION",
                    "ADD", "ALLOCATE", "ALTER", "ARE", "ASSERTION", "AT", "BIT",
                    "BIT_LENGTH", "BOTH", "CASCADE", "CASCADED", "CASE", "CAST",
                    "CATALOG", "CHAR_LENGTH", "CHARACTER_LENGTH", "COALESCE",
                    "COLLATE", "COLLATION", "COLUMN", "CONNECT", "CONNECTION",
                    "CONSTRAINT", "CONSTRAINTS", "CONVERT", "CORRESPONDING", "CROSS",
                    "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP",
                    "CURRENT_USER", "DATE", "DAY", "DEALLOATE", "DEFERRABLE",
                    "DEFERRED", "DESCRIBE", "DESCRIPTOR", "DIAGNOSTICS", "DISCONNECT",
                    "DOMAIN", "DROP", "ELSE", "END-EXEC", "EXCEPT", "EXCEPTION",
                    "EXECUTE", "EXTERNAL", "EXTRACT", "FALSE", "FIRST", "FULL", "GET",
                    "GLOBAL", "HOUR", "IDENTITY", "IMMEDIATE", "INITIALLY", "INNER",
                    "INPUT", "INSENSITIVE", "INTERSECT", "INTERVAL", "ISOLATION",
                    "JOIN", "LAST", "LEADING", "LEFT", "LEVEL", "LOCAL", "LOWER",
                    "MATCH", "MINUTE", "MONTH", "NAMES", "NATIONAL", "NATURAL",
                    "NCHAR", "NEXT", "NO", "NULLIF", "OCTET_LENGTH", "ONLY", "OUTER",
                    "OUTPUT", "OVERLAPS", "PAD", "PARTIAL", "POSITION", "PREPARE",
                    "PRESERVE", "PRIOR", "READ", "RELATIVE", "RESTRICT", "REVOKE",
                    "RIGHT", "ROWS", "SCROLL", "SECOND", "SESSION", "SESSION_USER",
                    "SIZE", "SPACE", "SQLSTATE", "SUBSTRING", "SYSTEM_USER",
                    "TEMPORARY", "THEN", "TIME", "TIMESTAMP", "TIMEZONE_HOUR",
                    "TIMEZONE_MINUTE", "TRAILING", "TRANSACTION", "TRANSLATE",
                    "TRANSLATION", "TRIM", "TRUE", "UNKNOWN", "UPPER", "USAGE",
                    "USING", "VALUE", "VARCHAR", "VARYING", "WHEN", "WRITE", "YEAR",
                    "ZONE" };

            /**
             * キーワード. ANSI SQL99
             * 
             * Eclipseプラグイン側から利用されています。
             */
            public static readonly String[] SQL99_RESERVED_WORDS = { "ADMIN", "AFTER",
                    "AGGREGATE", "ALIAS", "ARRAY", "BEFORE", "BINARY", "BLOB",
                    "BOOLEAN", "BREADTH", "CALL", "CLASS", "CLOB", "COMPLETION",
                    "CONDITION", "CONSTRUCTOR", "CUBE", "CURRENT_PATH", "CURRENT_ROLE",
                    "CYCLE", "DATA", "DEPTH", "DEREF", "DESTROY", "DESTRUCTOR",
                    "DETERMINISTIC", "DICTIONARY", "DO", "DYNAMIC", "EACH", "ELSEIF",
                    "EQUALS", "EVERY", "EXIT", "FREE", "FUNCTION", "GENERAL",
                    "GROUPING", "HANDLER", "HOST", "IF", "IGNORE", "INITIALIZE",
                    "INOUT", "ITERATE", "LARGE", "LATERAL", "LEAVE", "LESS", "LIMIT",
                    "LIST", "LOCALTIME", "LOCALTIMESTAMP", "LOCATOR", "LONG", "LOOP",
                    "MAP", "MODIFIES", "MODIFY", "NCLOB", "NEW", "NONE", "NUMBER",
                    "OBJECT", "OFF", "OLD", "OPERATION", "ORDINALITY", "OUT",
                    "PARAMETER", "PARAMETERS", "PATH", "POSTFIX", "PREFIX", "PREORDER",
                    "RAW", "READS", "RECURSIVE", "REDO" };

            /**
             * キーワード. ANSI SQL以外の構文
             * 
             * Eclipseプラグイン側から利用されています。
             */
            // C#への移植の際は不要?
            public static readonly String[] SQL_FAMOUS_WORDS = { "TRUNCATE" };
    }
}

AbstractSqlToken.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SQLFormatter
{
    class AbstractSqlToken
    {
            /**
             * フィールド [type]
             *
             * 項目の型 [int]<br>
             * トークン種別をあらわします。
             */
            private int fType;

            /**
             * フィールド [string]
             *
             * 項目の型 [java.lang.String]<br>
             * トークンの実際の文字列をあらわします。
             */
            private String fString;

            /**
             * フィールド [pos]
             *
             * 項目の型 [int]<br>
             * 規定値   [-1]<br>
             * 予約語、コメント、値などのトークンの位置をあらわすフィールド。ソース文字列の先頭からの位置をあらわします。値は ゼロ(ZERO)オリジンです。デフォルト値は (-1)で、(-1) の場合には「位置情報に意味がない」ことをあらわします。
             */
            private int fPos = -1;

            /**
             * フィールド [type]のセッターメソッド
             *
             * 項目の型 [int]<br>
             * トークン種別をあらわします。
             *
             * @param argType フィールド[type]に格納したい値
             */
            public void setType(int argType) {
                fType = argType;
            }

            /**
             * フィールド[type]のゲッターメソッド
             *
             * 項目の型 [int]<br>
             * トークン種別をあらわします。
             *
             * @return フィールド[type]に格納されている値
             */
            public int getType() {
                return fType;
            }

            /**
             * フィールド [string]のセッターメソッド
             *
             * 項目の型 [java.lang.String]<br>
             * トークンの実際の文字列をあらわします。
             *
             * @param argString フィールド[string]に格納したい値
             */
            public void setString(String argString) {
                fString = argString;
            }

            /**
             * フィールド[string]のゲッターメソッド
             *
             * 項目の型 [java.lang.String]<br>
             * トークンの実際の文字列をあらわします。
             *
             * @return フィールド[string]に格納されている値
             */
            public String getString() {
                return fString;
            }

            /**
             * フィールド [pos]のセッターメソッド
             *
             * 項目の型 [int]<br>
             * 予約語、コメント、値などのトークンの位置をあらわすフィールド。ソース文字列の先頭からの位置をあらわします。値は ゼロ(ZERO)オリジンです。デフォルト値は (-1)で、(-1) の場合には「位置情報に意味がない」ことをあらわします。
             *
             * @param argPos フィールド[pos]に格納したい値
             */
            public void setPos(int argPos) {
                fPos = argPos;
            }

            /**
             * フィールド[pos]のゲッターメソッド
             *
             * 項目の型 [int]<br>
             * 規定値   [-1]<br>
             * 予約語、コメント、値などのトークンの位置をあらわすフィールド。ソース文字列の先頭からの位置をあらわします。値は ゼロ(ZERO)オリジンです。デフォルト値は (-1)で、(-1) の場合には「位置情報に意味がない」ことをあらわします。
             *
             * @return フィールド[pos]に格納されている値
             */
            public int getPos() {
                return fPos;
            }

            /**
             * このバリューオブジェクトの文字列表現を取得します。
             *
             * オブジェクトのシャロー範囲でしかtoStringされない点に注意して利用してください。
             *
             * @return バリューオブジェクトの文字列表現。
             */
            public String ToString() {
                StringBuilder buf = new StringBuilder();
                buf.Append("AbstractBlancoSqlToken[");
                buf.Append("type=" + fType);
                buf.Append(",string=" + fString);
                buf.Append(",pos=" + fPos);
                buf.Append("]");
                return buf.ToString();
            }
    }
}

Linux(運用、管理、メールでコマンド)

運用、管理
top WindowsのタスクマネージャのLinux
シフト+mでメモリを喰っている順に並ぶ、qで閉じる
kill プロセスID(PID)でプロセスを強制終了させれる、PIDはps -efで見れる
rootで動いているプロセスは、rootからじゃないと強制終了させれない
vmstat Windowsのタスクマネージャ(パフォーマンス)のLinux

  • nをつけると、n秒ごとに表示

iostat ハードディスクごとに、ハードディスクをどれだけ読み書きしているかを見れる
iostatはyum install sysstatで入れる
df ディスク使用量見れる、-hをつけると見やすい形で表示される
de ディレクトリ内の容量を見れる、-hをつけると見やすい形で表示される
ln リンクを作ることができる
使い方はln -s 本物 偽者で、偽者へアクセスすると本物へ飛ばされるようになる
サーバ監視ソフト
入れ方はmysqlの設定まではhttp://www.ipentec.com/document/document.aspx?page=linux-install-cacti-centos62&culture=ja-jp参照
php-mysqlphp-snmpを入れる
mysqlの設定からはmysql-serverをインストールして、service mysqld startで起動
mysqladmin -u root password 新しいパスワードでパスワード設定
上2行が終わってからhttp://www.ipentec.com/document/document.aspx?page=linux-install-cacti-centos62&culture=ja-jpmysqlの設定からを参照
ちゃんと設定できて、ブラウザから操作し始めたらhttp://centossrv.com/rrdtool-cacti.shtmlを参照する
監視サーバは監視対象サーバと分けること
ログファイルを消す場合は、httpdを操作しているユーザに権限を与えるようにする
メールでコマンド
/etc/aliasesに追記していく
hoge: "|シェルスクリプト等|"という風に書く、追記したあとはnewaliacesで更新
これで、hogeさんにメールを送ると、シェルスクリプト等と書いた部分が動く

WindowsServer2012

2003と比べて 

CALはあるが、2003の時に出てきた入力(選択?)画面は無くなった

2003は同時接続ユーザを含めて3つあったが、USERCALとDEVICECALの2つになった

CALを買わなくても使えるが、使う時は買わなくてはいけない

2008から2012にアップグレードした時に2008のCALを持っていても、2012で使えない、あくまでも2008のCALは2008のCAL

逆に2012から2008等のダウングレードの時は、使える

I386フォルダをコピーしなくても、ディスク無しでサービスを追加することができる

ActiveDirectoryをインストールすると、自動でDNSも入る

ドメインコントローラに昇格させるには右上の△!マークから

役割の追加の画面は一緒

グループポリシーの管理は、サーバーマネージャー→ツール→グループポリシーの管理から

グループポリシー作成は、管理画面のOU上で右クリック→このドメインにGPOを作成し・・・をクリック→名前を入力してOK→作ったポリシーを右クリック→編集から

編集画面は2003と同じ

DNSは変わりない感じで設定できる

DHCPも変わりない感じ

WindowsUpdateはコントロールパネルから自動更新にしないとできない

共有の設定は、下の詳細な共有から共有設定をする、セキュリティは一緒

IPアドレス変更等はコントロールパネルのネットワークから

Hyper-V(仮想化)

役割と機能の追加から追加

CPUが対応していないと、追加できない

入れるメリット

・ホットスタンバイが作れる

・サービスごとにサーバを分けれる、昔のアプリ(サーバ)を動かすことができる

・↑の例、余計なものを入れずに動かしたいアプリがあるときに、専用のサーバを立てることができる、セキュリティ面、リソース面、アプリ面

DNSにCPUを○○%割り当て、メールサーバに○○%割り当てる等(リソース面)

・内部サーバと外部サーバに分けれる

・今現在のサーバを動かしたまま、検証ができる