Download
(require 'sqlserver-query)
(require 'csharp-mode nil t)
(defcustom sstec-sqlserver-type-csharp-type-alist
'((BIT . "bool")
(INT . "int")
(SMALLINT . "int")
(TINYINT . "int")
(NUMERIC . "decimal")
(DECIMAL . "decimal")
(MONEY . "decimal")
(SMALLMONEY . "decimal")
(FLOAT . "decimal")
(REAL . "decimal")
(DATETIME . "DateTime")
(SMALLDATETIME . "DateTime")
(TIMESTAMP . "string")
(UNIQUEIDENTIFIER . "string")
(CHAR . "string")
(VARCHAR . "string")
(TEXT . "string")
(NCHAR . "string")
(NVARCHAR . "string")
(NTEXT . "string")
(BINARY . "byte[]")
(VARBINARY . "byte[]")
(IMAGE . "byte[]")
)
"key must be upcase.
key 是db类型,value 是csharp 中对应类型.要求key大写"
:group 'convenience
)
(defun sstec-tablename2classname(tablename)
"从tablename 生成classname,目录直接以tablename作为类名"
tablename
)
(defun sstec-columnname2fieldname(columnname)
"由列名生成csharp Property名.目前直接用`columnname'作为生成的变量名。"
columnname
)
(defun camelize (s &optional separator )
"Convert under_score string S to CamelCase string."
(mapconcat 'identity (mapcar
'(lambda (word) (capitalize (downcase word)))
(if separator (split-string s "_") (list s))
) ""))
(defun camelize-method (s &optional separator)
"Convert under_score string S to camelCase string."
(mapconcat 'identity (mapcar-head
'(lambda (word) (downcase word))
'(lambda (word) (capitalize (downcase word)))
(if separator (split-string s "_") (list s))) ""))
(defun upcase-first-char (s &optional prefix)
"make the first char `upcase' and return (concat prefix upcasedstring)"
(when (> (length s) 0)
(let ( (first-char (substring s 0 1 ))
(rest (substring s 1 )))
(concat (or prefix "") (upcase first-char) rest))))
(defun un-camelcase-string (s &optional sep start)
"Convert CamelCase string S to lower case with word separator SEP.
Default for SEP is a hyphen \"-\".
If third argument START is non-nil, convert words after that
index in STRING."
(let ((case-fold-search nil))
(while (string-match "[A-Z]" s (or start 1))
(setq s (replace-match (concat (or sep "-")
(downcase (match-string 0 s)))
t nil s)))
(downcase s)))
(defun mapcar-head (fn-head fn-rest list)
"Like MAPCAR, but applies a different function to the first element."
(if list
(cons (funcall fn-head (car list)) (mapcar fn-rest (cdr list)))))
(defvar sstec-connection-4-sqlserver nil)
(defun sstec-get-csharp-type(db-type)
"find out csharp type depend on de-type from `sstec-sqlserver-type-csharp-type-alist'"
(cdr (assoc (intern (upcase db-type)) sstec-sqlserver-type-csharp-type-alist))
)
(defun sstec-query-all-tablename-in-db()
"从sqlserver 中查询出当前连接的数据库中所有的表名,用到了`sqlserver-query.el'"
(mapcar 'car (sqlserver-query "select name from sys.tables" sstec-connection-4-sqlserver)))
(defun sstec-query-table (tablename)
(sqlserver-query
(format " select c.name ,t.name from sys.columns c ,sys.types t, sys.objects o where c.user_type_id=t.user_type_id and o.object_id = c.object_id and o.name='%s'" tablename)
sstec-connection-4-sqlserver
)
)
(defun sstec-setter-getter(csharp-type filed-name)
(let(field property)
(if (string-match "[A-Z0-9_]" filed-name)
(progn (setq field (concat "_" filed-name))
(setq property filed-name))
(setq field filed-name)
(setq property (capitalize filed-name)))
(with-temp-buffer
(insert (concat "private " csharp-type " " field ";\n"))
(insert (concat "public " csharp-type " " property "\n"))
(insert "{\n")
(insert (format " set { %s = value ; }\n" field))
(insert (format " get { return %s ; }\n" field))
(insert "}\n")
(buffer-string))))
(defun sstec-generate-all-setter-getter-4table(tablename)
"为这张表生成所有的setter-getter ,以字符串形式返回."
(let (
(col-type-alist (sstec-query-table tablename))
field-type field-name)
(with-temp-buffer
(dolist (colomnname-type-item col-type-alist)
(setq field-type (sstec-get-csharp-type (cadr colomnname-type-item)))
(setq field-name (sstec-columnname2fieldname (car colomnname-type-item)))
(insert (sstec-setter-getter field-type field-name))
(insert "\n"))
(buffer-string)
)
)
)
(defun sstec-generate-class (setter-getters namespacename classname savepath)
"利用setter-getters 生成一个以`classname'为类名,namespace 为
`namespacename' 的csharp 实体保存到`savepath'路径下。
`setter-getters' is generated by function `sstec-generate-all-setter-getter-4table'
and `namespace' is namespace of generated csharp entity ,and `classname' is the name of
generated csharp entity . and the entity is saved in `savepath'"
(with-current-buffer (find-file-noselect
(expand-file-name
(concat classname ".cs") savepath))
(when (boundp 'flymake-mode)(flymake-mode -1) )
(erase-buffer)
(insert "using System;\n")
(insert "using System.Text;\n\n")
(insert (format "namespace %s\n" namespacename))
(insert "{\n")
(insert (format "public class %s\n" classname))
(insert "{\n")
(insert "\n #region Properties\n")
(insert setter-getters)
(insert " #endregion\n")
(insert "}\n")
(insert "}\n")
(when (featurep 'csharp-mode)
(csharp-mode)
(indent-region (point-min) (point-max)))
(save-buffer)
(kill-this-buffer)))
(defun sstec-generate-all-classes(namespace savepath)
(unless (and sstec-connection-4-sqlserver
(equal (process-status (nth 0 sstec-connection-4-sqlserver)) 'run))
(setq sstec-connection-4-sqlserver (call-interactively 'sqlserver-query-create-connection)))
(dolist (tablename (sstec-query-all-tablename-in-db))
(let ((classname (sstec-tablename2classname tablename) )
(setter-getters (sstec-generate-all-setter-getter-4table tablename)))
(sstec-generate-class setter-getters namespace classname savepath)))
(sqlserver-query-close-connection sstec-connection-4-sqlserver)
)
(defun sqlserver-table2entity-4csharp-interactively ()
(interactive)
(let ((namespace (read-string "csharp namespace name:" "" nil ""))
(savepath (read-directory-name "save generated class to directory:" )))
(if (not (file-directory-p savepath)) (make-directory savepath))
(sstec-generate-all-classes namespace savepath)
(dired savepath)))
(provide 'sqlserver-table2entity-4csharp)