ラブびあ

ビール。ときどきラブ

S2Dao.NETのDaoファイルとEntityファイルを自動生成する

S2Dao.NET(Oracle用)のDaoファイルとEntityファイルを自動生成するスクリプトです。Dao用に作成したSQLファイルをスクリプトファイルにドロップして使います。SQLファイルを使わないDaoの場合は、空のtablename.sqlファイルを作ってください。

スクリプトでやっていることは、

  1. テンプレートファイルを読み込む(ReadText)
  2. 予約語を動的パラメータに置換する(Replace)
  3. ファイルに保存する(WriteText)

だけなので、そういう処理のテンプレにも。例によってwow64.vbsとcmd.vbsはS2Dao.vbsと同じフォルダに入れておきます。


S2Dao.vbs

option explicit
dim wsh,fso
const ForReading   = 1
const ForWriting   = 2
const ForAppending = 8

dim OraSession
dim OraDatabase
const ORADB_DEFAULT    = &H0&
const ORADYN_DEFAULT   = &H0&
const ORAPARM_INPUT    = 1
const ORADB_INTEGER    = 3 'Integer
const ORADB_LONG       = 4 'LongInteger
const ORADB_SINGLE     = 6 'Single
const ORADB_DOUBLE     = 7 'Double
const ORADB_DATE       = 8 'Date
const ORADB_OBJECT     = 9 'OraBFILE..
const ORADB_TEXT       =10 'String
const ORADB_LONGBINARY =11 'String
const ORADB_MEMO       =12 'String

set wsh = CreateObject("Wscript.Shell")
set fso = CreateObject("Scripting.FileSystemObject")

include "cmd.vbs"
include "wow64.vbs"

call init
call main
call fini

msgbox "ファイルの生成が完了しました。"

set wsh = nothing
set fso = nothing

WScript.Quit '-----------------------------------------------------------------

sub init()
	dim database
	dim username
	dim password

	database = "orcl"
	username = "scott"
	password = "tiger"

	set fso         = CreateObject("Scripting.FileSystemObject")
	set OraSession  = CreateObject("OracleInProcServer.XOraSession")
	set OraDatabase = OraSession.OpenDatabase( _
									database, _
									username & "/" & password, _
									ORADB_DEFAULT)
	OraDatabase.Parameters.Add "column_name", 0, ORAPARM_INPUT
	OraDatabase.Parameters("column_name").AutoBindEnable
end sub

sub main()
	dim i
	for i = 0 to WScript.Arguments.Count - 1
		call createDao(WScript.Arguments(i))
		call createEntity(WScript.Arguments(i))
	next
end sub

sub createDao(arg)
	dim s
	s = ReadText(fso.BuildPath(fso.GetParentFolderName(WScript.ScriptFullName), "IDao.cs"))
	s = Replace(s, "%tablename%", fso.GetBaseName(arg))
	call WriteText(fso.BuildPath(fso.GetParentFolderName(arg), "I" + fso.GetBaseName(arg) + "Dao.cs"), s)
end sub

sub createEntity(arg)
	dim s
	s = ReadText(fso.BuildPath(fso.GetParentFolderName(WScript.ScriptFullName), "Entity.cs"))
	s = Replace(s, "%tablename%", fso.GetBaseName(arg))
	s = Replace(s, "%fields%", getFields(arg))
	call WriteText(fso.BuildPath(fso.GetParentFolderName(arg), fso.GetBaseName(arg) + ".cs"), s)
end sub

function ReadText(filename)
	with CreateObject("ADODB.Stream")
		.Charset = "UTF-8"
		.Open
		.LoadFromFile filename
		ReadText = .ReadText
		.Close
	end with
end function

sub WriteText(filename, text)
	with CreateObject("ADODB.Stream")
		.Charset = "UTF-8"
		.Open
		.WriteText text, 1      '最後に改行付き
		.SaveToFile filename, 2 '上書き
		.Close
	end with
end sub

function getFields(filename)
	dim i,t
	with OraDatabase.CreateDynaset(sql(filename), ORADYN_DEFAULT)
		t = ""
		for i = 0 to .Fields.Count - 1
			t = t + ""                                                                                      + vbCrLf
			t = t + "        /// <summary>"                                                                 + vbCrLf
			t = t + "        /// " + getComment(.Fields(i).Name)                                            + vbCrLf
			t = t + "        /// </summary>"                                                                + vbCrLf
			t = t + "        public " + getType(.Fields(i)) + " " + .Fields(i).Name + " { get; set; }" + vbCrLf
		next
		.Close
	end with

	getFields = t
end function

function sql(filename)
	dim s
	s = ReadText(filename)

	with CreateObject("VBScript.RegExp")
		.Pattern = "/\*.*?\*/"
		.Global = True
		s = .Replace(s, "")
	end with

	if Len(s) > 0 then
		sql = "SELECT * FROM (" + s + ") WHERE 1=0"
	else
		sql = "SELECT * FROM " + fso.GetBaseName(filename) + " WHERE 1=0"
	end if
end function

function getComment(fieldname)
	OraDatabase.Parameters("column_name").Value = fieldname
	with OraDatabase.CreateDynaset("select max(comments) from user_col_comments where column_name = :column_name", ORADYN_DEFAULT)
		if IsNull(.Fields(0)) then
			getComment = fieldname
		else
			getComment = .Fields(0).Value
		end if
	end with
end function

function getType(field)
	select case field.Type
	case ORADB_INTEGER
		gettype = "int"
	case ORADB_LONG
		gettype = "long"
	case ORADB_SINGLE
		gettype = "short"
	case ORADB_DOUBLE
		gettype = "double"
	case ORADB_DATE
		gettype = "DateTime"
	case ORADB_OBJECT
		gettype = "object"
	case ORADB_TEXT
		gettype = "string"
	case ORADB_LONGBINARY
		gettype = "string"
	case ORADB_MEMO
		gettype = "string"
	case else
		gettype = "string"
	end select

	if gettype <> "string" and field.OraNullOK then
		gettype = gettype + "?"
	end if
end function

sub fini()
	set OraDatabase = Nothing
	set OraSession  = Nothing
end sub

sub include(filename)
	filename = fso.BuildPath(fso.GetParentFolderName(WScript.ScriptFullName), filename)
	ExecuteGlobal fso.OpenTextFile(filename, ForReading, False).ReadAll()
end sub

hoge.sql

select
	a.*, b.*
from
	 a, b
where
	a.id=b.id

IDao.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using Seasar.Dao.Attrs;

namespace Company.Product.Dao
{
    /// <summary>
    /// I%tablename%Dao
    /// </summary>
    [Bean(typeof(%tablename%))]
    public interface I%tablename%Dao
    {
        IList<%tablename%> Select();
        int Insert(%tablename% entity);
        int Update(%tablename% entity);
        int Delete(%tablename% entity);
    }
}

Entity.cs

using System;
using System.Collections.Generic;
using Seasar.Dao.Attrs;

namespace Company.Product.Entity
{
    /// <summary>
    /// %tablename%
    /// </summary>
    public class %tablename%
    {
%fields%
    }
}


■追記
ALTER TABLE ADD columnで追加したカラムのField.Typeは、ORADB_TEXTになるみたいです。正しく取得できるようにするには、DROP & CREATE でテーブルを再作成する必要があります。