Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
梦境迷离
Scala Macro Tools
提交
ab74b018
S
Scala Macro Tools
项目概览
梦境迷离
/
Scala Macro Tools
上一次同步 大约 1 年
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
Scala Macro Tools
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
ab74b018
编写于
11月 03, 2022
作者:
梦境迷离
提交者:
GitHub
11月 03, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix some minors (#256)
上级
049effd2
变更
37
隐藏空白更改
内联
并排
Showing
37 changed file
with
356 addition
and
463 deletion
+356
-463
README.md
README.md
+3
-3
smt-annotations/src/main/scala/org/bitlap/tools/LogLevel.scala
...nnotations/src/main/scala/org/bitlap/tools/LogLevel.scala
+0
-46
smt-annotations/src/main/scala/org/bitlap/tools/elapsed.scala
...annotations/src/main/scala/org/bitlap/tools/elapsed.scala
+2
-3
smt-annotations/src/main/scala/org/bitlap/tools/internal/elapsedMacro.scala
...c/main/scala/org/bitlap/tools/internal/elapsedMacro.scala
+11
-16
smt-annotations/src/main/scala/org/bitlap/tools/internal/equalsAndHashCodeMacro.scala
...la/org/bitlap/tools/internal/equalsAndHashCodeMacro.scala
+1
-1
smt-annotations/src/main/scala/org/bitlap/tools/internal/internal.scala
...s/src/main/scala/org/bitlap/tools/internal/internal.scala
+0
-0
smt-annotations/src/main/scala/org/bitlap/tools/internal/logMacro.scala
...s/src/main/scala/org/bitlap/tools/internal/logMacro.scala
+6
-15
smt-annotations/src/main/scala/org/bitlap/tools/internal/toStringMacro.scala
.../main/scala/org/bitlap/tools/internal/toStringMacro.scala
+0
-2
smt-annotations/src/main/scala/org/bitlap/tools/log.scala
smt-annotations/src/main/scala/org/bitlap/tools/log.scala
+2
-3
smt-annotations/src/main/scala/org/bitlap/tools/logs/LogType.scala
...ations/src/main/scala/org/bitlap/tools/logs/LogType.scala
+19
-24
smt-annotations/src/main/scala/org/bitlap/tools/logs/extension/ScalaLoggingLazyImpl.scala
...rg/bitlap/tools/logs/extension/ScalaLoggingLazyImpl.scala
+2
-3
smt-annotations/src/main/scala/org/bitlap/tools/logs/extension/ScalaLoggingStrictImpl.scala
.../bitlap/tools/logs/extension/ScalaLoggingStrictImpl.scala
+2
-3
smt-annotations/src/main/scala/org/bitlap/tools/logs/impl/JLogImpl.scala
.../src/main/scala/org/bitlap/tools/logs/impl/JLogImpl.scala
+4
-5
smt-annotations/src/main/scala/org/bitlap/tools/logs/impl/Log4J2Impl.scala
...rc/main/scala/org/bitlap/tools/logs/impl/Log4J2Impl.scala
+4
-5
smt-annotations/src/main/scala/org/bitlap/tools/logs/impl/Slf4jImpl.scala
...src/main/scala/org/bitlap/tools/logs/impl/Slf4jImpl.scala
+4
-5
smt-annotations/src/main/scala/org/bitlap/tools/logs/package.scala
...ations/src/main/scala/org/bitlap/tools/logs/package.scala
+3
-5
smt-annotations/src/test/scala/org/bitlap/tools/ElapsedTest.scala
...tations/src/test/scala/org/bitlap/tools/ElapsedTest.scala
+30
-30
smt-annotations/src/test/scala/org/bitlap/tools/LogTest.scala
...annotations/src/test/scala/org/bitlap/tools/LogTest.scala
+39
-40
smt-cache/src/main/scala/org/bitlap/cache/CacheStrategy.scala
...cache/src/main/scala/org/bitlap/cache/CacheStrategy.scala
+3
-3
smt-common/src/main/scala/org/bitlap/common/Options.scala
smt-common/src/main/scala/org/bitlap/common/Options.scala
+4
-4
smt-common/src/main/scala/org/bitlap/common/jdbc/ResultSetTransformer.scala
...n/scala/org/bitlap/common/jdbc/ResultSetTransformer.scala
+3
-0
smt-common/src/test/scala/org/bitlap/common/TestEntity.scala
smt-common/src/test/scala/org/bitlap/common/TestEntity.scala
+1
-1
smt-csv-derive/src/main/scala/org/bitlap/csv/derive/DeriveCsvConverter.scala
...main/scala/org/bitlap/csv/derive/DeriveCsvConverter.scala
+1
-1
smt-csv/src/main/scala/org/bitlap/csv/FileUtils.scala
smt-csv/src/main/scala/org/bitlap/csv/FileUtils.scala
+10
-0
smt-csv/src/main/scala/org/bitlap/csv/Reader.scala
smt-csv/src/main/scala/org/bitlap/csv/Reader.scala
+3
-3
smt-csv/src/main/scala/org/bitlap/csv/ReaderBuilder.scala
smt-csv/src/main/scala/org/bitlap/csv/ReaderBuilder.scala
+9
-9
smt-csv/src/main/scala/org/bitlap/csv/ReaderImplicits.scala
smt-csv/src/main/scala/org/bitlap/csv/ReaderImplicits.scala
+9
-9
smt-csv/src/main/scala/org/bitlap/csv/ScalableHelper.scala
smt-csv/src/main/scala/org/bitlap/csv/ScalableHelper.scala
+0
-43
smt-csv/src/main/scala/org/bitlap/csv/Writer.scala
smt-csv/src/main/scala/org/bitlap/csv/Writer.scala
+3
-3
smt-csv/src/main/scala/org/bitlap/csv/WriterBuilder.scala
smt-csv/src/main/scala/org/bitlap/csv/WriterBuilder.scala
+9
-9
smt-csv/src/main/scala/org/bitlap/csv/WriterImplicits.scala
smt-csv/src/main/scala/org/bitlap/csv/WriterImplicits.scala
+9
-9
smt-csv/src/main/scala/org/bitlap/csv/internal/ReaderBuilderMacro.scala
...in/scala/org/bitlap/csv/internal/ReaderBuilderMacro.scala
+47
-47
smt-csv/src/main/scala/org/bitlap/csv/internal/WriterBuilderMacro.scala
...in/scala/org/bitlap/csv/internal/WriterBuilderMacro.scala
+32
-32
smt-csv/src/test/scala/org/bitlap/csv/test/ConverterTest.scala
...sv/src/test/scala/org/bitlap/csv/test/ConverterTest.scala
+8
-8
smt-csv/src/test/scala/org/bitlap/csv/test/CustomBuilderTest.scala
...rc/test/scala/org/bitlap/csv/test/CustomBuilderTest.scala
+34
-34
smt-csv/src/test/scala/org/bitlap/csv/test/ReaderTsvTest.scala
...sv/src/test/scala/org/bitlap/csv/test/ReaderTsvTest.scala
+5
-5
smt-csv/src/test/scala/org/bitlap/csv/test/WriterAndReaderTest.scala
.../test/scala/org/bitlap/csv/test/WriterAndReaderTest.scala
+34
-34
未找到文件。
README.md
浏览文件 @
ab74b018
...
...
@@ -34,7 +34,7 @@
-
通用的宏操作API的封装。
-
对象转换器(零依赖,类型安全)。
-
JDBC
`ResultSet`
对象转样例类
。
-
JDBC
`ResultSet`
转换器
。
```
scala
"org.bitlap"
%%
"smt-common"
%
"<VERSION>"
...
...
@@ -42,7 +42,7 @@
## csv
-
CSV/TSV文件
解析器
(零依赖,类型安全)。
-
CSV/TSV文件
读写工具
(零依赖,类型安全)。
```
scala
"org.bitlap"
%%
"smt-csv"
%
"<VERSION>"
...
...
@@ -50,7 +50,7 @@
## csv-derive
-
为Scala
`case class`
自动派生
`Converter`
实例
。
-
自动派生CSV/TSV文件读写工具
。
```
scala
"org.bitlap"
%%
"smt-csv-derive"
%
"<VERSION>"
...
...
smt-annotations/src/main/scala/org/bitlap/tools/LogLevel.scala
已删除
100644 → 0
浏览文件 @
049effd2
/*
* Copyright (c) 2022 bitlap
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package
org.bitlap.tools
/** Log Level for elapsed
*
* @author
* 梦境迷离
* @since 2021/8/7
* @version 1.0
*/
object
LogLevel
extends
Enumeration
{
type
LogLevel
=
Value
val
INFO
,
WARN
,
DEBUG
=
Value
private
[
bitlap
]
def
getLogLevel
(
shortType
:
String
)
:
LogLevel
=
{
// TODO not good way
val
tpe1
=
s
"$PACKAGE.$shortType"
// LogLevel.INFO
val
tpe2
=
s
"$PACKAGE.LogLevel.$shortType"
// INFO
val
v
=
LogLevel
.
values
.
find
{
p
=>
s
"$PACKAGE.LogLevel.${p.toString}"
==
tpe1
||
s
"$PACKAGE.LogLevel.${p.toString}"
==
tpe2
||
s
"$PACKAGE.LogLevel.${p.toString}"
==
shortType
}.
get
.
toString
LogLevel
.
withName
(
v
)
}
}
smt-annotations/src/main/scala/org/bitlap/tools/elapsed.scala
浏览文件 @
ab74b018
...
...
@@ -21,10 +21,9 @@
package
org.bitlap.tools
import
org.bitlap.tools.LogLevel.LogLevel
import
org.bitlap.tools.internal.elapsedMacro.ElapsedProcessor
import
scala.annotation.
{
compileTimeOnly
,
StaticAnnotation
}
import
scala.annotation.
_
/** annotation to record method cost time.
*
...
...
@@ -38,6 +37,6 @@ import scala.annotation.{ compileTimeOnly, StaticAnnotation }
* @version 1.0
*/
@compileTimeOnly
(
"enable macro to expand macro annotations"
)
final
class
elapsed
(
limit
:
Int
,
logLevel
:
LogLevel
)
extends
StaticAnnotation
{
final
class
elapsed
(
limit
:
Int
,
logLevel
:
String
)
extends
StaticAnnotation
{
def
macroTransform
(
annottees
:
Any*
)
:
Any
=
macro
ElapsedProcessor
.
impl
}
smt-annotations/src/main/scala/org/bitlap/tools/internal/elapsedMacro.scala
浏览文件 @
ab74b018
...
...
@@ -21,9 +21,6 @@
package
org.bitlap.tools.internal
import
org.bitlap.tools.LogLevel.LogLevel
import
org.bitlap.tools.
{
LogLevel
,
PACKAGE
}
import
scala.reflect.macros.whitebox
/**
...
...
@@ -47,16 +44,9 @@ object elapsedMacro {
private
lazy
val
start
:
c.universe.TermName
=
TermName
(
"$elapsedBegin"
)
private
lazy
val
valDef
:
c.universe.TermName
=
TermName
(
"$elapsed"
)
private
def
getLogLevel
(
logLevel
:
Tree
)
:
LogLevel
=
if
(
logLevel
.
children
.
exists
(
t
=>
t
.
toString
().
contains
(
PACKAGE
)))
{
evalTree
(
logLevel
)
}
else
{
LogLevel
.
getLogLevel
(
logLevel
.
toString
())
}
private
val
extractOptions
:
(
Int
,
LogLevel
)
=
c
.
prefix
.
tree
match
{
private
val
extractOptions
:
(
Int
,
String
)
=
c
.
prefix
.
tree
match
{
case
q
"new elapsed(limit=$limit, logLevel=$logLevel)"
=>
(
evalTree
(
limit
.
asInstanceOf
[
Tree
]),
getLogLevel
(
logLevel
.
asInstanceOf
[
Tree
]))
(
evalTree
(
limit
.
asInstanceOf
[
Tree
]),
evalTree
[
String
]
(
logLevel
.
asInstanceOf
[
Tree
]))
case
_
=>
c
.
abort
(
c
.
enclosingPosition
,
ErrorMessage
.
UNEXPECTED_PATTERN
)
}
...
...
@@ -74,10 +64,15 @@ object elapsedMacro {
if
(
log
.
isEmpty
)
{
// if there is no slf4j log, print it to the console
getLog
(
classNameAndMethodName
,
q
"_root_.scala.Predef.println"
)
}
else
{
extractOptions
.
_2
match
{
case
LogLevel
.
INFO
=>
getLog
(
classNameAndMethodName
,
q
"${log.get}.info"
)
case
LogLevel
.
DEBUG
=>
getLog
(
classNameAndMethodName
,
q
"${log.get}.debug"
)
case
LogLevel
.
WARN
=>
getLog
(
classNameAndMethodName
,
q
"${log.get}.warn"
)
extractOptions
.
_2
.
toLowerCase
match
{
case
"info"
=>
getLog
(
classNameAndMethodName
,
q
"${log.get}.info"
)
case
"debug"
=>
getLog
(
classNameAndMethodName
,
q
"${log.get}.debug"
)
case
"warn"
=>
getLog
(
classNameAndMethodName
,
q
"${log.get}.warn"
)
case
_
=>
c
.
abort
(
c
.
enclosingPosition
,
s
"${extractOptions._2.toLowerCase} is not in the supported list: info,debug,warn"
)
}
}
}
...
...
smt-annotations/src/main/scala/org/bitlap/tools/internal/equalsAndHashCodeMacro.scala
浏览文件 @
ab74b018
...
...
@@ -53,7 +53,7 @@ object equalsAndHashCodeMacro {
*/
private
def
getInternalFieldsTermNameExcludeLocal
(
annotteeClassDefinitions
:
Seq
[
Tree
])
:
Seq
[
TermName
]
=
{
if
(
annotteeClassDefinitions
.
exists
(
f
=>
isNotLocalClassMember
(
f
)))
{
c
.
info
(
c
.
enclosingPosition
,
s
"There is a non private class definition inside the class"
,
true
)
c
.
info
(
c
.
enclosingPosition
,
s
"There is a non private class definition inside the class"
,
force
=
true
)
}
getClassMemberValDefs
(
annotteeClassDefinitions
)
.
filter
(
p
=>
...
...
smt-annotations/src/main/scala/org/bitlap/tools/internal/
macros
.scala
→
smt-annotations/src/main/scala/org/bitlap/tools/internal/
internal
.scala
浏览文件 @
ab74b018
文件已移动
smt-annotations/src/main/scala/org/bitlap/tools/internal/logMacro.scala
浏览文件 @
ab74b018
...
...
@@ -21,9 +21,8 @@
package
org.bitlap.tools.internal
import
org.bitlap.tools.logs._
import
org.bitlap.tools.logs.LogType._
import
org.bitlap.tools.logs.
{
LogArgument
,
LogType
}
import
org.bitlap.tools.
{
logs
,
PACKAGE
}
import
scala.reflect.macros.whitebox
...
...
@@ -38,24 +37,16 @@ object logMacro {
import
c.universe._
private
val
extractOptions
:
logs.LogType.Value
=
c
.
prefix
.
tree
match
{
private
val
extractOptions
:
String
=
c
.
prefix
.
tree
match
{
case
q
"new log(logType=$logType)"
=>
val
tpe
=
getLogType
(
logType
.
asInstanceOf
[
Tree
])
tpe
evalTree
(
logType
.
asInstanceOf
[
Tree
])
case
q
"new log($logType)"
=>
val
tpe
=
getLogType
(
logType
.
asInstanceOf
[
Tree
])
tpe
evalTree
(
logType
.
asInstanceOf
[
Tree
])
case
q
"new log()"
=>
LogType
.
JLog
case
_
=>
c
.
abort
(
c
.
enclosingPosition
,
ErrorMessage
.
UNEXPECTED_PATTERN
)
case
_
=>
c
.
abort
(
c
.
enclosingPosition
,
s
"${ErrorMessage.UNEXPECTED_PATTERN}"
)
}
private
def
getLogType
(
logType
:
Tree
)
:
LogType
=
if
(
logType
.
children
.
exists
(
t
=>
t
.
toString
().
contains
(
PACKAGE
)))
{
evalTree
(
logType
)
}
else
{
LogType
.
getLogType
(
logType
.
toString
())
}
private
def
logTree
(
annottees
:
Seq
[
c.universe.Expr
[
Any
]])
:
c.universe.Tree
=
{
val
buildArg
=
(
name
:
Name
)
=>
LogArgument
(
name
.
toTermName
.
decodedName
.
toString
,
isClass
=
true
)
(
annottees
.
map
(
_
.
tree
)
match
{
...
...
smt-annotations/src/main/scala/org/bitlap/tools/internal/toStringMacro.scala
浏览文件 @
ab74b018
...
...
@@ -30,8 +30,6 @@ import scala.reflect.macros.whitebox
*/
object
toStringMacro
{
private
final
case
class
Argument
(
includeInternalFields
:
Boolean
,
includeFieldNames
:
Boolean
,
callSuper
:
Boolean
)
class
ToStringProcessor
(
override
val
c
:
whitebox.Context
)
extends
AbstractMacroProcessor
(
c
)
{
import
c.universe._
...
...
smt-annotations/src/main/scala/org/bitlap/tools/log.scala
浏览文件 @
ab74b018
...
...
@@ -21,10 +21,9 @@
package
org.bitlap.tools
import
org.bitlap.tools.logs.LogType
import
org.bitlap.tools.internal.logMacro
import
scala.annotation.
{
compileTimeOnly
,
StaticAnnotation
}
import
scala.annotation.
_
/** annotation to generate log.
*
...
...
@@ -36,6 +35,6 @@ import scala.annotation.{ compileTimeOnly, StaticAnnotation }
* @version 1.0
*/
@compileTimeOnly
(
"enable macro to expand macro annotations"
)
final
class
log
(
logType
:
LogType.LogType
=
LogType
.
JLog
)
extends
StaticAnnotation
{
final
class
log
(
logType
:
String
=
"JLog"
)
extends
StaticAnnotation
{
def
macroTransform
(
annottees
:
Any*
)
:
Any
=
macro
logMacro
.
LogProcessor
.
impl
}
smt-annotations/src/main/scala/org/bitlap/tools/logs/LogType.scala
浏览文件 @
ab74b018
...
...
@@ -21,40 +21,35 @@
package
org.bitlap.tools.logs
import
org.bitlap.tools.PACKAGE
import
org.bitlap.tools.logs.extension.
{
ScalaLoggingLazyImpl
,
ScalaLoggingStrictImpl
}
import
org.bitlap.tools.logs.impl.
{
JLogImpl
,
Log4J2Impl
,
Slf4jImpl
}
import
org.bitlap.tools.logs.extension._
import
org.bitlap.tools.logs.impl._
/** @author
* 梦境迷离
* @version 1.0,2022/3/29
*/
object
LogType
extends
Enumeration
{
object
LogType
{
type
LogType
=
Value
val
JLog
,
Log4j2
,
Slf4j
,
ScalaLoggingLazy
,
ScalaLoggingStrict
=
Value
val
JLog
=
"JLog"
val
Log4j2
=
"Log4j2"
val
Slf4j
=
"Slf4j"
val
ScalaLoggingLazy
=
"ScalaLoggingLazy"
val
ScalaLoggingStrict
=
"ScalaLoggingStrict"
private
lazy
val
types
:
Map
[
LogType
,
BaseLog
]
=
Map
(
private
lazy
val
types
:
Map
[
String
,
BaseLog
]
=
Map
(
JLogImpl
.
`type`
->
JLogImpl
,
Log4J2Impl
.
`type`
->
Log4J2Impl
,
Slf4jImpl
.
`type`
->
Slf4jImpl
,
ScalaLoggingStrictImpl
.
`type`
->
ScalaLoggingStrictImpl
,
ScalaLoggingLazyImpl
.
`type`
->
ScalaLoggingLazyImpl
)
def
getLogImpl
(
logType
:
LogType
)
:
BaseLog
=
types
.
getOrElse
(
logType
,
default
=
throw
new
Exception
(
s
"Not support log type: $logType"
))
// TODO not use Enumeration
def
getLogType
(
shortType
:
String
)
:
LogType
=
{
val
tpe1
=
s
"$PACKAGE.logs.$shortType"
// LogType.JLog
val
tpe2
=
s
"$PACKAGE.logs.LogType.$shortType"
// JLog
val
v
=
LogType
.
values
.
find
{
p
=>
s
"$PACKAGE.logs.LogType.${p.toString}"
==
tpe1
||
s
"$PACKAGE.logs.LogType.${p.toString}"
==
tpe2
||
s
"$PACKAGE.logs.LogType.${p.toString}"
==
shortType
}
.
getOrElse
(
throw
new
Exception
(
s
"Not support log type: $shortType"
))
.
toString
LogType
.
withName
(
v
)
}
).
map
(
kv
=>
kv
.
_1
.
toLowerCase
->
kv
.
_2
)
val
values
=
types
.
keySet
def
getLogImpl
(
logType
:
String
)
:
BaseLog
=
types
.
getOrElse
(
logType
.
toLowerCase
,
default
=
throw
new
Exception
(
s
"$logType is not in the supported list: ${values.mkString("
,
")}"
)
)
}
smt-annotations/src/main/scala/org/bitlap/tools/logs/extension/ScalaLoggingLazyImpl.scala
浏览文件 @
ab74b018
...
...
@@ -21,8 +21,7 @@
package
org.bitlap.tools.logs.extension
import
org.bitlap.tools.logs.LogType.LogType
import
org.bitlap.tools.logs.
{
BaseLog
,
LogArgument
,
LogType
}
import
org.bitlap.tools.logs._
import
scala.reflect.macros.whitebox
...
...
@@ -35,7 +34,7 @@ import scala.reflect.macros.whitebox
*/
object
ScalaLoggingLazyImpl
extends
BaseLog
{
override
val
`
type
`:
LogType
=
LogType
.
ScalaLoggingLazy
override
val
`
type
`:
String
=
LogType
.
ScalaLoggingLazy
override
def
getTemplate
(
c
:
whitebox.Context
)(
logArgument
:
LogArgument
)
:
c.Tree
=
{
import
c.universe._
...
...
smt-annotations/src/main/scala/org/bitlap/tools/logs/extension/ScalaLoggingStrictImpl.scala
浏览文件 @
ab74b018
...
...
@@ -21,8 +21,7 @@
package
org.bitlap.tools.logs.extension
import
org.bitlap.tools.logs.LogType.LogType
import
org.bitlap.tools.logs.
{
BaseLog
,
LogArgument
,
LogType
}
import
org.bitlap.tools.logs._
import
scala.reflect.macros.whitebox
...
...
@@ -35,7 +34,7 @@ import scala.reflect.macros.whitebox
*/
object
ScalaLoggingStrictImpl
extends
BaseLog
{
override
val
`
type
`:
LogType
=
LogType
.
ScalaLoggingStrict
override
val
`
type
`:
String
=
LogType
.
ScalaLoggingStrict
override
def
getTemplate
(
c
:
whitebox.Context
)(
logArgument
:
LogArgument
)
:
c.Tree
=
{
import
c.universe._
...
...
smt-annotations/src/main/scala/org/bitlap/tools/logs/impl/JLogImpl.scala
浏览文件 @
ab74b018
...
...
@@ -21,8 +21,7 @@
package
org.bitlap.tools.logs.impl
import
org.bitlap.tools.logs.
{
BaseLog
,
LogArgument
,
LogType
}
import
org.bitlap.tools.logs.LogType.LogType
import
org.bitlap.tools.logs._
import
scala.reflect.macros.whitebox
...
...
@@ -32,17 +31,17 @@ import scala.reflect.macros.whitebox
*/
object
JLogImpl
extends
BaseLog
{
override
val
`
type
`:
LogType
=
LogType
.
JLog
override
val
`
type
`:
String
=
LogType
.
JLog
override
def
getTemplate
(
c
:
whitebox.Context
)(
logArgument
:
LogArgument
)
:
c.Tree
=
{
import
c.universe._
if
(
logArgument
.
isClass
)
{
q
"""@transient private final val log: java.util.logging.Logger = java.util.logging.Logger.getLogger(classOf[${TypeName(
logArgument.className
Str
logArgument.className
)}].getName)"""
}
else
{
q
"""@transient private final val log: java.util.logging.Logger = java.util.logging.Logger.getLogger(${TermName(
logArgument.className
Str
logArgument.className
)}.getClass.getName)"""
}
}
...
...
smt-annotations/src/main/scala/org/bitlap/tools/logs/impl/Log4J2Impl.scala
浏览文件 @
ab74b018
...
...
@@ -21,8 +21,7 @@
package
org.bitlap.tools.logs.impl
import
org.bitlap.tools.logs.
{
BaseLog
,
LogArgument
,
LogType
}
import
org.bitlap.tools.logs.LogType.LogType
import
org.bitlap.tools.logs._
import
scala.reflect.macros.whitebox
...
...
@@ -32,17 +31,17 @@ import scala.reflect.macros.whitebox
*/
object
Log4J2Impl
extends
BaseLog
{
override
val
`
type
`:
LogType
=
LogType
.
Log4j2
override
val
`
type
`:
String
=
LogType
.
Log4j2
override
def
getTemplate
(
c
:
whitebox.Context
)(
logArgument
:
LogArgument
)
:
c.Tree
=
{
import
c.universe._
if
(
logArgument
.
isClass
)
{
q
"""@transient private final val log: org.apache.logging.log4j.Logger = org.apache.logging.log4j.LogManager.getLogger(classOf[${TypeName(
logArgument.className
Str
logArgument.className
)}].getName)"""
}
else
{
q
"""@transient private final val log: org.apache.logging.log4j.Logger = org.apache.logging.log4j.LogManager.getLogger(${TermName(
logArgument.className
Str
logArgument.className
)}.getClass.getName)"""
}
}
...
...
smt-annotations/src/main/scala/org/bitlap/tools/logs/impl/Slf4jImpl.scala
浏览文件 @
ab74b018
...
...
@@ -21,8 +21,7 @@
package
org.bitlap.tools.logs.impl
import
org.bitlap.tools.logs.
{
BaseLog
,
LogArgument
,
LogType
}
import
org.bitlap.tools.logs.LogType.LogType
import
org.bitlap.tools.logs._
import
scala.reflect.macros.whitebox
...
...
@@ -32,17 +31,17 @@ import scala.reflect.macros.whitebox
*/
object
Slf4jImpl
extends
BaseLog
{
override
val
`
type
`:
LogType
=
LogType
.
Slf4j
override
val
`
type
`:
String
=
LogType
.
Slf4j
override
def
getTemplate
(
c
:
whitebox.Context
)(
logArgument
:
LogArgument
)
:
c.Tree
=
{
import
c.universe._
if
(
logArgument
.
isClass
)
{
q
"""@transient private final val log: org.slf4j.Logger = org.slf4j.LoggerFactory.getLogger(classOf[${TypeName(
logArgument.className
Str
logArgument.className
)}])"""
}
else
{
q
"""@transient private final val log: org.slf4j.Logger = org.slf4j.LoggerFactory.getLogger(${TermName(
logArgument.className
Str
logArgument.className
)}.getClass)"""
}
}
...
...
smt-annotations/src/main/scala/org/bitlap/tools/logs/package.scala
浏览文件 @
ab74b018
...
...
@@ -21,8 +21,6 @@
package
org.bitlap.tools
import
org.bitlap.tools.logs.LogType.LogType
import
scala.reflect.macros.whitebox
/** @author
...
...
@@ -37,18 +35,18 @@ package object logs {
*/
private
[
tools
]
trait
BaseLog
{
val
`
type
`:
LogType
val
`
type
`:
String
def
getTemplate
(
c
:
whitebox.Context
)(
logArgument
:
LogArgument
)
:
c.Tree
}
/** @author
* 梦境迷离
* @param className
Str
* @param className
* The class Name.
* @param isClass
* Is it a class?
*/
private
[
tools
]
case
class
LogArgument
(
classNameStr
:
String
,
isClass
:
Boolean
)
private
[
tools
]
final
case
class
LogArgument
(
className
:
String
,
isClass
:
Boolean
)
}
smt-annotations/src/test/scala/org/bitlap/tools/ElapsedTest.scala
浏览文件 @
ab74b018
...
...
@@ -40,22 +40,22 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
// Duration and TimeUnit must Full class name
"""
| class A {
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.INFO
)
| @elapsed(limit = 1, logLevel =
"info"
)
| def i = ???
| }
|
| class B {
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.WARN
)
| @elapsed(limit = 1, logLevel =
"warn"
)
| def j = ???
| }
|
| class C {
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.DEBUG
)
| @elapsed(limit = 1, logLevel =
"debug"
)
| def j = ???
| }
|
| class D {
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.INFO
)
| @elapsed(limit = 1, logLevel =
"info"
)
| def i:String = ???
| }
| val a = new A()
...
...
@@ -69,13 +69,13 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
// Duration and TimeUnit must Full class name
"""
|class A {
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.INFO
)
| @elapsed(limit = 1, logLevel =
"info"
)
| def helloWorld: String = {
| println("hello world")
| "hello"
| }
|
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.INFO
)
| @elapsed(limit = 1, logLevel =
"info"
)
| def helloScala: String = {
| Thread.sleep(2000)
| println("hello world")
...
...
@@ -92,18 +92,18 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
// Duration and TimeUnit must Full class name
"""
| class A {
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.INFO
)
| @elapsed(limit = 1, logLevel =
"info"
)
| def helloWorld: String = {
| println("") ; println(""); ""
| }
|
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.INFO
)
| @elapsed(limit = 1, logLevel =
"info"
)
| def helloScala1: String = { println("") ; println(""); ""}
|
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.INFO
)
| @elapsed(limit = 1, logLevel =
"info"
)
| def helloScala2: String = { println("") ; println(""); "" }
|
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.INFO
)
| @elapsed(limit = 1, logLevel =
"info"
)
| def helloScala3: String = {
| val s = "hello"
| val x = "world"
...
...
@@ -118,7 +118,7 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
// Duration and TimeUnit must Full class name
"""
| class A {
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.INFO
)
| @elapsed(limit = 1, logLevel =
"info"
)
| def helloScala1: String = {
| val s = "hello"
| if (s == "hello") {
...
...
@@ -133,7 +133,7 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
| a.helloScala1
|
| class B {
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.INFO
)
| @elapsed(limit = 1, logLevel =
"info"
)
| def helloScala11: String = {
| val s = "hello"
| if (s == "hello") {
...
...
@@ -155,7 +155,7 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
@elapsed
(
limit
=
1
,
logLevel
=
org
.
bitlap
.
tools
.
LogLevel
.
INFO
logLevel
=
"info"
)
def
helloScala1
:
Future
[
String
]
=
{
Thread
.
sleep
(
1000
)
...
...
@@ -164,7 +164,7 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
@elapsed
(
limit
=
1
,
logLevel
=
org
.
bitlap
.
tools
.
LogLevel
.
DEBUG
logLevel
=
"info"
)
def
helloScala2
:
Future
[
String
]
=
{
Thread
.
sleep
(
2000
)
...
...
@@ -175,7 +175,7 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
@elapsed
(
limit
=
1
,
logLevel
=
org
.
bitlap
.
tools
.
LogLevel
.
WARN
logLevel
=
"info"
)
def
helloScala3
:
Future
[
String
]
=
Future
{
"hello world"
...
...
@@ -187,20 +187,20 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
class
B
{
@elapsed
(
limit
=
1
,
logLevel
=
org
.
bitlap
.
tools
.
LogLevel
.
WARN
logLevel
=
"info"
)
def
helloScala
(
t
:
String
)
:
Future
[
String
]
=
Future
(
t
)(
scala
.
concurrent
.
ExecutionContext
.
Implicits
.
global
)
@elapsed
(
limit
=
1
,
logLevel
=
org
.
bitlap
.
tools
.
LogLevel
.
WARN
logLevel
=
"warn"
)
def
helloScala11
(
t
:
String
)
:
Future
[
String
]
=
Future
(
t
)(
scala
.
concurrent
.
ExecutionContext
.
Implicits
.
global
)
@elapsed
(
limit
=
1
,
logLevel
=
org
.
bitlap
.
tools
.
LogLevel
.
INFO
logLevel
=
"info"
)
def
helloScala2
:
String
=
{
val
s
=
Future
(
""
)(
scala
.
concurrent
.
ExecutionContext
.
Implicits
.
global
)
...
...
@@ -214,13 +214,13 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
| object A {
| private final val log1: org.slf4j.Logger = org.slf4j.LoggerFactory.getLogger(A.getClass)
|
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.INFO
)
| @elapsed(limit = 1, logLevel =
"info"
)
| def helloScala1: Future[String] = {
| Thread.sleep(1000)
| Future.successful("hello world")
| }
|
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.DEBUG
)
| @elapsed(limit = 1, logLevel =
"debug"
)
| def helloScala2: Future[String] = {
| Thread.sleep(2000)
| Future {
...
...
@@ -228,7 +228,7 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
| }(scala.concurrent.ExecutionContext.Implicits.global)
| }
|
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.WARN
)
| @elapsed(limit = 1, logLevel =
"warn"
)
| def helloScala3: Future[String] = Future {
| "hello world"
| }(scala.concurrent.ExecutionContext.Implicits.global)
...
...
@@ -239,14 +239,14 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
"elapsed8"
should
"ok at input args"
in
{
@elapsed
(
limit
=
1
,
logLevel
=
LogLevel
.
WARN
logLevel
=
"warn"
)
def
helloScala1
:
String
=
{
println
(
""
)
println
(
""
)
"hello"
}
@elapsed
(
limit
=
1
,
logLevel
=
LogLevel
.
INFO
)
@elapsed
(
limit
=
1
,
logLevel
=
"info"
)
def
helloScala2
:
String
=
{
println
(
""
)
println
(
""
)
...
...
@@ -255,7 +255,7 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
@elapsed
(
limit
=
1
,
logLevel
=
org
.
bitlap
.
tools
.
LogLevel
.
WARN
logLevel
=
"warn"
)
def
helloScala3
:
String
=
{
println
(
""
)
...
...
@@ -269,7 +269,7 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
"elapsed9"
should
"failed at input args"
in
{
"""
|@elapsed(logLevel =
org.bitlap.tools.LogLevel.WARN
, limit = 1)
|@elapsed(logLevel =
"warn"
, limit = 1)
| def helloScala1: String = {
| println("")
| println("")
...
...
@@ -282,7 +282,7 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
@elapsed
(
limit
=
1
,
logLevel
=
org
.
bitlap
.
tools
.
LogLevel
.
INFO
logLevel
=
"info"
)
def
j
:
Int
=
{
var
i
=
1
...
...
@@ -305,7 +305,7 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
@elapsed
(
limit
=
1
,
logLevel
=
org
.
bitlap
.
tools
.
LogLevel
.
INFO
logLevel
=
"info"
)
def
k
:
Unit
=
{
var
i
=
1
...
...
@@ -340,7 +340,7 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
@elapsed
(
limit
=
1
,
logLevel
=
org
.
bitlap
.
tools
.
LogLevel
.
INFO
logLevel
=
"info"
)
def
l
:
Int
=
{
val
i
=
0
...
...
@@ -353,7 +353,7 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
@elapsed
(
limit
=
1
,
logLevel
=
org
.
bitlap
.
tools
.
LogLevel
.
INFO
logLevel
=
"info"
)
def
m
:
Int
=
{
var
i
=
1
...
...
@@ -377,7 +377,7 @@ class ElapsedTest extends AnyFlatSpec with Matchers {
"elapsed11"
should
"failed at abstract method"
in
{
"""
|abstract class A {
| @elapsed(limit = 1, logLevel =
org.bitlap.tools.LogLevel.WARN
)
| @elapsed(limit = 1, logLevel =
"warn"
)
| def hello:String
| }
|"""
.
stripMargin
shouldNot
compile
...
...
smt-annotations/src/test/scala/org/bitlap/tools/LogTest.scala
浏览文件 @
ab74b018
...
...
@@ -21,7 +21,6 @@
package
org.bitlap.tools
import
org.bitlap.tools.logs.LogType
import
org.scalatest.flatspec.AnyFlatSpec
import
org.scalatest.matchers.should.Matchers
...
...
@@ -39,8 +38,8 @@ class LogTest extends AnyFlatSpec with Matchers {
"""@log class TestClass2(val i: Int = 0, var j: Int)"""
should
compile
"""@log() class TestClass3(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.JLog
) class TestClass5(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.JLog
) class TestClass6(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
"JLog"
) class TestClass5(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
"JLog"
) class TestClass6(val i: Int = 0, var j: Int)"""
should
compile
}
"log3"
should
"ok on object"
in
{
...
...
@@ -51,8 +50,8 @@ class LogTest extends AnyFlatSpec with Matchers {
"""@log object TestClass2"""
should
compile
"""@log() object TestClass3"""
should
compile
"""@log object TestClass4"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.JLog
) object TestClass5"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.JLog
) object TestClass6"""
should
compile
"""@log(logType=
"JLog"
) object TestClass5"""
should
compile
"""@log(logType=
"JLog"
) object TestClass6"""
should
compile
}
"log4 log4j2"
should
"ok on object"
in
{
...
...
@@ -63,8 +62,8 @@ class LogTest extends AnyFlatSpec with Matchers {
"""@log object TestClass2"""
should
compile
"""@log() object TestClass3"""
should
compile
"""@log object TestClass4"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.Log4j2
) object TestClass5"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.Log4j2
) object TestClass6"""
should
compile
"""@log(logType=
"Log4j2"
) object TestClass5"""
should
compile
"""@log(logType=
"Log4j2"
) object TestClass6"""
should
compile
}
"log5 slf4j"
should
"ok on object"
in
{
...
...
@@ -75,8 +74,8 @@ class LogTest extends AnyFlatSpec with Matchers {
"""@log object TestClass2"""
should
compile
"""@log() object TestClass3"""
should
compile
"""@log object TestClass4"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.Slf4j
) object TestClass5"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.Slf4j
) object TestClass6"""
should
compile
"""@log(logType=
"Slf4j"
) object TestClass5"""
should
compile
"""@log(logType=
"Slf4j"
) object TestClass6"""
should
compile
}
"log6 log4j2"
should
"ok on class"
in
{
...
...
@@ -87,8 +86,8 @@ class LogTest extends AnyFlatSpec with Matchers {
"""@log class TestClass2(val i: Int = 0, var j: Int)"""
should
compile
"""@log() class TestClass3(val i: Int = 0, var j: Int)"""
should
compile
"""@log class TestClass4(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.Log4j2
) class TestClass5(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.Log4j2
) class TestClass6(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
"Log4j2"
) class TestClass5(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
"Log4j2"
) class TestClass6(val i: Int = 0, var j: Int)"""
should
compile
}
"log7 slf4j"
should
"ok on class"
in
{
...
...
@@ -99,10 +98,10 @@ class LogTest extends AnyFlatSpec with Matchers {
"""@toString @builder @log class TestClass2(val i: Int = 0, var j: Int)"""
should
compile
// Use with multiple annotations
"""@log() class TestClass3(val i: Int = 0, var j: Int)"""
should
compile
"""@log class TestClass4(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.Slf4j
) class TestClass5(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.Slf4j
) class TestClass6(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.Slf4j
) class TestClass6(val i: Int = 0, var j: Int){ log.info("hello world") }"""
should
compile
"""@log(logType =
org.bitlap.tools.logs.LogType.Slf4j
) class TestClass6(val i: Int = 0, var j: Int){ log.info("hello world") }"""
should
compile
"""@log(logType=
"Slf4j"
) class TestClass5(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
"Slf4j"
) class TestClass6(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
"Slf4j"
) class TestClass6(val i: Int = 0, var j: Int){ log.info("hello world") }"""
should
compile
"""@log(logType =
"Slf4j"
) class TestClass6(val i: Int = 0, var j: Int){ log.info("hello world") }"""
should
compile
}
"log8 slf4j"
should
"ok on class and has object"
in
{
...
...
@@ -113,13 +112,13 @@ class LogTest extends AnyFlatSpec with Matchers {
"""@toString @builder @log class TestClass2(val i: Int = 0, var j: Int)"""
should
compile
// Use with multiple annotations
"""@log() class TestClass3(val i: Int = 0, var j: Int)"""
should
compile
"""@log class TestClass4(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.Slf4j
) class TestClass5(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.Slf4j
) class TestClass6(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
org.bitlap.tools.logs.LogType.Slf4j
) class TestClass6(val i: Int = 0, var j: Int){ log.info("hello world") }"""
should
compile
"""@log(logType =
org.bitlap.tools.logs.LogType.Slf4j
) @builder class TestClass6(val i: Int = 0, var j: Int){ log.info("hello world") }
| @log(logType =
org.bitlap.tools.logs.LogType.Slf4j
) object TestClass6 { log.info("hello world");builder() }"""
.
stripMargin
should
compile
"""@log(logType=
"Slf4j"
) class TestClass5(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
"Slf4j"
) class TestClass6(val i: Int = 0, var j: Int)"""
should
compile
"""@log(logType=
"Slf4j"
) class TestClass6(val i: Int = 0, var j: Int){ log.info("hello world") }"""
should
compile
"""@log(logType =
"Slf4j"
) @builder class TestClass6(val i: Int = 0, var j: Int){ log.info("hello world") }
| @log(logType =
"Slf4j"
) object TestClass6 { log.info("hello world");builder() }"""
.
stripMargin
should
compile
@log
(
logType
=
org
.
bitlap
.
tools
.
logs
.
LogType
.
Slf4j
)
@log
(
logType
=
"Slf4j"
)
@builder
class
TestClass8
(
val
i
:
Int
=
0
,
var
j
:
Int
)
{
log
.
info
(
"hello world"
)
}
...
...
@@ -130,18 +129,18 @@ class LogTest extends AnyFlatSpec with Matchers {
"log9 slf4j"
should
"ok on class and it object"
in
{
"""
|@log(logType =
org.bitlap.tools.logs.LogType.Slf4j
) @builder class TestClass6(val i: Int = 0, var j: Int){ log.info("hello world") }
|@log(logType =
org.bitlap.tools.logs.LogType.Slf4j
) object TestClass6 { log.info("hello world"); builder()}
|@log(logType =
"Slf4j"
) @builder class TestClass6(val i: Int = 0, var j: Int){ log.info("hello world") }
|@log(logType =
"Slf4j"
) object TestClass6 { log.info("hello world"); builder()}
|"""
.
stripMargin
should
compile
}
"log10 slf4j"
should
"failed on case class"
in
{
"""
| @log(logType =
LogType.JLog
)
| @log(logType =
"JLog"
)
| @builder case class TestClass6_2(val i: Int = 0, var j: Int) {
| log.info("hello world")
| }
| @log(logType =
org.bitlap.tools.logs.LogType.Slf4j
) object TestClass6_2 {
| @log(logType =
"Slf4j"
) object TestClass6_2 {
| log.info("hello world"); builder()
| }
|"""
.
stripMargin
shouldNot
compile
...
...
@@ -149,22 +148,22 @@ class LogTest extends AnyFlatSpec with Matchers {
"log11 slf4j"
should
"ok on class and it object"
in
{
"""
| @log(logType =
org.bitlap.tools.logs.LogType.Slf4j
)
| @log(logType =
"Slf4j"
)
| @builder class TestClass6(val i: Int = 0, var j: Int) {
| log.info("hello world")
| }
|@log(logType =
org.bitlap.tools.logs.LogType.Slf4j
) object TestClass6 {
|@log(logType =
"Slf4j"
) object TestClass6 {
| log.info("hello world"); builder()
| }
|"""
.
stripMargin
should
compile
"""
| @builder
| @log(logType =
org.bitlap.tools.logs.LogType.Slf4j
)
| @log(logType =
"Slf4j"
)
| class TestClass6(val i: Int = 0, var j: Int) {
| log.info("hello world")
| }
|@log(logType =
org.bitlap.tools.logs.LogType.Slf4j
) object TestClass6 {
|@log(logType =
"Slf4j"
) object TestClass6 {
| log.info("hello world"); builder()
| }
|"""
.
stripMargin
should
compile
...
...
@@ -177,13 +176,13 @@ class LogTest extends AnyFlatSpec with Matchers {
@log
object
TestLog1
{
log
.
info
(
""
)
}
@log
(
logType
=
org
.
bitlap
.
tools
.
logs
.
LogType
.
Slf4j
)
class
TestLog2
()
{
@log
(
logType
=
"Slf4j"
)
class
TestLog2
()
{
log
.
info
(
""
)
}
@log
(
logType
=
JLog
)
class
TestLog3
()
{
@log
(
logType
=
"JLog"
)
class
TestLog3
()
{
log
.
info
(
""
)
}
@log
(
logType
=
LogType
.
Slf4j
)
class
TestLog4
()
{
@log
(
logType
=
"Slf4j"
)
class
TestLog4
()
{
log
.
info
(
""
)
}
}
...
...
@@ -191,19 +190,19 @@ class LogTest extends AnyFlatSpec with Matchers {
"log13 scala loggging lazy"
should
"ok when does not exists super class"
in
{
"""
| import org.bitlap.tools.logs.LogType
| @log(logType =
LogType.ScalaLoggingLazy
)
| @log(logType =
"ScalaLoggingLazy"
)
| class TestClass1(val i: Int = 0, var j: Int) {
| log.info("hello world")
| }
|"""
.
stripMargin
should
compile
@log
(
logType
=
LogType
.
ScalaLoggingLazy
)
@log
(
logType
=
"ScalaLoggingLazy"
)
class
TestClass2
(
val
i
:
Int
=
0
,
var
j
:
Int
)
{
log
.
info
(
"hello world"
)
}
"""
| import org.bitlap.tools.logs.LogType
| @log(logType =
LogType.ScalaLoggingLazy
)
| @log(logType =
"ScalaLoggingLazy"
)
| class TestClass3(val i: Int = 0, var j: Int) {
| log.info("hello world")
| }
...
...
@@ -211,7 +210,7 @@ class LogTest extends AnyFlatSpec with Matchers {
"""
| import org.bitlap.tools.logs.LogType
| @log(logType =
LogType.ScalaLoggingLazy
)
| @log(logType =
"ScalaLoggingLazy"
)
| object TestClass4 {
| log.info("hello world")
| }
...
...
@@ -221,19 +220,19 @@ class LogTest extends AnyFlatSpec with Matchers {
"log14 scala loggging strict"
should
"ok when exists super class"
in
{
"""
| import org.bitlap.tools.logs.LogType
| @log(logType =
LogType.ScalaLoggingStrict
)
| @log(logType =
"ScalaLoggingStrict"
)
| class TestClass1(val i: Int = 0, var j: Int) extends Serializable {
| log.info("hello world")
| }
|"""
.
stripMargin
should
compile
@log
(
logType
=
LogType
.
ScalaLoggingStrict
)
@log
(
logType
=
"ScalaLoggingStrict"
)
class
TestClass2
(
val
i
:
Int
=
0
,
var
j
:
Int
)
extends
Serializable
{
log
.
info
(
"hello world"
)
}
"""
| import org.bitlap.tools.logs.LogType
| @log(logType =
LogType.ScalaLoggingStrict
)
| @log(logType =
"ScalaLoggingStrict"
)
| class TestClass3(val i: Int = 0, var j: Int) extends Serializable {
| log.info("hello world")
| }
...
...
@@ -241,7 +240,7 @@ class LogTest extends AnyFlatSpec with Matchers {
"""
| import org.bitlap.tools.logs.LogType
| @log(logType =
LogType.ScalaLoggingStrict
)
| @log(logType =
"ScalaLoggingStrict"
)
| object TestClass4 extends Serializable {
| log.info("hello world")
| }
...
...
smt-cache/src/main/scala/org/bitlap/cache/CacheStrategy.scala
浏览文件 @
ab74b018
...
...
@@ -29,7 +29,7 @@ trait CacheStrategy
object
CacheStrategy
{
case
class
Lru
(
maxSize
:
Int
=
1000
)
extends
CacheStrategy
case
object
Normal
extends
CacheStrategy
case
class
CustomCacheStrategy
[
V
](
cacheAdapter
:
CacheAdapter
[
V
])
extends
CacheStrategy
final
case
class
Lru
(
maxSize
:
Int
=
1000
)
extends
CacheStrategy
final
case
object
Normal
extends
CacheStrategy
final
case
class
CustomCacheStrategy
[
V
](
cacheAdapter
:
CacheAdapter
[
V
])
extends
CacheStrategy
}
smt-common/src/main/scala/org/bitlap/common/Options.scala
浏览文件 @
ab74b018
...
...
@@ -29,12 +29,12 @@ sealed trait Options
object
Options
{
case
object
enableOptionDefaultsToNone
extends
Options
final
case
object
enableOptionDefaultsToNone
extends
Options
case
object
enableCollectionDefaultsToEmpty
extends
Options
final
case
object
enableCollectionDefaultsToEmpty
extends
Options
case
object
disableCollectionDefaultsToEmpty
extends
Options
final
case
object
disableCollectionDefaultsToEmpty
extends
Options
case
object
disableOptionDefaultsToNone
extends
Options
final
case
object
disableOptionDefaultsToNone
extends
Options
}
smt-common/src/main/scala/org/bitlap/common/jdbc/ResultSetTransformer.scala
浏览文件 @
ab74b018
...
...
@@ -40,6 +40,9 @@ trait ResultSetTransformer[T <: GenericRow] {
case
Types
.
INTEGER
=>
resultSet
.
getInt
(
name
)
case
Types
.
DOUBLE
=>
resultSet
.
getDouble
(
name
)
case
Types
.
TIMESTAMP
=>
resultSet
.
getTimestamp
(
name
)
case
Types
.
TIME
=>
resultSet
.
getTime
(
name
)
case
Types
.
FLOAT
=>
resultSet
.
getFloat
(
name
)
case
Types
.
DATE
=>
resultSet
.
getDate
(
name
)
case
_
=>
resultSet
.
getObject
(
name
)
}
}
...
...
smt-common/src/test/scala/org/bitlap/common/TestEntity.scala
浏览文件 @
ab74b018
...
...
@@ -25,7 +25,7 @@ package org.bitlap.common
* 梦境迷离
* @version 1.0,6/8/22
*/
case
class
TestEntity
(
final
case
class
TestEntity
(
name
:
String
,
id
:
String
,
key
:
String
,
...
...
smt-csv-derive/src/main/scala/org/bitlap/csv/derive/DeriveCsvConverter.scala
浏览文件 @
ab74b018
...
...
@@ -47,7 +47,7 @@ object DeriveCsvConverter {
val
typeName
=
clazzName
.
toTypeName
val
tree
=
q
"""
new Converter[$typeName] {
new
$packageName.
Converter[$typeName] {
override def toScala($lineTermName: String): _root_.scala.Option[$typeName] = $packageName.internal.ToCaseClassMacro[$typeName]($lineTermName)($csvFormat)
override def toCsvString($tTermName: $typeName): String = $packageName.internal.ToStringMacro[$typeName]($tTermName)($csvFormat)
}
...
...
smt-csv/src/main/scala/org/bitlap/csv/FileUtils.scala
浏览文件 @
ab74b018
...
...
@@ -103,4 +103,14 @@ object FileUtils {
}
ts
.
result
()
}
def
readCsvFromClassPath
[
T
<:
Product
](
fileName
:
String
)(
func
:
String
=>
Option
[
T
])
:
List
[
Option
[
T
]]
=
{
val
reader
=
new
InputStreamReader
(
ClassLoader
.
getSystemResourceAsStream
(
fileName
))
FileUtils
.
readFileFunc
[
T
](
new
BufferedReader
(
reader
),
func
)
}
def
readCsvFromFile
[
T
<:
Product
](
file
:
File
)(
func
:
String
=>
Option
[
T
])
:
List
[
Option
[
T
]]
=
{
val
reader
=
new
BufferedReader
(
new
FileReader
(
file
))
FileUtils
.
readFileFunc
[
T
](
reader
,
func
)
}
}
smt-csv/src/main/scala/org/bitlap/csv/
Scalable
.scala
→
smt-csv/src/main/scala/org/bitlap/csv/
Reader
.scala
浏览文件 @
ab74b018
...
...
@@ -28,7 +28,7 @@ package org.bitlap.csv
* @since 2022/04/30
* @version 1.0
*/
trait
Scalable
[
T
]
{
trait
Reader
[
T
]
{
/** API for processing a specific column value of CSV line data.
*
...
...
@@ -39,8 +39,8 @@ trait Scalable[T] {
def
transform
(
column
:
String
)
:
Option
[
T
]
}
object
Scalable
extends
Scalable
Implicits
{
object
Reader
extends
Reader
Implicits
{
def
apply
[
T
](
implicit
st
:
Scalable
[
T
])
:
Scalable
[
T
]
=
st
def
apply
[
T
](
implicit
st
:
Reader
[
T
])
:
Reader
[
T
]
=
st
}
smt-csv/src/main/scala/org/bitlap/csv/
Scalable
Builder.scala
→
smt-csv/src/main/scala/org/bitlap/csv/
Reader
Builder.scala
浏览文件 @
ab74b018
...
...
@@ -21,7 +21,7 @@
package
org.bitlap.csv
import
org.bitlap.csv.internal.
Scalable
BuilderMacro
import
org.bitlap.csv.internal.
Reader
BuilderMacro
import
java.io.InputStream
/** Builder to create a custom Csv Decoder.
...
...
@@ -30,7 +30,7 @@ import java.io.InputStream
* 梦境迷离
* @version 1.0,2022/4/30
*/
class
Scalable
Builder
[
T
]
{
class
Reader
Builder
[
T
]
{
/** Convert any Scala types to this CSV column string.
*
...
...
@@ -42,8 +42,8 @@ class ScalableBuilder[T] {
* The field type, generally, it is not necessary to specify, but it is safer if specify.
* @return
*/
def
setField
[
SF
](
scalaField
:
T
=>
SF
,
value
:
String
=>
SF
)
:
Scalable
Builder
[
T
]
=
macro
Scalable
BuilderMacro
.
setFieldImpl
[
T
,
SF
]
def
setField
[
SF
](
scalaField
:
T
=>
SF
,
value
:
String
=>
SF
)
:
Reader
Builder
[
T
]
=
macro
Reader
BuilderMacro
.
setFieldImpl
[
T
,
SF
]
/** Create a custom builder for converting this CSV line to scala values.
*
...
...
@@ -53,7 +53,7 @@ class ScalableBuilder[T] {
* For processing CSV in the specified format.
* @return
*/
def
convert
(
line
:
String
)(
implicit
format
:
CsvFormat
)
:
Option
[
T
]
=
macro
Scalable
BuilderMacro
.
convertOneImpl
[
T
]
def
convert
(
line
:
String
)(
implicit
format
:
CsvFormat
)
:
Option
[
T
]
=
macro
Reader
BuilderMacro
.
convertOneImpl
[
T
]
/** Convert all CSV lines to the sequence of Scala case class.
*
...
...
@@ -64,7 +64,7 @@ class ScalableBuilder[T] {
* @return
*/
def
convert
(
lines
:
List
[
String
])(
implicit
format
:
CsvFormat
)
:
List
[
Option
[
T
]]
=
macro
Scalable
BuilderMacro
.
convertAllImpl
[
T
]
macro
Reader
BuilderMacro
.
convertAllImpl
[
T
]
/** Read all CSV lines of the file and convert them to the sequence of Scala case class.
*
...
...
@@ -75,12 +75,12 @@ class ScalableBuilder[T] {
* @return
*/
def
convertFrom
(
file
:
InputStream
)(
implicit
format
:
CsvFormat
)
:
List
[
Option
[
T
]]
=
macro
Scalable
BuilderMacro
.
convertFromFileImpl
[
T
]
macro
Reader
BuilderMacro
.
convertFromFileImpl
[
T
]
}
object
Scalable
Builder
{
object
Reader
Builder
{
def
apply
[
T
<:
Product
]
:
ScalableBuilder
[
T
]
=
macro
Scalable
BuilderMacro
.
applyImpl
[
T
]
def
apply
[
T
<:
Product
]
:
ReaderBuilder
[
T
]
=
macro
Reader
BuilderMacro
.
applyImpl
[
T
]
}
smt-csv/src/main/scala/org/bitlap/csv/
Scalable
Implicits.scala
→
smt-csv/src/main/scala/org/bitlap/csv/
Reader
Implicits.scala
浏览文件 @
ab74b018
...
...
@@ -27,37 +27,37 @@ import scala.util.Try
* 梦境迷离
* @version 1.0,2022/5/1
*/
trait
Scalable
Implicits
{
trait
Reader
Implicits
{
implicit
final
val
string
Scalable
:
Scalable
[
String
]
=
new
Scalable
[
String
]
{
implicit
final
val
string
Reader
:
Reader
[
String
]
=
new
Reader
[
String
]
{
override
def
transform
(
column
:
String
)
:
Option
[
String
]
=
if
(
column
.
isEmpty
)
None
else
Some
(
column
)
}
implicit
final
val
int
Scalable
:
Scalable
[
Int
]
=
new
Scalable
[
Int
]
{
implicit
final
val
int
Reader
:
Reader
[
Int
]
=
new
Reader
[
Int
]
{
override
def
transform
(
column
:
String
)
:
Option
[
Int
]
=
Try
(
column
.
toInt
).
toOption
}
implicit
final
val
char
Scalable
:
Scalable
[
Char
]
=
new
Scalable
[
Char
]
{
implicit
final
val
char
Reader
:
Reader
[
Char
]
=
new
Reader
[
Char
]
{
override
def
transform
(
column
:
String
)
:
Option
[
Char
]
=
if
(
column
.
isEmpty
)
None
else
Try
(
column
.
charAt
(
0
)).
toOption
}
implicit
final
val
long
Scalable
:
Scalable
[
Long
]
=
new
Scalable
[
Long
]
{
implicit
final
val
long
Reader
:
Reader
[
Long
]
=
new
Reader
[
Long
]
{
override
def
transform
(
column
:
String
)
:
Option
[
Long
]
=
Try
(
column
.
toLong
).
toOption
}
implicit
final
val
short
Scalable
:
Scalable
[
Short
]
=
new
Scalable
[
Short
]
{
implicit
final
val
short
Reader
:
Reader
[
Short
]
=
new
Reader
[
Short
]
{
override
def
transform
(
column
:
String
)
:
Option
[
Short
]
=
Try
(
column
.
toShort
).
toOption
}
implicit
final
val
double
Scalable
:
Scalable
[
Double
]
=
new
Scalable
[
Double
]
{
implicit
final
val
double
Reader
:
Reader
[
Double
]
=
new
Reader
[
Double
]
{
override
def
transform
(
column
:
String
)
:
Option
[
Double
]
=
Try
(
column
.
toDouble
).
toOption
}
implicit
final
val
float
Scalable
:
Scalable
[
Float
]
=
new
Scalable
[
Float
]
{
implicit
final
val
float
Reader
:
Reader
[
Float
]
=
new
Reader
[
Float
]
{
override
def
transform
(
column
:
String
)
:
Option
[
Float
]
=
Try
(
column
.
toFloat
).
toOption
}
implicit
final
val
boolean
Scalable
:
Scalable
[
Boolean
]
=
new
Scalable
[
Boolean
]
{
implicit
final
val
boolean
Reader
:
Reader
[
Boolean
]
=
new
Reader
[
Boolean
]
{
override
def
transform
(
column
:
String
)
:
Option
[
Boolean
]
=
Try
(
column
.
toBoolean
).
toOption
}
}
smt-csv/src/main/scala/org/bitlap/csv/ScalableHelper.scala
已删除
100644 → 0
浏览文件 @
049effd2
/*
* Copyright (c) 2022 bitlap
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package
org.bitlap.csv
import
java.io.
{
BufferedReader
,
File
,
FileReader
,
InputStreamReader
}
/** Tool class for parsing CSV files.
*
* @author
* 梦境迷离
* @version 1.0,2022/5/13
*/
object
ScalableHelper
{
def
readCsvFromClassPath
[
T
<:
Product
](
fileName
:
String
)(
func
:
String
=>
Option
[
T
])
:
List
[
Option
[
T
]]
=
{
val
reader
=
new
InputStreamReader
(
ClassLoader
.
getSystemResourceAsStream
(
fileName
))
FileUtils
.
readFileFunc
[
T
](
new
BufferedReader
(
reader
),
func
)
}
def
readCsvFromFile
[
T
<:
Product
](
file
:
File
)(
func
:
String
=>
Option
[
T
])
:
List
[
Option
[
T
]]
=
{
val
reader
=
new
BufferedReader
(
new
FileReader
(
file
))
FileUtils
.
readFileFunc
[
T
](
reader
,
func
)
}
}
smt-csv/src/main/scala/org/bitlap/csv/
Csvable
.scala
→
smt-csv/src/main/scala/org/bitlap/csv/
Writer
.scala
浏览文件 @
ab74b018
...
...
@@ -28,7 +28,7 @@ package org.bitlap.csv
* @since 2022/04/27
* @version 1.0
*/
trait
Csvable
[
T
]
{
trait
Writer
[
T
]
{
/** API for processing a specific field of case class object.
*
...
...
@@ -40,8 +40,8 @@ trait Csvable[T] {
}
object
Csvable
extends
Csvable
Implicits
{
object
Writer
extends
Writer
Implicits
{
def
apply
[
T
](
implicit
st
:
Csvable
[
T
])
:
Csvable
[
T
]
=
st
def
apply
[
T
](
implicit
st
:
Writer
[
T
])
:
Writer
[
T
]
=
st
}
smt-csv/src/main/scala/org/bitlap/csv/
Csvable
Builder.scala
→
smt-csv/src/main/scala/org/bitlap/csv/
Writer
Builder.scala
浏览文件 @
ab74b018
...
...
@@ -21,7 +21,7 @@
package
org.bitlap.csv
import
org.bitlap.csv.internal.
Csvable
BuilderMacro
import
org.bitlap.csv.internal.
Writer
BuilderMacro
import
java.io.File
/** Builder to create a custom Csv Encoder.
...
...
@@ -30,7 +30,7 @@ import java.io.File
* 梦境迷离
* @version 1.0,2022/4/30
*/
class
Csvable
Builder
[
T
]
{
class
Writer
Builder
[
T
]
{
/** Convert this CSV column string to any Scala types.
*
...
...
@@ -42,8 +42,8 @@ class CsvableBuilder[T] {
* The field type, generally, it is not necessary to specify, but it is safer if specify.
* @return
*/
def
setField
[
SF
](
scalaField
:
T
=>
SF
,
value
:
SF
=>
String
)
:
Csvable
Builder
[
T
]
=
macro
Csvable
BuilderMacro
.
setFieldImpl
[
T
,
SF
]
def
setField
[
SF
](
scalaField
:
T
=>
SF
,
value
:
SF
=>
String
)
:
Writer
Builder
[
T
]
=
macro
Writer
BuilderMacro
.
setFieldImpl
[
T
,
SF
]
/** Create a custom builder for converting this scala value to CSV line string.
*
...
...
@@ -54,7 +54,7 @@ class CsvableBuilder[T] {
* @return
* The string of one CSV line.
*/
def
convert
(
t
:
T
)(
implicit
format
:
CsvFormat
)
:
String
=
macro
Csvable
BuilderMacro
.
convertOneImpl
[
T
]
def
convert
(
t
:
T
)(
implicit
format
:
CsvFormat
)
:
String
=
macro
Writer
BuilderMacro
.
convertOneImpl
[
T
]
/** Convert the sequence of Scala case class to CSV string.
*
...
...
@@ -65,7 +65,7 @@ class CsvableBuilder[T] {
* @return
* The string of all CSV lines.
*/
def
convert
(
ts
:
List
[
T
])(
implicit
format
:
CsvFormat
)
:
String
=
macro
Csvable
BuilderMacro
.
convertAllImpl
[
T
]
def
convert
(
ts
:
List
[
T
])(
implicit
format
:
CsvFormat
)
:
String
=
macro
Writer
BuilderMacro
.
convertAllImpl
[
T
]
/** Convert the sequence of Scala case class to CSV string and write to file.
*
...
...
@@ -79,12 +79,12 @@ class CsvableBuilder[T] {
* The string of all CSV lines.
*/
def
convertTo
(
ts
:
List
[
T
],
file
:
File
)(
implicit
format
:
CsvFormat
)
:
Boolean
=
macro
Csvable
BuilderMacro
.
convertToFileImpl
[
T
]
macro
Writer
BuilderMacro
.
convertToFileImpl
[
T
]
}
object
Csvable
Builder
{
object
Writer
Builder
{
def
apply
[
T
<:
Product
]
:
CsvableBuilder
[
T
]
=
macro
Csvable
BuilderMacro
.
applyImpl
[
T
]
def
apply
[
T
<:
Product
]
:
WriterBuilder
[
T
]
=
macro
Writer
BuilderMacro
.
applyImpl
[
T
]
}
smt-csv/src/main/scala/org/bitlap/csv/
Csvable
Implicits.scala
→
smt-csv/src/main/scala/org/bitlap/csv/
Writer
Implicits.scala
浏览文件 @
ab74b018
...
...
@@ -25,37 +25,37 @@ package org.bitlap.csv
* 梦境迷离
* @version 1.0,2022/5/1
*/
trait
Csvable
Implicits
{
trait
Writer
Implicits
{
implicit
final
val
string
Csvable
:
Csvable
[
String
]
=
new
Csvable
[
String
]
{
implicit
final
val
string
Writer
:
Writer
[
String
]
=
new
Writer
[
String
]
{
override
def
transform
(
s
:
String
)
:
String
=
s
}
implicit
final
val
int
Csvable
:
Csvable
[
Int
]
=
new
Csvable
[
Int
]
{
implicit
final
val
int
Writer
:
Writer
[
Int
]
=
new
Writer
[
Int
]
{
override
def
transform
(
column
:
Int
)
:
String
=
column
.
toString
}
implicit
final
val
char
Csvable
:
Csvable
[
Char
]
=
new
Csvable
[
Char
]
{
implicit
final
val
char
Writer
:
Writer
[
Char
]
=
new
Writer
[
Char
]
{
override
def
transform
(
t
:
Char
)
:
String
=
t
.
toString
}
implicit
final
val
long
Csvable
:
Csvable
[
Long
]
=
new
Csvable
[
Long
]
{
implicit
final
val
long
Writer
:
Writer
[
Long
]
=
new
Writer
[
Long
]
{
override
def
transform
(
column
:
Long
)
:
String
=
column
.
toString
}
implicit
final
val
short
Csvable
:
Csvable
[
Short
]
=
new
Csvable
[
Short
]
{
implicit
final
val
short
Writer
:
Writer
[
Short
]
=
new
Writer
[
Short
]
{
override
def
transform
(
column
:
Short
)
:
String
=
column
.
toString
}
implicit
final
val
double
Csvable
:
Csvable
[
Double
]
=
new
Csvable
[
Double
]
{
implicit
final
val
double
Writer
:
Writer
[
Double
]
=
new
Writer
[
Double
]
{
override
def
transform
(
column
:
Double
)
:
String
=
column
.
toString
}
implicit
final
val
float
Csvable
:
Csvable
[
Float
]
=
new
Csvable
[
Float
]
{
implicit
final
val
float
Writer
:
Writer
[
Float
]
=
new
Writer
[
Float
]
{
override
def
transform
(
column
:
Float
)
:
String
=
column
.
toString
}
implicit
final
val
boolean
Csvable
:
Csvable
[
Boolean
]
=
new
Csvable
[
Boolean
]
{
implicit
final
val
boolean
Writer
:
Writer
[
Boolean
]
=
new
Writer
[
Boolean
]
{
override
def
transform
(
column
:
Boolean
)
:
String
=
column
.
toString
}
}
smt-csv/src/main/scala/org/bitlap/csv/internal/
Scalable
BuilderMacro.scala
→
smt-csv/src/main/scala/org/bitlap/csv/internal/
Reader
BuilderMacro.scala
浏览文件 @
ab74b018
...
...
@@ -23,7 +23,7 @@ package org.bitlap.csv.internal
import
org.bitlap.common.MacroCache
import
org.bitlap.common.internal.AbstractMacroProcessor
import
org.bitlap.csv.
{
CsvFormat
,
Scalable
Builder
}
import
org.bitlap.csv.
{
CsvFormat
,
Reader
Builder
}
import
java.io.InputStream
import
scala.collection.mutable
...
...
@@ -33,59 +33,59 @@ import scala.reflect.macros.whitebox
* 梦境迷离
* @version 1.0,2022/4/29
*/
class
Scalable
BuilderMacro
(
override
val
c
:
whitebox.Context
)
extends
AbstractMacroProcessor
(
c
)
{
class
Reader
BuilderMacro
(
override
val
c
:
whitebox.Context
)
extends
AbstractMacroProcessor
(
c
)
{
import
c.universe._
protected
val
packageName
=
q
"_root_.org.bitlap.csv"
private
val
annoBuilderPrefix
=
"_Anon
Scalable
Builder$"
private
val
annoBuilderPrefix
=
"_Anon
Reader
Builder$"
private
val
builderFunctionPrefix
=
"_
Scalable
BuilderFunction$"
private
val
builderFunctionPrefix
=
"_
Reader
BuilderFunction$"
private
val
innerColumnFuncTermName
=
TermName
(
"_columns"
)
private
val
innerLName
=
q
"_l"
private
val
innerTempTermName
=
TermName
(
"_line"
)
private
val
scalableInstanceTermName
=
TermName
(
"_scalable
Instance"
)
private
val
scalable
ImplClassNamePrefix
=
"_ScalaAnno$"
private
val
innerColumnFuncTermName
=
TermName
(
"_columns"
)
private
val
innerLName
=
q
"_l"
private
val
innerTempTermName
=
TermName
(
"_line"
)
private
val
readerInstanceTermName
=
TermName
(
"_Reader
Instance"
)
private
val
reader
ImplClassNamePrefix
=
"_ScalaAnno$"
// scalafmt: { maxColumn = 400 }
@unchecked
def
setFieldImpl
[
T
,
SF
](
scalaField
:
Expr
[
T
=>
SF
],
value
:
Expr
[
String
=>
SF
])
:
Expr
[
Scalable
Builder
[
T
]]
=
{
def
setFieldImpl
[
T
,
SF
](
scalaField
:
Expr
[
T
=>
SF
],
value
:
Expr
[
String
=>
SF
])
:
Expr
[
Reader
Builder
[
T
]]
=
{
val
Function
(
_
,
Select
(
_
,
termName
))
=
scalaField
.
tree
val
builderId
=
getBuilderId
(
annoBuilderPrefix
)
MacroCache
.
builderFunctionTrees
.
getOrElseUpdate
(
builderId
,
mutable
.
Map
.
empty
).
update
(
termName
.
toString
,
value
)
val
tree
=
q
"new ${c.prefix.actualType}"
exprPrintTree
[
Scalable
Builder
[
T
]](
force
=
false
,
tree
)
exprPrintTree
[
Reader
Builder
[
T
]](
force
=
false
,
tree
)
}
def
applyImpl
[
T:
WeakTypeTag
]
:
Expr
[
Scalable
Builder
[
T
]]
=
def
applyImpl
[
T:
WeakTypeTag
]
:
Expr
[
Reader
Builder
[
T
]]
=
deriveBuilderApplyImpl
[
T
]
def
convertOneImpl
[
T:
WeakTypeTag
](
line
:
Expr
[
String
])(
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
Option
[
T
]]
=
{
val
clazzName
=
resolveClassTypeName
[
T
]
derive
Scalable
Impl
[
T
](
clazzName
,
line
,
format
)
derive
Reader
Impl
[
T
](
clazzName
,
line
,
format
)
}
def
convertAllImpl
[
T:
WeakTypeTag
](
lines
:
Expr
[
List
[
String
]])(
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
List
[
Option
[
T
]]]
=
{
val
clazzName
=
resolveClassTypeName
[
T
]
deriveFull
Scalable
Impl
[
T
](
clazzName
,
lines
,
format
)
deriveFull
Reader
Impl
[
T
](
clazzName
,
lines
,
format
)
}
def
convertFromFileImpl
[
T:
WeakTypeTag
](
file
:
Expr
[
InputStream
])(
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
List
[
Option
[
T
]]]
=
{
val
clazzName
=
resolveClassTypeName
[
T
]
deriveFullFromFile
Scalable
Impl
[
T
](
clazzName
,
file
,
format
)
deriveFullFromFile
Reader
Impl
[
T
](
clazzName
,
file
,
format
)
}
private
def
deriveBuilderApplyImpl
[
T:
WeakTypeTag
]
:
Expr
[
Scalable
Builder
[
T
]]
=
{
private
def
deriveBuilderApplyImpl
[
T:
WeakTypeTag
]
:
Expr
[
Reader
Builder
[
T
]]
=
{
val
className
=
TypeName
(
annoBuilderPrefix
+
MacroCache
.
getBuilderId
)
val
caseClazzName
=
weakTypeOf
[
T
].
typeSymbol
.
name
.
toTypeName
val
tree
=
q
"""
class $className extends $packageName.
Scalable
Builder[$caseClazzName]
class $className extends $packageName.
Reader
Builder[$caseClazzName]
new $className
"""
exprPrintTree
[
Scalable
Builder
[
T
]](
force
=
false
,
tree
)
exprPrintTree
[
Reader
Builder
[
T
]](
force
=
false
,
tree
)
}
private
def
getPreTree
:
Iterable
[
Tree
]
=
{
...
...
@@ -101,57 +101,57 @@ class ScalableBuilderMacro(override val c: whitebox.Context) extends AbstractMac
}
// scalafmt: { maxColumn = 400 }
private
def
deriveFullFromFile
Scalable
Impl
[
T:
WeakTypeTag
](
clazzName
:
TypeName
,
file
:
Expr
[
InputStream
],
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
List
[
Option
[
T
]]]
=
{
// NOTE: preTrees must be at the same level as
Scalable
private
def
deriveFullFromFile
Reader
Impl
[
T:
WeakTypeTag
](
clazzName
:
TypeName
,
file
:
Expr
[
InputStream
],
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
List
[
Option
[
T
]]]
=
{
// NOTE: preTrees must be at the same level as
Reader
val
tree
=
q
"""
..$getPreTree
..${getAnnoClassObject[T](clazzName, format)}
$packageName.FileUtils.reader($file, $format).map { ($innerLName: String) =>
$
scalable
InstanceTermName.$innerTempTermName = ${TermName(innerLName.toString())}
$
scalable
InstanceTermName.transform($innerLName)
$
reader
InstanceTermName.$innerTempTermName = ${TermName(innerLName.toString())}
$
reader
InstanceTermName.transform($innerLName)
}
"""
exprPrintTree
[
List
[
Option
[
T
]]](
force
=
false
,
tree
)
}
// scalafmt: { maxColumn = 400 }
private
def
deriveFull
Scalable
Impl
[
T:
WeakTypeTag
](
clazzName
:
TypeName
,
lines
:
Expr
[
List
[
String
]],
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
List
[
Option
[
T
]]]
=
{
// NOTE: preTrees must be at the same level as
Scalable
private
def
deriveFull
Reader
Impl
[
T:
WeakTypeTag
](
clazzName
:
TypeName
,
lines
:
Expr
[
List
[
String
]],
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
List
[
Option
[
T
]]]
=
{
// NOTE: preTrees must be at the same level as
Reader
val
tree
=
q
"""
..$getPreTree
..${getAnnoClassObject[T](clazzName, format)}
$lines.map { ($innerLName: String) =>
$
scalable
InstanceTermName.$innerTempTermName = ${TermName(innerLName.toString())}
$
scalable
InstanceTermName.transform($innerLName)
$
reader
InstanceTermName.$innerTempTermName = ${TermName(innerLName.toString())}
$
reader
InstanceTermName.transform($innerLName)
}
"""
exprPrintTree
[
List
[
Option
[
T
]]](
force
=
false
,
tree
)
}
private
def
getAnnoClassObject
[
T:
WeakTypeTag
](
clazzName
:
TypeName
,
format
:
c.Expr
[
CsvFormat
])
:
Tree
=
{
val
annoClassName
=
TermName
(
scalable
ImplClassNamePrefix
+
MacroCache
.
getIdentityId
)
val
annoClassName
=
TermName
(
reader
ImplClassNamePrefix
+
MacroCache
.
getIdentityId
)
q
"""
object $annoClassName extends $packageName.
Scalable
[$clazzName] {
object $annoClassName extends $packageName.
Reader
[$clazzName] {
var $innerTempTermName: String = _
private val $innerColumnFuncTermName = () => $packageName.StringUtils.splitColumns(${annoClassName.toTermName}.$innerTempTermName, $format)
..${
scalable
Body[T](clazzName, innerColumnFuncTermName)}
..${
reader
Body[T](clazzName, innerColumnFuncTermName)}
}
private final lazy val $
scalable
InstanceTermName = $annoClassName
private final lazy val $
reader
InstanceTermName = $annoClassName
"""
}
// scalafmt: { maxColumn = 400 }
private
def
derive
Scalable
Impl
[
T:
WeakTypeTag
](
clazzName
:
TypeName
,
line
:
Expr
[
String
],
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
Option
[
T
]]
=
{
val
annoClassName
=
TermName
(
scalable
ImplClassNamePrefix
+
MacroCache
.
getIdentityId
)
// NOTE: preTrees must be at the same level as
Scalable
private
def
derive
Reader
Impl
[
T:
WeakTypeTag
](
clazzName
:
TypeName
,
line
:
Expr
[
String
],
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
Option
[
T
]]
=
{
val
annoClassName
=
TermName
(
reader
ImplClassNamePrefix
+
MacroCache
.
getIdentityId
)
// NOTE: preTrees must be at the same level as
Reader
val
tree
=
q
"""
..$getPreTree
object $annoClassName extends $packageName.
Scalable
[$clazzName] {
object $annoClassName extends $packageName.
Reader
[$clazzName] {
final lazy private val $innerColumnFuncTermName = () => $packageName.StringUtils.splitColumns($line, $format)
..${
scalable
Body[T](clazzName, innerColumnFuncTermName)}
..${
reader
Body[T](clazzName, innerColumnFuncTermName)}
}
$annoClassName.transform($line)
"""
...
...
@@ -159,7 +159,7 @@ class ScalableBuilderMacro(override val c: whitebox.Context) extends AbstractMac
}
// scalafmt: { maxColumn = 400 }
private
def
scalable
Body
[
T:
WeakTypeTag
](
clazzName
:
TypeName
,
innerFuncTermName
:
TermName
)
:
Tree
=
{
private
def
reader
Body
[
T:
WeakTypeTag
](
clazzName
:
TypeName
,
innerFuncTermName
:
TermName
)
:
Tree
=
{
val
customTrees
=
MacroCache
.
builderFunctionTrees
.
getOrElse
(
getBuilderId
(
annoBuilderPrefix
),
mutable
.
Map
.
empty
)
val
params
=
getCaseClassFieldInfoList
[
T
]()
val
fieldNames
=
params
.
map
(
_
.
fieldName
)
...
...
@@ -175,25 +175,25 @@ class ScalableBuilderMacro(override val c: whitebox.Context) extends AbstractMac
case
Nil
if
!
customTrees
.
contains
(
fieldNames
(
idx
))
=>
fieldType
match
{
case
t
if
t
=:=
typeOf
[
Int
]
=>
q
"$packageName.
Scalable
[$fieldTypeName].transform($columnValues).getOrElse(${fieldTreeInformation.zeroValue})"
q
"$packageName.
Reader
[$fieldTypeName].transform($columnValues).getOrElse(${fieldTreeInformation.zeroValue})"
case
t
if
t
=:=
typeOf
[
String
]
=>
q
"""$packageName.
Scalable
[$fieldTypeName].transform($columnValues).getOrElse(${fieldTreeInformation.zeroValue})"""
q
"""$packageName.
Reader
[$fieldTypeName].transform($columnValues).getOrElse(${fieldTreeInformation.zeroValue})"""
case
t
if
t
=:=
typeOf
[
Float
]
=>
q
"$packageName.
Scalable
[$fieldTypeName].transform($columnValues).getOrElse[Float](${fieldTreeInformation.zeroValue})"
q
"$packageName.
Reader
[$fieldTypeName].transform($columnValues).getOrElse[Float](${fieldTreeInformation.zeroValue})"
case
t
if
t
=:=
typeOf
[
Double
]
=>
q
"$packageName.
Scalable
[$fieldTypeName].transform($columnValues).getOrElse[Double](${fieldTreeInformation.zeroValue})"
q
"$packageName.
Reader
[$fieldTypeName].transform($columnValues).getOrElse[Double](${fieldTreeInformation.zeroValue})"
case
t
if
t
=:=
typeOf
[
Char
]
=>
q
"$packageName.
Scalable
[$fieldTypeName].transform($columnValues).getOrElse(${fieldTreeInformation.zeroValue})"
q
"$packageName.
Reader
[$fieldTypeName].transform($columnValues).getOrElse(${fieldTreeInformation.zeroValue})"
case
t
if
t
=:=
typeOf
[
Byte
]
=>
q
"$packageName.
Scalable
[$fieldTypeName].transform($columnValues).getOrElse(${fieldTreeInformation.zeroValue})"
q
"$packageName.
Reader
[$fieldTypeName].transform($columnValues).getOrElse(${fieldTreeInformation.zeroValue})"
case
t
if
t
=:=
typeOf
[
Short
]
=>
q
"$packageName.
Scalable
[$fieldTypeName].transform($columnValues).getOrElse(${fieldTreeInformation.zeroValue})"
q
"$packageName.
Reader
[$fieldTypeName].transform($columnValues).getOrElse(${fieldTreeInformation.zeroValue})"
case
t
if
t
=:=
typeOf
[
Boolean
]
=>
q
"$packageName.
Scalable
[$fieldTypeName].transform($columnValues).getOrElse(${fieldTreeInformation.zeroValue})"
q
"$packageName.
Reader
[$fieldTypeName].transform($columnValues).getOrElse(${fieldTreeInformation.zeroValue})"
case
t
if
t
=:=
typeOf
[
Long
]
=>
q
"$packageName.
Scalable
[$fieldTypeName].transform($columnValues).getOrElse(${fieldTreeInformation.zeroValue})"
q
"$packageName.
Reader
[$fieldTypeName].transform($columnValues).getOrElse(${fieldTreeInformation.zeroValue})"
case
_
=>
tryOptionGetOrElse
(
q
"$packageName.
Scalable
[$fieldTypeName].transform($columnValues)"
,
fieldTreeInformation
.
zeroValue
)
tryOptionGetOrElse
(
q
"$packageName.
Reader
[$fieldTypeName].transform($columnValues)"
,
fieldTreeInformation
.
zeroValue
)
}
case
generic
::
Nil
if
customTrees
.
contains
(
fieldNames
(
idx
))
&&
fieldTreeInformation
.
collectionsFlags
.
isList
=>
tryGetOrElse
(
q
"${customFunction()}.asInstanceOf[_root_.scala.List[$generic]]"
,
fieldTreeInformation
.
zeroValue
)
...
...
@@ -206,7 +206,7 @@ class ScalableBuilderMacro(override val c: whitebox.Context) extends AbstractMac
case
generic
::
Nil
if
customTrees
.
contains
(
fieldNames
(
idx
))
&&
fieldTreeInformation
.
collectionsFlags
.
isSeq
=>
tryGetOrElse
(
q
"${customFunction()}.asInstanceOf[_root_.scala.Seq[$generic]]"
,
fieldTreeInformation
.
zeroValue
)
case
generic
::
Nil
if
fieldTreeInformation
.
collectionsFlags
.
isOption
=>
tryOption
(
q
"$packageName.
Scalable
[$generic].transform($columnValues)"
)
tryOption
(
q
"$packageName.
Reader
[$generic].transform($columnValues)"
)
case
generic
=>
c
.
abort
(
c
.
enclosingPosition
,
...
...
smt-csv/src/main/scala/org/bitlap/csv/internal/
Csvable
BuilderMacro.scala
→
smt-csv/src/main/scala/org/bitlap/csv/internal/
Writer
BuilderMacro.scala
浏览文件 @
ab74b018
...
...
@@ -23,7 +23,7 @@ package org.bitlap.csv.internal
import
org.bitlap.common.MacroCache
import
org.bitlap.common.internal.AbstractMacroProcessor
import
org.bitlap.csv.
{
CsvFormat
,
Csvable
Builder
}
import
org.bitlap.csv.
{
CsvFormat
,
Writer
Builder
}
import
java.io.File
import
scala.collection.mutable
...
...
@@ -33,52 +33,52 @@ import scala.reflect.macros.whitebox
* 梦境迷离
* @version 1.0,2022/4/29
*/
class
Csvable
BuilderMacro
(
override
val
c
:
whitebox.Context
)
extends
AbstractMacroProcessor
(
c
)
{
class
Writer
BuilderMacro
(
override
val
c
:
whitebox.Context
)
extends
AbstractMacroProcessor
(
c
)
{
import
c.universe._
protected
val
packageName
=
q
"_root_.org.bitlap.csv"
private
val
annoBuilderPrefix
=
"_Anon
Csvable
Builder$"
private
val
annoBuilderPrefix
=
"_Anon
Writer
Builder$"
private
val
builderFunctionPrefix
=
"_
Csvable
BuilderFunction$"
private
val
builderFunctionPrefix
=
"_
Writer
BuilderFunction$"
private
val
innerTName
=
q
"_t"
private
val
innerTmpTermName
=
TermName
(
"_tt"
)
private
val
csvableInstanceTermName
=
TermName
(
"_csvable
Instance"
)
private
val
csvableImplClassNamePrefix
=
"_Csv
Anno$"
private
val
funcArgsTempTermName
=
TermName
(
"temp"
)
private
val
innerTName
=
q
"_t"
private
val
innerTmpTermName
=
TermName
(
"_tt"
)
private
val
writerInstanceTermName
=
TermName
(
"_Writer
Instance"
)
private
val
writerImplClassNamePrefix
=
"_CSV
Anno$"
private
val
funcArgsTempTermName
=
TermName
(
"temp"
)
// scalafmt: { maxColumn = 400 }
def
setFieldImpl
[
T
,
SF
](
scalaField
:
Expr
[
T
=>
SF
],
value
:
Expr
[
SF
=>
String
])
:
Expr
[
Csvable
Builder
[
T
]]
=
{
def
setFieldImpl
[
T
,
SF
](
scalaField
:
Expr
[
T
=>
SF
],
value
:
Expr
[
SF
=>
String
])
:
Expr
[
Writer
Builder
[
T
]]
=
{
val
Function
(
_
,
Select
(
_
,
termName
))
=
scalaField
.
tree
val
builderId
=
getBuilderId
(
annoBuilderPrefix
)
MacroCache
.
builderFunctionTrees
.
getOrElseUpdate
(
builderId
,
mutable
.
Map
.
empty
).
update
(
termName
.
toString
,
value
)
val
tree
=
q
"new ${c.prefix.actualType}"
exprPrintTree
[
Csvable
Builder
[
T
]](
force
=
false
,
tree
)
exprPrintTree
[
Writer
Builder
[
T
]](
force
=
false
,
tree
)
}
def
applyImpl
[
T:
WeakTypeTag
]
:
Expr
[
Csvable
Builder
[
T
]]
=
def
applyImpl
[
T:
WeakTypeTag
]
:
Expr
[
Writer
Builder
[
T
]]
=
deriveBuilderApplyImpl
[
T
]
def
convertOneImpl
[
T:
WeakTypeTag
](
t
:
Expr
[
T
])(
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
String
]
=
derive
Csvable
Impl
[
T
](
t
,
format
)
derive
Writer
Impl
[
T
](
t
,
format
)
def
convertAllImpl
[
T:
WeakTypeTag
](
ts
:
Expr
[
List
[
T
]])(
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
String
]
=
deriveFull
Csvable
Impl
[
T
](
ts
,
format
)
deriveFull
Writer
Impl
[
T
](
ts
,
format
)
def
convertToFileImpl
[
T:
WeakTypeTag
](
ts
:
Expr
[
List
[
T
]],
file
:
Expr
[
File
])(
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
Boolean
]
=
deriveFullIntoFile
Csvable
Impl
[
T
](
ts
,
file
,
format
)
deriveFullIntoFile
Writer
Impl
[
T
](
ts
,
file
,
format
)
private
def
deriveBuilderApplyImpl
[
T:
WeakTypeTag
]
:
Expr
[
Csvable
Builder
[
T
]]
=
{
private
def
deriveBuilderApplyImpl
[
T:
WeakTypeTag
]
:
Expr
[
Writer
Builder
[
T
]]
=
{
val
className
=
TypeName
(
annoBuilderPrefix
+
MacroCache
.
getBuilderId
)
val
caseClazzName
=
TypeName
(
weakTypeOf
[
T
].
typeSymbol
.
name
.
decodedName
.
toString
)
val
tree
=
q
"""
class $className extends $packageName.
Csvable
Builder[$caseClazzName]
class $className extends $packageName.
Writer
Builder[$caseClazzName]
new $className
"""
exprPrintTree
[
Csvable
Builder
[
T
]](
force
=
false
,
tree
)
exprPrintTree
[
Writer
Builder
[
T
]](
force
=
false
,
tree
)
}
private
def
getCustomPreTress
:
(
mutable.Map
[
String
,
Any
],
Iterable
[
Tree
])
=
{
...
...
@@ -94,7 +94,7 @@ class CsvableBuilderMacro(override val c: whitebox.Context) extends AbstractMacr
}
// scalafmt: { maxColumn = 400 }
private
def
deriveFullIntoFile
Csvable
Impl
[
T:
WeakTypeTag
](
ts
:
Expr
[
List
[
T
]],
file
:
Expr
[
File
],
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
Boolean
]
=
{
private
def
deriveFullIntoFile
Writer
Impl
[
T:
WeakTypeTag
](
ts
:
Expr
[
List
[
T
]],
file
:
Expr
[
File
],
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
Boolean
]
=
{
val
clazzName
=
resolveClassTypeName
[
T
]
val
(
customTrees
,
preTrees
)
=
getCustomPreTress
val
tree
=
...
...
@@ -102,8 +102,8 @@ class CsvableBuilderMacro(override val c: whitebox.Context) extends AbstractMacr
..$preTrees
..${getAnnoClassObject[T](customTrees, format)}
$packageName.FileUtils.writer($file, $ts.map { ($innerTName: $clazzName) =>
$
csvable
InstanceTermName.$innerTmpTermName = $innerTName
$
csvable
InstanceTermName.transform($innerTName)
$
writer
InstanceTermName.$innerTmpTermName = $innerTName
$
writer
InstanceTermName.transform($innerTName)
}, $format
)
"""
...
...
@@ -111,7 +111,7 @@ class CsvableBuilderMacro(override val c: whitebox.Context) extends AbstractMacr
}
// scalafmt: { maxColumn = 400 }
private
def
deriveFull
Csvable
Impl
[
T:
WeakTypeTag
](
ts
:
Expr
[
List
[
T
]],
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
String
]
=
{
private
def
deriveFull
Writer
Impl
[
T:
WeakTypeTag
](
ts
:
Expr
[
List
[
T
]],
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
String
]
=
{
val
clazzName
=
resolveClassTypeName
[
T
]
val
(
customTrees
,
preTrees
)
=
getCustomPreTress
val
tree
=
...
...
@@ -119,8 +119,8 @@ class CsvableBuilderMacro(override val c: whitebox.Context) extends AbstractMacr
..$preTrees
..${getAnnoClassObject[T](customTrees, format)}
lazy val lines = $ts.map { ($innerTName: $clazzName) =>
$
csvable
InstanceTermName.$innerTmpTermName = $innerTName
$
csvable
InstanceTermName.transform($innerTName)
$
writer
InstanceTermName.$innerTmpTermName = $innerTName
$
writer
InstanceTermName.transform($innerTName)
}
$packageName.StringUtils.combineRows(lines, $format)
"""
...
...
@@ -129,9 +129,9 @@ class CsvableBuilderMacro(override val c: whitebox.Context) extends AbstractMacr
private
def
getAnnoClassObject
[
T:
WeakTypeTag
](
customTrees
:
mutable.Map
[
String
,
Any
],
format
:
c.Expr
[
CsvFormat
])
:
Tree
=
{
val
clazzName
=
resolveClassTypeName
[
T
]
val
annoClassName
=
TermName
(
csvable
ImplClassNamePrefix
+
MacroCache
.
getIdentityId
)
val
annoClassName
=
TermName
(
writer
ImplClassNamePrefix
+
MacroCache
.
getIdentityId
)
q
"""
object $annoClassName extends $packageName.
Csvable
[$clazzName] {
object $annoClassName extends $packageName.
Writer
[$clazzName] {
var $innerTmpTermName: $clazzName = _
lazy private val _toCsv = ($funcArgsTempTermName: $clazzName) => {
...
...
@@ -142,18 +142,18 @@ class CsvableBuilderMacro(override val c: whitebox.Context) extends AbstractMacr
override def transform(t: $clazzName): String = _toCsv($annoClassName.$innerTmpTermName)
}
final lazy private val $
csvable
InstanceTermName = $annoClassName
final lazy private val $
writer
InstanceTermName = $annoClassName
"""
}
private
def
derive
Csvable
Impl
[
T:
WeakTypeTag
](
t
:
Expr
[
T
],
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
String
]
=
{
private
def
derive
Writer
Impl
[
T:
WeakTypeTag
](
t
:
Expr
[
T
],
format
:
c.Expr
[
CsvFormat
])
:
Expr
[
String
]
=
{
val
clazzName
=
resolveClassTypeName
[
T
]
val
(
customTrees
,
preTrees
)
=
getCustomPreTress
val
annoClassName
=
TermName
(
csvable
ImplClassNamePrefix
+
MacroCache
.
getIdentityId
)
val
annoClassName
=
TermName
(
writer
ImplClassNamePrefix
+
MacroCache
.
getIdentityId
)
val
tree
=
q
"""
..$preTrees
object $annoClassName extends $packageName.
Csvable
[$clazzName] {
object $annoClassName extends $packageName.
Writer
[$clazzName] {
final private val $innerTmpTermName = $t
override def transform(t: $clazzName): String = {
...
...
@@ -210,7 +210,7 @@ class CsvableBuilderMacro(override val c: whitebox.Context) extends AbstractMacr
case
t
if
t
<:<
typeOf
[
Option
[
_
]]
&&
!
customTrees
.
contains
(
fieldNames
(
indexType
.
_1
))
=>
val
genericType
=
c
.
typecheck
(
q
"${indexType._2}"
,
c
.
TYPEmode
).
tpe
.
dealias
.
typeArgs
.
head
q
"""
$packageName.
Csvable
[$genericType].transform {
$packageName.
Writer
[$genericType].transform {
if ($innerVarTermName.${indexByName(indexType._1)}.isEmpty) ""
else $innerVarTermName.${indexByName(indexType._1)}.get
}
...
...
@@ -218,7 +218,7 @@ class CsvableBuilderMacro(override val c: whitebox.Context) extends AbstractMacr
case
_
if
customTrees
.
contains
(
fieldNames
(
indexType
.
_1
))
=>
customFunction
()
case
_
=>
q
"$packageName.
Csvable
[${indexType._2}].transform($innerVarTermName.${indexByName(indexType._1)})"
q
"$packageName.
Writer
[${indexType._2}].transform($innerVarTermName.${indexByName(indexType._1)})"
}
}
}
...
...
smt-csv/src/test/scala/org/bitlap/csv/test/C
svC
onverterTest.scala
→
smt-csv/src/test/scala/org/bitlap/csv/test/ConverterTest.scala
浏览文件 @
ab74b018
...
...
@@ -29,9 +29,9 @@ import org.scalatest.matchers.should.Matchers
* 梦境迷离
* @version 1.0,2022/4/29
*/
class
C
svC
onverterTest
extends
AnyFlatSpec
with
Matchers
{
class
ConverterTest
extends
AnyFlatSpec
with
Matchers
{
"C
svC
onverter1"
should
"ok"
in
{
"Converter1"
should
"ok"
in
{
val
line
=
"abc,cdf,d,12,2,false,0.1,0.23333"
val
dimension
=
Converter
[
Dimension
].
toScala
(
line
)
assert
(
dimension
.
toString
==
"Some(Dimension(abc,Some(cdf),d,12,2,false,0.1,0.23333))"
)
...
...
@@ -40,7 +40,7 @@ class CsvConverterTest extends AnyFlatSpec with Matchers {
assert
(
csv
==
line
)
}
"C
svC
onverter2"
should
"ok when csv column empty"
in
{
"Converter2"
should
"ok when csv column empty"
in
{
val
line
=
"abc,,d,12,2,false,0.1,0.23333"
val
dimension
=
Converter
[
Dimension
].
toScala
(
line
)
...
...
@@ -52,7 +52,7 @@ class CsvConverterTest extends AnyFlatSpec with Matchers {
}
"C
svC
onverter3"
should
"failed when case class currying"
in
{
"Converter3"
should
"failed when case class currying"
in
{
"""
| case class Dimension(key: String, value: Option[String], d: Char, c: Long, e: Short, f: Boolean, g: Float)(h: Double)
| object Dimension {
...
...
@@ -64,7 +64,7 @@ class CsvConverterTest extends AnyFlatSpec with Matchers {
|"""
.
stripMargin
shouldNot
compile
}
"C
svC
onverter4"
should
"ok when using list"
in
{
"Converter4"
should
"ok when using list"
in
{
val
line
=
"""1,cdf,d,12,2,false,0.1,0.2
|2,cdf,d,12,2,false,0.1,0.1"""
.
stripMargin
...
...
@@ -78,7 +78,7 @@ class CsvConverterTest extends AnyFlatSpec with Matchers {
}
"C
svC
onverter5"
should
"ok when input empty"
in
{
"Converter5"
should
"ok when input empty"
in
{
val
empty1
=
Converter
[
List
[
Dimension
]].
toCsvString
(
Nil
)
println
(
empty1
)
assert
(
empty1
==
""
)
...
...
@@ -88,14 +88,14 @@ class CsvConverterTest extends AnyFlatSpec with Matchers {
assert
(
empty2
==
""
)
}
"C
svC
onverter6"
should
"ok when using json value"
in
{
"Converter6"
should
"ok when using json value"
in
{
val
line
=
"""abc,"{""a"":""b"",""c"":""d""}",d,12,2,false,0.1,0.23333"""
val
dimension
=
Converter
[
Dimension
].
toScala
(
line
)
println
(
dimension
)
assert
(
dimension
.
toString
==
"Some(Dimension(abc,Some({\"a\":\"b\",\"c\":\"d\"}),d,12,2,false,0.1,0.23333))"
)
}
"C
svC
onverter7"
should
"get None when error"
in
{
"Converter7"
should
"get None when error"
in
{
// xxx should be Boolean, but failure, can get false
val
line
=
"""abc,"{""a"":""b"",""c"":""d""}",d,12,2,xxx,0.1,0.23333"""
val
dimension
=
Converter
[
Dimension
].
toScala
(
line
)
...
...
smt-csv/src/test/scala/org/bitlap/csv/test/Custom
Converter
BuilderTest.scala
→
smt-csv/src/test/scala/org/bitlap/csv/test/CustomBuilderTest.scala
浏览文件 @
ab74b018
...
...
@@ -21,7 +21,7 @@
package
org.bitlap.csv.test
import
org.bitlap.csv.
{
CsvableBuilder
,
DefaultCsvFormat
,
Scalable
Builder
}
import
org.bitlap.csv.
{
DefaultCsvFormat
,
ReaderBuilder
,
Writer
Builder
}
import
org.scalatest.flatspec.AnyFlatSpec
import
org.scalatest.matchers.should.Matchers
...
...
@@ -29,27 +29,27 @@ import org.scalatest.matchers.should.Matchers
* 梦境迷离
* @version 1.0,2022/4/29
*/
class
Custom
Converter
BuilderTest
extends
AnyFlatSpec
with
Matchers
{
class
CustomBuilderTest
extends
AnyFlatSpec
with
Matchers
{
"Custom
ConverterBuilder
1"
should
"ok"
in
{
"Custom
BuilderTest
1"
should
"ok"
in
{
val
line
=
"abc,cdf,d,12,2,false,0.1,0.23333"
val
dimension
=
Scalable
Builder
[
Dimension2
].
convert
(
line
)
val
dimension
=
Reader
Builder
[
Dimension2
].
convert
(
line
)
assert
(
dimension
.
toString
==
"Some(Dimension2(abc,Some(cdf),d,12,2,false,0.1,0.23333))"
)
val
csv
=
Csvable
Builder
[
Dimension2
].
convert
(
dimension
.
get
)
val
csv
=
Writer
Builder
[
Dimension2
].
convert
(
dimension
.
get
)
println
(
csv
)
assert
(
csv
==
line
)
}
"Custom
ConverterBuilder
2"
should
"ok when using json value"
in
{
"Custom
BuilderTest
2"
should
"ok when using json value"
in
{
val
line
=
"""abc,"{""a"":""b"",""c"":""d""}",d,12,2,false,0.1,0.23333"""
val
dimension1
=
Scalable
Builder
[
Dimension2
]
val
dimension1
=
Reader
Builder
[
Dimension2
]
.
setField
(
_
.
c
,
_
=>
12L
)
.
convert
(
line
)
println
(
dimension1
)
assert
(
dimension1
.
toString
==
"Some(Dimension2(abc,Some({\"a\":\"b\",\"c\":\"d\"}),d,12,2,false,0.1,0.23333))"
)
val
csv
=
Csvable
Builder
[
Dimension2
]
val
csv
=
Writer
Builder
[
Dimension2
]
.
setField
[
Char
](
_
.
d
,
_
=>
"????????"
)
.
setField
[
Option
[
String
]](
_
.
value
,
js
=>
s
"""\"${js.get.replace("\"", "\"\"")}\""""
)
.
convert
(
dimension1
.
get
)
...
...
@@ -58,111 +58,111 @@ class CustomConverterBuilderTest extends AnyFlatSpec with Matchers {
assert
(
csv
==
"abc,\"{\"\"a\"\":\"\"b\"\",\"\"c\"\":\"\"d\"\"}\",????????,12,2,false,0.1,0.23333"
)
}
"Custom
ConverterBuilder
3"
should
"ok when using json value"
in
{
"Custom
BuilderTest
3"
should
"ok when using json value"
in
{
val
line
=
"""abc,"{""a"":""b"",""c"":""d""}",d,12,2,false,0.1,0.23333"""
val
d
=
Scalable
Builder
[
Dimension2
]
val
d
=
Reader
Builder
[
Dimension2
]
.
setField
(
_
.
value
,
_
=>
None
)
.
convert
(
line
)
assert
(
d
.
toString
==
"Some(Dimension2(abc,None,d,12,2,false,0.1,0.23333))"
)
val
d2
=
Scalable
Builder
[
Dimension2
]
val
d2
=
Reader
Builder
[
Dimension2
]
.
setField
(
_
.
value
,
_
=>
None
)
.
convert
(
"""abc,"{""a"":""b"",""c"":""d""}",d,12,2,false,0.1,0.23333"""
)
assert
(
d2
.
toString
==
"Some(Dimension2(abc,None,d,12,2,false,0.1,0.23333))"
)
val
e
=
Scalable
Builder
[
Dimension2
]
val
e
=
Reader
Builder
[
Dimension2
]
.
convert
(
line
)
println
(
e
)
assert
(
e
.
toString
==
"Some(Dimension2(abc,Some({\"a\":\"b\",\"c\":\"d\"}),d,12,2,false,0.1,0.23333))"
)
}
"Custom
ConverterBuilder
4"
should
"ok when using toCsvString"
in
{
"Custom
BuilderTest
4"
should
"ok when using toCsvString"
in
{
val
e
=
Dimension2
(
"1"
,
Some
(
"hello"
),
'c'
,
1L
,
1
,
false
,
0.1f
,
0.2
)
val
dimension1
=
Csvable
Builder
[
Dimension2
]
val
dimension1
=
Writer
Builder
[
Dimension2
]
.
convert
(
e
)
assert
(
dimension1
==
"1,hello,c,1,1,false,0.1,0.2"
)
val
dimension2
=
Csvable
Builder
[
Dimension2
]
val
dimension2
=
Writer
Builder
[
Dimension2
]
.
setField
[
Option
[
String
]](
_
.
value
,
_
=>
"hello world"
)
.
convert
(
e
)(
new
DefaultCsvFormat
{
override
val
delimiter
:
Char
=
'*'
})
assert
(
dimension2
==
"1*hello world*c*1*1*false*0.1*0.2"
)
val
dimension3
=
Csvable
Builder
[
Dimension2
]
val
dimension3
=
Writer
Builder
[
Dimension2
]
.
setField
[
Option
[
String
]](
_
.
value
,
_
=>
"hello world"
)
.
convert
(
Dimension2
(
"1"
,
Some
(
"hello"
),
'c'
,
1L
,
1
,
false
,
0.1f
,
0.2
))
assert
(
dimension3
==
"1,hello world,c,1,1,false,0.1,0.2"
)
}
"Custom
ConverterBuilder
5"
should
"ok when using list"
in
{
"Custom
BuilderTest
5"
should
"ok when using list"
in
{
val
es
=
List
(
Dimension2
(
"1"
,
Some
(
"hello"
),
'c'
,
1L
,
1
,
true
,
0.1f
,
0.2
),
Dimension2
(
"2"
,
Some
(
"hello bitlap"
),
'c'
,
1L
,
1
,
false
,
0.1f
,
0.2
)
)
val
dimension1
=
es
.
map
(
e
=>
Csvable
Builder
[
Dimension2
].
convert
(
e
))
val
dimension1
=
es
.
map
(
e
=>
Writer
Builder
[
Dimension2
].
convert
(
e
))
assert
(
dimension1
==
List
(
"1,hello,c,1,1,true,0.1,0.2"
,
"2,hello bitlap,c,1,1,false,0.1,0.2"
))
val
csv
=
List
(
"1,hello,c,1,1,true,0.1,0.2"
,
"2,hello bitlap,c,1,1,false,0.1,0.2"
)
val
scala
=
csv
.
map
(
f
=>
Scalable
Builder
[
Dimension2
].
convert
(
f
))
val
scala
=
csv
.
map
(
f
=>
Reader
Builder
[
Dimension2
].
convert
(
f
))
assert
(
scala
.
toString
()
==
"List(Some(Dimension2(1,Some(hello),c,1,1,true,0.1,0.2)), Some(Dimension2(2,Some(hello bitlap),c,1,1,false,0.1,0.2)))"
)
}
"Custom
ConverterBuilder
6"
should
"fail when find List or Seq but without using setFiled"
in
{
"Custom
BuilderTest
6"
should
"fail when find List or Seq but without using setFiled"
in
{
"""
|
Scalable
Builder[Metric2].convert(csv)
|
Reader
Builder[Metric2].convert(csv)
|"""
.
stripMargin
shouldNot
compile
"""
|
Csvable
Builder[Metric2].convert(metric)
|
Writer
Builder[Metric2].convert(metric)
|"""
.
stripMargin
shouldNot
compile
}
"Custom
ConverterBuilder
7"
should
"fail when find List or Seq but without using setFiled"
in
{
"Custom
BuilderTest
7"
should
"fail when find List or Seq but without using setFiled"
in
{
"""
|
Scalable
Builder[Metric2].convert(csv)
|
Reader
Builder[Metric2].convert(csv)
|"""
.
stripMargin
shouldNot
compile
"""
|
Csvable
Builder[Metric2].convert(metric2)
|
Writer
Builder[Metric2].convert(metric2)
|"""
.
stripMargin
shouldNot
compile
}
"Custom
ConverterBuilder
8"
should
"ok when not pass columnSeparator"
in
{
"Custom
BuilderTest
8"
should
"ok when not pass columnSeparator"
in
{
val
e
=
Dimension2
(
"1"
,
Some
(
"hello"
),
'c'
,
1L
,
1
,
false
,
0.1f
,
0.2
)
val
csv
=
Csvable
Builder
[
Dimension2
].
convert
(
e
)
val
csv
=
Writer
Builder
[
Dimension2
].
convert
(
e
)
println
(
csv
)
assert
(
csv
==
"1,hello,c,1,1,false,0.1,0.2"
)
val
scala
=
Scalable
Builder
[
Dimension2
].
convert
(
csv
)
val
scala
=
Reader
Builder
[
Dimension2
].
convert
(
csv
)
println
(
scala
)
assert
(
scala
.
get
==
e
)
}
"Custom
ConverterBuilder
9"
should
"fail if case class has currying"
in
{
"Custom
BuilderTest
9"
should
"fail if case class has currying"
in
{
"""
|case class Test(i:Int)(j:String)
| val t = Test(1)("hello")
|
Csvable
Builder[Test].convert(t)
|
Writer
Builder[Test].convert(t)
|"""
.
stripMargin
shouldNot
compile
}
"Custom
ConverterBuilder
10"
should
"get None when error"
in
{
"Custom
BuilderTest
10"
should
"get None when error"
in
{
val
e
=
Dimension2
(
"1"
,
Some
(
"hello"
),
'c'
,
1L
,
1
,
false
,
0.1f
,
0.0
)
// aaa should be Double, but failure, can get 0.0D
val
csv
=
"1,hello,c,1,1,false,0.1,aaa"
val
scala
=
Scalable
Builder
[
Dimension2
].
convert
(
csv
)
val
scala
=
Reader
Builder
[
Dimension2
].
convert
(
csv
)
println
(
scala
)
assert
(
scala
.
get
==
e
)
val
scala2
=
Scalable
Builder
[
Dimension2
].
setField
(
_
.
h
,
_
=>
throw
new
Exception
).
convert
(
csv
)
val
scala2
=
Reader
Builder
[
Dimension2
].
setField
(
_
.
h
,
_
=>
throw
new
Exception
).
convert
(
csv
)
assert
(
scala2
.
get
==
e
)
val
scala3
=
Scalable
Builder
[
Dimension2
].
setField
(
_
.
value
,
_
=>
throw
new
Exception
).
convert
(
csv
)
val
scala3
=
Reader
Builder
[
Dimension2
].
setField
(
_
.
value
,
_
=>
throw
new
Exception
).
convert
(
csv
)
assert
(
scala3
.
get
==
Dimension2
(
"1"
,
None
,
'c'
,
1L
,
1
,
false
,
0.1f
,
0.0
))
}
}
smt-csv/src/test/scala/org/bitlap/csv/test/
Scalable
TsvTest.scala
→
smt-csv/src/test/scala/org/bitlap/csv/test/
Reader
TsvTest.scala
浏览文件 @
ab74b018
...
...
@@ -21,7 +21,7 @@
package
org.bitlap.csv.test
import
org.bitlap.csv.
{
CsvableBuilder
,
ScalableBuilder
,
TsvFormat
}
import
org.bitlap.csv.
{
ReaderBuilder
,
TsvFormat
,
WriterBuilder
}
import
org.scalatest.flatspec.AnyFlatSpec
import
org.scalatest.matchers.should.Matchers
...
...
@@ -31,9 +31,9 @@ import java.io.File
* 梦境迷离
* @version 1.0,6/4/22
*/
class
Scalable
TsvTest
extends
AnyFlatSpec
with
Matchers
{
class
Reader
TsvTest
extends
AnyFlatSpec
with
Matchers
{
"
Scalable
TsvTest1"
should
"ok when file is tsv"
in
{
"
Reader
TsvTest1"
should
"ok when file is tsv"
in
{
implicit
val
format
=
new
TsvFormat
{
override
val
delimiter
:
Char
=
' '
override
val
ignoreEmptyLines
:
Boolean
=
true
...
...
@@ -41,7 +41,7 @@ class ScalableTsvTest extends AnyFlatSpec with Matchers {
override
val
prependHeader
:
List
[
String
]
=
List
(
"time"
,
"entity"
,
"dimensions"
,
"metricName"
,
"metricValue"
)
}
val
metrics
=
Scalable
Builder
[
Metric3
]
Reader
Builder
[
Metric3
]
.
convertFrom
(
ClassLoader
.
getSystemResourceAsStream
(
"simple_data_header.tsv"
))
println
(
metrics
)
assert
(
metrics
.
nonEmpty
)
...
...
@@ -51,7 +51,7 @@ class ScalableTsvTest extends AnyFlatSpec with Matchers {
)
val
file
=
new
File
(
"./simple_data_header.tsv"
)
Csvable
Builder
[
Metric3
]
Writer
Builder
[
Metric3
]
// NOTE: not support pass anonymous object to convertTo method.
.
convertTo
(
metrics
.
filter
(
_
.
isDefined
).
map
(
_
.
get
),
file
)
file
.
delete
()
...
...
smt-csv/src/test/scala/org/bitlap/csv/test/
CsvableAndScalable
Test.scala
→
smt-csv/src/test/scala/org/bitlap/csv/test/
WriterAndReader
Test.scala
浏览文件 @
ab74b018
...
...
@@ -23,8 +23,9 @@ package org.bitlap.csv.test
import
org.scalatest.flatspec.AnyFlatSpec
import
org.scalatest.matchers.should.Matchers
import
org.bitlap.csv.
{
CsvableBuilder
,
DefaultCsvFormat
,
ScalableBuilder
,
StringUtils
}
import
org.bitlap.csv.
_
import
java.io.File
import
org.bitlap.csv.FileUtils
/** Complex use of common tests
*
...
...
@@ -32,7 +33,7 @@ import java.io.File
* 梦境迷离
* @version 1.0,2022/5/1
*/
class
CsvableAndScalable
Test
extends
AnyFlatSpec
with
Matchers
{
class
WriterAndReader
Test
extends
AnyFlatSpec
with
Matchers
{
val
csvData
=
"""100,1,"{""city"":""北京"",""os"":""Mac""}",vv,1
...
...
@@ -52,12 +53,12 @@ class CsvableAndScalableTest extends AnyFlatSpec with Matchers {
|200,3,"{""city"":""北京"",""os"":""Mac""}",vv,1
|200,3,"{""city"":""北京"",""os"":""Mac""}",pv,2"""
.
stripMargin
"
CsvableAndScalable
1"
should
"ok"
in
{
"
WriterAndReaderTest
1"
should
"ok"
in
{
val
metrics
=
csvData
.
split
(
"\n"
)
.
toList
.
map
(
csv
=>
Scalable
Builder
[
Metric
]
Reader
Builder
[
Metric
]
.
setField
(
_
.
dimensions
,
dims
=>
{
...
...
@@ -79,7 +80,7 @@ class CsvableAndScalableTest extends AnyFlatSpec with Matchers {
assert
(
metrics
.
head
.
get
.
dimensions
.
head
.
value
==
"北京"
)
val
csv
=
metrics
.
map
(
metric
=>
Csvable
Builder
[
Metric
]
Writer
Builder
[
Metric
]
.
setField
(
_
.
dimensions
,
(
ds
:
List
[
Dimension3
])
=>
...
...
@@ -94,12 +95,12 @@ class CsvableAndScalableTest extends AnyFlatSpec with Matchers {
)
}
"
CsvableAndScalable
2" should "ok" in {
"
WriterAndReaderTest
2" should "ok" in {
val metrics = csvData
.split("\n")
.toList
.map(csv =>
Scalable
Builder[Metric2]
Reader
Builder[Metric2]
.setField[Seq[Dimension3]](
_.dimensions,
dims => {
...
...
@@ -121,11 +122,11 @@ class CsvableAndScalableTest extends AnyFlatSpec with Matchers {
assert(metrics.head.get.dimensions.head.value == "北京")
}
"
CsvableAndScalable
3" should "ok when using StringUtils" in {
"
WriterAndReaderTest
3" should "ok when using StringUtils" in {
val metrics = csvData
.split("\n")
.map(csv =>
Scalable
Builder[Metric2]
Reader
Builder[Metric2]
.setField[Seq[Dimension3]](
_.dimensions,
dims => StringUtils.extractJsonValues[Dimension3](dims)((k, v) => Dimension3(k, v))
...
...
@@ -139,10 +140,9 @@ class CsvableAndScalableTest extends AnyFlatSpec with Matchers {
assert(metrics.head.get.dimensions.head.value == "北京")
}
"CsvableAndScalable4" should "ok when reading from file" in {
import org.bitlap.csv.ScalableHelper
val metrics = ScalableHelper.readCsvFromClassPath[Metric2]("simple_data.csv") { line =>
ScalableBuilder[Metric2]
"WriterAndReaderTest4" should "ok when reading from file" in {
val metrics = FileUtils.readCsvFromClassPath[Metric2]("simple_data.csv") { line =>
ReaderBuilder[Metric2]
.setField[Seq[Dimension3]](
_.dimensions,
dims => StringUtils.extractJsonValues[Dimension3](dims)((k, v) => Dimension3(k, v))
...
...
@@ -155,14 +155,14 @@ class CsvableAndScalableTest extends AnyFlatSpec with Matchers {
assert(metrics.head.get.dimensions.head.value == "北京")
}
"
CsvableAndScalable
5" should "ok when using convert method" in {
"
WriterAndReaderTest
5" should "ok when using convert method" in {
val csvLines = csvData.split("\n").toList
val metrics =
Scalable
Builder[Metric3].convert(csvLines)
val metrics =
Reader
Builder[Metric3].convert(csvLines)
// if we don't define a custom function for convert `Metric3#dimension`
val csv =
Csvable
Builder[Metric3].convert(metrics.filter(_.isDefined).map(_.get))
val csv =
Writer
Builder[Metric3].convert(metrics.filter(_.isDefined).map(_.get))
println(metrics)
println(csv)
...
...
@@ -170,8 +170,8 @@ class CsvableAndScalableTest extends AnyFlatSpec with Matchers {
assert(csvData.replace("\"", "") == csv.replace("\"", ""))
}
"
CsvableAndScalable
6" should "ok when using convert and StringUtils" in {
val metrics =
Scalable
Builder[Metric2]
"
WriterAndReaderTest
6" should "ok when using convert and StringUtils" in {
val metrics =
Reader
Builder[Metric2]
.setField[Seq[Dimension3]](
_.dimensions,
dims => StringUtils.extractJsonValues[Dimension3](dims)((k, v) => Dimension3(k, v))
...
...
@@ -183,7 +183,7 @@ class CsvableAndScalableTest extends AnyFlatSpec with Matchers {
assert(metrics.head.get.dimensions.head.key == "city")
assert(metrics.head.get.dimensions.head.value == "北京")
val csv =
Csvable
Builder[Metric2]
val csv =
Writer
Builder[Metric2]
.setField(
_.dimensions,
(ds: Seq[Dimension3]) =>
...
...
@@ -194,9 +194,9 @@ class CsvableAndScalableTest extends AnyFlatSpec with Matchers {
println(csv)
}
"
CsvableAndScalable8
" should "ok when reading from file" in {
"
WriterAndReaderTest7
" should "ok when reading from file" in {
val metrics =
Scalable
Builder[Metric2]
Reader
Builder[Metric2]
.setField[Seq[Dimension3]](
_.dimensions,
dims => StringUtils.extractJsonValues[Dimension3](dims)((k, v) => Dimension3(k, v))
...
...
@@ -207,7 +207,7 @@ class CsvableAndScalableTest extends AnyFlatSpec with Matchers {
assert(metrics.nonEmpty)
val file = new File("./simple_data.csv")
Csvable
Builder[Metric2]
Writer
Builder[Metric2]
.setField[Seq[Dimension3]](
_.dimensions,
ds => s"""
\
"{${ds.map(kv => s"""
\
"\"${kv.key}\"\":\"\"${kv.value}\"\""""
).
mkString
(
","
)}}\
""""
...
...
@@ -217,14 +217,14 @@ class CsvableAndScalableTest extends AnyFlatSpec with Matchers {
file.delete()
}
"
CsvableAndScalable9
" should "ok when use custom format" in {
"
WriterAndReaderTest8
" should "ok when use custom format" in {
implicit val format = new DefaultCsvFormat {
override val ignoreEmptyLines: Boolean = true
override val ignoreHeader: Boolean = true
override val prependHeader: List[String] = List("time", "entity", "dimensions", "metricName", "metricValue")
}
val metrics =
Scalable
Builder[Metric2]
Reader
Builder[Metric2]
.setField[Seq[Dimension3]](
_.dimensions,
dims => StringUtils.extractJsonValues[Dimension3](dims)((k, v) => Dimension3(k, v))
...
...
@@ -235,7 +235,7 @@ class CsvableAndScalableTest extends AnyFlatSpec with Matchers {
assert(metrics.nonEmpty)
val file = new File("./simple_data_header.csv")
Csvable
Builder[Metric2]
Writer
Builder[Metric2]
.setField[Seq[Dimension3]](
_.dimensions,
ds => s"""
\
"{${ds.map(kv => s"""
\
"\"${kv.key}\"\":\"\"${kv.value}\"\""""
).
mkString
(
","
)}}\
""""
...
...
@@ -244,20 +244,20 @@ class CsvableAndScalableTest extends AnyFlatSpec with Matchers {
file.delete()
}
"
CsvableAndScalable10
" should "failure if not setField" in {
"
WriterAndReaderTest9
" should "failure if not setField" in {
"""
|
val
metrics
=
Scalable
Builder
[
Metric
].
convert
(
csvData
.
split
(
"\n"
).
toList
)
|
val
csv
=
Csvable
Builder
[
Metric
].
convert
(
metrics
.
filter
(
_
.
isDefined
).
map
(
_
.
get
))
|
val
metrics
=
Reader
Builder
[
Metric
].
convert
(
csvData
.
split
(
"\n"
).
toList
)
|
val
csv
=
Writer
Builder
[
Metric
].
convert
(
metrics
.
filter
(
_
.
isDefined
).
map
(
_
.
get
))
|
|
val
metrics2
=
Scalable
Builder
[
Metric2
].
convert
(
csvData
.
split
(
"\n"
).
toList
)
|
val
csv2
=
Csvable
Builder
[
Metric2
].
convert
(
metrics2
.
filter
(
_
.
isDefined
).
map
(
_
.
get
))
|
val
metrics2
=
Reader
Builder
[
Metric2
].
convert
(
csvData
.
split
(
"\n"
).
toList
)
|
val
csv2
=
Writer
Builder
[
Metric2
].
convert
(
metrics2
.
filter
(
_
.
isDefined
).
map
(
_
.
get
))
|
|
|
val
metrics3
=
Scalable
Builder
[
Metric4
].
convert
(
csvData
.
split
(
"\n"
).
toList
)
|
val
csv3
=
Csvable
Builder
[
Metric4
].
convert
(
metrics3
.
filter
(
_
.
isDefined
).
map
(
_
.
get
))
|
val
metrics3
=
Reader
Builder
[
Metric4
].
convert
(
csvData
.
split
(
"\n"
).
toList
)
|
val
csv3
=
Writer
Builder
[
Metric4
].
convert
(
metrics3
.
filter
(
_
.
isDefined
).
map
(
_
.
get
))
|
|
val
metrics4
=
Scalable
Builder
[
Metric5
].
convert
(
csvData
.
split
(
"\n"
).
toList
)
|
val
csv4
=
Csvable
Builder
[
Metric5
].
convert
(
metrics4
.
filter
(
_
.
isDefined
).
map
(
_
.
get
))
|
val
metrics4
=
Reader
Builder
[
Metric5
].
convert
(
csvData
.
split
(
"\n"
).
toList
)
|
val
csv4
=
Writer
Builder
[
Metric5
].
convert
(
metrics4
.
filter
(
_
.
isDefined
).
map
(
_
.
get
))
|
""
"
.
stripMargin
shouldNot
compile
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录