2020-04-25 16:25:11 +00:00
// Copyright 2020 The Xorm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package dialects
import (
"context"
2021-07-20 09:43:28 +00:00
"database/sql"
"errors"
"math/big"
2020-04-25 16:25:11 +00:00
"net/url"
2021-07-20 09:43:28 +00:00
"strings"
2020-04-25 16:25:11 +00:00
2021-07-20 09:43:28 +00:00
"xorm.io/xorm/convert"
2020-04-25 16:25:11 +00:00
"xorm.io/xorm/core"
"xorm.io/xorm/schemas"
)
type clickhouse struct {
Base
2021-07-20 09:43:28 +00:00
baseDriver
}
func ( p * clickhouse ) Parse ( driverName , dataSourceName string ) ( * URI , error ) {
return ParseClickHouse ( dataSourceName )
2020-04-25 16:25:11 +00:00
}
func ( db * clickhouse ) Init ( uri * URI ) error {
return db . Base . Init ( db , uri )
}
2021-07-20 09:43:28 +00:00
func ( db * clickhouse ) Version ( ctx context . Context , queryer core . Queryer ) ( * schemas . Version , error ) {
rows , err := queryer . QueryContext ( ctx ,
"SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel') AS ProductLevel, SERVERPROPERTY ('edition') AS ProductEdition" )
if err != nil {
return nil , err
}
defer rows . Close ( )
var version , level , edition string
if ! rows . Next ( ) {
if rows . Err ( ) != nil {
return nil , rows . Err ( )
}
return nil , errors . New ( "unknow version" )
}
if err := rows . Scan ( & version , & level , & edition ) ; err != nil {
return nil , err
}
// MSSQL: Microsoft SQL Server 2017 (RTM-CU13) (KB4466404) - 14.0.3048.4 (X64) Nov 30 2018 12:57:58 Copyright (C) 2017 Microsoft Corporation Developer Edition (64-bit) on Linux (Ubuntu 16.04.5 LTS)
return & schemas . Version {
Number : version ,
Level : level ,
Edition : edition ,
} , nil
}
func ( db * clickhouse ) ColumnTypeKind ( t string ) int {
switch t {
case "Date" , "DateTime" , "DateTime64" :
return schemas . TIME_TYPE
case "String" , "FixedString" , "UUID" , "Enum" :
return schemas . TEXT_TYPE
case "Int8" , "Int16" , "Int32" , "Int64" , "Int128" , "Int256" ,
"UInt8" , "UInt16" , "UInt32" , "UInt64" , "UInt256" ,
"Float32" , "Float64" ,
"Decimal32" , "Decimal64" , "Decimal128" , "Decimal256" :
return schemas . NUMERIC_TYPE
default :
if strings . HasPrefix ( t , "Array(" ) {
return schemas . ARRAY_TYPE
}
return schemas . UNKNOW_TYPE
}
}
2020-04-25 16:25:11 +00:00
func ( db * clickhouse ) IsReserved ( name string ) bool {
return false
}
func ( db * clickhouse ) SQLType ( c * schemas . Column ) string {
return ""
}
func ( db * clickhouse ) SetQuotePolicy ( quotePolicy QuotePolicy ) {
}
func ( * clickhouse ) AutoIncrStr ( ) string {
return ""
}
func ( * clickhouse ) CreateTableSQL ( t * schemas . Table , tableName string ) ( [ ] string , bool ) {
return nil , false
}
func ( * clickhouse ) IsTableExist ( queryer core . Queryer , ctx context . Context , tableName string ) ( bool , error ) {
return false , nil
}
func ( * clickhouse ) Filters ( ) [ ] Filter {
return [ ] Filter { }
}
func ( * clickhouse ) GetColumns ( core . Queryer , context . Context , string ) ( [ ] string , map [ string ] * schemas . Column , error ) {
return nil , nil , nil
}
func ( db * clickhouse ) GetIndexes ( queryer core . Queryer , ctx context . Context , tableName string ) ( map [ string ] * schemas . Index , error ) {
return nil , nil
}
func ( db * clickhouse ) IndexCheckSQL ( tableName , idxName string ) ( string , [ ] interface { } ) {
return "" , nil
}
func ( db * clickhouse ) GetTables ( queryer core . Queryer , ctx context . Context ) ( [ ] * schemas . Table , error ) {
return nil , nil
}
2021-07-20 09:43:28 +00:00
func ( db * clickhouse ) GenScanResult ( colType string ) ( interface { } , error ) {
switch colType {
case "Date" , "DateTime" , "DateTime64" :
return & sql . NullString { } , nil
case "String" , "FixedString" , "UUID" , "Enum" :
return & sql . NullString { } , nil
case "Int8" , "Int16" , "Int32" :
return & sql . NullInt32 { } , nil
case "Int64" :
return & sql . NullInt64 { } , nil
case "Int128" , "Int256" :
return & big . Int { } , nil
case "UInt8" , "UInt16" , "UInt32" :
return & convert . NullUint32 { } , nil
case "UInt64" :
return & convert . NullUint64 { } , nil
case "UInt256" :
return & big . Int { } , nil
case "Float32" , "Float64" :
return & sql . NullFloat64 { } , nil
case "Decimal32" , "Decimal64" , "Decimal128" , "Decimal256" :
return & sql . NullString { } , nil
default :
return & sql . RawBytes { } , nil
}
}
2020-04-25 16:25:11 +00:00
// ParseClickHouse parsed clickhouse connection string
// tcp://host1:9000?username=user&password=qwerty&database=clicks&read_timeout=10&write_timeout=20&alt_hosts=host2:9000,host3:9000
func ParseClickHouse ( connStr string ) ( * URI , error ) {
u , err := url . Parse ( connStr )
if err != nil {
return nil , err
}
forms := u . Query ( )
return & URI {
DBType : schemas . CLICKHOUSE ,
Proto : u . Scheme ,
Host : u . Hostname ( ) ,
Port : u . Port ( ) ,
DBName : forms . Get ( "database" ) ,
User : forms . Get ( "username" ) ,
Passwd : forms . Get ( "password" ) ,
} , nil
}