Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
jobily
Questdb
提交
995ed2ec
Q
Questdb
项目概览
jobily
/
Questdb
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
Questdb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
995ed2ec
编写于
1月 15, 2019
作者:
V
Vlad Ilyushchenko
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
CUTLASS: TextLoader changes to make it possible using TIMESTAMP type
上级
89d403fa
变更
26
显示空白变更内容
内联
并排
Showing
26 changed file
with
1051 addition
and
395 deletion
+1051
-395
core/src/main/java/com/questdb/cairo/TableReaderIncrementalRecordCursor.java
...com/questdb/cairo/TableReaderIncrementalRecordCursor.java
+16
-1
core/src/main/java/com/questdb/cairo/sql/CairoEngine.java
core/src/main/java/com/questdb/cairo/sql/CairoEngine.java
+5
-2
core/src/main/java/com/questdb/cutlass/text/CairoTextWriter.java
...c/main/java/com/questdb/cutlass/text/CairoTextWriter.java
+61
-104
core/src/main/java/com/questdb/cutlass/text/TextLexer.java
core/src/main/java/com/questdb/cutlass/text/TextLexer.java
+12
-6
core/src/main/java/com/questdb/cutlass/text/TextLoader.java
core/src/main/java/com/questdb/cutlass/text/TextLoader.java
+18
-5
core/src/main/java/com/questdb/cutlass/text/TextMetadataDetector.java
...n/java/com/questdb/cutlass/text/TextMetadataDetector.java
+34
-37
core/src/main/java/com/questdb/cutlass/text/TextMetadataParser.java
...ain/java/com/questdb/cutlass/text/TextMetadataParser.java
+85
-61
core/src/main/java/com/questdb/cutlass/text/TextUtil.java
core/src/main/java/com/questdb/cutlass/text/TextUtil.java
+57
-0
core/src/main/java/com/questdb/cutlass/text/typeprobe/BadDateProbe.java
...java/com/questdb/cutlass/text/typeprobe/BadDateProbe.java
+52
-0
core/src/main/java/com/questdb/cutlass/text/typeprobe/BooleanProbe.java
...java/com/questdb/cutlass/text/typeprobe/BooleanProbe.java
+9
-9
core/src/main/java/com/questdb/cutlass/text/typeprobe/ByteProbe.java
...in/java/com/questdb/cutlass/text/typeprobe/ByteProbe.java
+52
-0
core/src/main/java/com/questdb/cutlass/text/typeprobe/DateProbe.java
...in/java/com/questdb/cutlass/text/typeprobe/DateProbe.java
+35
-15
core/src/main/java/com/questdb/cutlass/text/typeprobe/DoubleProbe.java
.../java/com/questdb/cutlass/text/typeprobe/DoubleProbe.java
+9
-9
core/src/main/java/com/questdb/cutlass/text/typeprobe/FloatProbe.java
...n/java/com/questdb/cutlass/text/typeprobe/FloatProbe.java
+52
-0
core/src/main/java/com/questdb/cutlass/text/typeprobe/IntProbe.java
...ain/java/com/questdb/cutlass/text/typeprobe/IntProbe.java
+12
-0
core/src/main/java/com/questdb/cutlass/text/typeprobe/LongProbe.java
...in/java/com/questdb/cutlass/text/typeprobe/LongProbe.java
+12
-11
core/src/main/java/com/questdb/cutlass/text/typeprobe/ShortProbe.java
...n/java/com/questdb/cutlass/text/typeprobe/ShortProbe.java
+52
-0
core/src/main/java/com/questdb/cutlass/text/typeprobe/StringProbe.java
.../java/com/questdb/cutlass/text/typeprobe/StringProbe.java
+61
-0
core/src/main/java/com/questdb/cutlass/text/typeprobe/SymbolProbe.java
.../java/com/questdb/cutlass/text/typeprobe/SymbolProbe.java
+61
-0
core/src/main/java/com/questdb/cutlass/text/typeprobe/TypeProbe.java
...in/java/com/questdb/cutlass/text/typeprobe/TypeProbe.java
+4
-10
core/src/main/java/com/questdb/cutlass/text/typeprobe/TypeProbeCollection.java
...m/questdb/cutlass/text/typeprobe/TypeProbeCollection.java
+80
-12
core/src/main/java/com/questdb/std/NetworkFacade.java
core/src/main/java/com/questdb/std/NetworkFacade.java
+58
-0
core/src/main/java/com/questdb/std/NetworkFacadeImpl.java
core/src/main/java/com/questdb/std/NetworkFacadeImpl.java
+108
-0
core/src/test/java/com/questdb/cutlass/text/PlainTextImportTest.java
...st/java/com/questdb/cutlass/text/PlainTextImportTest.java
+20
-22
core/src/test/java/com/questdb/cutlass/text/TextMetadataParserTest.java
...java/com/questdb/cutlass/text/TextMetadataParserTest.java
+71
-86
core/src/test/java/com/questdb/cutlass/text/TypeProbeCollectionTest.java
...ava/com/questdb/cutlass/text/TypeProbeCollectionTest.java
+15
-5
未找到文件。
core/src/main/java/com/questdb/cairo/TableReaderIncrementalRecordCursor.java
浏览文件 @
995ed2ec
...
@@ -28,12 +28,19 @@ public class TableReaderIncrementalRecordCursor extends TableReaderRecordCursor
...
@@ -28,12 +28,19 @@ public class TableReaderIncrementalRecordCursor extends TableReaderRecordCursor
private
long
txn
=
TableUtils
.
INITIAL_TXN
;
private
long
txn
=
TableUtils
.
INITIAL_TXN
;
private
long
lastRowId
=
-
1
;
private
long
lastRowId
=
-
1
;
// todo: test
// when cursor is not fetch to completion and calling code needs
// to consider current record processed it has to call bookmark();
public
void
bookmark
()
{
lastRowId
=
record
.
getRowId
();
}
@Override
@Override
public
boolean
hasNext
()
{
public
boolean
hasNext
()
{
if
(
super
.
hasNext
())
{
if
(
super
.
hasNext
())
{
return
true
;
return
true
;
}
}
lastRowId
=
record
.
getRowId
();
bookmark
();
return
false
;
return
false
;
}
}
...
@@ -41,9 +48,17 @@ public class TableReaderIncrementalRecordCursor extends TableReaderRecordCursor
...
@@ -41,9 +48,17 @@ public class TableReaderIncrementalRecordCursor extends TableReaderRecordCursor
long
txn
;
long
txn
;
if
(
reader
.
reload
())
{
if
(
reader
.
reload
())
{
seekToLast
();
seekToLast
();
// todo: there was a bug where last record was read twice without this line
this
.
txn
=
reader
.
getTxn
();
return
true
;
return
true
;
}
}
// when reader is created against table that already has data
// TableReader.reload() would return 'false'. This method
// must return 'true' in those conditions
// todo: this doesn't seem to have been tested
// none of tests fail when these lines are removed
txn
=
reader
.
getTxn
();
txn
=
reader
.
getTxn
();
if
(
txn
>
this
.
txn
)
{
if
(
txn
>
this
.
txn
)
{
this
.
txn
=
txn
;
this
.
txn
=
txn
;
...
...
core/src/main/java/com/questdb/cairo/sql/CairoEngine.java
浏览文件 @
995ed2ec
...
@@ -31,6 +31,9 @@ import org.jetbrains.annotations.Nullable;
...
@@ -31,6 +31,9 @@ import org.jetbrains.annotations.Nullable;
import
java.io.Closeable
;
import
java.io.Closeable
;
public
interface
CairoEngine
extends
Closeable
{
public
interface
CairoEngine
extends
Closeable
{
@Override
void
close
();
TableReader
getReader
(
CharSequence
tableName
,
long
version
);
TableReader
getReader
(
CharSequence
tableName
,
long
version
);
int
getStatus
(
Path
path
,
CharSequence
tableName
,
int
lo
,
int
hi
);
int
getStatus
(
Path
path
,
CharSequence
tableName
,
int
lo
,
int
hi
);
...
@@ -47,9 +50,9 @@ public interface CairoEngine extends Closeable {
...
@@ -47,9 +50,9 @@ public interface CairoEngine extends Closeable {
boolean
releaseAllWriters
();
boolean
releaseAllWriters
();
void
unlock
(
CharSequence
tableName
,
@Nullable
TableWriter
writer
);
void
remove
(
Path
path
,
CharSequence
tableName
);
void
remove
(
Path
path
,
CharSequence
tableName
);
void
rename
(
Path
path
,
CharSequence
tableName
,
Path
otherPath
,
String
newName
);
void
rename
(
Path
path
,
CharSequence
tableName
,
Path
otherPath
,
String
newName
);
void
unlock
(
CharSequence
tableName
,
@Nullable
TableWriter
writer
);
}
}
core/src/main/java/com/questdb/cutlass/text/CairoTextWriter.java
浏览文件 @
995ed2ec
...
@@ -26,19 +26,21 @@ package com.questdb.cutlass.text;
...
@@ -26,19 +26,21 @@ package com.questdb.cutlass.text;
import
com.questdb.cairo.*
;
import
com.questdb.cairo.*
;
import
com.questdb.cairo.sql.CairoEngine
;
import
com.questdb.cairo.sql.CairoEngine
;
import
com.questdb.cairo.sql.RecordMetadata
;
import
com.questdb.cairo.sql.RecordMetadata
;
import
com.questdb.cutlass.text.typeprobe.TypeProbe
;
import
com.questdb.cutlass.text.typeprobe.TypeProbeCollection
;
import
com.questdb.log.Log
;
import
com.questdb.log.Log
;
import
com.questdb.log.LogFactory
;
import
com.questdb.log.LogFactory
;
import
com.questdb.log.LogRecord
;
import
com.questdb.log.LogRecord
;
import
com.questdb.std.*
;
import
com.questdb.std.LongList
;
import
com.questdb.std.str.CharSink
;
import
com.questdb.std.Misc
;
import
com.questdb.std.Mutable
;
import
com.questdb.std.ObjList
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.std.str.DirectCharSink
;
import
com.questdb.std.str.DirectCharSink
;
import
com.questdb.std.str.Path
;
import
com.questdb.std.str.Path
;
import
java.io.Closeable
;
import
java.io.Closeable
;
import
static
com
.
questdb
.
std
.
Chars
.
utf8DecodeMultiByte
;
public
class
CairoTextWriter
implements
TextLexer
.
Listener
,
Closeable
,
Mutable
{
public
class
CairoTextWriter
implements
TextLexer
.
Listener
,
Closeable
,
Mutable
{
private
static
final
Log
LOG
=
LogFactory
.
getLog
(
CairoTextWriter
.
class
);
private
static
final
Log
LOG
=
LogFactory
.
getLog
(
CairoTextWriter
.
class
);
private
final
CairoConfiguration
configuration
;
private
final
CairoConfiguration
configuration
;
...
@@ -48,46 +50,27 @@ public class CairoTextWriter implements TextLexer.Listener, Closeable, Mutable {
...
@@ -48,46 +50,27 @@ public class CairoTextWriter implements TextLexer.Listener, Closeable, Mutable {
private
final
AppendMemory
appendMemory
=
new
AppendMemory
();
private
final
AppendMemory
appendMemory
=
new
AppendMemory
();
private
final
Path
path
;
private
final
Path
path
;
private
final
TableStructureAdapter
tableStructureAdapter
=
new
TableStructureAdapter
();
private
final
TableStructureAdapter
tableStructureAdapter
=
new
TableStructureAdapter
();
private
final
TypeProbeCollection
typeProbeCollection
;
private
CharSequence
tableName
;
private
CharSequence
tableName
;
private
ObjList
<
TextMetadata
>
textMetadata
;
private
TableWriter
writer
;
private
TableWriter
writer
;
private
long
_size
;
private
long
_size
;
private
boolean
overwrite
;
private
boolean
overwrite
;
private
boolean
durable
;
private
boolean
durable
;
private
int
atomicity
;
private
int
atomicity
;
private
ObjList
<
TypeProbe
>
types
;
public
CairoTextWriter
(
CairoConfiguration
configuration
,
CairoEngine
engine
,
Path
path
,
TextConfiguration
textConfiguration
)
{
public
CairoTextWriter
(
CairoConfiguration
configuration
,
CairoEngine
engine
,
Path
path
,
TextConfiguration
textConfiguration
,
TypeProbeCollection
typeProbeCollection
)
{
this
.
configuration
=
configuration
;
this
.
configuration
=
configuration
;
this
.
engine
=
engine
;
this
.
engine
=
engine
;
this
.
path
=
path
;
this
.
path
=
path
;
this
.
utf8Sink
=
new
DirectCharSink
(
textConfiguration
.
getUtf8SinkCapacity
());
this
.
utf8Sink
=
new
DirectCharSink
(
textConfiguration
.
getUtf8SinkCapacity
());
}
this
.
typeProbeCollection
=
typeProbeCollection
;
public
static
boolean
utf8Decode
(
long
lo
,
long
hi
,
CharSink
sink
)
{
long
p
=
lo
;
int
quoteCount
=
0
;
while
(
p
<
hi
)
{
byte
b
=
Unsafe
.
getUnsafe
().
getByte
(
p
);
if
(
b
<
0
)
{
int
n
=
utf8DecodeMultiByte
(
p
,
hi
,
b
,
sink
);
if
(
n
==
-
1
)
{
// UTF8 error
return
false
;
}
p
+=
n
;
}
else
{
if
(
b
==
'"'
)
{
if
(
quoteCount
++
%
2
==
0
)
{
sink
.
put
(
'"'
);
}
}
else
{
sink
.
put
((
char
)
b
);
}
++
p
;
}
}
return
true
;
}
}
@Override
@Override
...
@@ -142,44 +125,9 @@ public class CairoTextWriter implements TextLexer.Listener, Closeable, Mutable {
...
@@ -142,44 +125,9 @@ public class CairoTextWriter implements TextLexer.Listener, Closeable, Mutable {
continue
;
continue
;
}
}
try
{
try
{
final
TextMetadata
m
=
textMetadata
.
getQuick
(
i
);
types
.
getQuick
(
i
).
write
(
w
,
i
,
values
.
getQuick
(
i
));
final
DirectByteCharSequence
dbcs
=
values
.
getQuick
(
i
);
}
catch
(
Exception
ignore
)
{
switch
(
m
.
type
)
{
LogRecord
logRecord
=
LOG
.
error
().
$
(
"type syntax [type="
).
$
(
ColumnType
.
nameOf
(
types
.
getQuick
(
i
).
getType
())).
$
(
"]\n\t"
);
case
ColumnType
.
BOOLEAN
:
w
.
putBool
(
i
,
Chars
.
equalsIgnoreCase
(
values
.
getQuick
(
i
),
"true"
));
break
;
case
ColumnType
.
STRING
:
w
.
putStr
(
i
,
decode
(
dbcs
));
break
;
case
ColumnType
.
DOUBLE
:
w
.
putDouble
(
i
,
Numbers
.
parseDouble
(
dbcs
));
break
;
case
ColumnType
.
BYTE
:
w
.
putByte
(
i
,
(
byte
)
Numbers
.
parseInt
(
dbcs
));
break
;
case
ColumnType
.
SHORT
:
w
.
putShort
(
i
,
(
short
)
Numbers
.
parseInt
(
dbcs
));
break
;
case
ColumnType
.
INT
:
w
.
putInt
(
i
,
Numbers
.
parseInt
(
dbcs
));
break
;
case
ColumnType
.
FLOAT
:
w
.
putFloat
(
i
,
Numbers
.
parseFloat
(
dbcs
));
break
;
case
ColumnType
.
DATE
:
w
.
putDate
(
i
,
m
.
dateFormat
.
parse
(
decode
(
dbcs
),
m
.
dateLocale
));
break
;
case
ColumnType
.
SYMBOL
:
w
.
putSym
(
i
,
decode
(
dbcs
));
break
;
case
ColumnType
.
LONG
:
w
.
putLong
(
i
,
Numbers
.
parseLong
(
dbcs
));
break
;
default
:
break
;
}
}
catch
(
NumericException
|
Utf8Exception
ignore
)
{
LogRecord
logRecord
=
LOG
.
error
().
$
(
"type syntax [type="
).
$
(
ColumnType
.
nameOf
(
textMetadata
.
getQuick
(
i
).
type
)).
$
(
"]\n\t"
);
logRecord
.
$
(
'['
).
$
(
line
).
$
(
':'
).
$
(
i
).
$
(
"] -> "
).
$
(
values
.
getQuick
(
i
)).
$
();
logRecord
.
$
(
'['
).
$
(
line
).
$
(
':'
).
$
(
i
).
$
(
"] -> "
).
$
(
values
.
getQuick
(
i
)).
$
();
columnErrorCounts
.
increment
(
i
);
columnErrorCounts
.
increment
(
i
);
switch
(
atomicity
)
{
switch
(
atomicity
)
{
...
@@ -198,26 +146,19 @@ public class CairoTextWriter implements TextLexer.Listener, Closeable, Mutable {
...
@@ -198,26 +146,19 @@ public class CairoTextWriter implements TextLexer.Listener, Closeable, Mutable {
w
.
append
();
w
.
append
();
}
}
private
void
createTable
(
ObjList
<
TextMetadata
>
importMetadata
)
{
private
void
createTable
(
ObjList
<
CharSequence
>
names
,
ObjList
<
TypeProbe
>
detectedTypes
)
{
TableUtils
.
createTable
(
TableUtils
.
createTable
(
configuration
.
getFilesFacade
(),
configuration
.
getFilesFacade
(),
appendMemory
,
appendMemory
,
path
,
path
,
configuration
.
getRoot
(),
configuration
.
getRoot
(),
tableStructureAdapter
.
of
(
importMetadata
),
tableStructureAdapter
.
of
(
names
,
detectedTypes
),
configuration
.
getMkDirMode
()
configuration
.
getMkDirMode
()
);
);
this
.
types
=
detectedTypes
;
}
}
private
CharSequence
decode
(
DirectByteCharSequence
value
)
throws
Utf8Exception
{
private
TableWriter
openWriterAndOverrideImportTypes
(
ObjList
<
TypeProbe
>
detectedTypes
)
{
utf8Sink
.
clear
();
if
(
utf8Decode
(
value
.
getLo
(),
value
.
getHi
(),
utf8Sink
))
{
return
utf8Sink
;
}
throw
Utf8Exception
.
INSTANCE
;
}
private
TableWriter
openWriterAndOverrideImportTypes
()
{
TableWriter
writer
=
engine
.
getWriter
(
tableName
);
TableWriter
writer
=
engine
.
getWriter
(
tableName
);
RecordMetadata
metadata
=
writer
.
getMetadata
();
RecordMetadata
metadata
=
writer
.
getMetadata
();
...
@@ -225,48 +166,62 @@ public class CairoTextWriter implements TextLexer.Listener, Closeable, Mutable {
...
@@ -225,48 +166,62 @@ public class CairoTextWriter implements TextLexer.Listener, Closeable, Mutable {
// now, compare column count.
// now, compare column count.
// Cannot continue if different
// Cannot continue if different
if
(
metadata
.
getColumnCount
()
<
this
.
textMetadata
.
size
())
{
if
(
metadata
.
getColumnCount
()
<
detectedTypes
.
size
())
{
writer
.
close
();
writer
.
close
();
throw
CairoException
.
instance
(
0
)
throw
CairoException
.
instance
(
0
)
.
put
(
"column count mismatch [textColumnCount="
).
put
(
textMetadata
.
size
())
.
put
(
"column count mismatch [textColumnCount="
).
put
(
detectedTypes
.
size
())
.
put
(
", tableColumnCount="
).
put
(
metadata
.
getColumnCount
())
.
put
(
", tableColumnCount="
).
put
(
metadata
.
getColumnCount
())
.
put
(
", table="
).
put
(
tableName
)
.
put
(
", table="
).
put
(
tableName
)
.
put
(
']'
);
.
put
(
']'
);
}
}
this
.
types
=
detectedTypes
;
// Go over "discovered" textMetadata and really adjust it
// now overwrite detected types with actual table column types
// to what journal can actually take
for
(
int
i
=
0
,
n
=
this
.
types
.
size
();
i
<
n
;
i
++)
{
// one useful thing discovered type can bring is information
final
int
columnType
=
metadata
.
getColumnType
(
i
);
// about date format. The rest of it we will pretty much overwrite
if
(
this
.
types
.
getQuick
(
i
).
getType
()
!=
columnType
)
{
// when DATE type is mis-detected as STRING we
for
(
int
i
=
0
,
n
=
this
.
textMetadata
.
size
();
i
<
n
;
i
++)
{
// wouldn't have neither date format nor locale to
this
.
textMetadata
.
getQuick
(
i
).
type
=
metadata
.
getColumnType
(
i
);
// use when populating this field
switch
(
columnType
)
{
case
ColumnType
.
DATE
:
LOG
.
info
()
.
$
(
"mis-detected [table="
).
$
(
tableName
)
.
$
(
", column="
).
$
(
i
)
.
$
(
", type="
).
$
(
ColumnType
.
nameOf
(
this
.
types
.
getQuick
(
i
).
getType
()))
.
$
(
']'
).
$
();
this
.
types
.
setQuick
(
i
,
typeProbeCollection
.
getBadDateProbe
());
break
;
default
:
this
.
types
.
setQuick
(
i
,
typeProbeCollection
.
getProbeForType
(
columnType
));
break
;
}
}
}
}
return
writer
;
return
writer
;
}
}
void
prepareTable
(
ObjList
<
TextMetadata
>
metadata
)
{
void
prepareTable
(
ObjList
<
CharSequence
>
names
,
ObjList
<
TypeProbe
>
detectedTypes
)
{
assert
writer
==
null
;
assert
writer
==
null
;
if
(
metadata
.
size
()
==
0
)
{
if
(
detectedTypes
.
size
()
==
0
)
{
throw
CairoException
.
instance
(
0
).
put
(
"cannot determine text structure"
);
throw
CairoException
.
instance
(
0
).
put
(
"cannot determine text structure"
);
}
}
this
.
textMetadata
=
metadata
;
switch
(
engine
.
getStatus
(
path
,
tableName
))
{
switch
(
engine
.
getStatus
(
path
,
tableName
))
{
case
TableUtils
.
TABLE_DOES_NOT_EXIST
:
case
TableUtils
.
TABLE_DOES_NOT_EXIST
:
createTable
(
metadata
);
createTable
(
names
,
detectedTypes
);
writer
=
engine
.
getWriter
(
tableName
);
writer
=
engine
.
getWriter
(
tableName
);
break
;
break
;
case
TableUtils
.
TABLE_EXISTS
:
case
TableUtils
.
TABLE_EXISTS
:
if
(
overwrite
)
{
if
(
overwrite
)
{
engine
.
remove
(
path
,
tableName
);
engine
.
remove
(
path
,
tableName
);
createTable
(
metadata
);
createTable
(
names
,
detectedTypes
);
writer
=
engine
.
getWriter
(
tableName
);
writer
=
engine
.
getWriter
(
tableName
);
}
else
{
}
else
{
writer
=
openWriterAndOverrideImportTypes
();
writer
=
openWriterAndOverrideImportTypes
(
detectedTypes
);
}
}
break
;
break
;
default
:
default
:
...
@@ -277,21 +232,22 @@ public class CairoTextWriter implements TextLexer.Listener, Closeable, Mutable {
...
@@ -277,21 +232,22 @@ public class CairoTextWriter implements TextLexer.Listener, Closeable, Mutable {
}
}
private
class
TableStructureAdapter
implements
TableStructure
{
private
class
TableStructureAdapter
implements
TableStructure
{
private
ObjList
<
TextMetadata
>
importMetadata
;
private
ObjList
<
CharSequence
>
names
;
private
ObjList
<
TypeProbe
>
types
;
@Override
@Override
public
int
getColumnCount
()
{
public
int
getColumnCount
()
{
return
importMetadata
.
size
();
return
types
.
size
();
}
}
@Override
@Override
public
CharSequence
getColumnName
(
int
columnIndex
)
{
public
CharSequence
getColumnName
(
int
columnIndex
)
{
return
importMetadata
.
getQuick
(
columnIndex
).
name
;
return
names
.
getQuick
(
columnIndex
)
;
}
}
@Override
@Override
public
int
getColumnType
(
int
columnIndex
)
{
public
int
getColumnType
(
int
columnIndex
)
{
return
importMetadata
.
getQuick
(
columnIndex
).
type
;
return
types
.
getQuick
(
columnIndex
).
getType
()
;
}
}
@Override
@Override
...
@@ -331,8 +287,9 @@ public class CairoTextWriter implements TextLexer.Listener, Closeable, Mutable {
...
@@ -331,8 +287,9 @@ public class CairoTextWriter implements TextLexer.Listener, Closeable, Mutable {
return
-
1
;
return
-
1
;
}
}
TableStructureAdapter
of
(
ObjList
<
TextMetadata
>
importMetadata
)
{
TableStructureAdapter
of
(
ObjList
<
CharSequence
>
names
,
ObjList
<
TypeProbe
>
types
)
{
this
.
importMetadata
=
importMetadata
;
this
.
names
=
names
;
this
.
types
=
types
;
return
this
;
return
this
;
}
}
}
}
...
...
core/src/main/java/com/questdb/cutlass/text/TextLexer.java
浏览文件 @
995ed2ec
...
@@ -23,6 +23,7 @@
...
@@ -23,6 +23,7 @@
package
com.questdb.cutlass.text
;
package
com.questdb.cutlass.text
;
import
com.questdb.cutlass.text.typeprobe.TypeProbe
;
import
com.questdb.cutlass.text.typeprobe.TypeProbeCollection
;
import
com.questdb.cutlass.text.typeprobe.TypeProbeCollection
;
import
com.questdb.log.Log
;
import
com.questdb.log.Log
;
import
com.questdb.log.LogFactory
;
import
com.questdb.log.LogFactory
;
...
@@ -75,14 +76,23 @@ public class TextLexer implements Closeable, Mutable {
...
@@ -75,14 +76,23 @@ public class TextLexer implements Closeable, Mutable {
int
len
,
int
len
,
int
lineCountLimit
,
int
lineCountLimit
,
boolean
forceHeader
,
boolean
forceHeader
,
ObjList
<
TextMetadata
>
seedMetadata
ObjList
<
CharSequence
>
names
,
ObjList
<
TypeProbe
>
types
)
{
)
{
metadataDetector
.
of
(
seedMetadata
,
forceHeader
);
metadataDetector
.
of
(
names
,
types
,
forceHeader
);
parse
(
address
,
len
,
lineCountLimit
,
metadataDetector
);
parse
(
address
,
len
,
lineCountLimit
,
metadataDetector
);
metadataDetector
.
evaluateResults
(
lineCount
,
errorCount
);
metadataDetector
.
evaluateResults
(
lineCount
,
errorCount
);
restart
(
isHeaderDetected
());
restart
(
isHeaderDetected
());
}
}
ObjList
<
CharSequence
>
getColumnNames
()
{
return
metadataDetector
.
getColumnNames
();
}
ObjList
<
TypeProbe
>
getColumnTypes
()
{
return
metadataDetector
.
getColumnTypes
();
}
@Override
@Override
public
final
void
clear
()
{
public
final
void
clear
()
{
restart
(
false
);
restart
(
false
);
...
@@ -153,10 +163,6 @@ public class TextLexer implements Closeable, Mutable {
...
@@ -153,10 +163,6 @@ public class TextLexer implements Closeable, Mutable {
this
.
fieldLo
=
this
.
fieldHi
=
ptr
;
this
.
fieldLo
=
this
.
fieldHi
=
ptr
;
}
}
ObjList
<
TextMetadata
>
getDetectedMetadata
()
{
return
metadataDetector
.
getMetadata
();
}
private
boolean
growRollBuf
(
long
requiredLength
)
{
private
boolean
growRollBuf
(
long
requiredLength
)
{
if
(
requiredLength
>
lineRollBufLimit
)
{
if
(
requiredLength
>
lineRollBufLimit
)
{
// todo: log content of roll buffer
// todo: log content of roll buffer
...
...
core/src/main/java/com/questdb/cutlass/text/TextLoader.java
浏览文件 @
995ed2ec
...
@@ -33,6 +33,7 @@ import com.questdb.log.Log;
...
@@ -33,6 +33,7 @@ import com.questdb.log.Log;
import
com.questdb.log.LogFactory
;
import
com.questdb.log.LogFactory
;
import
com.questdb.std.LongList
;
import
com.questdb.std.LongList
;
import
com.questdb.std.Mutable
;
import
com.questdb.std.Mutable
;
import
com.questdb.std.str.DirectCharSink
;
import
com.questdb.std.str.Path
;
import
com.questdb.std.str.Path
;
import
com.questdb.std.time.DateFormatFactory
;
import
com.questdb.std.time.DateFormatFactory
;
import
com.questdb.std.time.DateLocaleFactory
;
import
com.questdb.std.time.DateLocaleFactory
;
...
@@ -51,9 +52,11 @@ public class TextLoader implements Closeable, Mutable {
...
@@ -51,9 +52,11 @@ public class TextLoader implements Closeable, Mutable {
private
final
Path
path
=
new
Path
();
private
final
Path
path
=
new
Path
();
private
final
int
textAnalysisMaxLines
;
private
final
int
textAnalysisMaxLines
;
private
final
TextDelimiterScanner
textDelimiterScanner
;
private
final
TextDelimiterScanner
textDelimiterScanner
;
private
final
DirectCharSink
utf8Sink
;
private
int
state
;
private
int
state
;
private
boolean
forceHeaders
=
false
;
private
boolean
forceHeaders
=
false
;
private
byte
columnDelimiter
=
-
1
;
private
byte
columnDelimiter
=
-
1
;
private
final
TypeProbeCollection
typeProbeCollection
;
public
TextLoader
(
public
TextLoader
(
CairoConfiguration
configuration
,
CairoConfiguration
configuration
,
...
@@ -62,7 +65,8 @@ public class TextLoader implements Closeable, Mutable {
...
@@ -62,7 +65,8 @@ public class TextLoader implements Closeable, Mutable {
DateLocaleFactory
dateLocaleFactory
,
DateLocaleFactory
dateLocaleFactory
,
DateFormatFactory
dateFormatFactory
DateFormatFactory
dateFormatFactory
)
{
)
{
TypeProbeCollection
typeProbeCollection
=
new
TypeProbeCollection
();
this
.
utf8Sink
=
new
DirectCharSink
(
textConfiguration
.
getUtf8SinkCapacity
());
this
.
typeProbeCollection
=
new
TypeProbeCollection
(
utf8Sink
);
textLexer
=
new
TextLexer
(
textLexer
=
new
TextLexer
(
textConfiguration
,
textConfiguration
,
typeProbeCollection
,
typeProbeCollection
,
...
@@ -73,8 +77,8 @@ public class TextLoader implements Closeable, Mutable {
...
@@ -73,8 +77,8 @@ public class TextLoader implements Closeable, Mutable {
textConfiguration
.
getJsonCacheSize
(),
textConfiguration
.
getJsonCacheSize
(),
textConfiguration
.
getJsonCacheLimit
()
textConfiguration
.
getJsonCacheLimit
()
);
);
textWriter
=
new
CairoTextWriter
(
configuration
,
engine
,
path
,
textConfiguration
);
textWriter
=
new
CairoTextWriter
(
configuration
,
engine
,
path
,
textConfiguration
,
typeProbeCollection
);
textMetadataParser
=
new
TextMetadataParser
(
textConfiguration
,
dateLocaleFactory
,
dateFormatFactory
);
textMetadataParser
=
new
TextMetadataParser
(
textConfiguration
,
dateLocaleFactory
,
dateFormatFactory
,
utf8Sink
,
typeProbeCollection
);
textAnalysisMaxLines
=
textConfiguration
.
getTextAnalysisMaxLines
();
textAnalysisMaxLines
=
textConfiguration
.
getTextAnalysisMaxLines
();
textDelimiterScanner
=
new
TextDelimiterScanner
(
textConfiguration
);
textDelimiterScanner
=
new
TextDelimiterScanner
(
textConfiguration
);
}
}
...
@@ -87,6 +91,7 @@ public class TextLoader implements Closeable, Mutable {
...
@@ -87,6 +91,7 @@ public class TextLoader implements Closeable, Mutable {
jsonLexer
.
clear
();
jsonLexer
.
clear
();
forceHeaders
=
false
;
forceHeaders
=
false
;
columnDelimiter
=
-
1
;
columnDelimiter
=
-
1
;
typeProbeCollection
.
clear
();
}
}
@Override
@Override
...
@@ -97,6 +102,7 @@ public class TextLoader implements Closeable, Mutable {
...
@@ -97,6 +102,7 @@ public class TextLoader implements Closeable, Mutable {
jsonLexer
.
close
();
jsonLexer
.
close
();
path
.
close
();
path
.
close
();
textDelimiterScanner
.
close
();
textDelimiterScanner
.
close
();
utf8Sink
.
close
();
}
}
public
void
configureColumnDelimiter
(
byte
columnDelimiter
)
{
public
void
configureColumnDelimiter
(
byte
columnDelimiter
)
{
...
@@ -158,8 +164,15 @@ public class TextLoader implements Closeable, Mutable {
...
@@ -158,8 +164,15 @@ public class TextLoader implements Closeable, Mutable {
}
else
{
}
else
{
textLexer
.
of
(
textDelimiterScanner
.
scan
(
address
,
len
));
textLexer
.
of
(
textDelimiterScanner
.
scan
(
address
,
len
));
}
}
textLexer
.
analyseStructure
(
address
,
len
,
textAnalysisMaxLines
,
forceHeaders
,
textMetadataParser
.
getTextMetadata
());
textLexer
.
analyseStructure
(
textWriter
.
prepareTable
(
textLexer
.
getDetectedMetadata
());
address
,
len
,
textAnalysisMaxLines
,
forceHeaders
,
textMetadataParser
.
getColumnNames
(),
textMetadataParser
.
getColumnTypes
()
);
textWriter
.
prepareTable
(
textLexer
.
getColumnNames
(),
textLexer
.
getColumnTypes
());
textLexer
.
parse
(
address
,
len
,
Integer
.
MAX_VALUE
,
textWriter
);
textLexer
.
parse
(
address
,
len
,
Integer
.
MAX_VALUE
,
textWriter
);
break
;
break
;
case
LOAD_DATA:
case
LOAD_DATA:
...
...
core/src/main/java/com/questdb/cutlass/text/TextMetadataDetector.java
浏览文件 @
995ed2ec
...
@@ -32,7 +32,6 @@ import com.questdb.std.str.CharSink;
...
@@ -32,7 +32,6 @@ import com.questdb.std.str.CharSink;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.std.str.DirectCharSink
;
import
com.questdb.std.str.DirectCharSink
;
import
com.questdb.std.str.StringSink
;
import
com.questdb.std.str.StringSink
;
import
com.questdb.store.ColumnType
;
import
java.io.Closeable
;
import
java.io.Closeable
;
...
@@ -41,11 +40,11 @@ import static com.questdb.std.Chars.utf8DecodeMultiByte;
...
@@ -41,11 +40,11 @@ import static com.questdb.std.Chars.utf8DecodeMultiByte;
public
class
TextMetadataDetector
implements
TextLexer
.
Listener
,
Mutable
,
Closeable
{
public
class
TextMetadataDetector
implements
TextLexer
.
Listener
,
Mutable
,
Closeable
{
private
static
final
Log
LOG
=
LogFactory
.
getLog
(
TextMetadataDetector
.
class
);
private
static
final
Log
LOG
=
LogFactory
.
getLog
(
TextMetadataDetector
.
class
);
private
final
StringSink
tempSink
=
new
StringSink
();
private
final
StringSink
tempSink
=
new
StringSink
();
private
final
ObjList
<
T
extMetadata
>
_metadata
=
new
ObjList
<>();
private
final
ObjList
<
T
ypeProbe
>
columnTypes
=
new
ObjList
<>();
private
final
ObjList
<
String
>
_header
s
=
new
ObjList
<>();
private
final
ObjList
<
CharSequence
>
columnName
s
=
new
ObjList
<>();
private
final
IntList
_blanks
=
new
IntList
();
private
final
IntList
_blanks
=
new
IntList
();
private
final
IntList
_histogram
=
new
IntList
();
private
final
IntList
_histogram
=
new
IntList
();
private
final
CharSequenceObjHashMap
<
T
extMetadata
>
schemaColumns
=
new
CharSequenceObjHashMap
<>();
private
final
CharSequenceObjHashMap
<
T
ypeProbe
>
schemaColumns
=
new
CharSequenceObjHashMap
<>();
private
final
ObjectPool
<
TextMetadata
>
mPool
=
new
ObjectPool
<>(
TextMetadata:
:
new
,
256
);
private
final
ObjectPool
<
TextMetadata
>
mPool
=
new
ObjectPool
<>(
TextMetadata:
:
new
,
256
);
private
final
TypeProbeCollection
typeProbeCollection
;
private
final
TypeProbeCollection
typeProbeCollection
;
private
final
DirectCharSink
utf8Sink
;
private
final
DirectCharSink
utf8Sink
;
...
@@ -84,12 +83,12 @@ public class TextMetadataDetector implements TextLexer.Listener, Mutable, Closea
...
@@ -84,12 +83,12 @@ public class TextMetadataDetector implements TextLexer.Listener, Mutable, Closea
@Override
@Override
public
void
clear
()
{
public
void
clear
()
{
tempSink
.
clear
();
tempSink
.
clear
();
_header
s
.
clear
();
columnName
s
.
clear
();
_blanks
.
clear
();
_blanks
.
clear
();
_histogram
.
clear
();
_histogram
.
clear
();
fieldCount
=
0
;
fieldCount
=
0
;
header
=
false
;
header
=
false
;
_metadata
.
clear
();
columnTypes
.
clear
();
schemaColumns
.
clear
();
schemaColumns
.
clear
();
forceHeader
=
false
;
forceHeader
=
false
;
mPool
.
clear
();
mPool
.
clear
();
...
@@ -106,9 +105,6 @@ public class TextMetadataDetector implements TextLexer.Listener, Mutable, Closea
...
@@ -106,9 +105,6 @@ public class TextMetadataDetector implements TextLexer.Listener, Mutable, Closea
// if some fields come up as non-string after subtracting row - we have a header
// if some fields come up as non-string after subtracting row - we have a header
if
((
calcTypes
(
lineCount
-
errorCount
,
true
)
&&
!
calcTypes
(
lineCount
-
errorCount
-
1
,
false
))
||
forceHeader
)
{
if
((
calcTypes
(
lineCount
-
errorCount
,
true
)
&&
!
calcTypes
(
lineCount
-
errorCount
-
1
,
false
))
||
forceHeader
)
{
// copy headers
// copy headers
for
(
int
i
=
0
;
i
<
fieldCount
;
i
++)
{
_metadata
.
getQuick
(
i
).
name
=
_headers
.
getQuick
(
i
);
}
header
=
true
;
header
=
true
;
}
else
{
}
else
{
LOG
.
info
()
LOG
.
info
()
...
@@ -121,40 +117,36 @@ public class TextMetadataDetector implements TextLexer.Listener, Mutable, Closea
...
@@ -121,40 +117,36 @@ public class TextMetadataDetector implements TextLexer.Listener, Mutable, Closea
// make up field names if there is no header
// make up field names if there is no header
for
(
int
i
=
0
;
i
<
fieldCount
;
i
++)
{
for
(
int
i
=
0
;
i
<
fieldCount
;
i
++)
{
final
TextMetadata
metadata
=
_metadata
.
getQuick
(
i
);
if
(!
header
||
columnNames
.
getQuick
(
i
).
length
()
==
0
)
{
if
(
metadata
.
name
.
length
()
==
0
)
{
tempSink
.
clear
();
tempSink
.
clear
();
tempSink
.
put
(
'f'
).
put
(
i
);
tempSink
.
put
(
'f'
).
put
(
i
);
metadata
.
name
=
tempSink
.
toString
(
);
columnNames
.
setQuick
(
i
,
tempSink
.
toString
()
);
}
}
}
}
// override calculated types with user-supplied information
// override calculated types with user-supplied information
//
if
(
schemaColumns
.
size
()
>
0
)
{
if
(
schemaColumns
.
size
()
>
0
)
{
for
(
int
i
=
0
,
k
=
_metadata
.
size
();
i
<
k
;
i
++)
{
for
(
int
i
=
0
,
k
=
columnNames
.
size
();
i
<
k
;
i
++)
{
TextMetadata
_m
=
_metadata
.
getQuick
(
i
);
TypeProbe
type
=
schemaColumns
.
get
(
columnNames
.
getQuick
(
i
));
TextMetadata
m
=
schemaColumns
.
get
(
_m
.
name
);
if
(
type
!=
null
)
{
if
(
m
!=
null
)
{
columnTypes
.
setQuick
(
i
,
type
);
m
.
copyTo
(
_m
);
}
}
}
}
}
}
}
}
public
ObjList
<
TextMetadata
>
getMetadata
()
{
return
_metadata
;
}
public
boolean
isHeader
()
{
public
boolean
isHeader
()
{
return
header
;
return
header
;
}
}
public
void
of
(
ObjList
<
TextMetadata
>
seedMetadata
,
boolean
forceHeader
)
{
public
void
of
(
ObjList
<
CharSequence
>
names
,
ObjList
<
TypeProbe
>
types
,
boolean
forceHeader
)
{
clear
();
clear
();
if
(
seedMetadata
!=
null
)
{
if
(
names
!=
null
&&
types
!=
null
)
{
for
(
int
i
=
0
,
n
=
seedMetadata
.
size
();
i
<
n
;
i
++)
{
final
int
n
=
names
.
size
();
TextMetadata
m
=
seedMetadata
.
getQuick
(
i
);
assert
n
==
types
.
size
();
schemaColumns
.
put
(
m
.
name
,
m
);
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
schemaColumns
.
put
(
names
.
getQuick
(
i
),
types
.
getQuick
(
i
));
}
}
}
}
this
.
forceHeader
=
forceHeader
;
this
.
forceHeader
=
forceHeader
;
...
@@ -201,15 +193,11 @@ public class TextMetadataDetector implements TextLexer.Listener, Mutable, Closea
...
@@ -201,15 +193,11 @@ public class TextMetadataDetector implements TextLexer.Listener, Mutable, Closea
int
offset
=
i
*
probeCount
;
int
offset
=
i
*
probeCount
;
int
blanks
=
_blanks
.
getQuick
(
i
);
int
blanks
=
_blanks
.
getQuick
(
i
);
boolean
unprobed
=
true
;
boolean
unprobed
=
true
;
TextMetadata
m
=
_metadata
.
getQuick
(
i
);
for
(
int
k
=
0
;
k
<
probeCount
;
k
++)
{
for
(
int
k
=
0
;
k
<
probeCount
;
k
++)
{
if
(
_histogram
.
getQuick
(
k
+
offset
)
+
blanks
==
count
&&
blanks
<
count
)
{
if
(
_histogram
.
getQuick
(
k
+
offset
)
+
blanks
==
count
&&
blanks
<
count
)
{
unprobed
=
false
;
unprobed
=
false
;
TypeProbe
probe
=
typeProbeCollection
.
getProbe
(
k
);
columnTypes
.
setQuick
(
i
,
typeProbeCollection
.
getProbe
(
k
));
m
.
type
=
probe
.
getType
();
m
.
dateFormat
=
probe
.
getDateFormat
();
m
.
dateLocale
=
probe
.
getDateLocale
();
if
(
allStrings
)
{
if
(
allStrings
)
{
allStrings
=
false
;
allStrings
=
false
;
}
}
...
@@ -218,13 +206,24 @@ public class TextMetadataDetector implements TextLexer.Listener, Mutable, Closea
...
@@ -218,13 +206,24 @@ public class TextMetadataDetector implements TextLexer.Listener, Mutable, Closea
}
}
if
(
setDefault
&&
unprobed
)
{
if
(
setDefault
&&
unprobed
)
{
m
.
type
=
ColumnType
.
STRING
;
columnTypes
.
setQuick
(
i
,
typeProbeCollection
.
getStringProbe
())
;
}
}
}
}
return
allStrings
;
return
allStrings
;
}
}
ObjList
<
CharSequence
>
getColumnNames
()
{
return
columnNames
;
}
ObjList
<
TypeProbe
>
getColumnTypes
()
{
return
columnTypes
;
}
// metadata detector is essentially part of text lexer
// we can potentially keep a cache of char sequences until the whole
// system is reset, similar to flyweight char sequence over array of chars
private
String
normalise
(
CharSequence
seq
)
{
private
String
normalise
(
CharSequence
seq
)
{
boolean
capNext
=
false
;
boolean
capNext
=
false
;
tempSink
.
clear
();
tempSink
.
clear
();
...
@@ -272,10 +271,8 @@ public class TextMetadataDetector implements TextLexer.Listener, Mutable, Closea
...
@@ -272,10 +271,8 @@ public class TextMetadataDetector implements TextLexer.Listener, Mutable, Closea
private
void
seedFields
(
int
count
)
{
private
void
seedFields
(
int
count
)
{
this
.
_histogram
.
setAll
((
fieldCount
=
count
)
*
typeProbeCollection
.
getProbeCount
(),
0
);
this
.
_histogram
.
setAll
((
fieldCount
=
count
)
*
typeProbeCollection
.
getProbeCount
(),
0
);
this
.
_blanks
.
setAll
(
count
,
0
);
this
.
_blanks
.
setAll
(
count
,
0
);
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
this
.
columnTypes
.
extendAndSet
(
count
-
1
,
null
);
this
.
_metadata
.
add
(
mPool
.
next
());
this
.
columnNames
.
setAll
(
count
,
""
);
}
this
.
_headers
.
setAll
(
count
,
""
);
}
}
void
setTableName
(
CharSequence
tableName
)
{
void
setTableName
(
CharSequence
tableName
)
{
...
@@ -287,7 +284,7 @@ public class TextMetadataDetector implements TextLexer.Listener, Mutable, Closea
...
@@ -287,7 +284,7 @@ public class TextMetadataDetector implements TextLexer.Listener, Mutable, Closea
DirectByteCharSequence
value
=
values
.
getQuick
(
i
);
DirectByteCharSequence
value
=
values
.
getQuick
(
i
);
utf8Sink
.
clear
();
utf8Sink
.
clear
();
if
(
utf8Decode
(
value
.
getLo
(),
value
.
getHi
(),
utf8Sink
))
{
if
(
utf8Decode
(
value
.
getLo
(),
value
.
getHi
(),
utf8Sink
))
{
_header
s
.
setQuick
(
i
,
normalise
(
utf8Sink
));
columnName
s
.
setQuick
(
i
,
normalise
(
utf8Sink
));
}
else
{
}
else
{
LOG
.
info
().
$
(
"utf8 error [table="
).
$
(
tableName
).
$
(
", line=0, col="
).
$
(
i
).
$
(
']'
).
$
();
LOG
.
info
().
$
(
"utf8 error [table="
).
$
(
tableName
).
$
(
", line=0, col="
).
$
(
i
).
$
(
']'
).
$
();
}
}
...
...
core/src/main/java/com/questdb/cutlass/text/TextMetadataParser.java
浏览文件 @
995ed2ec
...
@@ -27,11 +27,14 @@ import com.questdb.cairo.ColumnType;
...
@@ -27,11 +27,14 @@ import com.questdb.cairo.ColumnType;
import
com.questdb.cutlass.json.JsonException
;
import
com.questdb.cutlass.json.JsonException
;
import
com.questdb.cutlass.json.JsonLexer
;
import
com.questdb.cutlass.json.JsonLexer
;
import
com.questdb.cutlass.json.JsonParser
;
import
com.questdb.cutlass.json.JsonParser
;
import
com.questdb.cutlass.text.typeprobe.DateProbe
;
import
com.questdb.cutlass.text.typeprobe.TypeProbe
;
import
com.questdb.cutlass.text.typeprobe.TypeProbeCollection
;
import
com.questdb.log.Log
;
import
com.questdb.log.Log
;
import
com.questdb.log.LogFactory
;
import
com.questdb.log.LogFactory
;
import
com.questdb.std.*
;
import
com.questdb.std.*
;
import
com.questdb.std.str.AbstractCharSequence
;
import
com.questdb.std.str.AbstractCharSequence
;
import
com.questdb.std.
time.DateFormat
;
import
com.questdb.std.
str.DirectCharSink
;
import
com.questdb.std.time.DateFormatFactory
;
import
com.questdb.std.time.DateFormatFactory
;
import
com.questdb.std.time.DateLocale
;
import
com.questdb.std.time.DateLocale
;
import
com.questdb.std.time.DateLocaleFactory
;
import
com.questdb.std.time.DateLocaleFactory
;
...
@@ -52,19 +55,64 @@ public class TextMetadataParser implements JsonParser, Mutable, Closeable {
...
@@ -52,19 +55,64 @@ public class TextMetadataParser implements JsonParser, Mutable, Closeable {
private
final
DateLocaleFactory
dateLocaleFactory
;
private
final
DateLocaleFactory
dateLocaleFactory
;
private
final
ObjectPool
<
FloatingCharSequence
>
csPool
;
private
final
ObjectPool
<
FloatingCharSequence
>
csPool
;
private
final
DateFormatFactory
dateFormatFactory
;
private
final
DateFormatFactory
dateFormatFactory
;
private
final
ObjectPool
<
TextMetadata
>
textMetadataPool
;
private
final
ObjList
<
CharSequence
>
columnNames
;
private
final
ObjList
<
TextMetadata
>
textMetadata
;
private
final
ObjList
<
TypeProbe
>
columnTypes
;
private
final
DirectCharSink
utf8Sink
;
private
int
state
=
S_NEED_ARRAY
;
private
int
state
=
S_NEED_ARRAY
;
private
CharSequence
name
;
private
CharSequence
name
;
private
int
type
=
-
1
;
private
int
type
=
-
1
;
private
CharSequence
pattern
;
private
CharSequence
pattern
;
private
DateFormat
dateFormat
;
private
final
TypeProbeCollection
typeProbeCollection
;
private
DateLocale
dateL
ocale
;
private
CharSequence
l
ocale
;
private
int
propertyIndex
;
private
int
propertyIndex
;
private
long
buf
;
private
long
buf
;
private
long
bufCapacity
=
0
;
private
long
bufCapacity
=
0
;
private
int
bufSize
=
0
;
private
int
bufSize
=
0
;
private
CharSequence
tableName
;
private
CharSequence
tableName
;
private
int
localePosition
;
public
TextMetadataParser
(
TextConfiguration
textConfiguration
,
DateLocaleFactory
dateLocaleFactory
,
DateFormatFactory
dateFormatFactory
,
DirectCharSink
utf8Sink
,
TypeProbeCollection
typeProbeCollection
)
{
this
.
columnNames
=
new
ObjList
<>();
this
.
columnTypes
=
new
ObjList
<>();
this
.
csPool
=
new
ObjectPool
<>(
FloatingCharSequence:
:
new
,
textConfiguration
.
getMetadataStringPoolSize
());
this
.
dateLocaleFactory
=
dateLocaleFactory
;
this
.
dateFormatFactory
=
dateFormatFactory
;
this
.
utf8Sink
=
utf8Sink
;
this
.
typeProbeCollection
=
typeProbeCollection
;
}
@Override
public
void
clear
()
{
bufSize
=
0
;
state
=
S_NEED_ARRAY
;
columnNames
.
clear
();
columnTypes
.
clear
();
csPool
.
clear
();
clearStage
();
}
@Override
public
void
close
()
{
clear
();
if
(
bufCapacity
>
0
)
{
Unsafe
.
free
(
buf
,
bufCapacity
);
bufCapacity
=
0
;
}
}
public
ObjList
<
CharSequence
>
getColumnNames
()
{
return
columnNames
;
}
public
ObjList
<
TypeProbe
>
getColumnTypes
()
{
return
columnTypes
;
}
@Override
@Override
public
void
onEvent
(
int
code
,
CharSequence
tag
,
int
position
)
throws
JsonException
{
public
void
onEvent
(
int
code
,
CharSequence
tag
,
int
position
)
throws
JsonException
{
...
@@ -99,14 +147,11 @@ public class TextMetadataParser implements JsonParser, Mutable, Closeable {
...
@@ -99,14 +147,11 @@ public class TextMetadataParser implements JsonParser, Mutable, Closeable {
}
}
break
;
break
;
case
P_PATTERN:
case
P_PATTERN:
dateFormat
=
dateFormatFactory
.
get
(
tag
);
pattern
=
copy
(
tag
);
pattern
=
copy
(
tag
);
break
;
break
;
case
P_LOCALE:
case
P_LOCALE:
dateLocale
=
dateLocaleFactory
.
getDateLocale
(
tag
);
locale
=
copy
(
tag
);
if
(
dateLocale
==
null
)
{
localePosition
=
position
;
throw
JsonException
.
with
(
"Invalid date locale"
,
position
);
}
break
;
break
;
default
:
default
:
LOG
.
info
().
$
(
"ignoring [table="
).
$
(
tableName
).
$
(
", value="
).
$
(
tag
).
$
(
']'
).
$
();
LOG
.
info
().
$
(
"ignoring [table="
).
$
(
tableName
).
$
(
", value="
).
$
(
tag
).
$
(
']'
).
$
();
...
@@ -124,52 +169,16 @@ public class TextMetadataParser implements JsonParser, Mutable, Closeable {
...
@@ -124,52 +169,16 @@ public class TextMetadataParser implements JsonParser, Mutable, Closeable {
}
}
}
}
public
TextMetadataParser
(
TextConfiguration
textConfiguration
,
DateLocaleFactory
dateLocaleFactory
,
DateFormatFactory
dateFormatFactory
)
{
this
.
textMetadataPool
=
new
ObjectPool
<>(
TextMetadata:
:
new
,
textConfiguration
.
getMetadataPoolSize
());
this
.
textMetadata
=
new
ObjList
<>();
this
.
csPool
=
new
ObjectPool
<>(
FloatingCharSequence:
:
new
,
textConfiguration
.
getMetadataStringPoolSize
());
this
.
dateLocaleFactory
=
dateLocaleFactory
;
this
.
dateFormatFactory
=
dateFormatFactory
;
}
@Override
public
void
clear
()
{
bufSize
=
0
;
state
=
S_NEED_ARRAY
;
textMetadata
.
clear
();
csPool
.
clear
();
clearStage
();
textMetadataPool
.
clear
();
textMetadata
.
clear
();
}
@Override
public
void
close
()
{
clear
();
if
(
bufCapacity
>
0
)
{
Unsafe
.
free
(
buf
,
bufCapacity
);
bufCapacity
=
0
;
}
}
void
setTableName
(
CharSequence
tableName
)
{
this
.
tableName
=
tableName
;
}
private
void
clearStage
()
{
private
void
clearStage
()
{
name
=
null
;
name
=
null
;
pattern
=
null
;
type
=
-
1
;
type
=
-
1
;
dateLocale
=
null
;
pattern
=
null
;
dateFormat
=
null
;
locale
=
null
;
localePosition
=
0
;
}
}
private
CharSequence
copy
(
CharSequence
tag
)
{
private
CharSequence
copy
(
CharSequence
tag
)
{
final
int
l
=
tag
.
length
();
final
int
l
=
tag
.
length
()
*
2
;
final
long
n
=
bufSize
+
l
;
final
long
n
=
bufSize
+
l
;
if
(
n
>
bufCapacity
)
{
if
(
n
>
bufCapacity
)
{
long
ptr
=
Unsafe
.
malloc
(
n
*
2
);
long
ptr
=
Unsafe
.
malloc
(
n
*
2
);
...
@@ -181,7 +190,7 @@ public class TextMetadataParser implements JsonParser, Mutable, Closeable {
...
@@ -181,7 +190,7 @@ public class TextMetadataParser implements JsonParser, Mutable, Closeable {
bufCapacity
=
n
*
2
;
bufCapacity
=
n
*
2
;
}
}
Chars
.
strcpy
(
tag
,
l
,
buf
+
bufSize
);
Chars
.
strcpy
w
(
tag
,
l
/
2
,
buf
+
bufSize
);
CharSequence
cs
=
csPool
.
next
().
of
(
bufSize
,
bufSize
+
l
);
CharSequence
cs
=
csPool
.
next
().
of
(
bufSize
,
bufSize
+
l
);
bufSize
+=
l
;
bufSize
+=
l
;
return
cs
;
return
cs
;
...
@@ -196,19 +205,26 @@ public class TextMetadataParser implements JsonParser, Mutable, Closeable {
...
@@ -196,19 +205,26 @@ public class TextMetadataParser implements JsonParser, Mutable, Closeable {
throw
JsonException
.
with
(
"Missing 'type' property"
,
position
);
throw
JsonException
.
with
(
"Missing 'type' property"
,
position
);
}
}
TextMetadata
m
=
textMetadataPool
.
next
();
columnNames
.
add
(
name
);
m
.
name
=
name
;
m
.
type
=
type
;
m
.
dateFormat
=
dateFormat
;
m
.
dateLocale
=
dateLocale
==
null
&&
type
==
ColumnType
.
DATE
?
dateLocaleFactory
.
getDefaultDateLocale
()
:
dateLocale
;
textMetadata
.
add
(
m
);
switch
(
type
)
{
case
ColumnType
.
DATE
:
DateLocale
dateLocale
=
locale
==
null
?
dateLocaleFactory
.
getDefaultDateLocale
()
:
dateLocaleFactory
.
getDateLocale
(
locale
);
if
(
dateLocale
==
null
)
{
throw
JsonException
.
with
(
"Invalid date locale"
,
localePosition
);
}
columnTypes
.
add
(((
DateProbe
)
typeProbeCollection
.
getProbeForType
(
type
)).
of
(
dateFormatFactory
.
get
(
pattern
),
dateLocale
));
break
;
default
:
columnTypes
.
add
(
typeProbeCollection
.
getProbeForType
(
type
));
break
;
}
// prepare for next iteration
// prepare for next iteration
clearStage
();
clearStage
();
}
}
ObjList
<
TextMetadata
>
getTextMetadata
(
)
{
void
setTableName
(
CharSequence
tableName
)
{
return
textMetadata
;
this
.
tableName
=
tableName
;
}
}
private
class
FloatingCharSequence
extends
AbstractCharSequence
implements
Mutable
{
private
class
FloatingCharSequence
extends
AbstractCharSequence
implements
Mutable
{
...
@@ -222,12 +238,12 @@ public class TextMetadataParser implements JsonParser, Mutable, Closeable {
...
@@ -222,12 +238,12 @@ public class TextMetadataParser implements JsonParser, Mutable, Closeable {
@Override
@Override
public
int
length
()
{
public
int
length
()
{
return
hi
-
lo
;
return
(
hi
-
lo
)
/
2
;
}
}
@Override
@Override
public
char
charAt
(
int
index
)
{
public
char
charAt
(
int
index
)
{
return
(
char
)
Unsafe
.
getUnsafe
().
getByte
(
buf
+
lo
+
index
);
return
Unsafe
.
getUnsafe
().
getChar
(
buf
+
lo
+
index
*
2
);
}
}
CharSequence
of
(
int
lo
,
int
hi
)
{
CharSequence
of
(
int
lo
,
int
hi
)
{
...
@@ -235,6 +251,14 @@ public class TextMetadataParser implements JsonParser, Mutable, Closeable {
...
@@ -235,6 +251,14 @@ public class TextMetadataParser implements JsonParser, Mutable, Closeable {
this
.
hi
=
hi
;
this
.
hi
=
hi
;
return
this
;
return
this
;
}
}
long
getHi
()
{
return
buf
+
hi
;
}
long
getLo
()
{
return
buf
+
lo
;
}
}
}
static
{
static
{
...
...
core/src/main/java/com/questdb/cutlass/text/TextUtil.java
0 → 100644
浏览文件 @
995ed2ec
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2018 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package
com.questdb.cutlass.text
;
import
com.questdb.std.Unsafe
;
import
com.questdb.std.str.CharSink
;
import
static
com
.
questdb
.
std
.
Chars
.
utf8DecodeMultiByte
;
public
class
TextUtil
{
public
static
void
utf8Decode
(
long
lo
,
long
hi
,
CharSink
sink
)
throws
Utf8Exception
{
long
p
=
lo
;
int
quoteCount
=
0
;
while
(
p
<
hi
)
{
byte
b
=
Unsafe
.
getUnsafe
().
getByte
(
p
);
if
(
b
<
0
)
{
int
n
=
utf8DecodeMultiByte
(
p
,
hi
,
b
,
sink
);
if
(
n
==
-
1
)
{
// UTF8 error
throw
Utf8Exception
.
INSTANCE
;
}
p
+=
n
;
}
else
{
if
(
b
==
'"'
)
{
if
(
quoteCount
++
%
2
==
0
)
{
sink
.
put
(
'"'
);
}
}
else
{
sink
.
put
((
char
)
b
);
}
++
p
;
}
}
}
}
core/src/main/java/com/questdb/cutlass/text/typeprobe/BadDateProbe.java
0 → 100644
浏览文件 @
995ed2ec
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2018 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package
com.questdb.cutlass.text.typeprobe
;
import
com.questdb.cairo.TableWriter
;
import
com.questdb.std.Numbers
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.store.ColumnType
;
public
class
BadDateProbe
implements
TypeProbe
{
@Override
public
int
getType
()
{
return
ColumnType
.
DATE
;
}
@Override
public
boolean
probe
(
CharSequence
text
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
void
write
(
TableWriter
.
Row
row
,
int
column
,
DirectByteCharSequence
value
)
throws
Exception
{
row
.
putDate
(
column
,
Numbers
.
LONG_NaN
);
}
@Override
public
String
toString
()
{
return
"DATE"
;
}
}
core/src/main/java/com/questdb/cutlass/text/typeprobe/BooleanProbe.java
浏览文件 @
995ed2ec
...
@@ -23,21 +23,16 @@
...
@@ -23,21 +23,16 @@
package
com.questdb.cutlass.text.typeprobe
;
package
com.questdb.cutlass.text.typeprobe
;
import
com.questdb.cairo.TableWriter
;
import
com.questdb.std.Chars
;
import
com.questdb.std.Chars
;
import
com.questdb.std.time.DateFormat
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.std.time.DateLocale
;
import
com.questdb.store.ColumnType
;
import
com.questdb.store.ColumnType
;
public
class
BooleanProbe
implements
TypeProbe
{
public
class
BooleanProbe
implements
TypeProbe
{
@Override
@Override
public
DateFormat
getDateFormat
()
{
public
String
toString
()
{
return
null
;
return
"BOOLEAN"
;
}
@Override
public
DateLocale
getDateLocale
()
{
return
null
;
}
}
@Override
@Override
...
@@ -49,4 +44,9 @@ public class BooleanProbe implements TypeProbe {
...
@@ -49,4 +44,9 @@ public class BooleanProbe implements TypeProbe {
public
boolean
probe
(
CharSequence
text
)
{
public
boolean
probe
(
CharSequence
text
)
{
return
Chars
.
equalsIgnoreCase
(
text
,
"true"
)
||
Chars
.
equalsIgnoreCase
(
text
,
"false"
);
return
Chars
.
equalsIgnoreCase
(
text
,
"true"
)
||
Chars
.
equalsIgnoreCase
(
text
,
"false"
);
}
}
@Override
public
void
write
(
TableWriter
.
Row
row
,
int
column
,
DirectByteCharSequence
value
)
throws
Exception
{
row
.
putBool
(
column
,
Chars
.
equalsIgnoreCase
(
value
,
"true"
));
}
}
}
core/src/main/java/com/questdb/cutlass/text/typeprobe/ByteProbe.java
0 → 100644
浏览文件 @
995ed2ec
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2018 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package
com.questdb.cutlass.text.typeprobe
;
import
com.questdb.cairo.TableWriter
;
import
com.questdb.std.Numbers
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.store.ColumnType
;
public
class
ByteProbe
implements
TypeProbe
{
@Override
public
int
getType
()
{
return
ColumnType
.
BYTE
;
}
@Override
public
boolean
probe
(
CharSequence
text
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
void
write
(
TableWriter
.
Row
row
,
int
column
,
DirectByteCharSequence
value
)
throws
Exception
{
row
.
putByte
(
column
,
(
byte
)
Numbers
.
parseInt
(
value
));
}
@Override
public
String
toString
()
{
return
"BYTE"
;
}
}
core/src/main/java/com/questdb/cutlass/text/typeprobe/DateProbe.java
浏览文件 @
995ed2ec
...
@@ -23,29 +23,31 @@
...
@@ -23,29 +23,31 @@
package
com.questdb.cutlass.text.typeprobe
;
package
com.questdb.cutlass.text.typeprobe
;
import
com.questdb.cairo.TableWriter
;
import
com.questdb.cutlass.text.TextUtil
;
import
com.questdb.std.Mutable
;
import
com.questdb.std.NumericException
;
import
com.questdb.std.NumericException
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.std.str.DirectCharSink
;
import
com.questdb.std.time.DateFormat
;
import
com.questdb.std.time.DateFormat
;
import
com.questdb.std.time.DateFormatFactory
;
import
com.questdb.std.time.DateLocale
;
import
com.questdb.std.time.DateLocale
;
import
com.questdb.store.ColumnType
;
import
com.questdb.store.ColumnType
;
public
class
DateProbe
implements
TypeProbe
{
public
class
DateProbe
implements
TypeProbe
,
Mutable
{
private
final
DateLocale
dateLocale
;
private
final
DirectCharSink
utf8Sink
;
private
final
DateFormat
format
;
private
DateLocale
locale
;
private
DateFormat
format
;
public
DateProbe
(
DateFormatFactory
dateFormatFactory
,
DateLocale
dateLocale
,
CharSequence
pattern
)
{
public
DateProbe
(
this
.
dateLocale
=
dateLocale
;
DirectCharSink
utf8Sink
this
.
format
=
dateFormatFactory
.
get
(
pattern
);
)
{
this
.
utf8Sink
=
utf8Sink
;
}
}
@Override
@Override
public
DateFormat
getDateFormat
()
{
public
void
clear
()
{
return
format
;
this
.
format
=
null
;
}
this
.
locale
=
null
;
@Override
public
DateLocale
getDateLocale
()
{
return
dateLocale
;
}
}
@Override
@Override
...
@@ -53,13 +55,31 @@ public class DateProbe implements TypeProbe {
...
@@ -53,13 +55,31 @@ public class DateProbe implements TypeProbe {
return
ColumnType
.
DATE
;
return
ColumnType
.
DATE
;
}
}
public
DateProbe
of
(
DateFormat
format
,
DateLocale
locale
)
{
this
.
format
=
format
;
this
.
locale
=
locale
;
return
this
;
}
@Override
@Override
public
boolean
probe
(
CharSequence
text
)
{
public
boolean
probe
(
CharSequence
text
)
{
try
{
try
{
format
.
parse
(
text
,
dateL
ocale
);
format
.
parse
(
text
,
l
ocale
);
return
true
;
return
true
;
}
catch
(
NumericException
e
)
{
}
catch
(
NumericException
e
)
{
return
false
;
return
false
;
}
}
}
}
@Override
public
void
write
(
TableWriter
.
Row
row
,
int
column
,
DirectByteCharSequence
value
)
throws
Exception
{
utf8Sink
.
clear
();
TextUtil
.
utf8Decode
(
value
.
getLo
(),
value
.
getHi
(),
utf8Sink
);
row
.
putDate
(
column
,
format
.
parse
(
utf8Sink
,
locale
));
}
@Override
public
String
toString
()
{
return
"DATE"
;
}
}
}
core/src/main/java/com/questdb/cutlass/text/typeprobe/DoubleProbe.java
浏览文件 @
995ed2ec
...
@@ -23,22 +23,17 @@
...
@@ -23,22 +23,17 @@
package
com.questdb.cutlass.text.typeprobe
;
package
com.questdb.cutlass.text.typeprobe
;
import
com.questdb.cairo.TableWriter
;
import
com.questdb.std.Numbers
;
import
com.questdb.std.Numbers
;
import
com.questdb.std.NumericException
;
import
com.questdb.std.NumericException
;
import
com.questdb.std.time.DateFormat
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.std.time.DateLocale
;
import
com.questdb.store.ColumnType
;
import
com.questdb.store.ColumnType
;
public
class
DoubleProbe
implements
TypeProbe
{
public
class
DoubleProbe
implements
TypeProbe
{
@Override
@Override
public
DateFormat
getDateFormat
()
{
public
String
toString
()
{
return
null
;
return
"DOUBLE"
;
}
@Override
public
DateLocale
getDateLocale
()
{
return
null
;
}
}
@Override
@Override
...
@@ -58,4 +53,9 @@ public class DoubleProbe implements TypeProbe {
...
@@ -58,4 +53,9 @@ public class DoubleProbe implements TypeProbe {
return
false
;
return
false
;
}
}
}
}
@Override
public
void
write
(
TableWriter
.
Row
row
,
int
column
,
DirectByteCharSequence
value
)
throws
Exception
{
row
.
putDouble
(
column
,
Numbers
.
parseDouble
(
value
));
}
}
}
core/src/main/java/com/questdb/cutlass/text/typeprobe/FloatProbe.java
0 → 100644
浏览文件 @
995ed2ec
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2018 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package
com.questdb.cutlass.text.typeprobe
;
import
com.questdb.cairo.TableWriter
;
import
com.questdb.std.Numbers
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.store.ColumnType
;
public
class
FloatProbe
implements
TypeProbe
{
@Override
public
int
getType
()
{
return
ColumnType
.
FLOAT
;
}
@Override
public
boolean
probe
(
CharSequence
text
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
void
write
(
TableWriter
.
Row
row
,
int
column
,
DirectByteCharSequence
value
)
throws
Exception
{
row
.
putFloat
(
column
,
Numbers
.
parseFloat
(
value
));
}
@Override
public
String
toString
()
{
return
"FLOAT"
;
}
}
core/src/main/java/com/questdb/cutlass/text/typeprobe/IntProbe.java
浏览文件 @
995ed2ec
...
@@ -23,8 +23,10 @@
...
@@ -23,8 +23,10 @@
package
com.questdb.cutlass.text.typeprobe
;
package
com.questdb.cutlass.text.typeprobe
;
import
com.questdb.cairo.TableWriter
;
import
com.questdb.std.Numbers
;
import
com.questdb.std.Numbers
;
import
com.questdb.std.NumericException
;
import
com.questdb.std.NumericException
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.store.ColumnType
;
import
com.questdb.store.ColumnType
;
public
class
IntProbe
implements
TypeProbe
{
public
class
IntProbe
implements
TypeProbe
{
...
@@ -46,4 +48,14 @@ public class IntProbe implements TypeProbe {
...
@@ -46,4 +48,14 @@ public class IntProbe implements TypeProbe {
return
false
;
return
false
;
}
}
}
}
@Override
public
String
toString
()
{
return
"INT"
;
}
@Override
public
void
write
(
TableWriter
.
Row
row
,
int
column
,
DirectByteCharSequence
value
)
throws
Exception
{
row
.
putInt
(
column
,
Numbers
.
parseInt
(
value
));
}
}
}
core/src/main/java/com/questdb/cutlass/text/typeprobe/LongProbe.java
浏览文件 @
995ed2ec
...
@@ -23,22 +23,13 @@
...
@@ -23,22 +23,13 @@
package
com.questdb.cutlass.text.typeprobe
;
package
com.questdb.cutlass.text.typeprobe
;
import
com.questdb.cairo.TableWriter
;
import
com.questdb.std.Numbers
;
import
com.questdb.std.Numbers
;
import
com.questdb.std.NumericException
;
import
com.questdb.std.NumericException
;
import
com.questdb.std.time.DateFormat
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.std.time.DateLocale
;
import
com.questdb.store.ColumnType
;
import
com.questdb.store.ColumnType
;
public
class
LongProbe
implements
TypeProbe
{
public
class
LongProbe
implements
TypeProbe
{
@Override
public
DateFormat
getDateFormat
()
{
return
null
;
}
@Override
public
DateLocale
getDateLocale
()
{
return
null
;
}
@Override
@Override
public
int
getType
()
{
public
int
getType
()
{
...
@@ -57,4 +48,14 @@ public class LongProbe implements TypeProbe {
...
@@ -57,4 +48,14 @@ public class LongProbe implements TypeProbe {
return
false
;
return
false
;
}
}
}
}
@Override
public
String
toString
()
{
return
"LONG"
;
}
@Override
public
void
write
(
TableWriter
.
Row
row
,
int
column
,
DirectByteCharSequence
value
)
throws
Exception
{
row
.
putLong
(
column
,
Numbers
.
parseLong
(
value
));
}
}
}
core/src/main/java/com/questdb/cutlass/text/typeprobe/ShortProbe.java
0 → 100644
浏览文件 @
995ed2ec
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2018 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package
com.questdb.cutlass.text.typeprobe
;
import
com.questdb.cairo.TableWriter
;
import
com.questdb.std.Numbers
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.store.ColumnType
;
public
class
ShortProbe
implements
TypeProbe
{
@Override
public
int
getType
()
{
return
ColumnType
.
SHORT
;
}
@Override
public
boolean
probe
(
CharSequence
text
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
void
write
(
TableWriter
.
Row
row
,
int
column
,
DirectByteCharSequence
value
)
throws
Exception
{
row
.
putShort
(
column
,
(
short
)
Numbers
.
parseInt
(
value
));
}
@Override
public
String
toString
()
{
return
"SHORT"
;
}
}
core/src/main/java/com/questdb/cutlass/text/typeprobe/StringProbe.java
0 → 100644
浏览文件 @
995ed2ec
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2018 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package
com.questdb.cutlass.text.typeprobe
;
import
com.questdb.cairo.TableWriter
;
import
com.questdb.cutlass.text.TextUtil
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.std.str.DirectCharSink
;
import
com.questdb.store.ColumnType
;
public
class
StringProbe
implements
TypeProbe
{
private
final
DirectCharSink
utf8Sink
;
public
StringProbe
(
DirectCharSink
utf8Sink
)
{
this
.
utf8Sink
=
utf8Sink
;
}
@Override
public
int
getType
()
{
return
ColumnType
.
STRING
;
}
@Override
public
boolean
probe
(
CharSequence
text
)
{
return
true
;
}
@Override
public
void
write
(
TableWriter
.
Row
row
,
int
column
,
DirectByteCharSequence
value
)
throws
Exception
{
utf8Sink
.
clear
();
TextUtil
.
utf8Decode
(
value
.
getLo
(),
value
.
getHi
(),
utf8Sink
);
row
.
putStr
(
column
,
utf8Sink
);
}
@Override
public
String
toString
()
{
return
"STRING"
;
}
}
core/src/main/java/com/questdb/cutlass/text/typeprobe/SymbolProbe.java
0 → 100644
浏览文件 @
995ed2ec
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2018 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package
com.questdb.cutlass.text.typeprobe
;
import
com.questdb.cairo.TableWriter
;
import
com.questdb.cutlass.text.TextUtil
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.std.str.DirectCharSink
;
import
com.questdb.store.ColumnType
;
public
class
SymbolProbe
implements
TypeProbe
{
private
final
DirectCharSink
utf8Sink
;
public
SymbolProbe
(
DirectCharSink
utf8Sink
)
{
this
.
utf8Sink
=
utf8Sink
;
}
@Override
public
int
getType
()
{
return
ColumnType
.
SYMBOL
;
}
@Override
public
boolean
probe
(
CharSequence
text
)
{
return
true
;
}
@Override
public
void
write
(
TableWriter
.
Row
row
,
int
column
,
DirectByteCharSequence
value
)
throws
Exception
{
utf8Sink
.
clear
();
TextUtil
.
utf8Decode
(
value
.
getLo
(),
value
.
getHi
(),
utf8Sink
);
row
.
putSym
(
column
,
utf8Sink
);
}
@Override
public
String
toString
()
{
return
"SYMBOL"
;
}
}
core/src/main/java/com/questdb/cutlass/text/typeprobe/TypeProbe.java
浏览文件 @
995ed2ec
...
@@ -23,19 +23,13 @@
...
@@ -23,19 +23,13 @@
package
com.questdb.cutlass.text.typeprobe
;
package
com.questdb.cutlass.text.typeprobe
;
import
com.questdb.
std.time.DateFormat
;
import
com.questdb.
cairo.TableWriter
;
import
com.questdb.std.
time.DateLocal
e
;
import
com.questdb.std.
str.DirectByteCharSequenc
e
;
public
interface
TypeProbe
{
public
interface
TypeProbe
{
default
DateFormat
getDateFormat
()
{
return
null
;
}
default
DateLocale
getDateLocale
()
{
return
null
;
}
int
getType
();
int
getType
();
boolean
probe
(
CharSequence
text
);
boolean
probe
(
CharSequence
text
);
void
write
(
TableWriter
.
Row
row
,
int
column
,
DirectByteCharSequence
value
)
throws
Exception
;
}
}
core/src/main/java/com/questdb/cutlass/text/typeprobe/TypeProbeCollection.java
浏览文件 @
995ed2ec
...
@@ -28,25 +28,43 @@ import com.questdb.log.Log;
...
@@ -28,25 +28,43 @@ import com.questdb.log.Log;
import
com.questdb.log.LogFactory
;
import
com.questdb.log.LogFactory
;
import
com.questdb.std.*
;
import
com.questdb.std.*
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.std.str.DirectByteCharSequence
;
import
com.questdb.std.str.DirectCharSink
;
import
com.questdb.std.str.Path
;
import
com.questdb.std.str.Path
;
import
com.questdb.std.time.DateFormatFactory
;
import
com.questdb.std.time.DateFormatFactory
;
import
com.questdb.std.time.DateFormatUtils
;
import
com.questdb.std.time.DateFormatUtils
;
import
com.questdb.std.time.DateLocale
;
import
com.questdb.std.time.DateLocale
;
import
com.questdb.std.time.DateLocaleFactory
;
import
com.questdb.std.time.DateLocaleFactory
;
import
com.questdb.store.ColumnType
;
public
class
TypeProbeCollection
{
public
class
TypeProbeCollection
implements
Mutable
{
private
static
final
Log
LOG
=
LogFactory
.
getLog
(
TypeProbeCollection
.
class
);
private
static
final
Log
LOG
=
LogFactory
.
getLog
(
TypeProbeCollection
.
class
);
private
static
final
ObjList
<
String
>
DEFAULT_DATE_FORMATS
=
new
ObjList
<>();
private
static
final
ObjList
<
String
>
DEFAULT_DATE_FORMATS
=
new
ObjList
<>();
private
final
ObjList
<
TypeProbe
>
probes
=
new
ObjList
<>();
private
final
ObjList
<
TypeProbe
>
probes
=
new
ObjList
<>();
private
final
int
probeCount
;
private
final
int
probeCount
;
private
final
StringProbe
stringProbe
;
private
final
DirectCharSink
utf8Sink
;
private
final
BooleanProbe
booleanProbe
=
new
BooleanProbe
();
private
final
DoubleProbe
doubleProbe
=
new
DoubleProbe
();
private
final
IntProbe
intProbe
=
new
IntProbe
();
private
final
LongProbe
longProbe
=
new
LongProbe
();
private
final
ShortProbe
shortProbe
=
new
ShortProbe
();
private
final
ObjectPool
<
DateProbe
>
dateProbePool
;
private
final
FloatProbe
floatProbe
=
new
FloatProbe
();
private
final
ByteProbe
byteProbe
=
new
ByteProbe
();
private
final
BadDateProbe
badDateProbe
=
new
BadDateProbe
();
private
final
SymbolProbe
symbolProbe
;
public
TypeProbeCollection
()
{
public
TypeProbeCollection
(
DirectCharSink
utf8Sink
)
{
this
.
utf8Sink
=
utf8Sink
;
this
.
dateProbePool
=
new
ObjectPool
<>(()
->
new
DateProbe
(
utf8Sink
),
16
);
this
.
stringProbe
=
new
StringProbe
(
utf8Sink
);
this
.
symbolProbe
=
new
SymbolProbe
(
utf8Sink
);
addDefaultProbes
();
addDefaultProbes
();
DateFormatFactory
dateFormatFactory
=
new
DateFormatFactory
();
DateFormatFactory
dateFormatFactory
=
new
DateFormatFactory
();
DateLocale
dateLocale
=
DateLocaleFactory
.
INSTANCE
.
getDefaultDateLocale
();
DateLocale
dateLocale
=
DateLocaleFactory
.
INSTANCE
.
getDefaultDateLocale
();
for
(
int
i
=
0
,
n
=
DEFAULT_DATE_FORMATS
.
size
();
i
<
n
;
i
++)
{
for
(
int
i
=
0
,
n
=
DEFAULT_DATE_FORMATS
.
size
();
i
<
n
;
i
++)
{
probes
.
add
(
new
DateProbe
(
dateFormatFactory
,
dateLocale
,
DEFAULT_DATE_FORMATS
.
getQuick
(
i
)
));
probes
.
add
(
new
DateProbe
(
utf8Sink
).
of
(
dateFormatFactory
.
get
(
DEFAULT_DATE_FORMATS
.
getQuick
(
i
)),
dateLocale
));
}
}
this
.
probeCount
=
probes
.
size
();
this
.
probeCount
=
probes
.
size
();
}
}
...
@@ -56,13 +74,27 @@ public class TypeProbeCollection {
...
@@ -56,13 +74,27 @@ public class TypeProbeCollection {
@Transient
Path
path
,
@Transient
Path
path
,
CharSequence
file
,
CharSequence
file
,
DateFormatFactory
dateFormatFactory
,
DateFormatFactory
dateFormatFactory
,
DateLocaleFactory
dateLocaleFactory
DateLocaleFactory
dateLocaleFactory
,
DirectCharSink
utf8Sink
)
{
)
{
this
.
utf8Sink
=
utf8Sink
;
this
.
dateProbePool
=
new
ObjectPool
<>(()
->
new
DateProbe
(
utf8Sink
),
16
);
this
.
stringProbe
=
new
StringProbe
(
utf8Sink
);
this
.
symbolProbe
=
new
SymbolProbe
(
utf8Sink
);
addDefaultProbes
();
addDefaultProbes
();
parseFile
(
ff
,
path
,
file
,
dateFormatFactory
,
dateLocaleFactory
);
parseFile
(
ff
,
path
,
file
,
dateFormatFactory
,
dateLocaleFactory
);
this
.
probeCount
=
probes
.
size
();
this
.
probeCount
=
probes
.
size
();
}
}
@Override
public
void
clear
()
{
dateProbePool
.
clear
();
}
public
BadDateProbe
getBadDateProbe
()
{
return
badDateProbe
;
}
public
TypeProbe
getProbe
(
int
index
)
{
public
TypeProbe
getProbe
(
int
index
)
{
return
probes
.
getQuick
(
index
);
return
probes
.
getQuick
(
index
);
}
}
...
@@ -71,11 +103,47 @@ public class TypeProbeCollection {
...
@@ -71,11 +103,47 @@ public class TypeProbeCollection {
return
probeCount
;
return
probeCount
;
}
}
public
TypeProbe
getProbeForType
(
int
columnType
)
{
switch
(
columnType
)
{
case
ColumnType
.
BYTE
:
return
byteProbe
;
case
ColumnType
.
SHORT
:
return
shortProbe
;
case
ColumnType
.
INT
:
return
intProbe
;
case
ColumnType
.
LONG
:
return
longProbe
;
case
ColumnType
.
BOOLEAN
:
return
booleanProbe
;
case
ColumnType
.
FLOAT
:
return
floatProbe
;
case
ColumnType
.
DOUBLE
:
return
doubleProbe
;
case
ColumnType
.
STRING
:
return
stringProbe
;
case
ColumnType
.
SYMBOL
:
return
symbolProbe
;
case
ColumnType
.
DATE
:
return
dateProbePool
.
next
();
case
ColumnType
.
BINARY
:
assert
false
;
case
ColumnType
.
TIMESTAMP
:
assert
false
;
default
:
assert
false
;
}
return
null
;
}
public
StringProbe
getStringProbe
()
{
return
stringProbe
;
}
private
void
addDefaultProbes
()
{
private
void
addDefaultProbes
()
{
probes
.
add
(
new
IntProbe
()
);
probes
.
add
(
intProbe
);
probes
.
add
(
new
LongProbe
()
);
probes
.
add
(
longProbe
);
probes
.
add
(
new
DoubleProbe
()
);
probes
.
add
(
doubleProbe
);
probes
.
add
(
new
BooleanProbe
()
);
probes
.
add
(
booleanProbe
);
}
}
private
void
parseFile
(
private
void
parseFile
(
...
@@ -169,7 +237,7 @@ public class TypeProbeCollection {
...
@@ -169,7 +237,7 @@ public class TypeProbeCollection {
comment
=
true
;
comment
=
true
;
continue
;
continue
;
}
}
probes
.
add
(
new
DateProbe
(
dateFormatFactory
,
locale
,
pattern
));
probes
.
add
(
new
DateProbe
(
utf8Sink
).
of
(
dateFormatFactory
.
get
(
pattern
),
locale
));
}
}
break
;
break
;
case
'\n'
:
case
'\n'
:
...
@@ -179,17 +247,17 @@ public class TypeProbeCollection {
...
@@ -179,17 +247,17 @@ public class TypeProbeCollection {
s
=
dbcs
.
of
(
_lo
,
p
-
1
).
toString
();
s
=
dbcs
.
of
(
_lo
,
p
-
1
).
toString
();
if
(
pattern
==
null
)
{
if
(
pattern
==
null
)
{
// no date locale, use default
// no date locale, use default
probes
.
add
(
new
DateProbe
(
dateFormatFactory
,
dateLocaleFactory
.
getDefaultDateLocale
(),
s
));
probes
.
add
(
new
DateProbe
(
utf8Sink
).
of
(
dateFormatFactory
.
get
(
s
),
dateLocaleFactory
.
getDefaultDateLocale
()
));
}
else
{
}
else
{
DateLocale
locale
=
dateLocaleFactory
.
getDateLocale
(
s
);
DateLocale
locale
=
dateLocaleFactory
.
getDateLocale
(
s
);
if
(
locale
==
null
)
{
if
(
locale
==
null
)
{
LOG
.
error
().
$
(
"Unknown date locale: "
).
$
(
s
).
$
();
LOG
.
error
().
$
(
"Unknown date locale: "
).
$
(
s
).
$
();
}
else
{
}
else
{
probes
.
add
(
new
DateProbe
(
dateFormatFactory
,
locale
,
pattern
));
probes
.
add
(
new
DateProbe
(
utf8Sink
).
of
(
dateFormatFactory
.
get
(
pattern
),
locale
));
}
}
}
}
}
else
if
(
pattern
!=
null
)
{
}
else
if
(
pattern
!=
null
)
{
probes
.
add
(
new
DateProbe
(
dateFormatFactory
,
dateLocaleFactory
.
getDefaultDateLocale
(),
pattern
));
probes
.
add
(
new
DateProbe
(
utf8Sink
).
of
(
dateFormatFactory
.
get
(
pattern
),
dateLocaleFactory
.
getDefaultDateLocale
()
));
}
}
}
}
...
...
core/src/main/java/com/questdb/std/NetworkFacade.java
0 → 100644
浏览文件 @
995ed2ec
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2018 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package
com.questdb.std
;
public
interface
NetworkFacade
{
void
abortAccept
(
long
fd
);
long
accept
(
long
serverFd
);
boolean
bindTcp
(
long
fd
,
int
address
,
int
port
);
void
close
(
long
fd
);
void
configureNoLinger
(
long
fd
);
void
configureNonBlocking
(
long
fd
);
int
connect
(
long
fd
,
long
sockaddr
);
void
freeSockAddr
(
long
socketAddress
);
long
getPeerIP
(
long
fd
);
void
listen
(
long
serverFd
,
int
backlog
);
int
recv
(
long
fd
,
long
buffer
,
int
bufferLen
);
int
send
(
long
fd
,
long
buffer
,
int
bufferLen
);
void
sendTo
(
long
fd
,
long
lo
,
int
len
,
long
socketAddress
);
long
sockaddr
(
int
address
,
int
port
);
long
socketTcp
(
boolean
blocking
);
long
socketUdp
();
}
core/src/main/java/com/questdb/std/NetworkFacadeImpl.java
0 → 100644
浏览文件 @
995ed2ec
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (C) 2014-2018 Appsicle
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package
com.questdb.std
;
public
class
NetworkFacadeImpl
implements
NetworkFacade
{
public
static
final
NetworkFacade
INSTANCE
=
new
NetworkFacadeImpl
();
@Override
public
void
abortAccept
(
long
fd
)
{
Net
.
abortAccept
(
fd
);
}
@Override
public
long
accept
(
long
serverFd
)
{
return
Net
.
accept
(
serverFd
);
}
@Override
public
boolean
bindTcp
(
long
fd
,
int
address
,
int
port
)
{
return
Net
.
bindTcp
(
fd
,
address
,
port
);
}
@Override
public
void
close
(
long
fd
)
{
Net
.
close
(
fd
);
}
@Override
public
void
configureNoLinger
(
long
fd
)
{
Net
.
configureNoLinger
(
fd
);
}
@Override
public
void
configureNonBlocking
(
long
fd
)
{
Net
.
configureNonBlocking
(
fd
);
}
@Override
public
int
connect
(
long
fd
,
long
sockaddr
)
{
return
Net
.
connect
(
fd
,
sockaddr
);
}
@Override
public
void
freeSockAddr
(
long
socketAddress
)
{
Net
.
freeSockAddr
(
socketAddress
);
}
@Override
public
long
getPeerIP
(
long
fd
)
{
return
Net
.
getPeerIP
(
fd
);
}
@Override
public
void
listen
(
long
serverFd
,
int
backlog
)
{
Net
.
listen
(
serverFd
,
backlog
);
}
@Override
public
int
recv
(
long
fd
,
long
buffer
,
int
bufferLen
)
{
return
Net
.
recv
(
fd
,
buffer
,
bufferLen
);
}
@Override
public
int
send
(
long
fd
,
long
buffer
,
int
bufferLen
)
{
return
Net
.
send
(
fd
,
buffer
,
bufferLen
);
}
@Override
public
void
sendTo
(
long
fd
,
long
ptr
,
int
len
,
long
socketAddress
)
{
Net
.
sendTo
(
fd
,
ptr
,
len
,
socketAddress
);
}
@Override
public
long
sockaddr
(
int
address
,
int
port
)
{
return
Net
.
sockaddr
(
address
,
port
);
}
@Override
public
long
socketTcp
(
boolean
blocking
)
{
return
Net
.
socketTcp
(
blocking
);
}
@Override
public
long
socketUdp
()
{
return
Net
.
socketUdp
();
}
}
core/src/test/java/com/questdb/cutlass/text/PlainTextImportTest.java
浏览文件 @
995ed2ec
...
@@ -332,8 +332,8 @@ public class PlainTextImportTest extends AbstractCairoTest {
...
@@ -332,8 +332,8 @@ public class PlainTextImportTest extends AbstractCairoTest {
}
}
},
},
"{\"columnCount\":9,\"columns\":[{\"index\":0,\"name\":\"№ПП\",\"type\":\"INT\"},{\"index\":1,\"name\":\"ОбъектыКонтрольногоМероприятия\",\"type\":\"STRING\"},{\"index\":2,\"name\":\"ВидКонтрольногоМероприятия\",\"type\":\"STRING\"},{\"index\":3,\"name\":\"ТемаКонтрольногоМероприятия\",\"type\":\"STRING\"},{\"index\":4,\"name\":\"ПроверяемыйПериод\",\"type\":\"STRING\"},{\"index\":5,\"name\":\"f5\",\"type\":\"STRING\"},{\"index\":6,\"name\":\"ОкончаниеПроверки\",\"type\":\"STRING\"},{\"index\":7,\"name\":\"ВыявленныеНарушенияНедостатки\",\"type\":\"STRING\"},{\"index\":8,\"name\":\"РезультатыПроверки\",\"type\":\"STRING\"}],\"timestampIndex\":-1}",
"{\"columnCount\":9,\"columns\":[{\"index\":0,\"name\":\"№ПП\",\"type\":\"INT\"},{\"index\":1,\"name\":\"ОбъектыКонтрольногоМероприятия\",\"type\":\"STRING\"},{\"index\":2,\"name\":\"ВидКонтрольногоМероприятия\",\"type\":\"STRING\"},{\"index\":3,\"name\":\"ТемаКонтрольногоМероприятия\",\"type\":\"STRING\"},{\"index\":4,\"name\":\"ПроверяемыйПериод\",\"type\":\"STRING\"},{\"index\":5,\"name\":\"f5\",\"type\":\"STRING\"},{\"index\":6,\"name\":\"ОкончаниеПроверки\",\"type\":\"STRING\"},{\"index\":7,\"name\":\"ВыявленныеНарушенияНедостатки\",\"type\":\"STRING\"},{\"index\":8,\"name\":\"РезультатыПроверки\",\"type\":\"STRING\"}],\"timestampIndex\":-1}",
36,
36
L
,
36
36
L
);
);
});
});
}
}
...
@@ -576,15 +576,14 @@ public class PlainTextImportTest extends AbstractCairoTest {
...
@@ -576,15 +576,14 @@ public class PlainTextImportTest extends AbstractCairoTest {
textLoader.setForceHeaders(true);
textLoader.setForceHeaders(true);
textLoader.setState(TextLoader.ANALYZE_STRUCTURE);
textLoader.setState(TextLoader.ANALYZE_STRUCTURE);
playText(
playText0(textLoader, csv, 1024, ENTITY_MANIPULATOR);
textLoader,
sink.clear();
csv,
textLoader.getMetadata().toJson(sink);
1024,
TestUtils.assertEquals("{\"columnCount\":2,\"columns\":[{\"index\":0,\"name\":\"name\",\"type\":\"STRING\"},{\"index\":1,\"name\":\"date\",\"type\":\"DATE\"}],\"timestampIndex\":-1}", sink);
expected,
Assert.assertEquals(3L, textLoader.getParsedLineCount());
"{\"columnCount\":2,\"columns\":[{\"index\":0,\"name\":\"name\",\"type\":\"STRING\"},{\"index\":1,\"name\":\"date\",\"type\":\"DATE\"}],\"timestampIndex\":-1}",
Assert.assertEquals(3L, textLoader.getWrittenLineCount());
3,
assertTable(expected);
3
textLoader.clear();
);
});
});
}
}
...
@@ -612,15 +611,14 @@ public class PlainTextImportTest extends AbstractCairoTest {
...
@@ -612,15 +611,14 @@ public class PlainTextImportTest extends AbstractCairoTest {
textLoader.setForceHeaders(true);
textLoader.setForceHeaders(true);
textLoader.setState(TextLoader.ANALYZE_STRUCTURE);
textLoader.setState(TextLoader.ANALYZE_STRUCTURE);
playText(
playText0(textLoader, csv, 1024, ENTITY_MANIPULATOR);
textLoader,
sink.clear();
csv,
textLoader.getMetadata().toJson(sink);
1024,
TestUtils.assertEquals("{\"columnCount\":2,\"columns\":[{\"index\":0,\"name\":\"name\",\"type\":\"STRING\"},{\"index\":1,\"name\":\"date\",\"type\":\"DATE\"}],\"timestampIndex\":-1}", sink);
expected,
Assert.assertEquals(3L, textLoader.getParsedLineCount());
"{\"columnCount\":2,\"columns\":[{\"index\":0,\"name\":\"name\",\"type\":\"STRING\"},{\"index\":1,\"name\":\"date\",\"type\":\"DATE\"}],\"timestampIndex\":-1}",
Assert.assertEquals(3L, textLoader.getWrittenLineCount());
3,
assertTable(expected);
3
textLoader.clear();
);
});
});
}
}
...
@@ -1875,8 +1873,8 @@ public class PlainTextImportTest extends AbstractCairoTest {
...
@@ -1875,8 +1873,8 @@ public class PlainTextImportTest extends AbstractCairoTest {
sink.clear();
sink.clear();
textLoader.getMetadata().toJson(sink);
textLoader.getMetadata().toJson(sink);
TestUtils.assertEquals("{\"columnCount\":10,\"columns\":[{\"index\":0,\"name\":\"f0\",\"type\":\"STRING\"},{\"index\":1,\"name\":\"f1\",\"type\":\"INT\"},{\"index\":2,\"name\":\"f2\",\"type\":\"INT\"},{\"index\":3,\"name\":\"f3\",\"type\":\"DOUBLE\"},{\"index\":4,\"name\":\"f4\",\"type\":\"DATE\"},{\"index\":5,\"name\":\"f5\",\"type\":\"DATE\"},{\"index\":6,\"name\":\"f6\",\"type\":\"DATE\"},{\"index\":7,\"name\":\"f7\",\"type\":\"INT\"},{\"index\":8,\"name\":\"f8\",\"type\":\"BOOLEAN\"},{\"index\":9,\"name\":\"f9\",\"type\":\"INT\"}],\"timestampIndex\":-1}", sink);
TestUtils.assertEquals("{\"columnCount\":10,\"columns\":[{\"index\":0,\"name\":\"f0\",\"type\":\"STRING\"},{\"index\":1,\"name\":\"f1\",\"type\":\"INT\"},{\"index\":2,\"name\":\"f2\",\"type\":\"INT\"},{\"index\":3,\"name\":\"f3\",\"type\":\"DOUBLE\"},{\"index\":4,\"name\":\"f4\",\"type\":\"DATE\"},{\"index\":5,\"name\":\"f5\",\"type\":\"DATE\"},{\"index\":6,\"name\":\"f6\",\"type\":\"DATE\"},{\"index\":7,\"name\":\"f7\",\"type\":\"INT\"},{\"index\":8,\"name\":\"f8\",\"type\":\"BOOLEAN\"},{\"index\":9,\"name\":\"f9\",\"type\":\"INT\"}],\"timestampIndex\":-1}", sink);
Assert.assertEquals(
(long) 12
, textLoader.getParsedLineCount());
Assert.assertEquals(
12L
, textLoader.getParsedLineCount());
Assert.assertEquals(
(long) 10
, textLoader.getWrittenLineCount());
Assert.assertEquals(
10L
, textLoader.getWrittenLineCount());
Assert.assertEquals("[0,0,1,0,0,0,0,0,0,1]", textLoader.getColumnErrorCounts().toString());
Assert.assertEquals("[0,0,1,0,0,0,0,0,0,1]", textLoader.getColumnErrorCounts().toString());
assertTable(expected);
assertTable(expected);
textLoader.clear();
textLoader.clear();
...
...
core/src/test/java/com/questdb/cutlass/text/TextMetadataParserTest.java
浏览文件 @
995ed2ec
...
@@ -23,58 +23,57 @@
...
@@ -23,58 +23,57 @@
package
com.questdb.cutlass.text
;
package
com.questdb.cutlass.text
;
import
com.questdb.BootstrapEnv
;
import
com.questdb.cutlass.json.JsonException
;
import
com.questdb.cutlass.json.JsonException
;
import
com.questdb.cutlass.json.JsonLexer
;
import
com.questdb.cutlass.json.JsonLexer
;
import
com.questdb.
std.ObjList
;
import
com.questdb.
cutlass.text.typeprobe.TypeProbeCollection
;
import
com.questdb.std.Unsafe
;
import
com.questdb.std.Unsafe
;
import
com.questdb.std.str.DirectCharSink
;
import
com.questdb.std.time.DateFormatFactory
;
import
com.questdb.std.time.DateFormatFactory
;
import
com.questdb.std.time.DateLocaleFactory
;
import
com.questdb.std.time.DateLocaleFactory
;
import
com.questdb.std.time.TimeZoneRuleFactory
;
import
com.questdb.test.tools.TestUtils
;
import
com.questdb.test.tools.TestUtils
;
import
org.junit.*
;
import
org.junit.*
;
public
class
TextMetadataParserTest
{
public
class
TextMetadataParserTest
{
private
static
final
JsonLexer
LEXER
=
new
JsonLexer
(
1024
,
4096
);
private
static
final
JsonLexer
LEXER
=
new
JsonLexer
(
1024
,
4096
);
private
static
TextMetadataParser
textMetadataParser
;
private
static
TextMetadataParser
textMetadataParser
;
private
static
String
defaultLocaleId
;
private
static
TypeProbeCollection
typeProbeCollection
;
private
static
DirectCharSink
utf8Sink
;
@BeforeClass
@BeforeClass
public
static
void
setUpClass
()
{
public
static
void
setUpClass
()
{
BootstrapEnv
env
=
new
BootstrapEnv
();
utf8Sink
=
new
DirectCharSink
(
1024
);
env
.
dateFormatFactory
=
new
DateFormatFactory
();
typeProbeCollection
=
new
TypeProbeCollection
(
utf8Sink
);
env
.
dateLocaleFactory
=
new
DateLocaleFactory
(
new
TimeZoneRuleFactory
());
defaultLocaleId
=
env
.
dateLocaleFactory
.
getDefaultDateLocale
().
getId
();
textMetadataParser
=
new
TextMetadataParser
(
textMetadataParser
=
new
TextMetadataParser
(
new
DefaultTextConfiguration
(),
new
DefaultTextConfiguration
(),
DateLocaleFactory
.
INSTANCE
,
DateLocaleFactory
.
INSTANCE
,
new
DateFormatFactory
()
new
DateFormatFactory
(),
utf8Sink
,
typeProbeCollection
);
);
}
}
@AfterClass
@AfterClass
public
static
void
tearDown
()
{
public
static
void
tearDown
()
{
LEXER
.
close
();
LEXER
.
close
();
utf8Sink
.
close
();
}
}
@Before
@Before
public
void
setUp
()
{
public
void
setUp
()
{
LEXER
.
clear
();
LEXER
.
clear
();
textMetadataParser
.
clear
();
textMetadataParser
.
clear
();
typeProbeCollection
.
clear
();
}
}
@Test
@Test
public
void
testArrayProperty
()
{
public
void
testArrayProperty
()
{
String
in
=
"[\n"
+
assertFailure
(
"[\n"
+
"{\"name\": \"x\", \"type\": \"DOUBLE\", \"pattern\":\"xyz\", \"locale\": []}\n"
+
"{\"name\": \"x\", \"type\": \"DOUBLE\", \"pattern\":\"xyz\", \"locale\": []}\n"
+
"]"
;
"]"
,
try
{
62
,
parseMetadata
(
in
);
"Unexpected array"
Assert
.
fail
();
);
}
catch
(
JsonException
e
)
{
Assert
.
assertEquals
(
"Unexpected array"
,
e
.
getMessage
());
Assert
.
assertEquals
(
62
,
e
.
getPosition
());
}
}
}
@Test
@Test
...
@@ -84,25 +83,35 @@ public class TextMetadataParserTest {
...
@@ -84,25 +83,35 @@ public class TextMetadataParserTest {
"{\"name\": \"y\", \"type\": \"DATE\", \"pattern\":\"xyz\"}\n"
+
"{\"name\": \"y\", \"type\": \"DATE\", \"pattern\":\"xyz\"}\n"
+
"]"
;
"]"
;
ObjList
<
TextMetadata
>
metadata
=
parseMetadata
(
in
);
long
buf
=
TestUtils
.
toMemory
(
in
);
Assert
.
assertEquals
(
2
,
metadata
.
size
());
try
{
Assert
.
assertEquals
(
"TextMetadata{type=INT, dateLocale=en-US, name=x}"
,
metadata
.
get
(
0
).
toString
());
LEXER
.
parse
(
buf
,
in
.
length
(),
textMetadataParser
);
Assert
.
assertEquals
(
"TextMetadata{type=DATE, dateLocale="
+
defaultLocaleId
+
", name=y}"
,
metadata
.
get
(
1
).
toString
());
Assert
.
assertEquals
(
2
,
textMetadataParser
.
getColumnTypes
().
size
());
Assert
.
assertEquals
(
2
,
textMetadataParser
.
getColumnNames
().
size
());
Assert
.
assertEquals
(
"[INT,DATE]"
,
textMetadataParser
.
getColumnTypes
().
toString
());
Assert
.
assertEquals
(
"[x,y]"
,
textMetadataParser
.
getColumnNames
().
toString
());
}
finally
{
Unsafe
.
free
(
buf
,
in
.
length
());
}
}
}
@Test
@Test
public
void
testEmptyList
()
throws
Exception
{
public
void
testEmptyList
()
throws
Exception
{
Assert
.
assertEquals
(
0
,
parseMetadata
(
"[]"
).
size
());
String
in
=
"[]"
;
long
buf
=
TestUtils
.
toMemory
(
in
);
try
{
LEXER
.
parse
(
buf
,
in
.
length
(),
textMetadataParser
);
Assert
.
assertEquals
(
0
,
textMetadataParser
.
getColumnTypes
().
size
());
Assert
.
assertEquals
(
0
,
textMetadataParser
.
getColumnNames
().
size
());
}
finally
{
Unsafe
.
free
(
buf
,
in
.
length
());
}
}
}
@Test
@Test
public
void
testEmptyObject
()
{
public
void
testEmptyObject
()
{
try
{
assertFailure
(
"[{}]"
,
3
,
"Missing 'name' property"
);
parseMetadata
(
"[{}]"
);
Assert
.
fail
();
}
catch
(
JsonException
e
)
{
Assert
.
assertEquals
(
3
,
e
.
getPosition
());
}
}
}
@Test
@Test
...
@@ -112,13 +121,7 @@ public class TextMetadataParserTest {
...
@@ -112,13 +121,7 @@ public class TextMetadataParserTest {
"{\"type\": \"DOUBLE\", \"pattern\":\"xyz\"}\n"
+
"{\"type\": \"DOUBLE\", \"pattern\":\"xyz\"}\n"
+
"]"
;
"]"
;
try
{
assertFailure
(
in
,
103
,
"Missing 'name' property"
);
parseMetadata
(
in
);
Assert
.
fail
();
}
catch
(
JsonException
e
)
{
Assert
.
assertEquals
(
"Missing 'name' property"
,
e
.
getMessage
());
Assert
.
assertEquals
(
103
,
e
.
getPosition
());
}
}
}
@Test
@Test
...
@@ -127,75 +130,57 @@ public class TextMetadataParserTest {
...
@@ -127,75 +130,57 @@ public class TextMetadataParserTest {
"{\"name\": \"x\", \"pattern\":\"xyz\", \"locale\": \"en-GB\"},\n"
+
"{\"name\": \"x\", \"pattern\":\"xyz\", \"locale\": \"en-GB\"},\n"
+
"{\"name\": \"y\", \"type\": \"DOUBLE\", \"pattern\":\"xyz\"}\n"
+
"{\"name\": \"y\", \"type\": \"DOUBLE\", \"pattern\":\"xyz\"}\n"
+
"]"
;
"]"
;
try
{
assertFailure
(
in
,
51
,
"Missing 'type' property"
);
parseMetadata
(
in
);
Assert
.
fail
();
}
catch
(
JsonException
e
)
{
Assert
.
assertEquals
(
"Missing 'type' property"
,
e
.
getMessage
());
Assert
.
assertEquals
(
51
,
e
.
getPosition
());
}
}
}
@Test
@Test
public
void
testNonArray
()
{
public
void
testNonArray
()
{
try
{
assertFailure
(
"{}"
,
1
,
"Unexpected object"
);
parseMetadata
(
"{}"
);
Assert
.
fail
();
}
catch
(
JsonException
e
)
{
Assert
.
assertEquals
(
"Unexpected object"
,
e
.
getMessage
());
Assert
.
assertEquals
(
1
,
e
.
getPosition
());
}
}
}
@Test
@Test
public
void
testNonObjectArrayMember
()
{
public
void
testNonObjectArrayMember
()
{
String
in
=
"[2,\n"
+
assertFailure
(
"[2,\n"
+
"{\"name\": \"x\", \"type\": \"DOUBLE\", \"pattern\":\"xyz\"}\n"
+
"{\"name\": \"x\", \"type\": \"DOUBLE\", \"pattern\":\"xyz\"}\n"
+
"]"
;
"]"
,
try
{
2
,
parseMetadata
(
in
);
"Must be an object"
Assert
.
fail
();
);
}
catch
(
JsonException
e
)
{
Assert
.
assertEquals
(
"Must be an object"
,
e
.
getMessage
());
Assert
.
assertEquals
(
2
,
e
.
getPosition
());
}
}
}
@Test
@Test
public
void
testWrongDateLocale
()
{
public
void
testWrongDateLocale
()
{
String
in
=
"[\n"
+
assertFailure
(
"{\"name\": \"x\", \"type\": \"DOUBLE\", \"pattern\":\"xyz\", \"locale\": \"enk\"}\n"
+
"[\n"
+
"]"
;
"{\"name\": \"x\", \"type\": \"DATE\", \"pattern\":\"xyz\", \"locale\": \"enk\"}\n"
+
try
{
"]"
,
parseMetadata
(
in
);
61
,
Assert
.
fail
();
"Invalid date locale"
}
catch
(
JsonException
e
)
{
);
Assert
.
assertEquals
(
"Invalid date locale"
,
e
.
getMessage
());
Assert
.
assertEquals
(
63
,
e
.
getPosition
());
}
}
}
@Test
@Test
public
void
testWrongType
()
{
public
void
testWrongType
()
{
String
in
=
"[\n"
+
assertFailure
(
"[\n"
+
"{\"name\": \"y\", \"type\": \"ABC\", \"pattern\":\"xyz\"}\n"
+
"{\"name\": \"y\", \"type\": \"ABC\", \"pattern\":\"xyz\"}\n"
+
"]"
;
"]"
,
try
{
26
,
parseMetadata
(
in
);
"Invalid type"
Assert
.
fail
();
);
}
catch
(
JsonException
e
)
{
Assert
.
assertEquals
(
"Invalid type"
,
e
.
getMessage
());
Assert
.
assertEquals
(
26
,
e
.
getPosition
());
}
}
}
private
ObjList
<
TextMetadata
>
parseMetadata
(
CharSequence
in
)
throws
JsonException
{
private
void
assertFailure
(
CharSequence
schema
,
int
position
,
CharSequence
message
)
{
long
buf
=
TestUtils
.
toMemory
(
in
);
long
buf
=
TestUtils
.
toMemory
(
schema
);
try
{
try
{
LEXER
.
parse
(
buf
,
in
.
length
(),
textMetadataParser
);
LEXER
.
parse
(
buf
,
schema
.
length
(),
textMetadataParser
);
return
textMetadataParser
.
getTextMetadata
();
Assert
.
fail
();
}
catch
(
JsonException
e
)
{
Assert
.
assertEquals
(
position
,
e
.
getPosition
());
TestUtils
.
assertContains
(
e
.
getMessage
(),
message
);
}
finally
{
}
finally
{
Unsafe
.
free
(
buf
,
in
.
length
());
Unsafe
.
free
(
buf
,
schema
.
length
());
}
}
}
}
}
}
\ No newline at end of file
core/src/test/java/com/questdb/cutlass/text/TypeProbeCollectionTest.java
浏览文件 @
995ed2ec
...
@@ -26,6 +26,7 @@ package com.questdb.cutlass.text;
...
@@ -26,6 +26,7 @@ package com.questdb.cutlass.text;
import
com.questdb.cutlass.text.typeprobe.*
;
import
com.questdb.cutlass.text.typeprobe.*
;
import
com.questdb.std.FilesFacadeImpl
;
import
com.questdb.std.FilesFacadeImpl
;
import
com.questdb.std.Os
;
import
com.questdb.std.Os
;
import
com.questdb.std.str.DirectCharSink
;
import
com.questdb.std.str.Path
;
import
com.questdb.std.str.Path
;
import
com.questdb.std.time.DateFormatFactory
;
import
com.questdb.std.time.DateFormatFactory
;
import
com.questdb.std.time.DateLocale
;
import
com.questdb.std.time.DateLocale
;
...
@@ -40,8 +41,17 @@ public class TypeProbeCollectionTest {
...
@@ -40,8 +41,17 @@ public class TypeProbeCollectionTest {
if
(
Os
.
type
==
Os
.
WINDOWS
&&
fileName
.
startsWith
(
"/"
))
{
if
(
Os
.
type
==
Os
.
WINDOWS
&&
fileName
.
startsWith
(
"/"
))
{
fileName
=
fileName
.
substring
(
1
);
fileName
=
fileName
.
substring
(
1
);
}
}
try
(
Path
path
=
new
Path
())
{
try
(
TypeProbeCollection
typeProbeCollection
=
new
TypeProbeCollection
(
FilesFacadeImpl
.
INSTANCE
,
path
,
fileName
,
new
DateFormatFactory
(),
DateLocaleFactory
.
INSTANCE
);
Path
path
=
new
Path
();
DirectCharSink
utf8Sink
=
new
DirectCharSink
(
1024
)
)
{
TypeProbeCollection
typeProbeCollection
=
new
TypeProbeCollection
(
FilesFacadeImpl
.
INSTANCE
,
path
,
fileName
,
new
DateFormatFactory
(),
DateLocaleFactory
.
INSTANCE
,
utf8Sink
);
Assert
.
assertEquals
(
7
,
typeProbeCollection
.
getProbeCount
());
Assert
.
assertEquals
(
7
,
typeProbeCollection
.
getProbeCount
());
Assert
.
assertTrue
(
typeProbeCollection
.
getProbe
(
0
)
instanceof
IntProbe
);
Assert
.
assertTrue
(
typeProbeCollection
.
getProbe
(
0
)
instanceof
IntProbe
);
...
@@ -54,11 +64,11 @@ public class TypeProbeCollectionTest {
...
@@ -54,11 +64,11 @@ public class TypeProbeCollectionTest {
DateLocale
defaultLocale
=
DateLocaleFactory
.
INSTANCE
.
getDefaultDateLocale
();
DateLocale
defaultLocale
=
DateLocaleFactory
.
INSTANCE
.
getDefaultDateLocale
();
Assert
.
assertEquals
(
defaultLocale
.
getId
(),
typeProbeCollection
.
getProbe
(
4
).
getDateLocale
().
getId
());
//
Assert.assertEquals(defaultLocale.getId(), typeProbeCollection.getProbe(4).getDateLocale().getId());
Assert
.
assertEquals
(
"es-PA"
,
typeProbeCollection
.
getProbe
(
5
).
getDateLocale
().
getId
());
//
Assert.assertEquals("es-PA", typeProbeCollection.getProbe(5).getDateLocale().getId());
Assert
.
assertEquals
(
defaultLocale
.
getId
(),
typeProbeCollection
.
getProbe
(
6
).
getDateLocale
().
getId
());
//
Assert.assertEquals(defaultLocale.getId(), typeProbeCollection.getProbe(6).getDateLocale().getId());
}
}
}
}
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录