parent
3662181ff2
commit
b3efc470c8
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), 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.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Collections;
|
||||
|
||||
namespace TDengineDriver
|
||||
{
|
||||
class TDengineTest
|
||||
{
|
||||
//connect parameters
|
||||
private string host;
|
||||
private string configDir;
|
||||
private string user;
|
||||
private string password;
|
||||
private short port = 0;
|
||||
|
||||
//sql parameters
|
||||
private string dbName;
|
||||
private string tbName;
|
||||
private string precision;
|
||||
|
||||
private bool isInsertData;
|
||||
private bool isQueryData;
|
||||
|
||||
private long tableCount;
|
||||
private long totalRows;
|
||||
private long batchRows;
|
||||
private long beginTimestamp = 1551369600000L;
|
||||
|
||||
private IntPtr conn = IntPtr.Zero;
|
||||
private long rowsInserted = 0;
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
TDengineTest tester = new TDengineTest();
|
||||
tester.ReadArgument(args);
|
||||
|
||||
|
||||
tester.InitTDengine();
|
||||
tester.ConnectTDengine();
|
||||
tester.createDatabase();
|
||||
tester.useDatabase();
|
||||
tester.checkDropTable();
|
||||
tester.createTable();
|
||||
tester.checkInsert();
|
||||
tester.checkSelect();
|
||||
tester.checkDropTable();
|
||||
tester.dropDatabase();
|
||||
tester.CloseConnection();
|
||||
tester.cleanup();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public long GetArgumentAsLong(String[] argv, String argName, int minVal, int maxVal, int defaultValue)
|
||||
{
|
||||
int argc = argv.Length;
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
if (argName != argv[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (i < argc - 1)
|
||||
{
|
||||
String tmp = argv[i + 1];
|
||||
if (tmp[0] == '-')
|
||||
{
|
||||
Console.WriteLine("option {0:G} requires an argument", tmp);
|
||||
ExitProgram();
|
||||
}
|
||||
|
||||
long tmpVal = Convert.ToInt64(tmp);
|
||||
if (tmpVal < minVal || tmpVal > maxVal)
|
||||
{
|
||||
Console.WriteLine("option {0:G} should in range [{1:G}, {2:G}]", argName, minVal, maxVal);
|
||||
ExitProgram();
|
||||
}
|
||||
|
||||
return tmpVal;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public String GetArgumentAsString(String[] argv, String argName, String defaultValue)
|
||||
{
|
||||
int argc = argv.Length;
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
if (argName != argv[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (i < argc - 1)
|
||||
{
|
||||
String tmp = argv[i + 1];
|
||||
if (tmp[0] == '-')
|
||||
{
|
||||
Console.WriteLine("option {0:G} requires an argument", tmp);
|
||||
ExitProgram();
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void PrintHelp(String[] argv)
|
||||
{
|
||||
for (int i = 0; i < argv.Length; ++i)
|
||||
{
|
||||
if ("--help" == argv[i])
|
||||
{
|
||||
String indent = " ";
|
||||
Console.WriteLine("taosTest is simple example to operate TDengine use C# Language.\n");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-h");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "TDEngine server IP address to connect");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-u");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "The TDEngine user name to use when connecting to the server, default is root");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-p");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "The TDEngine user name to use when connecting to the server, default is taosdata");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-d");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Database used to create table or import data, default is db");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-s");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Super Tables used to create table, default is mt");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-t");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Table prefixs, default is t");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-w");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Whether to insert data");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-r");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Whether to query data");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-n");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "How many Tables to create, default is 10");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-b");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "How many rows per insert batch, default is 10");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-i");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "How many rows to insert, default is 100");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-c");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Configuration directory");
|
||||
//
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-ps");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Configurate db precision,default millisecond");
|
||||
ExitProgram();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ReadArgument(String[] argv)
|
||||
{
|
||||
PrintHelp(argv);
|
||||
host = this.GetArgumentAsString(argv, "-h", "127.0.0.1");
|
||||
user = this.GetArgumentAsString(argv, "-u", "root");
|
||||
password = this.GetArgumentAsString(argv, "-p", "taosdata");
|
||||
dbName = this.GetArgumentAsString(argv, "-d", "test");
|
||||
tbName = this.GetArgumentAsString(argv, "-s", "weather");
|
||||
precision = this.GetArgumentAsString(argv, "-ps", "ms");
|
||||
isInsertData = this.GetArgumentAsLong(argv, "-w", 0, 1, 1) != 0;
|
||||
isQueryData = this.GetArgumentAsLong(argv, "-r", 0, 1, 1) != 0;
|
||||
tableCount = this.GetArgumentAsLong(argv, "-n", 1, 10000, 10);
|
||||
batchRows = this.GetArgumentAsLong(argv, "-b", 1, 1000, 500);
|
||||
totalRows = this.GetArgumentAsLong(argv, "-i", 1, 10000000, 10000);
|
||||
configDir = this.GetArgumentAsString(argv, "-c", "C:/TDengine/cfg");
|
||||
}
|
||||
|
||||
public void InitTDengine()
|
||||
{
|
||||
TDengine.Options((int)TDengineInitOption.TDDB_OPTION_CONFIGDIR, this.configDir);
|
||||
TDengine.Options((int)TDengineInitOption.TDDB_OPTION_SHELL_ACTIVITY_TIMER, "60");
|
||||
Console.WriteLine("init...");
|
||||
TDengine.Init();
|
||||
Console.WriteLine("get connection starting...");
|
||||
}
|
||||
|
||||
public void ConnectTDengine()
|
||||
{
|
||||
string db = "";
|
||||
this.conn = TDengine.Connect(this.host, this.user, this.password, db, this.port);
|
||||
if (this.conn == IntPtr.Zero)
|
||||
{
|
||||
Console.WriteLine("connection failed: " + this.host);
|
||||
ExitProgram();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("[ OK ] Connection established.");
|
||||
}
|
||||
}
|
||||
public void createDatabase()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("create database if not exists ").Append(this.dbName).Append(" precision '").Append(this.precision).Append("'");
|
||||
execute(sql.ToString());
|
||||
}
|
||||
public void useDatabase()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("use ").Append(this.dbName);
|
||||
execute(sql.ToString());
|
||||
}
|
||||
public void checkSelect()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("select * from ").Append(this.dbName).Append(".").Append(this.tbName);
|
||||
ExecuteQuery(sql.ToString());
|
||||
}
|
||||
public void createTable()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("create table if not exists ").Append(this.dbName).Append(".").Append(this.tbName).Append("(ts timestamp, temperature float, humidity int)");
|
||||
execute(sql.ToString());
|
||||
}
|
||||
public void checkInsert()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("insert into ").Append(this.dbName).Append(".").Append(this.tbName).Append("(ts, temperature, humidity) values(now, 20.5, 34)");
|
||||
execute(sql.ToString());
|
||||
}
|
||||
public void checkDropTable()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("drop table if exists ").Append(this.dbName).Append(".").Append(this.tbName).Append("");
|
||||
execute(sql.ToString());
|
||||
}
|
||||
public void dropDatabase()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("drop database if exists ").Append(this.dbName);
|
||||
execute(sql.ToString());
|
||||
}
|
||||
public void execute(string sql)
|
||||
{
|
||||
DateTime dt1 = DateTime.Now;
|
||||
IntPtr res = TDengine.Query(this.conn, sql.ToString());
|
||||
DateTime dt2 = DateTime.Now;
|
||||
TimeSpan span = dt2 - dt1;
|
||||
|
||||
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
|
||||
{
|
||||
Console.Write(sql.ToString() + " failure, ");
|
||||
if (res != IntPtr.Zero) {
|
||||
Console.Write("reason: " + TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
ExitProgram();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(sql.ToString() + " success");
|
||||
}
|
||||
TDengine.FreeResult(res);
|
||||
}
|
||||
|
||||
public void ExecuteQuery(string sql)
|
||||
{
|
||||
|
||||
DateTime dt1 = DateTime.Now;
|
||||
long queryRows = 0;
|
||||
IntPtr res = TDengine.Query(conn, sql);
|
||||
getPrecision(res);
|
||||
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
|
||||
{
|
||||
Console.Write(sql.ToString() + " failure, ");
|
||||
if (res != IntPtr.Zero) {
|
||||
Console.Write("reason: " + TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
ExitProgram();
|
||||
}
|
||||
DateTime dt2 = DateTime.Now;
|
||||
TimeSpan span = dt2 - dt1;
|
||||
Console.WriteLine("[OK] time cost: " + span.ToString() + "ms, execute statement ====> " + sql.ToString());
|
||||
int fieldCount = TDengine.FieldCount(res);
|
||||
|
||||
List<TDengineMeta> metas = TDengine.FetchFields(res);
|
||||
for (int j = 0; j < metas.Count; j++)
|
||||
{
|
||||
TDengineMeta meta = (TDengineMeta)metas[j];
|
||||
}
|
||||
|
||||
IntPtr rowdata;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero)
|
||||
{
|
||||
queryRows++;
|
||||
for (int fields = 0; fields < fieldCount; ++fields)
|
||||
{
|
||||
TDengineMeta meta = metas[fields];
|
||||
int offset = IntPtr.Size * fields;
|
||||
IntPtr data = Marshal.ReadIntPtr(rowdata, offset);
|
||||
|
||||
builder.Append("---");
|
||||
|
||||
if (data == IntPtr.Zero)
|
||||
{
|
||||
builder.Append("NULL");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ((TDengineDataType)meta.type)
|
||||
{
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
|
||||
bool v1 = Marshal.ReadByte(data) == 0 ? false : true;
|
||||
builder.Append(v1);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
|
||||
byte v2 = Marshal.ReadByte(data);
|
||||
builder.Append(v2);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
|
||||
short v3 = Marshal.ReadInt16(data);
|
||||
builder.Append(v3);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_INT:
|
||||
int v4 = Marshal.ReadInt32(data);
|
||||
builder.Append(v4);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
|
||||
long v5 = Marshal.ReadInt64(data);
|
||||
builder.Append(v5);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
|
||||
float v6 = (float)Marshal.PtrToStructure(data, typeof(float));
|
||||
builder.Append(v6);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
|
||||
double v7 = (double)Marshal.PtrToStructure(data, typeof(double));
|
||||
builder.Append(v7);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
|
||||
string v8 = Marshal.PtrToStringAnsi(data);
|
||||
builder.Append(v8);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
long v9 = Marshal.ReadInt64(data);
|
||||
builder.Append(v9);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
|
||||
string v10 = Marshal.PtrToStringAnsi(data);
|
||||
builder.Append(v10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
builder.Append("---");
|
||||
|
||||
if (queryRows <= 10)
|
||||
{
|
||||
Console.WriteLine(builder.ToString());
|
||||
}
|
||||
builder.Clear();
|
||||
}
|
||||
|
||||
if (TDengine.ErrorNo(res) != 0)
|
||||
{
|
||||
Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
|
||||
TDengine.FreeResult(res);
|
||||
|
||||
}
|
||||
|
||||
public void CloseConnection()
|
||||
{
|
||||
if (this.conn != IntPtr.Zero)
|
||||
{
|
||||
TDengine.Close(this.conn);
|
||||
Console.WriteLine("connection closed.");
|
||||
}
|
||||
}
|
||||
|
||||
static void ExitProgram()
|
||||
{
|
||||
System.Environment.Exit(0);
|
||||
}
|
||||
|
||||
public void cleanup()
|
||||
{
|
||||
Console.WriteLine("clean up...");
|
||||
System.Environment.Exit(0);
|
||||
}
|
||||
// method to get db precision
|
||||
public void getPrecision(IntPtr res)
|
||||
{
|
||||
int psc=TDengine.ResultPrecision(res);
|
||||
switch(psc)
|
||||
{
|
||||
case 0:
|
||||
Console.WriteLine("db:[{0:G}]'s precision is {1:G}",this.dbName,"millisecond");
|
||||
break;
|
||||
case 1:
|
||||
Console.WriteLine("db:[{0:G}]'s precision is {1:G}",this.dbName,"microsecond");
|
||||
break;
|
||||
case 2:
|
||||
Console.WriteLine("db:[{0:G}]'s precision is {1:G}",this.dbName,"nanosecond");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), 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.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace TDengineDriver
|
||||
{
|
||||
enum TDengineDataType
|
||||
{
|
||||
TSDB_DATA_TYPE_NULL = 0, // 1 bytes
|
||||
TSDB_DATA_TYPE_BOOL = 1, // 1 bytes
|
||||
TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes
|
||||
TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes
|
||||
TSDB_DATA_TYPE_INT = 4, // 4 bytes
|
||||
TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes
|
||||
TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes
|
||||
TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes
|
||||
TSDB_DATA_TYPE_BINARY = 8, // string
|
||||
TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes
|
||||
TSDB_DATA_TYPE_NCHAR = 10, // unicode string
|
||||
TSDB_DATA_TYPE_UTINYINT = 11,// 1 byte
|
||||
TSDB_DATA_TYPE_USMALLINT= 12,// 2 bytes
|
||||
TSDB_DATA_TYPE_UINT = 13, // 4 bytes
|
||||
TSDB_DATA_TYPE_UBIGINT= 14 // 8 bytes
|
||||
}
|
||||
|
||||
enum TDengineInitOption
|
||||
{
|
||||
TSDB_OPTION_LOCALE = 0,
|
||||
TSDB_OPTION_CHARSET = 1,
|
||||
TSDB_OPTION_TIMEZONE = 2,
|
||||
TDDB_OPTION_CONFIGDIR = 3,
|
||||
TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4
|
||||
}
|
||||
|
||||
class TDengineMeta
|
||||
{
|
||||
public string name;
|
||||
public short size;
|
||||
public byte type;
|
||||
public string TypeName()
|
||||
{
|
||||
switch ((TDengineDataType)type)
|
||||
{
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
|
||||
return "BOOL";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
|
||||
return "TINYINT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
|
||||
return "SMALLINT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_INT:
|
||||
return "INT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
|
||||
return "BIGINT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_UTINYINT:
|
||||
return "TINYINT UNSIGNED";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_USMALLINT:
|
||||
return "SMALLINT UNSIGNED";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_UINT:
|
||||
return "INT UNSIGNED";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_UBIGINT:
|
||||
return "BIGINT UNSIGNED";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
|
||||
return "FLOAT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
|
||||
return "DOUBLE";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
|
||||
return "STRING";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
return "TIMESTAMP";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
|
||||
return "NCHAR";
|
||||
default:
|
||||
return "undefine";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TDengine
|
||||
{
|
||||
public const int TSDB_CODE_SUCCESS = 0;
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Init();
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Cleanup();
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Options(int option, string value);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr Connect(string ip, string user, string password, string db, short port);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern private IntPtr taos_errstr(IntPtr res);
|
||||
static public string Error(IntPtr res)
|
||||
{
|
||||
IntPtr errPtr = taos_errstr(res);
|
||||
return Marshal.PtrToStringAnsi(errPtr);
|
||||
}
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int ErrorNo(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr Query(IntPtr conn, string sqlstr);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int AffectRows(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int FieldCount(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern private IntPtr taos_fetch_fields(IntPtr res);
|
||||
static public List<TDengineMeta> FetchFields(IntPtr res)
|
||||
{
|
||||
const int fieldSize = 68;
|
||||
|
||||
List<TDengineMeta> metas = new List<TDengineMeta>();
|
||||
if (res == IntPtr.Zero)
|
||||
{
|
||||
return metas;
|
||||
}
|
||||
|
||||
int fieldCount = FieldCount(res);
|
||||
IntPtr fieldsPtr = taos_fetch_fields(res);
|
||||
|
||||
for (int i = 0; i < fieldCount; ++i)
|
||||
{
|
||||
int offset = i * fieldSize;
|
||||
|
||||
TDengineMeta meta = new TDengineMeta();
|
||||
meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset);
|
||||
meta.type = Marshal.ReadByte(fieldsPtr + offset + 65);
|
||||
meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66);
|
||||
metas.Add(meta);
|
||||
}
|
||||
|
||||
return metas;
|
||||
}
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr FetchRows(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr FreeResult(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int Close(IntPtr taos);
|
||||
|
||||
//get precision£¬in parameter restultset
|
||||
[DllImport("taos", EntryPoint = "taos_result_precision", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int ResultPrecision(IntPtr taos);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), 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.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace TDengineDriver
|
||||
{
|
||||
enum TDengineDataType
|
||||
{
|
||||
TSDB_DATA_TYPE_NULL = 0, // 1 bytes
|
||||
TSDB_DATA_TYPE_BOOL = 1, // 1 bytes
|
||||
TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes
|
||||
TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes
|
||||
TSDB_DATA_TYPE_INT = 4, // 4 bytes
|
||||
TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes
|
||||
TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes
|
||||
TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes
|
||||
TSDB_DATA_TYPE_BINARY = 8, // string
|
||||
TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes
|
||||
TSDB_DATA_TYPE_NCHAR = 10, // unicode string
|
||||
TSDB_DATA_TYPE_UTINYINT = 11,// 1 byte
|
||||
TSDB_DATA_TYPE_USMALLINT= 12,// 2 bytes
|
||||
TSDB_DATA_TYPE_UINT = 13, // 4 bytes
|
||||
TSDB_DATA_TYPE_UBIGINT= 14 // 8 bytes
|
||||
}
|
||||
|
||||
enum TDengineInitOption
|
||||
{
|
||||
TSDB_OPTION_LOCALE = 0,
|
||||
TSDB_OPTION_CHARSET = 1,
|
||||
TSDB_OPTION_TIMEZONE = 2,
|
||||
TDDB_OPTION_CONFIGDIR = 3,
|
||||
TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4
|
||||
}
|
||||
|
||||
class TDengineMeta
|
||||
{
|
||||
public string name;
|
||||
public short size;
|
||||
public byte type;
|
||||
public string TypeName()
|
||||
{
|
||||
switch ((TDengineDataType)type)
|
||||
{
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
|
||||
return "BOOL";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
|
||||
return "TINYINT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
|
||||
return "SMALLINT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_INT:
|
||||
return "INT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
|
||||
return "BIGINT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_UTINYINT:
|
||||
return "TINYINT UNSIGNED";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_USMALLINT:
|
||||
return "SMALLINT UNSIGNED";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_UINT:
|
||||
return "INT UNSIGNED";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_UBIGINT:
|
||||
return "BIGINT UNSIGNED";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
|
||||
return "FLOAT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
|
||||
return "DOUBLE";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
|
||||
return "STRING";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
return "TIMESTAMP";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
|
||||
return "NCHAR";
|
||||
default:
|
||||
return "undefine";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TDengine
|
||||
{
|
||||
public const int TSDB_CODE_SUCCESS = 0;
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Init();
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Cleanup();
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Options(int option, string value);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr Connect(string ip, string user, string password, string db, short port);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern private IntPtr taos_errstr(IntPtr res);
|
||||
static public string Error(IntPtr res)
|
||||
{
|
||||
IntPtr errPtr = taos_errstr(res);
|
||||
return Marshal.PtrToStringAnsi(errPtr);
|
||||
}
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int ErrorNo(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr Query(IntPtr conn, string sqlstr);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int AffectRows(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int FieldCount(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern private IntPtr taos_fetch_fields(IntPtr res);
|
||||
static public List<TDengineMeta> FetchFields(IntPtr res)
|
||||
{
|
||||
const int fieldSize = 68;
|
||||
|
||||
List<TDengineMeta> metas = new List<TDengineMeta>();
|
||||
if (res == IntPtr.Zero)
|
||||
{
|
||||
return metas;
|
||||
}
|
||||
|
||||
int fieldCount = FieldCount(res);
|
||||
IntPtr fieldsPtr = taos_fetch_fields(res);
|
||||
|
||||
for (int i = 0; i < fieldCount; ++i)
|
||||
{
|
||||
int offset = i * fieldSize;
|
||||
|
||||
TDengineMeta meta = new TDengineMeta();
|
||||
meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset);
|
||||
meta.type = Marshal.ReadByte(fieldsPtr + offset + 65);
|
||||
meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66);
|
||||
metas.Add(meta);
|
||||
}
|
||||
|
||||
return metas;
|
||||
}
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr FetchRows(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr FreeResult(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int Close(IntPtr taos);
|
||||
|
||||
//get precision£¬in parameter restultset
|
||||
[DllImport("taos", EntryPoint = "taos_result_precision", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int ResultPrecision(IntPtr taos);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,495 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), 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.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Collections;
|
||||
|
||||
namespace TDengineDriver
|
||||
{
|
||||
class TDengineTest
|
||||
{
|
||||
//connect parameters
|
||||
private string host;
|
||||
private string configDir;
|
||||
private string user;
|
||||
private string password;
|
||||
private short port = 0;
|
||||
|
||||
//sql parameters
|
||||
private string dbName;
|
||||
private string stableName;
|
||||
private string tablePrefix;
|
||||
|
||||
private bool isInsertData;
|
||||
private bool isQueryData;
|
||||
|
||||
private long tableCount;
|
||||
private long totalRows;
|
||||
private long batchRows;
|
||||
private long beginTimestamp = 1551369600000L;
|
||||
|
||||
private IntPtr conn = IntPtr.Zero;
|
||||
private long rowsInserted = 0;
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
TDengineTest tester = new TDengineTest();
|
||||
tester.ReadArgument(args);
|
||||
|
||||
Console.WriteLine("---------------------------------------------------------------");
|
||||
Console.WriteLine("Starting Testing...");
|
||||
Console.WriteLine("---------------------------------------------------------------");
|
||||
|
||||
tester.InitTDengine();
|
||||
tester.ConnectTDengine();
|
||||
tester.CreateDbAndTable();
|
||||
tester.ExecuteInsert();
|
||||
tester.ExecuteQuery();
|
||||
tester.CloseConnection();
|
||||
|
||||
Console.WriteLine("---------------------------------------------------------------");
|
||||
Console.WriteLine("Stop Testing...");
|
||||
Console.WriteLine("---------------------------------------------------------------");
|
||||
|
||||
}
|
||||
|
||||
public long GetArgumentAsLong(String[] argv, String argName, int minVal, int maxVal, int defaultValue)
|
||||
{
|
||||
int argc = argv.Length;
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
if (argName != argv[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (i < argc - 1)
|
||||
{
|
||||
String tmp = argv[i + 1];
|
||||
if (tmp[0] == '-')
|
||||
{
|
||||
Console.WriteLine("option {0:G} requires an argument", tmp);
|
||||
ExitProgram();
|
||||
}
|
||||
|
||||
long tmpVal = Convert.ToInt64(tmp);
|
||||
if (tmpVal < minVal || tmpVal > maxVal)
|
||||
{
|
||||
Console.WriteLine("option {0:G} should in range [{1:G}, {2:G}]", argName, minVal, maxVal);
|
||||
ExitProgram();
|
||||
}
|
||||
|
||||
return tmpVal;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public String GetArgumentAsString(String[] argv, String argName, String defaultValue)
|
||||
{
|
||||
int argc = argv.Length;
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
if (argName != argv[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (i < argc - 1)
|
||||
{
|
||||
String tmp = argv[i + 1];
|
||||
if (tmp[0] == '-')
|
||||
{
|
||||
Console.WriteLine("option {0:G} requires an argument", tmp);
|
||||
ExitProgram();
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void PrintHelp(String[] argv)
|
||||
{
|
||||
for (int i = 0; i < argv.Length; ++i)
|
||||
{
|
||||
if ("--help" == argv[i])
|
||||
{
|
||||
String indent = " ";
|
||||
Console.WriteLine("taosTest is simple example to operate TDengine use C# Language.\n");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-h");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "TDEngine server IP address to connect");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-u");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "The TDEngine user name to use when connecting to the server, default is root");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-p");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "The TDEngine user name to use when connecting to the server, default is taosdata");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-d");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Database used to create table or import data, default is db");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-s");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Super Tables used to create table, default is mt");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-t");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Table prefixs, default is t");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-w");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Whether to insert data");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-r");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Whether to query data");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-n");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "How many Tables to create, default is 10");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-b");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "How many rows per insert batch, default is 10");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-i");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "How many rows to insert, default is 100");
|
||||
Console.WriteLine("{0:G}{1:G}", indent, "-c");
|
||||
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Configuration directory");
|
||||
|
||||
ExitProgram();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ReadArgument(String[] argv)
|
||||
{
|
||||
PrintHelp(argv);
|
||||
host = this.GetArgumentAsString(argv, "-h", "127.0.0.1");
|
||||
user = this.GetArgumentAsString(argv, "-u", "root");
|
||||
password = this.GetArgumentAsString(argv, "-p", "taosdata");
|
||||
dbName = this.GetArgumentAsString(argv, "-d", "db");
|
||||
stableName = this.GetArgumentAsString(argv, "-s", "st");
|
||||
tablePrefix = this.GetArgumentAsString(argv, "-t", "t");
|
||||
isInsertData = this.GetArgumentAsLong(argv, "-w", 0, 1, 1) != 0;
|
||||
isQueryData = this.GetArgumentAsLong(argv, "-r", 0, 1, 1) != 0;
|
||||
tableCount = this.GetArgumentAsLong(argv, "-n", 1, 10000, 10);
|
||||
batchRows = this.GetArgumentAsLong(argv, "-b", 1, 1000, 500);
|
||||
totalRows = this.GetArgumentAsLong(argv, "-i", 1, 10000000, 10000);
|
||||
configDir = this.GetArgumentAsString(argv, "-c", "C:/TDengine/cfg");
|
||||
}
|
||||
|
||||
public void InitTDengine()
|
||||
{
|
||||
TDengine.Options((int)TDengineInitOption.TDDB_OPTION_CONFIGDIR, this.configDir);
|
||||
TDengine.Options((int)TDengineInitOption.TDDB_OPTION_SHELL_ACTIVITY_TIMER, "60");
|
||||
TDengine.Init();
|
||||
Console.WriteLine("TDengine Initialization finished");
|
||||
}
|
||||
|
||||
public void ConnectTDengine()
|
||||
{
|
||||
string db = "";
|
||||
this.conn = TDengine.Connect(this.host, this.user, this.password, db, this.port);
|
||||
if (this.conn == IntPtr.Zero)
|
||||
{
|
||||
Console.WriteLine("Connect to TDengine failed");
|
||||
ExitProgram();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Connect to TDengine success");
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateDbAndTable()
|
||||
{
|
||||
if (!this.isInsertData)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("create database if not exists ").Append(this.dbName);
|
||||
IntPtr res = TDengine.Query(this.conn, sql.ToString());
|
||||
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
|
||||
{
|
||||
Console.Write(sql.ToString() + " failure, ");
|
||||
if (res != IntPtr.Zero) {
|
||||
Console.Write("reason: " + TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
ExitProgram();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(sql.ToString() + " success");
|
||||
}
|
||||
TDengine.FreeResult(res);
|
||||
|
||||
sql.Clear();
|
||||
sql.Append("use ").Append(this.dbName);
|
||||
res = TDengine.Query(this.conn, sql.ToString());
|
||||
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
|
||||
{
|
||||
Console.Write(sql.ToString() + " failure, ");
|
||||
if (res != IntPtr.Zero) {
|
||||
Console.Write("reason: " + TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
ExitProgram();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(sql.ToString() + " success");
|
||||
}
|
||||
TDengine.FreeResult(res);
|
||||
|
||||
sql.Clear();
|
||||
sql.Append("create table if not exists ").Append(this.stableName).Append("(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 float, v7 double, v8 binary(10), v9 nchar(10)) tags(t1 int)");
|
||||
res = TDengine.Query(this.conn, sql.ToString());
|
||||
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
|
||||
{
|
||||
Console.Write(sql.ToString() + " failure, ");
|
||||
if (res != IntPtr.Zero) {
|
||||
Console.Write("reason: " + TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
ExitProgram();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(sql.ToString() + " success");
|
||||
}
|
||||
TDengine.FreeResult(res);
|
||||
|
||||
for (int i = 0; i < this.tableCount; i++)
|
||||
{
|
||||
sql.Clear();
|
||||
sql = sql.Append("create table if not exists ").Append(this.tablePrefix).Append(i)
|
||||
.Append(" using ").Append(this.stableName).Append(" tags(").Append(i).Append(")");
|
||||
res = TDengine.Query(this.conn, sql.ToString());
|
||||
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
|
||||
{
|
||||
Console.Write(sql.ToString() + " failure, ");
|
||||
if (res != IntPtr.Zero) {
|
||||
Console.Write("reason: " + TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
ExitProgram();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(sql.ToString() + " success");
|
||||
}
|
||||
TDengine.FreeResult(res);
|
||||
}
|
||||
|
||||
Console.WriteLine("create db and table success");
|
||||
}
|
||||
|
||||
public void ExecuteInsert()
|
||||
{
|
||||
if (!this.isInsertData)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
System.DateTime start = new System.DateTime();
|
||||
long loopCount = this.totalRows / this.batchRows;
|
||||
|
||||
for (int table = 0; table < this.tableCount; ++table)
|
||||
{
|
||||
for (long loop = 0; loop < loopCount; loop++)
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("insert into ").Append(this.tablePrefix).Append(table).Append(" values");
|
||||
for (int batch = 0; batch < this.batchRows; ++batch)
|
||||
{
|
||||
long rows = loop * this.batchRows + batch;
|
||||
sql.Append("(")
|
||||
.Append(this.beginTimestamp + rows)
|
||||
.Append(", 1, 2, 3,")
|
||||
.Append(rows)
|
||||
.Append(", 5, 6, 7, 'abc', 'def')");
|
||||
}
|
||||
IntPtr res = TDengine.Query(this.conn, sql.ToString());
|
||||
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
|
||||
{
|
||||
Console.Write(sql.ToString() + " failure, ");
|
||||
if (res != IntPtr.Zero) {
|
||||
Console.Write("reason: " + TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
}
|
||||
|
||||
int affectRows = TDengine.AffectRows(res);
|
||||
this.rowsInserted += affectRows;
|
||||
|
||||
TDengine.FreeResult(res);
|
||||
}
|
||||
}
|
||||
|
||||
System.DateTime end = new System.DateTime();
|
||||
TimeSpan ts = end - start;
|
||||
|
||||
Console.Write("Total {0:G} rows inserted, {1:G} rows failed, time spend {2:G} seconds.\n"
|
||||
, this.rowsInserted, this.totalRows * this.tableCount - this.rowsInserted, ts.TotalSeconds);
|
||||
}
|
||||
|
||||
public void ExecuteQuery()
|
||||
{
|
||||
if (!this.isQueryData)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
System.DateTime start = new System.DateTime();
|
||||
long queryRows = 0;
|
||||
|
||||
for (int i = 0; i < 1/*this.tableCount*/; ++i)
|
||||
{
|
||||
String sql = "select * from " + this.dbName + "." + tablePrefix + i;
|
||||
Console.WriteLine(sql);
|
||||
|
||||
IntPtr res = TDengine.Query(conn, sql);
|
||||
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
|
||||
{
|
||||
Console.Write(sql.ToString() + " failure, ");
|
||||
if (res != IntPtr.Zero) {
|
||||
Console.Write("reason: " + TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
ExitProgram();
|
||||
}
|
||||
|
||||
int fieldCount = TDengine.FieldCount(res);
|
||||
Console.WriteLine("field count: " + fieldCount);
|
||||
|
||||
List<TDengineMeta> metas = TDengine.FetchFields(res);
|
||||
for (int j = 0; j < metas.Count; j++)
|
||||
{
|
||||
TDengineMeta meta = (TDengineMeta)metas[j];
|
||||
Console.WriteLine("index:" + j + ", type:" + meta.type + ", typename:" + meta.TypeName() + ", name:" + meta.name + ", size:" + meta.size);
|
||||
}
|
||||
|
||||
IntPtr rowdata;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero)
|
||||
{
|
||||
queryRows++;
|
||||
for (int fields = 0; fields < fieldCount; ++fields)
|
||||
{
|
||||
TDengineMeta meta = metas[fields];
|
||||
int offset = IntPtr.Size * fields;
|
||||
IntPtr data = Marshal.ReadIntPtr(rowdata, offset);
|
||||
|
||||
builder.Append("---");
|
||||
|
||||
if (data == IntPtr.Zero)
|
||||
{
|
||||
builder.Append("NULL");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ((TDengineDataType)meta.type)
|
||||
{
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
|
||||
bool v1 = Marshal.ReadByte(data) == 0 ? false : true;
|
||||
builder.Append(v1);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
|
||||
byte v2 = Marshal.ReadByte(data);
|
||||
builder.Append(v2);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
|
||||
short v3 = Marshal.ReadInt16(data);
|
||||
builder.Append(v3);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_INT:
|
||||
int v4 = Marshal.ReadInt32(data);
|
||||
builder.Append(v4);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
|
||||
long v5 = Marshal.ReadInt64(data);
|
||||
builder.Append(v5);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
|
||||
float v6 = (float)Marshal.PtrToStructure(data, typeof(float));
|
||||
builder.Append(v6);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
|
||||
double v7 = (double)Marshal.PtrToStructure(data, typeof(double));
|
||||
builder.Append(v7);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
|
||||
string v8 = Marshal.PtrToStringAnsi(data);
|
||||
builder.Append(v8);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
long v9 = Marshal.ReadInt64(data);
|
||||
builder.Append(v9);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
|
||||
string v10 = Marshal.PtrToStringAnsi(data);
|
||||
builder.Append(v10);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_UTINYINT:
|
||||
byte v11 = Marshal.ReadByte(data);
|
||||
builder.Append(v11);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_USMALLINT:
|
||||
ushort v12 = (ushort)Marshal.ReadInt16(data);
|
||||
builder.Append(v12);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_UINT:
|
||||
uint v13 = (uint)Marshal.ReadInt32(data);
|
||||
builder.Append(v13);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_UBIGINT:
|
||||
ulong v14 = (ulong)Marshal.ReadInt64(data);
|
||||
builder.Append(v14);
|
||||
break;
|
||||
}
|
||||
}
|
||||
builder.Append("---");
|
||||
|
||||
if (queryRows <= 10)
|
||||
{
|
||||
Console.WriteLine(builder.ToString());
|
||||
}
|
||||
builder.Clear();
|
||||
}
|
||||
|
||||
if (TDengine.ErrorNo(res) != 0)
|
||||
{
|
||||
Console.Write("Query is not complete, Error {0:G}",
|
||||
TDengine.ErrorNo(res), TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
|
||||
TDengine.FreeResult(res);
|
||||
}
|
||||
|
||||
System.DateTime end = new System.DateTime();
|
||||
TimeSpan ts = end - start;
|
||||
|
||||
Console.Write("Total {0:G} rows inserted, {1:G} rows query, time spend {2:G} seconds.\n"
|
||||
, this.rowsInserted, queryRows, ts.TotalSeconds);
|
||||
}
|
||||
|
||||
public void CloseConnection()
|
||||
{
|
||||
if (this.conn != IntPtr.Zero)
|
||||
{
|
||||
TDengine.Close(this.conn);
|
||||
}
|
||||
}
|
||||
|
||||
static void ExitProgram()
|
||||
{
|
||||
TDengine.Cleanup();
|
||||
System.Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
FROM tdengine/tdengine-beta:latest
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ARG MIRROR=archive.ubuntu.com
|
||||
RUN sed -Ei 's/\w+.ubuntu.com/'${MIRROR}'/' /etc/apt/sources.list && apt update && apt install mono-devel -y
|
||||
RUN apt-get install wget -y \
|
||||
&& wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \
|
||||
&& dpkg -i packages-microsoft-prod.deb \
|
||||
&& rm packages-microsoft-prod.deb \
|
||||
&& apt-get update && apt-get install -y dotnet-sdk-5.0
|
||||
COPY ./*.cs *.csproj /tmp/
|
||||
WORKDIR /tmp/
|
||||
RUN dotnet build -c Release && cp bin/Release/net5.0/taosdemo bin/Release/net5.0/taosdemo.* /usr/local/bin/ && rm -rf /tmp/*
|
||||
|
||||
FROM tdengine/tdengine-beta:latest
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get install wget -y \
|
||||
&& wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \
|
||||
&& dpkg -i packages-microsoft-prod.deb \
|
||||
&& rm packages-microsoft-prod.deb \
|
||||
&& apt-get update && apt-get install -y dotnet-runtime-5.0
|
||||
COPY --from=0 /usr/local/bin/taosdemo* /usr/local/bin/
|
||||
CMD ["/usr/local/bin/taosdemo"]
|
|
@ -0,0 +1,65 @@
|
|||
# C# Taosdemo
|
||||
|
||||
## For Mono
|
||||
|
||||
install build environment
|
||||
|
||||
```sh
|
||||
yum/apt install mono-complete
|
||||
```
|
||||
|
||||
build C# version taosdemo.
|
||||
|
||||
```sh
|
||||
mcs -out:taosdemo *.cs
|
||||
./taosdemo --help
|
||||
```
|
||||
|
||||
## For DotNet
|
||||
|
||||
install dotnet environment.
|
||||
|
||||
```sh
|
||||
wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \
|
||||
&& dpkg -i packages-microsoft-prod.deb \
|
||||
&& rm packages-microsoft-prod.deb \
|
||||
&& apt-get update && apt-get install -y dotnet-sdk-5.0
|
||||
```
|
||||
|
||||
Build DotNet version taosdemo.
|
||||
|
||||
```sh
|
||||
dotnet build -c Release
|
||||
./bin/Release/net5.0/taosdemo --help
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
Usage: mono taosdemo.exe [OPTION...]
|
||||
|
||||
--help Show usage.
|
||||
|
||||
-h <hostname> host, The host to connect to TDengine. Default is localhost.
|
||||
-p <port> port, The TCP/IP port number to use for the connection. Default is 0.
|
||||
-u <username> user, The user name to use when connecting to the server. Default is 'root'.
|
||||
-P <password> password, The password to use when connecting to the server. Default is 'taosdata'.
|
||||
-d <dbname> database, Destination database. Default is 'test'.
|
||||
-a <replications> replica, Set the replica parameters of the database, Default 1, min: 1, max: 5.
|
||||
-m <table prefix> table_prefix, Table prefix name. Default is 't'.
|
||||
-M stable, Use super table.
|
||||
-s <stable prefix> stable_prefix, STable prefix name. Default is 'st'
|
||||
-Q <DEFAULT | command> query, Execute query command. set 'DEFAULT' means select * from each table
|
||||
-T <number> num_of_threads, The number of threads. Default is 10.
|
||||
-r <number> num_of_records_per_req, The number of records per request. Default is 1000.
|
||||
-t <number> num_of_tables, The number of tables. Default is 1.
|
||||
-n <number> num_of_records_per_table, The number of records per table. Default is 1.
|
||||
-c <path> config_directory, Configuration directory. Default is '/etc/taos/'.
|
||||
-x flag, Insert only flag.
|
||||
-O order, Insert mode--0: In order, 1: Out of order. Default is in order.
|
||||
-R <number> rate, Out of order data's rate--if order=1 Default 10, min: 0, max: 50.
|
||||
-D <number> Delete data methods 0: don't delete, 1: delete by table, 2: delete by stable, 3: delete by database.
|
||||
-v Print verbose output
|
||||
-g Print debug output
|
||||
-y Skip read key for continous test, default is not skip
|
||||
```
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), 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.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace TDengineDriver
|
||||
{
|
||||
enum TDengineDataType
|
||||
{
|
||||
TSDB_DATA_TYPE_NULL = 0, // 1 bytes
|
||||
TSDB_DATA_TYPE_BOOL = 1, // 1 bytes
|
||||
TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes
|
||||
TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes
|
||||
TSDB_DATA_TYPE_INT = 4, // 4 bytes
|
||||
TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes
|
||||
TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes
|
||||
TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes
|
||||
TSDB_DATA_TYPE_BINARY = 8, // string
|
||||
TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes
|
||||
TSDB_DATA_TYPE_NCHAR = 10, // unicode string
|
||||
TSDB_DATA_TYPE_UTINYINT = 11,// 1 byte
|
||||
TSDB_DATA_TYPE_USMALLINT= 12,// 2 bytes
|
||||
TSDB_DATA_TYPE_UINT = 13, // 4 bytes
|
||||
TSDB_DATA_TYPE_UBIGINT= 14 // 8 bytes
|
||||
}
|
||||
|
||||
enum TDengineInitOption
|
||||
{
|
||||
TSDB_OPTION_LOCALE = 0,
|
||||
TSDB_OPTION_CHARSET = 1,
|
||||
TSDB_OPTION_TIMEZONE = 2,
|
||||
TDDB_OPTION_CONFIGDIR = 3,
|
||||
TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4
|
||||
}
|
||||
|
||||
class TDengineMeta
|
||||
{
|
||||
public string name;
|
||||
public short size;
|
||||
public byte type;
|
||||
public string TypeName()
|
||||
{
|
||||
switch ((TDengineDataType)type)
|
||||
{
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
|
||||
return "BOOL";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
|
||||
return "TINYINT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
|
||||
return "SMALLINT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_INT:
|
||||
return "INT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
|
||||
return "BIGINT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_UTINYINT:
|
||||
return "TINYINT UNSIGNED";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_USMALLINT:
|
||||
return "SMALLINT UNSIGNED";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_UINT:
|
||||
return "INT UNSIGNED";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_UBIGINT:
|
||||
return "BIGINT UNSIGNED";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
|
||||
return "FLOAT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
|
||||
return "DOUBLE";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
|
||||
return "STRING";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
return "TIMESTAMP";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
|
||||
return "NCHAR";
|
||||
default:
|
||||
return "undefine";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TDengine
|
||||
{
|
||||
public const int TSDB_CODE_SUCCESS = 0;
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Init();
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Cleanup();
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Options(int option, string value);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr Connect(string ip, string user, string password, string db, short port);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern private IntPtr taos_errstr(IntPtr res);
|
||||
static public string Error(IntPtr res)
|
||||
{
|
||||
IntPtr errPtr = taos_errstr(res);
|
||||
return Marshal.PtrToStringAnsi(errPtr);
|
||||
}
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int ErrorNo(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr Query(IntPtr conn, string sqlstr);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int AffectRows(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int FieldCount(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern private IntPtr taos_fetch_fields(IntPtr res);
|
||||
static public List<TDengineMeta> FetchFields(IntPtr res)
|
||||
{
|
||||
const int fieldSize = 68;
|
||||
|
||||
List<TDengineMeta> metas = new List<TDengineMeta>();
|
||||
if (res == IntPtr.Zero)
|
||||
{
|
||||
return metas;
|
||||
}
|
||||
|
||||
int fieldCount = FieldCount(res);
|
||||
IntPtr fieldsPtr = taos_fetch_fields(res);
|
||||
|
||||
for (int i = 0; i < fieldCount; ++i)
|
||||
{
|
||||
int offset = i * fieldSize;
|
||||
|
||||
TDengineMeta meta = new TDengineMeta();
|
||||
meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset);
|
||||
meta.type = Marshal.ReadByte(fieldsPtr + offset + 65);
|
||||
meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66);
|
||||
metas.Add(meta);
|
||||
}
|
||||
|
||||
return metas;
|
||||
}
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr FetchRows(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr FreeResult(IntPtr res);
|
||||
|
||||
[DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int Close(IntPtr taos);
|
||||
//get precision£¬in parameter restultset
|
||||
[DllImport("taos", EntryPoint = "taos_result_precision", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int ResultPrecision(IntPtr taos);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,902 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), 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.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Collections;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace TDengineDriver
|
||||
{
|
||||
class TDengineTest
|
||||
{
|
||||
//connect parameters
|
||||
private string host = "127.0.0.1";
|
||||
private string configDir = "C:/TDengine/cfg";
|
||||
private string user = "root";
|
||||
private string password = "taosdata";
|
||||
private short port = 0;
|
||||
|
||||
//sql parameters
|
||||
private string dbName = "db";
|
||||
private string stablePrefix = "st";
|
||||
private string tablePrefix = "t";
|
||||
|
||||
private bool isInsertOnly = false;
|
||||
private string query = "NONE";
|
||||
private short queryMode = 1;
|
||||
|
||||
private long recordsPerTable = 1;
|
||||
private int recordsPerRequest = 1;
|
||||
private int colsPerRecord = 3;
|
||||
private long batchRows = 1000;
|
||||
private long numOfTables = 1;
|
||||
private short replica = 1;
|
||||
|
||||
private IntPtr conn = IntPtr.Zero;
|
||||
// private long rowsInserted = 0;
|
||||
private bool useStable = false;
|
||||
private short methodOfDelete = 0;
|
||||
private long numOfThreads = 1;
|
||||
private short rateOfOutorder = 10;
|
||||
private bool order = true;
|
||||
private bool skipReadKey = false;
|
||||
private bool verbose = false;
|
||||
private bool debug = false;
|
||||
|
||||
|
||||
static void HelpPrint(string arg, string desc)
|
||||
{
|
||||
string indent = " ";
|
||||
Console.WriteLine("{0}{1}", indent, arg.PadRight(25) + desc);
|
||||
}
|
||||
|
||||
static void PrintHelp(String[] argv)
|
||||
{
|
||||
for (int i = 0; i < argv.Length; ++i)
|
||||
{
|
||||
if ("--help" == argv[i])
|
||||
{
|
||||
Console.WriteLine("Usage: mono taosdemo.exe [OPTION...]");
|
||||
Console.WriteLine("");
|
||||
HelpPrint("--help", "Show usage.");
|
||||
Console.WriteLine("");
|
||||
|
||||
HelpPrint("-h <hostname>", "host, The host to connect to TDengine. Default is localhost.");
|
||||
HelpPrint("-p <port>", "port, The TCP/IP port number to use for the connection. Default is 0.");
|
||||
HelpPrint("-u <username>", "user, The user name to use when connecting to the server. Default is 'root'.");
|
||||
HelpPrint("-P <password>", "password, The password to use when connecting to the server. Default is 'taosdata'.");
|
||||
HelpPrint("-d <dbname>", "database, Destination database. Default is 'test'.");
|
||||
HelpPrint("-a <replications>", "replica, Set the replica parameters of the database, Default 1, min: 1, max: 5.");
|
||||
HelpPrint("-m <table prefix>", "table_prefix, Table prefix name. Default is 't'.");
|
||||
HelpPrint("-M", "stable, Use super table.");
|
||||
HelpPrint("-s <stable prefix>", "stable_prefix, STable prefix name. Default is 'st'");
|
||||
HelpPrint("-Q <DEFAULT | command>", "query, Execute query command. set 'DEFAULT' means select * from each table");
|
||||
/* NOT SUPPORT SO FAR
|
||||
HelpPrint("-o", "outputfile, Direct output to the named file. Default is './output.txt'.");
|
||||
HelpPrint("-q", "query_mode, Query mode--0: SYNC, 1: ASYNC. Default is SYNC.");
|
||||
HelpPrint("-b", "type_of_cols, data_type of columns: 'INT', 'TINYINT', 'SMALLINT', 'BIGINT', 'FLOAT', 'DOUBLE', 'BINARY'. Default is 'INT'.");
|
||||
HelpPrint("-w", "length_of_binary, The length of data_type 'BINARY'. Only applicable when type of cols is 'BINARY'. Default is 8");
|
||||
HelpPrint("-l", "num_of_cols_per_record, The number of columns per record. Default is 3.");
|
||||
*/
|
||||
HelpPrint("-T <number>", "num_of_threads, The number of threads. Default is 10.");
|
||||
HelpPrint("-r <number>", "num_of_records_per_req, The number of records per request. Default is 1000.");
|
||||
HelpPrint("-t <number>", "num_of_tables, The number of tables. Default is 1.");
|
||||
HelpPrint("-n <number>", "num_of_records_per_table, The number of records per table. Default is 1.");
|
||||
HelpPrint("-c <path>", "config_directory, Configuration directory. Default is '/etc/taos/'.");
|
||||
HelpPrint("-x", "flag, Insert only flag.");
|
||||
HelpPrint("-O", "order, Insert mode--0: In order, 1: Out of order. Default is in order.");
|
||||
HelpPrint("-R <number>", "rate, Out of order data's rate--if order=1 Default 10, min: 0, max: 50.");
|
||||
HelpPrint("-D <number>", "Delete data methods 0: don't delete, 1: delete by table, 2: delete by stable, 3: delete by database.");
|
||||
HelpPrint("-v", "Print verbose output");
|
||||
HelpPrint("-g", "Print debug output");
|
||||
HelpPrint("-y", "Skip read key for continous test, default is not skip");
|
||||
|
||||
System.Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ReadArgument(String[] argv)
|
||||
{
|
||||
host = this.GetArgumentAsString(argv, "-h", "127.0.0.1");
|
||||
port = (short)this.GetArgumentAsLong(argv, "-p", 0, 65535, 6030);
|
||||
user = this.GetArgumentAsString(argv, "-u", "root");
|
||||
password = this.GetArgumentAsString(argv, "-P", "taosdata");
|
||||
dbName = this.GetArgumentAsString(argv, "-d", "db");
|
||||
stablePrefix = this.GetArgumentAsString(argv, "-s", "st");
|
||||
tablePrefix = this.GetArgumentAsString(argv, "-m", "t");
|
||||
isInsertOnly = this.GetArgumentAsFlag(argv, "-x", true);
|
||||
query = this.GetArgumentAsString(argv, "-Q", "NONE");
|
||||
queryMode = (short)this.GetArgumentAsLong(argv, "-q", 0, 1, 0);
|
||||
numOfTables = this.GetArgumentAsLong(argv, "-t", 1, 1000000000, 1);
|
||||
batchRows = this.GetArgumentAsLong(argv, "-r", 1, 10000, 1000);
|
||||
recordsPerTable = this.GetArgumentAsLong(argv, "-n", 1, 100000000000, 1);
|
||||
recordsPerRequest = (int)this.GetArgumentAsLong(argv, "-r", 1, 10000, 1);
|
||||
colsPerRecord = (int)this.GetArgumentAsLong(argv, "-l", 1, 1024, 3);
|
||||
configDir = this.GetArgumentAsString(argv, "-c", "C:/TDengine/cfg");
|
||||
useStable = this.GetArgumentAsFlag(argv, "-M", true);
|
||||
|
||||
replica = (short)this.GetArgumentAsLong(argv, "-a", 1, 5, 1);
|
||||
methodOfDelete = (short)this.GetArgumentAsLong(argv, "-D", 0, 3, 0);
|
||||
numOfThreads = (short)this.GetArgumentAsLong(argv, "-T", 1, 10000, 1);
|
||||
order = this.GetArgumentAsFlag(argv, "-O", false);
|
||||
rateOfOutorder = (short)this.GetArgumentAsLong(argv, "-R", 0, 50, 10);
|
||||
|
||||
skipReadKey = this.GetArgumentAsFlag(argv, "-y", true);
|
||||
verbose = this.GetArgumentAsFlag(argv, "-v", true);
|
||||
debug = this.GetArgumentAsFlag(argv, "-g", true);
|
||||
|
||||
VerbosePrint("###################################################################\n");
|
||||
VerbosePrintFormat("# Server IP: {0}\n", host);
|
||||
VerbosePrintFormat("# User: {0}\n", user);
|
||||
VerbosePrintFormat("# Password: {0}\n", password);
|
||||
VerbosePrintFormat("# Number of Columns per record: {0}\n", colsPerRecord);
|
||||
VerbosePrintFormat("# Number of Threads: {0}\n", numOfThreads);
|
||||
VerbosePrintFormat("# Number of Tables: {0}\n", numOfTables);
|
||||
VerbosePrintFormat("# Number of records per Table: {0}\n", recordsPerTable);
|
||||
VerbosePrintFormat("# Records/Request: {0}\n", recordsPerRequest);
|
||||
VerbosePrintFormat("# Database name: {0}\n", dbName);
|
||||
VerbosePrintFormat("# Replica: {0}\n", replica);
|
||||
VerbosePrintFormat("# Use STable: {0}\n", useStable);
|
||||
VerbosePrintFormat("# Table prefix: {0}\n", tablePrefix);
|
||||
if (useStable == true)
|
||||
{
|
||||
VerbosePrintFormat("# STable prefix: {0}\n", stablePrefix);
|
||||
}
|
||||
VerbosePrintFormat("# Data order: {0}\n", order);
|
||||
VerbosePrintFormat("# Data out of order rate: {0}\n", rateOfOutorder);
|
||||
VerbosePrintFormat("# Delete method: {0}\n", methodOfDelete);
|
||||
VerbosePrintFormat("# Query command: {0}\n", query);
|
||||
VerbosePrintFormat("# Query Mode: {0}\n", queryMode);
|
||||
VerbosePrintFormat("# Insert Only: {0}\n", isInsertOnly);
|
||||
VerbosePrintFormat("# Verbose output {0}\n", verbose);
|
||||
VerbosePrintFormat("# Test time: {0}\n", DateTime.Now.ToString("h:mm:ss tt"));
|
||||
|
||||
VerbosePrint("###################################################################\n");
|
||||
|
||||
if (skipReadKey == false)
|
||||
{
|
||||
Console.Write("Press any key to continue..\n");
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
|
||||
public bool GetArgumentAsFlag(String[] argv, String argName, bool defaultValue)
|
||||
{
|
||||
int argc = argv.Length;
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
if (argName == argv[i])
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
return !defaultValue;
|
||||
}
|
||||
|
||||
public long GetArgumentAsLong(String[] argv, String argName, int minVal, long maxVal, int defaultValue)
|
||||
{
|
||||
int argc = argv.Length;
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
if (argName != argv[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (i < argc - 1)
|
||||
{
|
||||
String tmp = argv[i + 1];
|
||||
if (tmp[0] == '-')
|
||||
{
|
||||
Console.WriteLine("option {0:G} requires an argument", argName);
|
||||
ExitProgram(1);
|
||||
}
|
||||
|
||||
long tmpVal = Convert.ToInt64(tmp);
|
||||
if (tmpVal < minVal || tmpVal > maxVal)
|
||||
{
|
||||
Console.WriteLine("option {0:G} value should in range [{1:G}, {2:G}]", argName, minVal, maxVal);
|
||||
ExitProgram(1);
|
||||
}
|
||||
|
||||
return tmpVal;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public String GetArgumentAsString(String[] argv, String argName, String defaultValue)
|
||||
{
|
||||
int argc = argv.Length;
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
if (argName != argv[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (i < argc - 1)
|
||||
{
|
||||
String tmp = argv[i + 1];
|
||||
if (tmp[0] == '-')
|
||||
{
|
||||
Console.WriteLine("option {0:G} requires an argument", argName);
|
||||
ExitProgram(1);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
static void CleanAndExitProgram(int ret)
|
||||
{
|
||||
TDengine.Cleanup();
|
||||
System.Environment.Exit(ret);
|
||||
}
|
||||
|
||||
static void ExitProgram(int ret)
|
||||
{
|
||||
System.Environment.Exit(ret);
|
||||
}
|
||||
|
||||
private void VerbosePrintFormat(string format, params object[] parameters)
|
||||
{
|
||||
if (verbose == true)
|
||||
{
|
||||
Console.Write(format, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
private void VerbosePrint(string str)
|
||||
{
|
||||
if (verbose == true)
|
||||
{
|
||||
Console.Write(str);
|
||||
}
|
||||
}
|
||||
|
||||
private void DebugPrintFormat(string format, params object[] parameters)
|
||||
{
|
||||
if (debug == true)
|
||||
{
|
||||
Console.Write(format, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
private void DebugPrint(string str)
|
||||
{
|
||||
if (debug == true)
|
||||
{
|
||||
Console.Write(str);
|
||||
}
|
||||
}
|
||||
|
||||
public void InitTDengine()
|
||||
{
|
||||
TDengine.Options((int)TDengineInitOption.TDDB_OPTION_CONFIGDIR, this.configDir);
|
||||
TDengine.Options((int)TDengineInitOption.TDDB_OPTION_SHELL_ACTIVITY_TIMER, "60");
|
||||
TDengine.Init();
|
||||
VerbosePrint("TDengine Initialization finished\n");
|
||||
}
|
||||
|
||||
public void ConnectTDengine()
|
||||
{
|
||||
string db = "";
|
||||
VerbosePrintFormat("host:{0} user:{1}, pass:{2}; db:{3}, port:{4}\n",
|
||||
this.host, this.user, this.password, db, this.port);
|
||||
this.conn = TDengine.Connect(this.host, this.user, this.password, db, this.port);
|
||||
if (this.conn == IntPtr.Zero)
|
||||
{
|
||||
Console.WriteLine("Connect to TDengine failed");
|
||||
CleanAndExitProgram(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerbosePrint("Connect to TDengine success\n");
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateTablesByThreads()
|
||||
{
|
||||
Thread[] threadArr = new Thread[numOfThreads];
|
||||
|
||||
long quotition = numOfTables / numOfThreads;
|
||||
if (quotition < 1)
|
||||
{
|
||||
numOfThreads = numOfTables;
|
||||
quotition = 1;
|
||||
}
|
||||
|
||||
long remainder = 0;
|
||||
if (numOfThreads != 0)
|
||||
{
|
||||
remainder = numOfTables % numOfThreads;
|
||||
}
|
||||
|
||||
long last = 0;
|
||||
|
||||
for (int i = 0; i < numOfThreads; i++)
|
||||
{
|
||||
CreateTableThread createTableThread = new CreateTableThread();
|
||||
createTableThread.id = i;
|
||||
createTableThread.verbose = verbose;
|
||||
createTableThread.debug = debug;
|
||||
createTableThread.dbName = this.dbName;
|
||||
createTableThread.tablePrefix = this.tablePrefix;
|
||||
createTableThread.useStable = useStable;
|
||||
if (useStable)
|
||||
{
|
||||
createTableThread.stablePrefix = stablePrefix;
|
||||
}
|
||||
createTableThread.conn = conn;
|
||||
|
||||
createTableThread.start = last;
|
||||
if (i < remainder)
|
||||
{
|
||||
createTableThread.end = last + quotition;
|
||||
}
|
||||
else
|
||||
{
|
||||
createTableThread.end = last + quotition - 1;
|
||||
}
|
||||
last = createTableThread.end + 1;
|
||||
|
||||
threadArr[i] = new Thread(createTableThread.ThreadMain);
|
||||
threadArr[i].Start();
|
||||
threadArr[i].Join();
|
||||
}
|
||||
}
|
||||
|
||||
public void dropDatabase()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("DROP DATABASE IF EXISTS ").Append(this.dbName);
|
||||
IntPtr res = TDengine.Query(this.conn, sql.ToString());
|
||||
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
|
||||
{
|
||||
Console.Write(sql.ToString() + " failure, ");
|
||||
if (res != IntPtr.Zero) {
|
||||
Console.Write("reason: " + TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
CleanAndExitProgram(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerbosePrint(sql.ToString() + " success\n");
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateDb()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.Append("CREATE DATABASE IF NOT EXISTS ").Append(this.dbName).Append(" replica ").Append(this.replica).Append(" keep 36500");
|
||||
IntPtr res = TDengine.Query(this.conn, sql.ToString());
|
||||
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
|
||||
{
|
||||
Console.Write(sql.ToString() + " failure, ");
|
||||
if (res != IntPtr.Zero) {
|
||||
Console.Write("reason: " + TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
CleanAndExitProgram(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerbosePrint(sql.ToString() + " success\n");
|
||||
}
|
||||
TDengine.FreeResult(res);
|
||||
}
|
||||
|
||||
public void CreateStable()
|
||||
{
|
||||
StringBuilder sql = new StringBuilder();
|
||||
|
||||
sql.Clear();
|
||||
sql.Append("CREATE TABLE IF NOT EXISTS ").
|
||||
Append(this.dbName).Append(".").Append(this.stablePrefix).
|
||||
Append("(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 float, v7 double, v8 binary(10), v9 nchar(10), v10 tinyint unsigned, v11 smallint unsigned, v12 int unsigned, v13 bigint unsigned) tags(t1 int)");
|
||||
IntPtr res = TDengine.Query(this.conn, sql.ToString());
|
||||
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
|
||||
{
|
||||
Console.Write(sql.ToString() + " failure, ");
|
||||
if (res != IntPtr.Zero) {
|
||||
Console.Write("reason: " + TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
CleanAndExitProgram(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerbosePrint(sql.ToString() + " success\n");
|
||||
}
|
||||
TDengine.FreeResult(res);
|
||||
}
|
||||
|
||||
public void InsertByThreads()
|
||||
{
|
||||
Thread[] threadArr = new Thread[numOfThreads];
|
||||
|
||||
long quotition = numOfTables / numOfThreads;
|
||||
if (quotition < 1)
|
||||
{
|
||||
numOfThreads = numOfTables;
|
||||
quotition = 1;
|
||||
}
|
||||
|
||||
long remainder = 0;
|
||||
if (numOfThreads != 0)
|
||||
{
|
||||
remainder = numOfTables % numOfThreads;
|
||||
}
|
||||
|
||||
long last = 0;
|
||||
|
||||
for (int i = 0; i < numOfThreads; i++)
|
||||
{
|
||||
InsertDataThread insertThread = new InsertDataThread();
|
||||
insertThread.id = i;
|
||||
insertThread.recordsPerTable = recordsPerTable;
|
||||
insertThread.batchRows = batchRows;
|
||||
insertThread.numOfTables = numOfTables;
|
||||
insertThread.verbose = verbose;
|
||||
insertThread.debug = debug;
|
||||
insertThread.dbName = this.dbName;
|
||||
insertThread.tablePrefix = this.tablePrefix;
|
||||
insertThread.order = this.order;
|
||||
insertThread.rateOfOutorder = this.rateOfOutorder;
|
||||
if (useStable)
|
||||
{
|
||||
insertThread.stablePrefix = stablePrefix;
|
||||
}
|
||||
insertThread.conn = conn;
|
||||
|
||||
insertThread.start = last;
|
||||
if (i < remainder)
|
||||
{
|
||||
insertThread.end = last + quotition;
|
||||
}
|
||||
else
|
||||
{
|
||||
insertThread.end = last + quotition - 1;
|
||||
}
|
||||
last = insertThread.end + 1;
|
||||
|
||||
threadArr[i] = new Thread(insertThread.ThreadMain);
|
||||
threadArr[i].Start();
|
||||
threadArr[i].Join();
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteQuery()
|
||||
{
|
||||
long queryRows = 0;
|
||||
|
||||
for (int i = 0; i < this.numOfTables; ++i)
|
||||
{
|
||||
string sql;
|
||||
|
||||
if (query == "DEFAULT")
|
||||
{
|
||||
sql = "select * from " + this.dbName + "." + tablePrefix + i;
|
||||
}
|
||||
else
|
||||
{
|
||||
sql = query;
|
||||
}
|
||||
DebugPrintFormat("query: {0}, sql:{1}\n", query, sql);
|
||||
|
||||
IntPtr res = TDengine.Query(conn, sql);
|
||||
DebugPrintFormat("res: {0}\n", res);
|
||||
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
|
||||
{
|
||||
Console.Write(sql.ToString() + " failure, ");
|
||||
if (res != IntPtr.Zero) {
|
||||
Console.Write("reason: " + TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
CleanAndExitProgram(1);
|
||||
}
|
||||
|
||||
int fieldCount = TDengine.FieldCount(res);
|
||||
DebugPrint("field count: " + fieldCount + "\n");
|
||||
|
||||
List<TDengineMeta> metas = TDengine.FetchFields(res);
|
||||
for (int j = 0; j < metas.Count; j++)
|
||||
{
|
||||
TDengineMeta meta = (TDengineMeta)metas[j];
|
||||
DebugPrint("index:" + j + ", type:" + meta.type + ", typename:" + meta.TypeName() + ", name:" + meta.name + ", size:" + meta.size + "\n");
|
||||
}
|
||||
|
||||
IntPtr rowdata;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero)
|
||||
{
|
||||
queryRows++;
|
||||
for (int fields = 0; fields < fieldCount; ++fields)
|
||||
{
|
||||
TDengineMeta meta = metas[fields];
|
||||
int offset = IntPtr.Size * fields;
|
||||
IntPtr data = Marshal.ReadIntPtr(rowdata, offset);
|
||||
|
||||
builder.Append(" | ");
|
||||
|
||||
if (data == IntPtr.Zero)
|
||||
{
|
||||
builder.Append("NULL");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ((TDengineDataType)meta.type)
|
||||
{
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
|
||||
bool v1 = Marshal.ReadByte(data) == 0 ? false : true;
|
||||
builder.Append(v1);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
|
||||
sbyte v2 = (sbyte)Marshal.ReadByte(data);
|
||||
builder.Append(v2);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
|
||||
short v3 = Marshal.ReadInt16(data);
|
||||
builder.Append(v3);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_INT:
|
||||
int v4 = Marshal.ReadInt32(data);
|
||||
builder.Append(v4);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
|
||||
long v5 = Marshal.ReadInt64(data);
|
||||
builder.Append(v5);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
|
||||
float v6 = (float)Marshal.PtrToStructure(data, typeof(float));
|
||||
builder.Append(v6);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
|
||||
double v7 = (double)Marshal.PtrToStructure(data, typeof(double));
|
||||
builder.Append(v7);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
|
||||
string v8 = Marshal.PtrToStringAnsi(data);
|
||||
builder.Append(v8);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
long v9 = Marshal.ReadInt64(data);
|
||||
builder.Append(v9);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
|
||||
string v10 = Marshal.PtrToStringAnsi(data);
|
||||
builder.Append(v10);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_UTINYINT:
|
||||
byte v11 = Marshal.ReadByte(data);
|
||||
builder.Append(v11);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_USMALLINT:
|
||||
ushort v12 = (ushort)Marshal.ReadInt16(data);
|
||||
builder.Append(v12);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_UINT:
|
||||
uint v13 = (uint)Marshal.ReadInt32(data);
|
||||
builder.Append(v13);
|
||||
break;
|
||||
case TDengineDataType.TSDB_DATA_TYPE_UBIGINT:
|
||||
ulong v14 = (ulong)Marshal.ReadInt64(data);
|
||||
builder.Append(v14);
|
||||
break;
|
||||
}
|
||||
}
|
||||
builder.Append(" | ");
|
||||
|
||||
VerbosePrint(builder.ToString() + "\n");
|
||||
builder.Clear();
|
||||
}
|
||||
|
||||
if (TDengine.ErrorNo(res) != 0)
|
||||
{
|
||||
Console.Write("Query is not complete, Error {0:G}",
|
||||
TDengine.ErrorNo(res), TDengine.Error(res));
|
||||
}
|
||||
|
||||
TDengine.FreeResult(res);
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseConnection()
|
||||
{
|
||||
if (this.conn != IntPtr.Zero)
|
||||
{
|
||||
TDengine.Close(this.conn);
|
||||
}
|
||||
}
|
||||
|
||||
// Main entry
|
||||
static void Main(string[] args)
|
||||
{
|
||||
PrintHelp(args);
|
||||
|
||||
TDengineTest tester = new TDengineTest();
|
||||
tester.ReadArgument(args);
|
||||
|
||||
tester.InitTDengine();
|
||||
tester.ConnectTDengine();
|
||||
|
||||
if (tester.isInsertOnly == false)
|
||||
{
|
||||
tester.dropDatabase();
|
||||
tester.CreateDb();
|
||||
|
||||
|
||||
if (tester.useStable == true)
|
||||
{
|
||||
tester.CreateStable();
|
||||
}
|
||||
|
||||
tester.CreateTablesByThreads();
|
||||
}
|
||||
|
||||
Stopwatch watch = Stopwatch.StartNew();
|
||||
tester.InsertByThreads();
|
||||
watch.Stop();
|
||||
double elapsedMs = watch.Elapsed.TotalMilliseconds;
|
||||
|
||||
Console.WriteLine("C# taosdemo: Spent {0} seconds to insert {1} records with {2} record(s) per request: {3} records/second",
|
||||
elapsedMs / 1000,
|
||||
tester.recordsPerTable * tester.numOfTables,
|
||||
tester.batchRows,
|
||||
(tester.recordsPerTable * tester.numOfTables * 1000) / elapsedMs);
|
||||
|
||||
tester.DebugPrintFormat("query command:{0}\n", tester.query);
|
||||
if (tester.query != "NONE")
|
||||
{
|
||||
watch = Stopwatch.StartNew();
|
||||
tester.ExecuteQuery();
|
||||
watch.Stop();
|
||||
elapsedMs = watch.Elapsed.TotalMilliseconds;
|
||||
Console.WriteLine("C# taosdemo: Spent {0} seconds to query {1} records.\n",
|
||||
elapsedMs / 1000,
|
||||
tester.recordsPerTable * tester.numOfTables
|
||||
);
|
||||
}
|
||||
tester.CloseConnection();
|
||||
|
||||
Console.WriteLine("End.");
|
||||
CleanAndExitProgram(0);
|
||||
}
|
||||
|
||||
public class InsertDataThread
|
||||
{
|
||||
public long id { set; get; }
|
||||
public long start { set; get; }
|
||||
public long end { set; get; }
|
||||
public string dbName { set; get; }
|
||||
public IntPtr conn { set; get; }
|
||||
public string tablePrefix { set; get; }
|
||||
public string stablePrefix { set; get; }
|
||||
public long recordsPerTable { set; get; }
|
||||
public long batchRows { set; get; }
|
||||
public long numOfTables { set; get; }
|
||||
public bool verbose { set; get; }
|
||||
public bool debug { set; get; }
|
||||
public bool order { set; get; }
|
||||
public short rateOfOutorder { set; get; }
|
||||
|
||||
private void VerbosePrintFormat(string format, params object[] parameters)
|
||||
{
|
||||
if (verbose == true)
|
||||
{
|
||||
Console.Write(format, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
private void VerbosePrint(string str)
|
||||
{
|
||||
if (verbose == true)
|
||||
{
|
||||
Console.Write(str);
|
||||
}
|
||||
}
|
||||
|
||||
private void DebugPrintFormat(string format, params object[] parameters)
|
||||
{
|
||||
if (debug == true)
|
||||
{
|
||||
Console.Write(format, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
private void DebugPrint(string str)
|
||||
{
|
||||
if (debug == true)
|
||||
{
|
||||
Console.Write(str);
|
||||
}
|
||||
}
|
||||
|
||||
public void ThreadMain()
|
||||
{
|
||||
VerbosePrintFormat("InsertDataThread {0} from {1} to {2}\n", id, start, end);
|
||||
StringBuilder sql = new StringBuilder();
|
||||
|
||||
DateTime now = DateTime.Now;
|
||||
int h = now.Hour;
|
||||
int m = now.Minute;
|
||||
int s = now.Second;
|
||||
|
||||
long baseTimestamp = -16094340000; // 1969-06-29 01:21:00
|
||||
VerbosePrintFormat("beginTime is {0} + {1}h:{2}m:{3}s\n", baseTimestamp, h, m, s);
|
||||
long beginTimestamp = baseTimestamp + ((h * 60 + m) * 60 + s) * 1000;
|
||||
Random random = new Random();
|
||||
|
||||
long rowsInserted = 0;
|
||||
|
||||
long i = 0;
|
||||
while (i < recordsPerTable)
|
||||
{
|
||||
for (long table = start; table <= end; ++table)
|
||||
{
|
||||
long inserted = i;
|
||||
|
||||
sql.Clear();
|
||||
sql.Append("INSERT INTO ").
|
||||
Append(this.dbName).Append(".").Append(this.tablePrefix).Append(table).
|
||||
Append(" VALUES");
|
||||
if (recordsPerTable < batchRows)
|
||||
{
|
||||
batchRows = recordsPerTable;
|
||||
}
|
||||
for (int batch = 0; batch < batchRows; ++batch)
|
||||
{
|
||||
long writeTimeStamp = beginTimestamp + i + batch;
|
||||
int rnd = 100;
|
||||
if (this.order == false)
|
||||
{
|
||||
rnd = random.Next(1, 100);
|
||||
if (rnd <= this.rateOfOutorder)
|
||||
{
|
||||
writeTimeStamp = writeTimeStamp + rnd * 10000;
|
||||
DebugPrint("### ");
|
||||
}
|
||||
DebugPrintFormat("order:{0} rnd:{1} timestamp:{2}\n", this.order, rnd, writeTimeStamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugPrintFormat("order:{0} timestamp:{1}\n", this.order, writeTimeStamp);
|
||||
}
|
||||
|
||||
sql.Append("(")
|
||||
.Append(writeTimeStamp)
|
||||
.Append(", 1, -2, -3,")
|
||||
.Append(i + batch - 127)
|
||||
.Append(", -5, -6, -7, 'abc', 'def', 254, 65534,")
|
||||
.Append(4294967294 - (uint)i - (uint)batch)
|
||||
.Append(",")
|
||||
.Append(18446744073709551614 - (ulong)i - (ulong)batch)
|
||||
.Append(")");
|
||||
|
||||
}
|
||||
VerbosePrint(sql.ToString() + "\n");
|
||||
IntPtr res = TDengine.Query(this.conn, sql.ToString());
|
||||
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
|
||||
{
|
||||
Console.Write(sql.ToString() + " failure, ");
|
||||
if (res != IntPtr.Zero) {
|
||||
Console.Write("reason: " + TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
}
|
||||
|
||||
inserted += this.batchRows;
|
||||
|
||||
int affectRows = TDengine.AffectRows(res);
|
||||
rowsInserted += affectRows;
|
||||
|
||||
TDengine.FreeResult(res);
|
||||
if (table == end)
|
||||
{
|
||||
i = inserted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class CreateTableThread
|
||||
{
|
||||
public long id { set; get; }
|
||||
public long start { set; get; }
|
||||
public long end { set; get; }
|
||||
public string dbName { set; get; }
|
||||
public IntPtr conn { set; get; }
|
||||
public string tablePrefix { set; get; }
|
||||
public string stablePrefix { set; get; }
|
||||
public bool verbose { set; get; }
|
||||
public bool debug { set; get; }
|
||||
public bool useStable { set; get; }
|
||||
|
||||
private void VerbosePrintFormat(string format, params object[] parameters)
|
||||
{
|
||||
if (verbose == true)
|
||||
{
|
||||
Console.Write(format, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
private void VerbosePrint(string str)
|
||||
{
|
||||
if (verbose == true)
|
||||
{
|
||||
Console.Write(str);
|
||||
}
|
||||
}
|
||||
|
||||
private void DebugPrintFormat(string format, params object[] parameters)
|
||||
{
|
||||
if (debug == true)
|
||||
{
|
||||
Console.Write(format, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
public void ThreadMain()
|
||||
{
|
||||
VerbosePrintFormat("CreateTable {0} from {1} to {2}\n", id, start, end);
|
||||
|
||||
StringBuilder sql = new StringBuilder();
|
||||
|
||||
for (long tableId = start; tableId <= end; tableId++)
|
||||
{
|
||||
sql.Clear();
|
||||
sql = sql.Append("CREATE TABLE IF NOT EXISTS ").
|
||||
Append(this.dbName).Append(".").Append(this.tablePrefix).Append(tableId);
|
||||
if (useStable == true)
|
||||
{
|
||||
sql = sql.Append(" USING ").Append(this.dbName).Append(".").Append(this.stablePrefix).
|
||||
Append(" TAGS(").Append(tableId).Append(")");
|
||||
}
|
||||
else
|
||||
{
|
||||
sql = sql.Append("(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 float, v7 double, v8 binary(10), v9 nchar(10), v10 tinyint unsigned, v11 smallint unsigned, v12 int unsigned, v13 bigint unsigned)");
|
||||
}
|
||||
IntPtr res = TDengine.Query(this.conn, sql.ToString());
|
||||
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
|
||||
{
|
||||
Console.Write(sql.ToString() + " failure, ");
|
||||
if (res != IntPtr.Zero) {
|
||||
Console.Write("reason: " + TDengine.Error(res));
|
||||
}
|
||||
Console.WriteLine("");
|
||||
CleanAndExitProgram(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerbosePrint(sql.ToString() + " success\n");
|
||||
}
|
||||
TDengine.FreeResult(res);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,268 @@
|
|||
# 如何在 windows环境下使用jdbc进行TDengine应用开发
|
||||
|
||||
本文以windows环境为例,介绍java如何进行TDengine开发应用
|
||||
|
||||
## 环境准备
|
||||
|
||||
(1)安装jdk
|
||||
|
||||
官网下载jdk-1.8,下载页面:https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html
|
||||
|
||||
安装,配置环境变量,把jdk加入到环境变量里。
|
||||
|
||||
命令行内查看java的版本。
|
||||
|
||||
```shell
|
||||
>java -version
|
||||
java version "1.8.0_131"
|
||||
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
|
||||
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
|
||||
```
|
||||
|
||||
|
||||
(2)安装配置maven
|
||||
|
||||
官网下载maven,下载地址:http://maven.apache.org/download.cgi
|
||||
|
||||
配置环境变量MAVEN_HOME,将MAVEN_HOME/bin添加到PATH
|
||||
|
||||
命令行里查看maven的版本
|
||||
|
||||
```shell
|
||||
>mvn --version
|
||||
Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2017-04-04T03:39:06+08:00)
|
||||
Maven home: D:\apache-maven-3.5.0\bin\..
|
||||
Java version: 1.8.0_131, vendor: Oracle Corporation
|
||||
Java home: C:\Program Files\Java\jdk1.8.0_131\jre
|
||||
Default locale: zh_CN, platform encoding: GBK
|
||||
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
|
||||
```
|
||||
|
||||
为了加快maven下载依赖的速度,可以为maven配置mirror,修改MAVEN_HOME\config\settings.xml文件
|
||||
|
||||
```xml
|
||||
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||
<!-- 配置本地maven仓库的路径 -->
|
||||
<localRepository>D:\apache-maven-localRepository</localRepository>
|
||||
|
||||
<mirrors>
|
||||
<!-- 配置阿里云Maven镜像仓库 -->
|
||||
<mirror>
|
||||
<id>alimaven</id>
|
||||
<name>aliyun maven</name>
|
||||
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
|
||||
<mirrorOf>central</mirrorOf>
|
||||
</mirror>
|
||||
</mirrors>
|
||||
|
||||
<profiles>
|
||||
<!-- 配置jdk,maven会默认使用java1.8 -->
|
||||
<profile>
|
||||
<id>jdk-1.8</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
<jdk>1.8</jdk>
|
||||
</activation>
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
</settings>
|
||||
```
|
||||
|
||||
|
||||
|
||||
(3)在linux服务器上安装TDengine-server
|
||||
|
||||
在taosdata官网下载TDengine-server,下载地址:https://www.taosdata.com/cn/all-downloads/
|
||||
|
||||
在linux服务器上安装TDengine-server
|
||||
|
||||
```shell
|
||||
# tar -zxvf package/TDengine-server-2.0.1.1-Linux-x64.tar.gz
|
||||
# cd TDengine-server/
|
||||
# ./install.sh
|
||||
```
|
||||
|
||||
启动taosd
|
||||
|
||||
```shell
|
||||
# systemctl start taosd
|
||||
```
|
||||
|
||||
在server上用taos连接taosd
|
||||
|
||||
```shell
|
||||
# taos
|
||||
taos> show dnodes;
|
||||
id | end_point | vnodes | cores | status | role | create_time |
|
||||
==================================================================================================================
|
||||
1 | td01:6030 | 2 | 4 | ready | any | 2020-08-19 18:40:25.045 |
|
||||
Query OK, 1 row(s) in set (0.005765s)
|
||||
```
|
||||
|
||||
如果可以正确连接到taosd实例,并打印出databases的信息,说明TDengine的server已经正确启动。这里查看server的hostname
|
||||
|
||||
```shell
|
||||
# hostname -f
|
||||
td01
|
||||
```
|
||||
|
||||
注意,如果安装TDengine后,使用默认的taos.cfg配置文件,taosd会使用当前server的hostname创建dnode实例。之后,在client也需要使用这个hostname来连接taosd。
|
||||
|
||||
|
||||
|
||||
(4)在windows上安装TDengine-client
|
||||
|
||||
在taosdata官网下载taos客户端,下载地址:
|
||||
https://www.taosdata.com/cn/all-downloads/
|
||||
下载后,双击exe安装。
|
||||
|
||||
修改client的hosts文件(C:\Windows\System32\drivers\etc\hosts),将server的hostname和ip配置到client的hosts文件中
|
||||
|
||||
```
|
||||
192.168.236.136 td01
|
||||
```
|
||||
|
||||
配置完成后,在命令行内使用taos shell连接server端
|
||||
|
||||
```shell
|
||||
C:\TDengine>taos -h td01
|
||||
Welcome to the TDengine shell from Linux, Client Version:2.0.1.1
|
||||
Copyright (c) 2017 by TAOS Data, Inc. All rights reserved.
|
||||
|
||||
taos> show databases;
|
||||
name | created_time | ntables | vgroups | replica | quorum | days | keep0,keep1,keep(D) | cache(MB) | blocks | minrows | maxrows | wallevel | fsync | comp | precision | status |
|
||||
===================================================================================================================================================================================================================================================================
|
||||
test | 2020-08-19 18:43:50.731 | 1 | 1 | 1 | 1 | 2 | 3650,3650,3650 | 16 | 6 | 100 | 4096 | 1 | 3000 | 2 | ms | ready |
|
||||
log | 2020-08-19 18:40:28.064 | 4 | 1 | 1 | 1 | 10 | 30,30,30 | 1 | 3 | 100 | 4096 | 1 | 3000 | 2 | us | ready |
|
||||
Query OK, 2 row(s) in set (0.068000s)
|
||||
```
|
||||
|
||||
如果windows上的client能够正常连接,并打印database信息,说明client可以正常连接server了。
|
||||
|
||||
|
||||
|
||||
## 应用开发
|
||||
|
||||
(1)新建maven工程,在pom.xml中引入taos-jdbcdriver依赖。
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.taosdata.demo</groupId>
|
||||
<artifactId>JdbcDemo</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>2.0.8</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
```
|
||||
|
||||
(2)使用jdbc查询TDengine数据库
|
||||
|
||||
下面是示例代码:
|
||||
|
||||
```java
|
||||
public class JdbcDemo {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Connection conn = getConn();
|
||||
Statement stmt = conn.createStatement();
|
||||
// create database
|
||||
stmt.executeUpdate("create database if not exists db");
|
||||
// use database
|
||||
stmt.executeUpdate("use db");
|
||||
// create table
|
||||
stmt.executeUpdate("create table if not exists tb (ts timestamp, temperature int, humidity float)");
|
||||
// insert data
|
||||
int affectedRows = stmt.executeUpdate("insert into tb values(now, 23, 10.3) (now + 1s, 20, 9.3)");
|
||||
System.out.println("insert " + affectedRows + " rows.");
|
||||
// query data
|
||||
ResultSet resultSet = stmt.executeQuery("select * from tb");
|
||||
Timestamp ts = null;
|
||||
int temperature = 0;
|
||||
float humidity = 0;
|
||||
while(resultSet.next()){
|
||||
ts = resultSet.getTimestamp(1);
|
||||
temperature = resultSet.getInt(2);
|
||||
humidity = resultSet.getFloat("humidity");
|
||||
System.out.printf("%s, %d, %s\n", ts, temperature, humidity);
|
||||
}
|
||||
}
|
||||
|
||||
public static Connection getConn() throws Exception{
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
String jdbcUrl = "jdbc:TAOS://td01:0/log?user=root&password=taosdata";
|
||||
Properties connProps = new Properties();
|
||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||
Connection conn = DriverManager.getConnection(jdbcUrl, connProps);
|
||||
return conn;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
(3)测试jdbc访问tdengine的sever实例
|
||||
|
||||
console输出:
|
||||
|
||||
```
|
||||
insert 2 rows.
|
||||
2020-08-26 00:06:34.575, 23, 10.3
|
||||
2020-08-26 00:06:35.575, 20, 9.3
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 指南
|
||||
|
||||
(1)如何设置主机名和hosts
|
||||
|
||||
在server上查看hostname和fqdn
|
||||
```shell
|
||||
查看hostname
|
||||
# hostname
|
||||
taos-server
|
||||
|
||||
查看fqdn
|
||||
# hostname -f
|
||||
taos-server
|
||||
```
|
||||
|
||||
windows下hosts文件位于:
|
||||
C:\\Windows\System32\drivers\etc\hosts
|
||||
修改hosts文件,添加server的ip和hostname
|
||||
|
||||
```s
|
||||
192.168.56.101 node5
|
||||
```
|
||||
|
||||
(2)什么是fqdn?
|
||||
|
||||
|
||||
> 什么是FQDN?
|
||||
>
|
||||
> FQDN(Full qualified domain name)全限定域名,fqdn由2部分组成:hostname+domainname。
|
||||
>
|
||||
> 例如,一个邮件服务器的fqdn可能是:mymail.somecollege.edu,其中mymail是hostname(主机名),somcollege.edu是domainname(域名)。本例中,.edu是顶级域名,.somecollege是二级域名。
|
||||
>
|
||||
> 当连接服务器时,必须指定fqdn,然后,dns服务器通过查看dns表,将hostname解析为相应的ip地址。如果只指定hostname(不指定domainname),应用程序可能服务解析主机名。因为如果你试图访问不在本地的远程服务器时,本地的dns服务器和可能没有远程服务器的hostname列表。
|
||||
>
|
||||
> 参考:https://kb.iu.edu/d/aiuv
|
|
@ -0,0 +1,104 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>JDBCDemo</artifactId>
|
||||
<version>SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<project.assembly.dir>src/main/resources/assembly</project.assembly.dir>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>2.0.34</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<executions>
|
||||
<!-- jdbcDemo -->
|
||||
<execution>
|
||||
<id>JdbcDemo</id>
|
||||
<configuration>
|
||||
<finalName>JdbcDemo</finalName>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>com.taosdata.example.JdbcDemo</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
|
||||
<execution>
|
||||
<id>JdbcRestfulDemo</id>
|
||||
<configuration>
|
||||
<finalName>JdbcRestfulDemo</finalName>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>com.taosdata.example.JdbcRestfulDemo</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
|
||||
<execution>
|
||||
<id>SubscribeDemo</id>
|
||||
<configuration>
|
||||
<finalName>SubscribeDemo</finalName>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>com.taosdata.example.SubscribeDemo</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,37 @@
|
|||
# How to Run the JDBC Demo Code On Linux OS
|
||||
TDengine's JDBC demo project is organized in a Maven way so that users can easily compile, package and run the project. If you don't have Maven on your server, you may install it using
|
||||
```
|
||||
sudo apt-get install maven
|
||||
```
|
||||
|
||||
## Install TDengine Client
|
||||
Make sure you have already installed a tdengine client on your current develop environment.
|
||||
Download the tdengine package on our website: ``https://www.taosdata.com/cn/all-downloads/`` and install the client.
|
||||
|
||||
## Run jdbcDemo using mvn plugin
|
||||
run command:
|
||||
```
|
||||
mvn clean compile exec:java -Dexec.mainClass="com.taosdata.example.JdbcDemo"
|
||||
```
|
||||
|
||||
and run with your customed args
|
||||
```
|
||||
mvn clean compile exec:java -Dexec.mainClass="com.taosdata.example.JdbcDemo" -Dexec.args="-host [HOSTNAME]"
|
||||
```
|
||||
|
||||
## Compile the Demo Code and Run It
|
||||
To compile taos-jdbcdriver, go to the source directory ``TDengine/src/connector/jdbc`` and execute
|
||||
```
|
||||
mvn clean package -Dmaven.test.skip=true
|
||||
```
|
||||
|
||||
To compile the demo project, go to the source directory ``TDengine/tests/examples/JDBC/JDBCDemo`` and execute
|
||||
```
|
||||
mvn clean package assembly:single
|
||||
```
|
||||
|
||||
To run JDBCDemo.jar, go to ``TDengine/tests/examples/JDBC/JDBCDemo`` and execute
|
||||
```
|
||||
java -Djava.ext.dirs=../../../../src/connector/jdbc/target:$JAVA_HOME/jre/lib/ext -jar target/JDBCDemo-SNAPSHOT-jar-with-dependencies.jar -host [HOSTNAME]
|
||||
```
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
package com.taosdata.example;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class JdbcDemo {
|
||||
private static String host;
|
||||
private static final String dbName = "test";
|
||||
private static final String tbName = "weather";
|
||||
private static final String user = "root";
|
||||
private static final String password = "taosdata";
|
||||
|
||||
private Connection connection;
|
||||
|
||||
public static void main(String[] args) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if ("-host".equalsIgnoreCase(args[i]) && i < args.length - 1)
|
||||
host = args[++i];
|
||||
}
|
||||
if (host == null) {
|
||||
printHelp();
|
||||
}
|
||||
JdbcDemo demo = new JdbcDemo();
|
||||
demo.init();
|
||||
demo.createDatabase();
|
||||
demo.useDatabase();
|
||||
demo.dropTable();
|
||||
demo.createTable();
|
||||
demo.insert();
|
||||
demo.select();
|
||||
demo.dropTable();
|
||||
demo.close();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
final String url = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password;
|
||||
// get connection
|
||||
try {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("charset", "UTF-8");
|
||||
properties.setProperty("locale", "en_US.UTF-8");
|
||||
properties.setProperty("timezone", "UTC-8");
|
||||
System.out.println("get connection starting...");
|
||||
connection = DriverManager.getConnection(url, properties);
|
||||
if (connection != null)
|
||||
System.out.println("[ OK ] Connection established.");
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void createDatabase() {
|
||||
String sql = "create database if not exists " + dbName;
|
||||
exuete(sql);
|
||||
}
|
||||
|
||||
private void useDatabase() {
|
||||
String sql = "use " + dbName;
|
||||
exuete(sql);
|
||||
}
|
||||
|
||||
private void dropTable() {
|
||||
final String sql = "drop table if exists " + dbName + "." + tbName + "";
|
||||
exuete(sql);
|
||||
}
|
||||
|
||||
private void createTable() {
|
||||
final String sql = "create table if not exists " + dbName + "." + tbName + " (ts timestamp, temperature float, humidity int)";
|
||||
exuete(sql);
|
||||
}
|
||||
|
||||
private void insert() {
|
||||
final String sql = "insert into " + dbName + "." + tbName + " (ts, temperature, humidity) values(now, 20.5, 34)";
|
||||
exuete(sql);
|
||||
}
|
||||
|
||||
private void select() {
|
||||
final String sql = "select * from " + dbName + "." + tbName;
|
||||
executeQuery(sql);
|
||||
}
|
||||
|
||||
private void close() {
|
||||
try {
|
||||
if (connection != null) {
|
||||
this.connection.close();
|
||||
System.out.println("connection closed.");
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void executeQuery(String sql) {
|
||||
long start = System.currentTimeMillis();
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
ResultSet resultSet = statement.executeQuery(sql);
|
||||
long end = System.currentTimeMillis();
|
||||
printSql(sql, true, (end - start));
|
||||
printResult(resultSet);
|
||||
} catch (SQLException e) {
|
||||
long end = System.currentTimeMillis();
|
||||
printSql(sql, false, (end - start));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void printResult(ResultSet resultSet) throws SQLException {
|
||||
ResultSetMetaData metaData = resultSet.getMetaData();
|
||||
while (resultSet.next()) {
|
||||
for (int i = 1; i <= metaData.getColumnCount(); i++) {
|
||||
String columnLabel = metaData.getColumnLabel(i);
|
||||
String value = resultSet.getString(i);
|
||||
System.out.printf("%s: %s\t", columnLabel, value);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
private void printSql(String sql, boolean succeed, long cost) {
|
||||
System.out.println("[ " + (succeed ? "OK" : "ERROR!") + " ] time cost: " + cost + " ms, execute statement ====> " + sql);
|
||||
}
|
||||
|
||||
private void exuete(String sql) {
|
||||
long start = System.currentTimeMillis();
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
boolean execute = statement.execute(sql);
|
||||
long end = System.currentTimeMillis();
|
||||
printSql(sql, true, (end - start));
|
||||
} catch (SQLException e) {
|
||||
long end = System.currentTimeMillis();
|
||||
printSql(sql, false, (end - start));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void printHelp() {
|
||||
System.out.println("Usage: java -jar JDBCDemo.jar -host <hostname>");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.taosdata.example;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class JdbcRestfulDemo {
|
||||
private static final String host = "localhost";
|
||||
private static final String dbname = "test";
|
||||
private static final String user = "root";
|
||||
private static final String password = "taosdata";
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
// use port 6041 in url when use JDBC-restful
|
||||
String url = "jdbc:TAOS-RS://" + host + ":6041/?user=" + user + "&password=" + password;
|
||||
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("charset", "UTF-8");
|
||||
properties.setProperty("locale", "en_US.UTF-8");
|
||||
properties.setProperty("timezone", "UTC-8");
|
||||
|
||||
Connection conn = DriverManager.getConnection(url, properties);
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
stmt.execute("drop database if exists " + dbname);
|
||||
stmt.execute("create database if not exists " + dbname);
|
||||
stmt.execute("use " + dbname);
|
||||
stmt.execute("create table " + dbname + ".weather(ts timestamp, temperature float) tags(location nchar(64))");
|
||||
stmt.executeUpdate("insert into t1 using " + dbname + ".weather tags('北京') values(now, 18.2)");
|
||||
ResultSet rs = stmt.executeQuery("select * from " + dbname + ".weather");
|
||||
ResultSetMetaData meta = rs.getMetaData();
|
||||
while (rs.next()) {
|
||||
for (int i = 1; i <= meta.getColumnCount(); i++) {
|
||||
System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
rs.close();
|
||||
stmt.close();
|
||||
conn.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package com.taosdata.example;
|
||||
|
||||
import com.taosdata.jdbc.TSDBConnection;
|
||||
import com.taosdata.jdbc.TSDBDriver;
|
||||
import com.taosdata.jdbc.TSDBResultSet;
|
||||
import com.taosdata.jdbc.TSDBSubscribe;
|
||||
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class SubscribeDemo {
|
||||
private static final String usage = "java -jar SubscribeDemo.jar -host <hostname> -database <database name> -topic <topic> -sql <sql>";
|
||||
|
||||
public static void main(String[] args) {
|
||||
// parse args from command line
|
||||
String host = "", database = "", topic = "", sql = "";
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if ("-host".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
host = args[++i];
|
||||
}
|
||||
if ("-database".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
database = args[++i];
|
||||
}
|
||||
if ("-topic".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
topic = args[++i];
|
||||
}
|
||||
if ("-sql".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
sql = args[++i];
|
||||
}
|
||||
}
|
||||
if (host.isEmpty() || database.isEmpty() || topic.isEmpty() || sql.isEmpty()) {
|
||||
System.out.println(usage);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
||||
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||
final String url = "jdbc:TAOS://" + host + ":6030/" + database + "?user=root&password=taosdata";
|
||||
// get TSDBConnection
|
||||
TSDBConnection connection = (TSDBConnection) DriverManager.getConnection(url, properties);
|
||||
// create TSDBSubscribe
|
||||
TSDBSubscribe sub = connection.subscribe(topic, sql, false);
|
||||
|
||||
int total = 0;
|
||||
while (true) {
|
||||
TSDBResultSet rs = sub.consume();
|
||||
int count = 0;
|
||||
ResultSetMetaData meta = rs.getMetaData();
|
||||
while (rs.next()) {
|
||||
for (int i = 1; i <= meta.getColumnCount(); i++) {
|
||||
System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t");
|
||||
}
|
||||
System.out.println();
|
||||
count++;
|
||||
}
|
||||
total += count;
|
||||
// System.out.printf("%d rows consumed, total %d\n", count, total);
|
||||
if (total >= 10)
|
||||
break;
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
}
|
||||
sub.close(false);
|
||||
connection.close();
|
||||
} catch (Exception e) {
|
||||
System.out.println("host: " + host + ", database: " + database + ", topic: " + topic + ", sql: " + sql);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
HELP.md
|
||||
target/
|
||||
.mvn/
|
||||
!**/src/main/**
|
||||
!**/src/test/**
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
|
@ -0,0 +1,91 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>SpringJdbcTemplate</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<name>SpringJdbcTemplate</name>
|
||||
<url>http://www.taosdata.com</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>5.2.8.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
<version>5.1.9.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>5.1.9.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>2.0.18</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>com.taosdata.example.jdbcTemplate.App</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
## TDengine Spring JDBC Template Demo
|
||||
|
||||
`Spring JDBC Template` 简化了原生 JDBC Connection 获取释放等操作,使得操作数据库更加方便。
|
||||
|
||||
### 配置
|
||||
|
||||
修改 `src/main/resources/applicationContext.xml` 文件中 TDengine 的配置信息:
|
||||
|
||||
```xml
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="com.taosdata.jdbc.TSDBDriver"></property>
|
||||
<property name="url" value="jdbc:TAOS://127.0.0.1:6030/log"></property>
|
||||
<property name="username" value="root"></property>
|
||||
<property name="password" value="taosdata"></property>
|
||||
</bean>
|
||||
|
||||
<bean id = "jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
|
||||
<property name="dataSource" ref = "dataSource" ></property>
|
||||
</bean>
|
||||
```
|
||||
|
||||
### 打包运行
|
||||
|
||||
进入 `TDengine/tests/examples/JDBC/SpringJdbcTemplate` 目录下,执行以下命令可以生成可执行 jar 包。
|
||||
```shell
|
||||
mvn clean package
|
||||
```
|
||||
打包成功之后,进入 `target/` 目录下,执行以下命令就可运行测试:
|
||||
```shell
|
||||
java -jar SpringJdbcTemplate-1.0-SNAPSHOT-jar-with-dependencies.jar
|
||||
```
|
|
@ -0,0 +1,48 @@
|
|||
package com.taosdata.example.jdbcTemplate;
|
||||
|
||||
|
||||
import com.taosdata.example.jdbcTemplate.dao.ExecuteAsStatement;
|
||||
import com.taosdata.example.jdbcTemplate.dao.WeatherDao;
|
||||
import com.taosdata.example.jdbcTemplate.domain.Weather;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class App {
|
||||
|
||||
private static Random random = new Random(System.currentTimeMillis());
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
|
||||
|
||||
ExecuteAsStatement executor = ctx.getBean(ExecuteAsStatement.class);
|
||||
// drop database
|
||||
executor.doExecute("drop database if exists test");
|
||||
// create database
|
||||
executor.doExecute("create database if not exists test");
|
||||
//use database
|
||||
executor.doExecute("use test");
|
||||
// create table
|
||||
executor.doExecute("create table if not exists test.weather (ts timestamp, temperature int, humidity float)");
|
||||
|
||||
WeatherDao weatherDao = ctx.getBean(WeatherDao.class);
|
||||
Weather weather = new Weather(new Timestamp(new Date().getTime()), random.nextFloat() * 50.0f, random.nextInt(100));
|
||||
// insert rows
|
||||
int affectedRows = weatherDao.add(weather);
|
||||
System.out.println("insert success " + affectedRows + " rows.");
|
||||
|
||||
// query for list
|
||||
int limit = 10, offset = 0;
|
||||
List<Weather> weatherList = weatherDao.queryForList(limit, offset);
|
||||
for (Weather w : weatherList) {
|
||||
System.out.println(w);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package com.taosdata.example.jdbcTemplate.dao;
|
||||
|
||||
public interface ExecuteAsStatement{
|
||||
|
||||
void doExecute(String sql);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.taosdata.example.jdbcTemplate.dao;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
|
||||
@Repository
|
||||
public class ExecuteAsStatementImpl implements ExecuteAsStatement {
|
||||
|
||||
@Autowired
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Override
|
||||
public void doExecute(String sql) {
|
||||
jdbcTemplate.execute(sql);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.taosdata.example.jdbcTemplate.dao;
|
||||
|
||||
import com.taosdata.example.jdbcTemplate.domain.Weather;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface WeatherDao {
|
||||
|
||||
|
||||
int add(Weather weather);
|
||||
|
||||
int[] batchInsert(List<Weather> weatherList);
|
||||
|
||||
List<Weather> queryForList(int limit, int offset);
|
||||
|
||||
int count();
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.taosdata.example.jdbcTemplate.dao;
|
||||
|
||||
import com.taosdata.example.jdbcTemplate.domain.Weather;
|
||||
import com.taosdata.example.jdbcTemplate.dao.WeatherDao;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class WeatherDaoImpl implements WeatherDao {
|
||||
|
||||
@Autowired
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Override
|
||||
public int add(Weather weather) {
|
||||
return jdbcTemplate.update(
|
||||
"insert into test.weather(ts, temperature, humidity) VALUES(?,?,?)",
|
||||
weather.getTs(), weather.getTemperature(), weather.getHumidity()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] batchInsert(List<Weather> weatherList) {
|
||||
return jdbcTemplate.batchUpdate("insert into test.weather(ts, temperature, humidity) values( ?, ?, ?)", new BatchPreparedStatementSetter() {
|
||||
@Override
|
||||
public void setValues(PreparedStatement ps, int i) throws SQLException {
|
||||
ps.setTimestamp(1, weatherList.get(i).getTs());
|
||||
ps.setFloat(2, weatherList.get(i).getTemperature());
|
||||
ps.setInt(3, weatherList.get(i).getHumidity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBatchSize() {
|
||||
return weatherList.size();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Weather> queryForList(int limit, int offset) {
|
||||
return jdbcTemplate.query("select * from test.weather limit ? offset ?", (rs, rowNum) -> {
|
||||
Timestamp ts = rs.getTimestamp("ts");
|
||||
float temperature = rs.getFloat("temperature");
|
||||
int humidity = rs.getInt("humidity");
|
||||
return new Weather(ts, temperature, humidity);
|
||||
}, limit, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int count() {
|
||||
return jdbcTemplate.queryForObject("select count(*) from test.weather", Integer.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.taosdata.example.jdbcTemplate.domain;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
public class Weather {
|
||||
|
||||
private Timestamp ts;
|
||||
private float temperature;
|
||||
private int humidity;
|
||||
|
||||
public Weather() {
|
||||
}
|
||||
|
||||
public Weather(Timestamp ts, float temperature, int humidity) {
|
||||
this.ts = ts;
|
||||
this.temperature = temperature;
|
||||
this.humidity = humidity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Weather{" +
|
||||
"ts=" + ts +
|
||||
", temperature=" + temperature +
|
||||
", humidity=" + humidity +
|
||||
'}';
|
||||
}
|
||||
|
||||
public Timestamp getTs() {
|
||||
return ts;
|
||||
}
|
||||
|
||||
public void setTs(Timestamp ts) {
|
||||
this.ts = ts;
|
||||
}
|
||||
|
||||
public float getTemperature() {
|
||||
return temperature;
|
||||
}
|
||||
|
||||
public void setTemperature(float temperature) {
|
||||
this.temperature = temperature;
|
||||
}
|
||||
|
||||
public int getHumidity() {
|
||||
return humidity;
|
||||
}
|
||||
|
||||
public void setHumidity(int humidity) {
|
||||
this.humidity = humidity;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
|
||||
default-autowire="byName">
|
||||
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="com.taosdata.jdbc.TSDBDriver"></property>
|
||||
<property name="url" value="jdbc:TAOS://127.0.0.1:6030/"></property>
|
||||
<property name="username" value="root"></property>
|
||||
<property name="password" value="taosdata"></property>
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
|
||||
<property name="dataSource" ref="dataSource"></property>
|
||||
</bean>
|
||||
|
||||
<context:component-scan base-package="com.taosdata.example.jdbcTemplate"/>
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,64 @@
|
|||
package com.taosdata.example.jdbcTemplate;
|
||||
|
||||
|
||||
import com.taosdata.example.jdbcTemplate.dao.ExecuteAsStatement;
|
||||
import com.taosdata.example.jdbcTemplate.dao.WeatherDao;
|
||||
import com.taosdata.example.jdbcTemplate.domain.Weather;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration({"classpath:applicationContext.xml"})
|
||||
public class BatcherInsertTest {
|
||||
|
||||
|
||||
@Autowired
|
||||
private WeatherDao weatherDao;
|
||||
@Autowired
|
||||
private ExecuteAsStatement executor;
|
||||
|
||||
private static final int numOfRecordsPerTable = 1000;
|
||||
private static long ts = 1496732686000l;
|
||||
private static Random random = new Random(System.currentTimeMillis());
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
// drop database
|
||||
executor.doExecute("drop database if exists test");
|
||||
// create database
|
||||
executor.doExecute("create database if not exists test");
|
||||
//use database
|
||||
executor.doExecute("use test");
|
||||
// create table
|
||||
executor.doExecute("create table if not exists test.weather (ts timestamp, temperature int, humidity float)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void batchInsert() {
|
||||
List<Weather> weatherList = new ArrayList<>();
|
||||
for (int i = 0; i < numOfRecordsPerTable; i++) {
|
||||
ts += 1000;
|
||||
Weather weather = new Weather(new Timestamp(ts), random.nextFloat() * 50.0f, random.nextInt(100));
|
||||
weatherList.add(weather);
|
||||
}
|
||||
long start = System.currentTimeMillis();
|
||||
weatherDao.batchInsert(weatherList);
|
||||
long end = System.currentTimeMillis();
|
||||
System.out.println("batch insert(" + numOfRecordsPerTable + " rows) time cost ==========> " + (end - start) + " ms");
|
||||
|
||||
int count = weatherDao.count();
|
||||
assertEquals(count, numOfRecordsPerTable);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
这个example中,我们适配了java常见的连接池:
|
||||
* HikariCP(默认)
|
||||
* druid
|
||||
* dbcp
|
||||
* c3p0
|
||||
|
||||
### 说明
|
||||
ConnectionPoolDemo的程序逻辑:
|
||||
1. 创建到host的connection连接池
|
||||
2. 创建名称为pool_test的database,创建表超级weather,创建tableSize个子表
|
||||
3. 总共插入totalNumber条数据。
|
||||
|
||||
### 如何运行这个例子:
|
||||
|
||||
```shell script
|
||||
mvn clean package assembly:single
|
||||
java -jar target/connectionPools-1.0-SNAPSHOT-jar-with-dependencies.jar -host 127.0.0.1
|
||||
```
|
||||
使用mvn运行ConnectionPoolDemo的main方法,可以指定参数
|
||||
```shell script
|
||||
Usage:
|
||||
java -jar target/connectionPools-1.0-SNAPSHOT-jar-with-dependencies.jar
|
||||
-host : hostname
|
||||
-poolType <c3p0| dbcp| druid| hikari>
|
||||
-poolSize <poolSize>
|
||||
-tableSize <tableSize>
|
||||
-batchSize : 每条Insert SQL中values的数量
|
||||
-sleep : 每次插入任务提交后的
|
||||
```
|
||||
|
||||
### 日志
|
||||
使用log4j,将日志和错误分别输出到了debug.log和error.log中
|
|
@ -0,0 +1,116 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<groupId>com.taosdata.demo</groupId>
|
||||
<artifactId>connectionPools</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<dependencies>
|
||||
<!-- taos -->
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>2.0.18</version>
|
||||
</dependency>
|
||||
<!-- druid -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.1.17</version>
|
||||
</dependency>
|
||||
<!-- HikariCP -->
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>3.2.0</version>
|
||||
</dependency>
|
||||
<!-- dbcp Connection Pool -->
|
||||
<dependency>
|
||||
<groupId>commons-pool</groupId>
|
||||
<artifactId>commons-pool</artifactId>
|
||||
<version>1.5.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-dbcp</groupId>
|
||||
<artifactId>commons-dbcp</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<!-- c3p0 -->
|
||||
<dependency>
|
||||
<groupId>com.mchange</groupId>
|
||||
<artifactId>c3p0</artifactId>
|
||||
<version>0.9.5.4</version>
|
||||
</dependency>
|
||||
<!-- log4j -->
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.14.1</version>
|
||||
</dependency>
|
||||
<!-- proxool -->
|
||||
<dependency>
|
||||
<groupId>com.cloudhopper.proxool</groupId>
|
||||
<artifactId>proxool</artifactId>
|
||||
<version>0.9.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>ConnectionPoolDemo</id>
|
||||
<configuration>
|
||||
<finalName>ConnectionPoolDemo</finalName>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>com.taosdata.example.ConnectionPoolDemo</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
|
||||
<execution>
|
||||
<id>ProxoolDemo</id>
|
||||
<configuration>
|
||||
<finalName>ProxoolDemo</finalName>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>com.taosdata.example.ProxoolDemo</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,137 @@
|
|||
package com.taosdata.example;
|
||||
|
||||
import com.taosdata.example.common.InsertTask;
|
||||
import com.taosdata.example.pool.C3p0Builder;
|
||||
import com.taosdata.example.pool.DbcpBuilder;
|
||||
import com.taosdata.example.pool.DruidPoolBuilder;
|
||||
import com.taosdata.example.pool.HikariCpBuilder;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ConnectionPoolDemo {
|
||||
|
||||
private static Logger logger = LogManager.getLogger(DruidPoolBuilder.class);
|
||||
private static final String dbName = "pool_test";
|
||||
|
||||
private static String poolType = "hikari";
|
||||
private static long totalSize = 1_000_000l;
|
||||
private static long tableSize = 1;
|
||||
private static long batchSize = 1;
|
||||
|
||||
private static int poolSize = 50;
|
||||
private static int threadCount = 50;
|
||||
private static int sleep = 0;
|
||||
|
||||
public static void main(String[] args) {
|
||||
String host = null;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if ("-host".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
host = args[++i];
|
||||
}
|
||||
if ("-poolType".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
poolType = args[++i];
|
||||
}
|
||||
if ("-recordNumber".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
totalSize = Long.parseLong(args[++i]);
|
||||
}
|
||||
if ("-tableNumber".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
tableSize = Long.parseLong(args[++i]);
|
||||
}
|
||||
if ("-batchNumber".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
batchSize = Long.parseLong(args[++i]);
|
||||
}
|
||||
|
||||
}
|
||||
if (host == null) {
|
||||
System.out.println("Usage: java -jar XXX.jar -host <hostname> " +
|
||||
"-poolType <c3p0| dbcp| druid| hikari>" +
|
||||
"-recordNumber <number> " +
|
||||
"-tableNumber <number> " +
|
||||
"-batchNumber <number> " +
|
||||
"-sleep <number> "
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
DataSource dataSource;
|
||||
switch (poolType) {
|
||||
case "c3p0":
|
||||
dataSource = C3p0Builder.getDataSource(host, poolSize);
|
||||
break;
|
||||
case "dbcp":
|
||||
dataSource = DbcpBuilder.getDataSource(host, poolSize);
|
||||
break;
|
||||
case "druid":
|
||||
dataSource = DruidPoolBuilder.getDataSource(host, poolSize);
|
||||
break;
|
||||
case "hikari":
|
||||
default:
|
||||
dataSource = HikariCpBuilder.getDataSource(host, poolSize);
|
||||
poolType = "hikari";
|
||||
}
|
||||
|
||||
logger.info(">>>>>>>>>>>>>> connection pool Type: " + poolType);
|
||||
init(dataSource);
|
||||
|
||||
// try {
|
||||
// Connection connection = dataSource.getConnection();
|
||||
// Statement statement = connection.createStatement();
|
||||
// String sql = "insert into " + dbName + ".t_1 values('2020-01-01 00:00:00.000',12.12,111)";
|
||||
// int affectRows = statement.executeUpdate(sql);
|
||||
// System.out.println("affectRows >>> " + affectRows);
|
||||
// affectRows = statement.executeUpdate(sql);
|
||||
// System.out.println("affectRows >>> " + affectRows);
|
||||
// statement.close();
|
||||
// connection.close();
|
||||
// } catch (SQLException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
|
||||
for (long i = 0; i < totalSize / tableSize / batchSize; i++) {
|
||||
executor.execute(new InsertTask(dataSource, dbName, tableSize, batchSize));
|
||||
// sleep few seconds
|
||||
try {
|
||||
if (sleep > 0)
|
||||
TimeUnit.MILLISECONDS.sleep(sleep);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
executor.shutdown();
|
||||
|
||||
}
|
||||
|
||||
private static void init(DataSource dataSource) {
|
||||
try (Connection conn = dataSource.getConnection()) {
|
||||
execute(conn, "drop database if exists " + dbName + "");
|
||||
execute(conn, "create database if not exists " + dbName + "");
|
||||
execute(conn, "use " + dbName + "");
|
||||
execute(conn, "create table weather(ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int)");
|
||||
for (int tb_ind = 1; tb_ind <= tableSize; tb_ind++) {
|
||||
execute(conn, "create table t_" + tb_ind + " using weather tags('beijing'," + (tb_ind + 1) + ")");
|
||||
}
|
||||
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>> init finished.");
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void execute(Connection con, String sql) {
|
||||
try (Statement stmt = con.createStatement()) {
|
||||
stmt.executeUpdate(sql);
|
||||
logger.info("SQL >>> " + sql);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.taosdata.example;
|
||||
|
||||
import org.logicalcobwebs.proxool.ProxoolException;
|
||||
import org.logicalcobwebs.proxool.configuration.JAXPConfigurator;
|
||||
|
||||
import java.sql.*;
|
||||
|
||||
public class ProxoolDemo {
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
String xml = parseConfigurationXml(args);
|
||||
if (xml == null) {
|
||||
printHelp();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
try {
|
||||
JAXPConfigurator.configure(xml, false);
|
||||
Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
|
||||
Connection connection = DriverManager.getConnection("proxool.ds");
|
||||
|
||||
Statement stmt = connection.createStatement();
|
||||
|
||||
ResultSet rs = stmt.executeQuery("show databases");
|
||||
ResultSetMetaData metaData = rs.getMetaData();
|
||||
while (rs.next()) {
|
||||
for (int i = 1; i <= metaData.getColumnCount(); i++) {
|
||||
System.out.print(metaData.getColumnLabel(i) + ": " + rs.getString(i));
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
stmt.close();
|
||||
|
||||
} catch (ClassNotFoundException | SQLException | ProxoolException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static String parseConfigurationXml(String[] args) {
|
||||
String host = null;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if ("--xml".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
host = args[++i];
|
||||
}
|
||||
}
|
||||
return host;
|
||||
}
|
||||
|
||||
private static void printHelp() {
|
||||
System.out.println("Usage: java -jar ProxoolDemo.jar --xml [xml]");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package com.taosdata.example.common;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Random;
|
||||
|
||||
public class InsertTask implements Runnable {
|
||||
private final Random random = new Random(System.currentTimeMillis());
|
||||
private static final Logger logger = LogManager.getLogger(InsertTask.class);
|
||||
|
||||
private final DataSource ds;
|
||||
private final String dbName;
|
||||
private final long tableSize;
|
||||
private final long batchSize;
|
||||
|
||||
public InsertTask(DataSource ds, String dbName, long tableSize, long batchSize) {
|
||||
this.ds = ds;
|
||||
this.dbName = dbName;
|
||||
this.tableSize = tableSize;
|
||||
this.batchSize = batchSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
int affectedRows = 0;
|
||||
long start = System.currentTimeMillis();
|
||||
try (Connection conn = ds.getConnection(); Statement stmt = conn.createStatement()) {
|
||||
for (int tb_index = 1; tb_index <= tableSize; tb_index++) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("insert into ").append(dbName).append(".t_").append(tb_index).append("(ts, temperature, humidity) values ");
|
||||
for (int i = 0; i < batchSize; i++) {
|
||||
sb.append("(").append(start + i).append(", ").append(random.nextFloat() * 30).append(", ").append(random.nextInt(70)).append(") ");
|
||||
}
|
||||
logger.info("SQL >>> " + sb.toString());
|
||||
affectedRows += stmt.executeUpdate(sb.toString());
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
logger.info(">>> affectedRows:" + affectedRows + " TimeCost:" + (System.currentTimeMillis() - start) + " ms");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.taosdata.example.pool;
|
||||
|
||||
import com.mchange.v2.c3p0.ComboPooledDataSource;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.beans.PropertyVetoException;
|
||||
|
||||
public class C3p0Builder {
|
||||
|
||||
public static DataSource getDataSource(String host, int poolSize) {
|
||||
ComboPooledDataSource ds = new ComboPooledDataSource();
|
||||
|
||||
try {
|
||||
ds.setDriverClass("com.taosdata.jdbc.TSDBDriver");
|
||||
} catch (PropertyVetoException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ds.setJdbcUrl("jdbc:TAOS://" + host + ":6030");
|
||||
ds.setUser("root");
|
||||
ds.setPassword("taosdata");
|
||||
|
||||
ds.setMinPoolSize(poolSize);
|
||||
ds.setMaxPoolSize(poolSize);
|
||||
ds.setAcquireIncrement(5);
|
||||
return ds;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.taosdata.example.pool;
|
||||
|
||||
import org.apache.commons.dbcp.BasicDataSource;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
public class DbcpBuilder {
|
||||
|
||||
public static DataSource getDataSource(String host, int poolSize) {
|
||||
BasicDataSource ds = new BasicDataSource();
|
||||
ds.setDriverClassName("com.taosdata.jdbc.TSDBDriver");
|
||||
ds.setUrl("jdbc:TAOS://" + host + ":6030");
|
||||
ds.setUsername("root");
|
||||
ds.setPassword("taosdata");
|
||||
|
||||
ds.setMaxActive(poolSize);
|
||||
ds.setMinIdle(poolSize);
|
||||
ds.setInitialSize(poolSize);
|
||||
return ds;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.taosdata.example.pool;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
public class DruidPoolBuilder {
|
||||
|
||||
public static DataSource getDataSource(String host, int poolSize) {
|
||||
final String url = "jdbc:TAOS://" + host + ":6030";
|
||||
|
||||
DruidDataSource dataSource = new DruidDataSource();
|
||||
// jdbc properties
|
||||
dataSource.setDriverClassName("com.taosdata.jdbc.TSDBDriver");
|
||||
dataSource.setUrl(url);
|
||||
dataSource.setUsername("root");
|
||||
dataSource.setPassword("taosdata");
|
||||
// pool configurations
|
||||
dataSource.setInitialSize(poolSize);
|
||||
dataSource.setMinIdle(poolSize);
|
||||
dataSource.setMaxActive(poolSize);
|
||||
dataSource.setMaxWait(30000);
|
||||
dataSource.setValidationQuery("select server_status()");
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.taosdata.example.pool;
|
||||
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
public class HikariCpBuilder {
|
||||
|
||||
public static DataSource getDataSource(String host, int poolSize) {
|
||||
HikariConfig config = new HikariConfig();
|
||||
// jdbc properties
|
||||
config.setDriverClassName("com.taosdata.jdbc.TSDBDriver");
|
||||
config.setJdbcUrl("jdbc:TAOS://" + host + ":6030");
|
||||
config.setUsername("root");
|
||||
config.setPassword("taosdata");
|
||||
// pool configurations
|
||||
config.setMinimumIdle(poolSize); //minimum number of idle connection
|
||||
config.setMaximumPoolSize(poolSize); //maximum number of connection in the pool
|
||||
config.setConnectionTimeout(30000); //maximum wait milliseconds for get connection from pool
|
||||
config.setMaxLifetime(0); // maximum life time for each connection
|
||||
config.setIdleTimeout(0); // max idle time for recycle idle connection
|
||||
config.setConnectionTestQuery("select server_status()"); //validation query
|
||||
|
||||
HikariDataSource ds = new HikariDataSource(config);
|
||||
return ds;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
### 设置###
|
||||
log4j.rootLogger=debug,stdout,DebugLog,ErrorLog
|
||||
### 输出信息到控制抬 ###
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.Target=System.out
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
|
||||
### 输出DEBUG 级别以上的日志到=logs/debug.log
|
||||
log4j.appender.DebugLog=org.apache.log4j.DailyRollingFileAppender
|
||||
log4j.appender.DebugLog.File=logs/debug.log
|
||||
log4j.appender.DebugLog.Append=true
|
||||
log4j.appender.DebugLog.Threshold=DEBUG
|
||||
log4j.appender.DebugLog.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.DebugLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
|
||||
### 输出ERROR 级别以上的日志到=logs/error.log
|
||||
log4j.appender.ErrorLog=org.apache.log4j.DailyRollingFileAppender
|
||||
log4j.appender.ErrorLog.File=logs/error.log
|
||||
log4j.appender.ErrorLog.Append=true
|
||||
log4j.appender.ErrorLog.Threshold=ERROR
|
||||
log4j.appender.ErrorLog.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.ErrorLog.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<something-else-entirely>
|
||||
<proxool>
|
||||
<alias>ds</alias>
|
||||
<!--数据源的别名-->
|
||||
<driver-url>jdbc:TAOS-RS://127.0.0.1:6041/log</driver-url>
|
||||
<!--url连接串-->
|
||||
<driver-class>com.taosdata.jdbc.rs.RestfulDriver</driver-class>
|
||||
<!--驱动类-->
|
||||
<driver-properties>
|
||||
<property name="user" value="root"/>
|
||||
<property name="password" value="taosdata"/>
|
||||
</driver-properties>
|
||||
<!--最大连接数(默认5个),超过了这个连接数,再有请求时,就排在队列中等候,最大的等待请求数由maximum-new-connections决定 -->
|
||||
<maximum-connection-count>100</maximum-connection-count>
|
||||
<!-- 定义连接池中的最大连接数 -->
|
||||
<maximum-active-time>100</maximum-active-time>
|
||||
<!--最少保持的空闲连接数(默认2个)-->
|
||||
<prototype-count>1</prototype-count>
|
||||
<!--最小连接数(默认2个)-->
|
||||
<minimum-connection-count>5</minimum-connection-count>
|
||||
<!--proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁 默认30秒-->
|
||||
<house-keeping-sleep-time>30000</house-keeping-sleep-time>
|
||||
<!--用于保持连接的测试语句 -->
|
||||
<house-keeping-test-sql>select server_status()</house-keeping-test-sql>
|
||||
</proxool>
|
||||
</something-else-entirely>
|
|
@ -0,0 +1,33 @@
|
|||
README.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright 2007-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.nio.channels.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class MavenWrapperDownloader {
|
||||
|
||||
private static final String WRAPPER_VERSION = "0.5.6";
|
||||
/**
|
||||
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
|
||||
*/
|
||||
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
|
||||
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
|
||||
|
||||
/**
|
||||
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
|
||||
* use instead of the default one.
|
||||
*/
|
||||
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
|
||||
".mvn/wrapper/maven-wrapper.properties";
|
||||
|
||||
/**
|
||||
* Path where the maven-wrapper.jar will be saved to.
|
||||
*/
|
||||
private static final String MAVEN_WRAPPER_JAR_PATH =
|
||||
".mvn/wrapper/maven-wrapper.jar";
|
||||
|
||||
/**
|
||||
* Name of the property which should be used to override the default download url for the wrapper.
|
||||
*/
|
||||
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
|
||||
|
||||
public static void main(String args[]) {
|
||||
System.out.println("- Downloader started");
|
||||
File baseDirectory = new File(args[0]);
|
||||
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
|
||||
|
||||
// If the maven-wrapper.properties exists, read it and check if it contains a custom
|
||||
// wrapperUrl parameter.
|
||||
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
|
||||
String url = DEFAULT_DOWNLOAD_URL;
|
||||
if (mavenWrapperPropertyFile.exists()) {
|
||||
FileInputStream mavenWrapperPropertyFileInputStream = null;
|
||||
try {
|
||||
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
|
||||
Properties mavenWrapperProperties = new Properties();
|
||||
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
|
||||
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
|
||||
} catch (IOException e) {
|
||||
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
|
||||
} finally {
|
||||
try {
|
||||
if (mavenWrapperPropertyFileInputStream != null) {
|
||||
mavenWrapperPropertyFileInputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignore ...
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("- Downloading from: " + url);
|
||||
|
||||
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
|
||||
if (!outputFile.getParentFile().exists()) {
|
||||
if (!outputFile.getParentFile().mkdirs()) {
|
||||
System.out.println(
|
||||
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
|
||||
}
|
||||
}
|
||||
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
|
||||
try {
|
||||
downloadFileFromURL(url, outputFile);
|
||||
System.out.println("Done");
|
||||
System.exit(0);
|
||||
} catch (Throwable e) {
|
||||
System.out.println("- Error downloading");
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
|
||||
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
|
||||
String username = System.getenv("MVNW_USERNAME");
|
||||
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
|
||||
Authenticator.setDefault(new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(username, password);
|
||||
}
|
||||
});
|
||||
}
|
||||
URL website = new URL(urlString);
|
||||
ReadableByteChannel rbc;
|
||||
rbc = Channels.newChannel(website.openStream());
|
||||
FileOutputStream fos = new FileOutputStream(destination);
|
||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
||||
fos.close();
|
||||
rbc.close();
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
|
||||
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
|
|
@ -0,0 +1,322 @@
|
|||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ]; then
|
||||
|
||||
if [ -f /etc/mavenrc ]; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ]; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false
|
||||
darwin=false
|
||||
mingw=false
|
||||
case "$(uname)" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true ;;
|
||||
Darwin*)
|
||||
darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
export JAVA_HOME="$(/usr/libexec/java_home)"
|
||||
else
|
||||
export JAVA_HOME="/Library/Java/Home"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -r /etc/gentoo-release ]; then
|
||||
JAVA_HOME=$(java-config --jre-home)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ]; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ]; do
|
||||
ls=$(ls -ld "$PRG")
|
||||
link=$(expr "$ls" : '.*-> \(.*\)$')
|
||||
if expr "$link" : '/.*' >/dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="$(dirname "$PRG")/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=$(pwd)
|
||||
|
||||
M2_HOME=$(dirname "$PRG")/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=$(cd "$M2_HOME" && pwd)
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=$(cygpath --unix "$M2_HOME")
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="$( (
|
||||
cd "$M2_HOME"
|
||||
pwd
|
||||
))"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="$( (
|
||||
cd "$JAVA_HOME"
|
||||
pwd
|
||||
))"
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="$(which javac)"
|
||||
if [ -n "$javaExecutable" ] && ! [ "$(expr \"$javaExecutable\" : '\([^ ]*\)')" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=$(which readlink)
|
||||
if [ ! $(expr "$readLink" : '\([^ ]*\)') = "no" ]; then
|
||||
if $darwin; then
|
||||
javaHome="$(dirname \"$javaExecutable\")"
|
||||
javaExecutable="$(cd \"$javaHome\" && pwd -P)/javac"
|
||||
else
|
||||
javaExecutable="$(readlink -f \"$javaExecutable\")"
|
||||
fi
|
||||
javaHome="$(dirname \"$javaExecutable\")"
|
||||
javaHome=$(expr "$javaHome" : '\(.*\)/bin')
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ]; then
|
||||
if [ -n "$JAVA_HOME" ]; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="$(which java)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ]; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ]; do
|
||||
if [ -d "$wdir"/.mvn ]; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=$(
|
||||
cd "$wdir/.."
|
||||
pwd
|
||||
)
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' <"$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=$(find_maven_basedir "$(pwd)")
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||
fi
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||
fi
|
||||
if [ -n "$MVNW_REPOURL" ]; then
|
||||
jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
else
|
||||
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
fi
|
||||
while IFS="=" read key value; do
|
||||
case "$key" in wrapperUrl)
|
||||
jarUrl="$value"
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done <"$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Downloading from: $jarUrl"
|
||||
fi
|
||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
if $cygwin; then
|
||||
wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
|
||||
fi
|
||||
|
||||
if command -v wget >/dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found wget ... using wget"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
wget "$jarUrl" -O "$wrapperJarPath"
|
||||
else
|
||||
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
|
||||
fi
|
||||
elif command -v curl >/dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found curl ... using curl"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
curl -o "$wrapperJarPath" "$jarUrl" -f
|
||||
else
|
||||
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
|
||||
fi
|
||||
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Falling back to using Java to download"
|
||||
fi
|
||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
# For Cygwin, switch paths to Windows format before running javac
|
||||
if $cygwin; then
|
||||
javaClass=$(cygpath --path --windows "$javaClass")
|
||||
fi
|
||||
if [ -e "$javaClass" ]; then
|
||||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
# Compiling the Java class
|
||||
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||
fi
|
||||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
# Running the downloader
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Running MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo $MAVEN_PROJECTBASEDIR
|
||||
fi
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=$(cygpath --path --windows "$M2_HOME")
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
|
@ -0,0 +1,182 @@
|
|||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
|
||||
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Found %WRAPPER_JAR%
|
||||
)
|
||||
) else (
|
||||
if not "%MVNW_REPOURL%" == "" (
|
||||
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
)
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %DOWNLOAD_URL%
|
||||
)
|
||||
|
||||
powershell -Command "&{"^
|
||||
"$webclient = new-object System.Net.WebClient;"^
|
||||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||
"}"^
|
||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
|
||||
"}"
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
@REM Provide a "standardized" way to retrieve the CLI args that will
|
||||
@REM work with both Windows and non-Windows executions.
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||
|
||||
exit /B %ERROR_CODE%
|
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.4.0</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.taosdata.example</groupId>
|
||||
<artifactId>mybatisplus-demo</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>mybatisplus-demo</name>
|
||||
<description>Demo project for tdengine</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>3.1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.1.17</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>2.0.18</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.17</version>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/Abstract*.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
|
@ -0,0 +1,15 @@
|
|||
package com.taosdata.example.mybatisplusdemo;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.taosdata.example.mybatisplusdemo.mapper")
|
||||
public class MybatisplusDemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MybatisplusDemoApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.taosdata.example.mybatisplusdemo.config;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class MybatisPlusConfig {
|
||||
|
||||
|
||||
/** mybatis 3.4.1 pagination config start ***/
|
||||
// @Bean
|
||||
// public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
// MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
// interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
|
||||
// return interceptor;
|
||||
// }
|
||||
|
||||
// @Bean
|
||||
// public ConfigurationCustomizer configurationCustomizer() {
|
||||
// return configuration -> configuration.setUseDeprecatedExecutor(false);
|
||||
// }
|
||||
|
||||
@Bean
|
||||
public PaginationInterceptor paginationInterceptor() {
|
||||
// return new PaginationInterceptor();
|
||||
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
|
||||
//TODO: mybatis-plus do not support TDengine, use postgresql Dialect
|
||||
paginationInterceptor.setDialectType("postgresql");
|
||||
|
||||
return paginationInterceptor;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.taosdata.example.mybatisplusdemo.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
@Data
|
||||
public class Temperature {
|
||||
|
||||
private Timestamp ts;
|
||||
private float temperature;
|
||||
private String location;
|
||||
private int tbIndex;
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.taosdata.example.mybatisplusdemo.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
@Data
|
||||
public class Weather {
|
||||
|
||||
private Timestamp ts;
|
||||
private float temperature;
|
||||
private int humidity;
|
||||
private String location;
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.taosdata.example.mybatisplusdemo.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.taosdata.example.mybatisplusdemo.domain.Temperature;
|
||||
import org.apache.ibatis.annotations.Insert;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
public interface TemperatureMapper extends BaseMapper<Temperature> {
|
||||
|
||||
@Update("CREATE TABLE if not exists temperature(ts timestamp, temperature float) tags(location nchar(64), tbIndex int)")
|
||||
int createSuperTable();
|
||||
|
||||
@Update("create table #{tbName} using temperature tags( #{location}, #{tbindex})")
|
||||
int createTable(@Param("tbName") String tbName, @Param("location") String location, @Param("tbindex") int tbindex);
|
||||
|
||||
@Update("drop table if exists temperature")
|
||||
void dropSuperTable();
|
||||
|
||||
@Insert("insert into t${tbIndex}(ts, temperature) values(#{ts}, #{temperature})")
|
||||
int insertOne(Temperature one);
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.taosdata.example.mybatisplusdemo.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.taosdata.example.mybatisplusdemo.domain.Weather;
|
||||
|
||||
public interface WeatherMapper extends BaseMapper<Weather> {
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
spring:
|
||||
datasource:
|
||||
driver-class-name: com.taosdata.jdbc.TSDBDriver
|
||||
url: jdbc:TAOS://localhost:6030/mp_test?charset=UTF-8&locale=en_US.UTF-8&timezone=UTC-8
|
||||
user: root
|
||||
password: taosdata
|
||||
|
||||
druid:
|
||||
initial-size: 5
|
||||
min-idle: 5
|
||||
max-active: 5
|
||||
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: false
|
||||
|
||||
logging:
|
||||
level:
|
||||
com:
|
||||
taosdata:
|
||||
example:
|
||||
mybatisplusdemo:
|
||||
mapper: debug
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
package com.taosdata.example.mybatisplusdemo.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.taosdata.example.mybatisplusdemo.domain.Temperature;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest
|
||||
public class TemperatureMapperTest {
|
||||
|
||||
private static Random random = new Random(System.currentTimeMillis());
|
||||
private static String[] locations = {"北京", "上海", "深圳", "广州", "杭州"};
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
mapper.dropSuperTable();
|
||||
// create table temperature
|
||||
mapper.createSuperTable();
|
||||
// create table t_X using temperature
|
||||
for (int i = 0; i < 10; i++) {
|
||||
mapper.createTable("t" + i, locations[random.nextInt(locations.length)], i);
|
||||
}
|
||||
// insert into table
|
||||
int affectRows = 0;
|
||||
// insert 10 tables
|
||||
for (int i = 0; i < 10; i++) {
|
||||
// each table insert 5 rows
|
||||
for (int j = 0; j < 5; j++) {
|
||||
Temperature one = new Temperature();
|
||||
one.setTs(new Timestamp(1605024000000l));
|
||||
one.setTemperature(random.nextFloat() * 50);
|
||||
one.setLocation("望京");
|
||||
one.setTbIndex(i);
|
||||
affectRows += mapper.insertOne(one);
|
||||
}
|
||||
}
|
||||
Assert.assertEquals(50, affectRows);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
mapper.dropSuperTable();
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private TemperatureMapper mapper;
|
||||
|
||||
/***
|
||||
* test SelectList
|
||||
* **/
|
||||
@Test
|
||||
public void testSelectList() {
|
||||
List<Temperature> temperatureList = mapper.selectList(null);
|
||||
temperatureList.forEach(System.out::println);
|
||||
}
|
||||
|
||||
/***
|
||||
* test InsertOne which is a custom metheod
|
||||
* ***/
|
||||
@Test
|
||||
public void testInsert() {
|
||||
Temperature one = new Temperature();
|
||||
one.setTs(new Timestamp(1605024000000l));
|
||||
one.setTemperature(random.nextFloat() * 50);
|
||||
one.setLocation("望京");
|
||||
int affectRows = mapper.insertOne(one);
|
||||
Assert.assertEquals(1, affectRows);
|
||||
}
|
||||
|
||||
/***
|
||||
* test SelectOne
|
||||
* **/
|
||||
@Test
|
||||
public void testSelectOne() {
|
||||
QueryWrapper<Temperature> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("location", "beijing");
|
||||
Temperature one = mapper.selectOne(wrapper);
|
||||
System.out.println(one);
|
||||
Assert.assertNotNull(one);
|
||||
}
|
||||
|
||||
/***
|
||||
* test select By map
|
||||
* ***/
|
||||
@Test
|
||||
public void testSelectByMap() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("location", "beijing");
|
||||
List<Temperature> temperatures = mapper.selectByMap(map);
|
||||
Assert.assertEquals(1, temperatures.size());
|
||||
}
|
||||
|
||||
/***
|
||||
* test selectObjs
|
||||
* **/
|
||||
@Test
|
||||
public void testSelectObjs() {
|
||||
List<Object> ts = mapper.selectObjs(null);
|
||||
System.out.println(ts);
|
||||
}
|
||||
|
||||
/**
|
||||
* test selectC ount
|
||||
* **/
|
||||
@Test
|
||||
public void testSelectCount() {
|
||||
int count = mapper.selectCount(null);
|
||||
Assert.assertEquals(5, count);
|
||||
}
|
||||
|
||||
/****
|
||||
* 分页
|
||||
*/
|
||||
@Test
|
||||
public void testSelectPage() {
|
||||
IPage page = new Page(1, 2);
|
||||
IPage<Temperature> temperatureIPage = mapper.selectPage(page, null);
|
||||
System.out.println("total : " + temperatureIPage.getTotal());
|
||||
System.out.println("pages : " + temperatureIPage.getPages());
|
||||
for (Temperature temperature : temperatureIPage.getRecords()) {
|
||||
System.out.println(temperature);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package com.taosdata.example.mybatisplusdemo.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.taosdata.example.mybatisplusdemo.domain.Weather;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest
|
||||
public class WeatherMapperTest {
|
||||
|
||||
private static Random random = new Random(System.currentTimeMillis());
|
||||
|
||||
@Autowired
|
||||
private WeatherMapper mapper;
|
||||
|
||||
@Test
|
||||
public void testSelectList() {
|
||||
List<Weather> weathers = mapper.selectList(null);
|
||||
weathers.forEach(System.out::println);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsert() {
|
||||
Weather one = new Weather();
|
||||
one.setTs(new Timestamp(1605024000000l));
|
||||
one.setTemperature(random.nextFloat() * 50);
|
||||
one.setHumidity(random.nextInt(100));
|
||||
one.setLocation("望京");
|
||||
int affectRows = mapper.insert(one);
|
||||
Assert.assertEquals(1, affectRows);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectOne() {
|
||||
QueryWrapper<Weather> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("location", "beijing");
|
||||
Weather one = mapper.selectOne(wrapper);
|
||||
System.out.println(one);
|
||||
Assert.assertEquals(12.22f, one.getTemperature(), 0.00f);
|
||||
Assert.assertEquals("beijing", one.getLocation());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectByMap() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("location", "beijing");
|
||||
List<Weather> weathers = mapper.selectByMap(map);
|
||||
Assert.assertEquals(1, weathers.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectObjs() {
|
||||
List<Object> ts = mapper.selectObjs(null);
|
||||
System.out.println(ts);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectCount() {
|
||||
int count = mapper.selectCount(null);
|
||||
// Assert.assertEquals(5, count);
|
||||
System.out.println(count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectPage() {
|
||||
IPage page = new Page(1, 2);
|
||||
IPage<Weather> weatherIPage = mapper.selectPage(page, null);
|
||||
System.out.println("total : " + weatherIPage.getTotal());
|
||||
System.out.println("pages : " + weatherIPage.getPages());
|
||||
for (Weather weather : weatherIPage.getRecords()) {
|
||||
System.out.println(weather);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
# TDengine examples
|
||||
|
||||
| No. | Name | Describe |
|
||||
| :--: | :----------------: | ------------------------------------------------------------ |
|
||||
| 1 | JDBCDemo | Example codes for JDBC-JNI, JDBC-RESTful, Subscribe |
|
||||
| 2 | connectionPools | Example codes for HikariCP, Druid, dbcp, c3p0 connection pools |
|
||||
| 3 | SpringJdbcTemplate | Example codes for spring jdbcTemplate |
|
||||
| 4 | mybatisplus-demo | Example codes for mybatis |
|
||||
| 5 | springbootdemo | Example codes for springboot |
|
||||
| 6 | taosdemo | This is an internal tool for testing Our JDBC-JNI, JDBC-RESTful, RESTful interfaces |
|
||||
|
||||
|
||||
more detail: https://www.taosdata.com/cn//documentation20/connector-java/
|
|
@ -0,0 +1,30 @@
|
|||
.mvn/
|
||||
target/
|
||||
!**/src/main/**
|
||||
!**/src/test/**
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
|
@ -0,0 +1,310 @@
|
|||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven2 Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
export JAVA_HOME="`/usr/libexec/java_home`"
|
||||
else
|
||||
export JAVA_HOME="/Library/Java/Home"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=`java-config --jre-home`
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ] ; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="`dirname "$PRG"`/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=`pwd`
|
||||
|
||||
M2_HOME=`dirname "$PRG"`/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="`which javac`"
|
||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=`which readlink`
|
||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||
else
|
||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||
fi
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="`which java`"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=`cd "$wdir/.."; pwd`
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' < "$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||
fi
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||
fi
|
||||
if [ -n "$MVNW_REPOURL" ]; then
|
||||
jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
|
||||
else
|
||||
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
|
||||
fi
|
||||
while IFS="=" read key value; do
|
||||
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
||||
esac
|
||||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Downloading from: $jarUrl"
|
||||
fi
|
||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
if $cygwin; then
|
||||
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
|
||||
fi
|
||||
|
||||
if command -v wget > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found wget ... using wget"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
wget "$jarUrl" -O "$wrapperJarPath"
|
||||
else
|
||||
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
|
||||
fi
|
||||
elif command -v curl > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found curl ... using curl"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
curl -o "$wrapperJarPath" "$jarUrl" -f
|
||||
else
|
||||
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
|
||||
fi
|
||||
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Falling back to using Java to download"
|
||||
fi
|
||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
# For Cygwin, switch paths to Windows format before running javac
|
||||
if $cygwin; then
|
||||
javaClass=`cygpath --path --windows "$javaClass"`
|
||||
fi
|
||||
if [ -e "$javaClass" ]; then
|
||||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
# Compiling the Java class
|
||||
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||
fi
|
||||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
# Running the downloader
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Running MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo $MAVEN_PROJECTBASEDIR
|
||||
fi
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||
fi
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
|
@ -0,0 +1,182 @@
|
|||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven2 Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
|
||||
|
||||
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Found %WRAPPER_JAR%
|
||||
)
|
||||
) else (
|
||||
if not "%MVNW_REPOURL%" == "" (
|
||||
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
|
||||
)
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %DOWNLOAD_URL%
|
||||
)
|
||||
|
||||
powershell -Command "&{"^
|
||||
"$webclient = new-object System.Net.WebClient;"^
|
||||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||
"}"^
|
||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
|
||||
"}"
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
@REM Provide a "standardized" way to retrieve the CLI args that will
|
||||
@REM work with both Windows and non-Windows executions.
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||
|
||||
exit /B %ERROR_CODE%
|
|
@ -0,0 +1,108 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.2.1.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.taosdata.example</groupId>
|
||||
<artifactId>springbootdemo</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>springbootdemo</name>
|
||||
<description>Demo project for using tdengine with Spring Boot</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>2.1.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>2.0.34</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>1.1.17</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*.properties</include>
|
||||
<include>**/*.xml</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
<includes>
|
||||
<include>**/*.properties</include>
|
||||
<include>**/*.xml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,96 @@
|
|||
## TDengine SpringBoot + Mybatis Demo
|
||||
|
||||
### 配置 application.properties
|
||||
```properties
|
||||
# datasource config
|
||||
spring.datasource.driver-class-name=com.taosdata.jdbc.TSDBDriver
|
||||
spring.datasource.url=jdbc:TAOS://127.0.0.1:6030/log
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=taosdata
|
||||
|
||||
spring.datasource.druid.initial-size=5
|
||||
spring.datasource.druid.min-idle=5
|
||||
spring.datasource.druid.max-active=5
|
||||
# max wait time for get connection, ms
|
||||
spring.datasource.druid.max-wait=60000
|
||||
|
||||
spring.datasource.druid.validation-query=select server_status();
|
||||
spring.datasource.druid.validation-query-timeout=5000
|
||||
spring.datasource.druid.test-on-borrow=false
|
||||
spring.datasource.druid.test-on-return=false
|
||||
spring.datasource.druid.test-while-idle=true
|
||||
spring.datasource.druid.time-between-eviction-runs-millis=60000
|
||||
spring.datasource.druid.min-evictable-idle-time-millis=600000
|
||||
spring.datasource.druid.max-evictable-idle-time-millis=900000
|
||||
|
||||
# mybatis
|
||||
mybatis.mapper-locations=classpath:mapper/*.xml
|
||||
|
||||
# log
|
||||
logging.level.com.taosdata.jdbc.springbootdemo.dao=debug
|
||||
```
|
||||
|
||||
### 主要功能
|
||||
|
||||
* 创建数据库和表
|
||||
```xml
|
||||
<!-- weatherMapper.xml -->
|
||||
<update id="createDB" >
|
||||
create database if not exists test;
|
||||
</update>
|
||||
|
||||
<update id="createTable" >
|
||||
create table if not exists test.weather(ts timestamp, temperature int, humidity float);
|
||||
</update>
|
||||
```
|
||||
|
||||
* 插入单条记录
|
||||
```xml
|
||||
<!-- weatherMapper.xml -->
|
||||
<insert id="insert" parameterType="Weather" >
|
||||
insert into test.weather (ts, temperature, humidity) values (now, #{temperature,jdbcType=INTEGER}, #{humidity,jdbcType=FLOAT})
|
||||
</insert>
|
||||
```
|
||||
* 插入多条记录
|
||||
```xml
|
||||
<!-- weatherMapper.xml -->
|
||||
<insert id="batchInsert" parameterType="java.util.List" >
|
||||
insert into test.weather (ts, temperature, humidity) values
|
||||
<foreach separator=" " collection="list" item="weather" index="index" >
|
||||
(now + #{index}a, #{weather.temperature}, #{weather.humidity})
|
||||
</foreach>
|
||||
</insert>
|
||||
```
|
||||
* 分页查询
|
||||
```xml
|
||||
<!-- weatherMapper.xml -->
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="WeatherMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="Weather">
|
||||
<id column="ts" jdbcType="TIMESTAMP" property="ts" />
|
||||
<result column="temperature" jdbcType="INTEGER" property="temperature" />
|
||||
<result column="humidity" jdbcType="FLOAT" property="humidity" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
ts, temperature, humidity
|
||||
</sql>
|
||||
|
||||
<select id="select" resultMap="BaseResultMap">
|
||||
select
|
||||
<include refid="Base_Column_List" />
|
||||
from test.weather
|
||||
order by ts desc
|
||||
<if test="limit != null">
|
||||
limit #{limit,jdbcType=BIGINT}
|
||||
</if>
|
||||
<if test="offset != null">
|
||||
offset #{offset,jdbcType=BIGINT}
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
||||
```
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.taosdata.example.springbootdemo;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@MapperScan(basePackages = {"com.taosdata.example.springbootdemo"})
|
||||
@SpringBootApplication
|
||||
public class SpringbootdemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringbootdemoApplication.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.taosdata.example.springbootdemo.controller;
|
||||
|
||||
import com.taosdata.example.springbootdemo.domain.Weather;
|
||||
import com.taosdata.example.springbootdemo.service.WeatherService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RequestMapping("/weather")
|
||||
@RestController
|
||||
public class WeatherController {
|
||||
|
||||
@Autowired
|
||||
private WeatherService weatherService;
|
||||
|
||||
@GetMapping("/lastOne")
|
||||
public Weather lastOne() {
|
||||
return weatherService.lastOne();
|
||||
}
|
||||
|
||||
@GetMapping("/init")
|
||||
public int init() {
|
||||
return weatherService.init();
|
||||
}
|
||||
|
||||
@GetMapping("/{limit}/{offset}")
|
||||
public List<Weather> queryWeather(@PathVariable Long limit, @PathVariable Long offset) {
|
||||
return weatherService.query(limit, offset);
|
||||
}
|
||||
|
||||
@PostMapping("/{temperature}/{humidity}")
|
||||
public int saveWeather(@PathVariable float temperature, @PathVariable float humidity) {
|
||||
return weatherService.save(temperature, humidity);
|
||||
}
|
||||
|
||||
@GetMapping("/count")
|
||||
public int count() {
|
||||
return weatherService.count();
|
||||
}
|
||||
|
||||
@GetMapping("/subTables")
|
||||
public List<String> getSubTables() {
|
||||
return weatherService.getSubTables();
|
||||
}
|
||||
|
||||
@GetMapping("/avg")
|
||||
public List<Weather> avg() {
|
||||
return weatherService.avg();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.taosdata.example.springbootdemo.dao;
|
||||
|
||||
import com.taosdata.example.springbootdemo.domain.Weather;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface WeatherMapper {
|
||||
|
||||
Map<String, Object> lastOne();
|
||||
|
||||
void dropDB();
|
||||
|
||||
void createDB();
|
||||
|
||||
void createSuperTable();
|
||||
|
||||
void createTable(Weather weather);
|
||||
|
||||
List<Weather> select(@Param("limit") Long limit, @Param("offset") Long offset);
|
||||
|
||||
int insert(Weather weather);
|
||||
|
||||
int count();
|
||||
|
||||
List<String> getSubTables();
|
||||
|
||||
List<Weather> avg();
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.taosdata.example.springbootdemo.dao.WeatherMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="com.taosdata.example.springbootdemo.domain.Weather">
|
||||
<id column="ts" jdbcType="TIMESTAMP" property="ts"/>
|
||||
<result column="temperature" jdbcType="FLOAT" property="temperature"/>
|
||||
<result column="humidity" jdbcType="FLOAT" property="humidity"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="lastOne" resultType="java.util.Map">
|
||||
select last_row(*), location, groupid
|
||||
from test.weather
|
||||
</select>
|
||||
|
||||
<update id="dropDB">
|
||||
drop
|
||||
database if exists test
|
||||
</update>
|
||||
|
||||
<update id="createDB">
|
||||
create
|
||||
database if not exists test
|
||||
</update>
|
||||
|
||||
<update id="createSuperTable">
|
||||
create table if not exists test.weather
|
||||
(
|
||||
ts
|
||||
timestamp,
|
||||
temperature
|
||||
float,
|
||||
humidity
|
||||
float,
|
||||
note
|
||||
binary
|
||||
(
|
||||
64
|
||||
)) tags
|
||||
(
|
||||
location nchar
|
||||
(
|
||||
64
|
||||
), groupId int)
|
||||
</update>
|
||||
|
||||
<update id="createTable" parameterType="com.taosdata.example.springbootdemo.domain.Weather">
|
||||
create table if not exists test.t#{groupId} using test.weather tags
|
||||
(
|
||||
#{location},
|
||||
#{groupId}
|
||||
)
|
||||
</update>
|
||||
|
||||
<select id="select" resultMap="BaseResultMap">
|
||||
select * from test.weather order by ts desc
|
||||
<if test="limit != null">
|
||||
limit #{limit,jdbcType=BIGINT}
|
||||
</if>
|
||||
<if test="offset != null">
|
||||
offset #{offset,jdbcType=BIGINT}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<insert id="insert" parameterType="com.taosdata.example.springbootdemo.domain.Weather">
|
||||
insert into test.t#{groupId} (ts, temperature, humidity, note)
|
||||
values (#{ts}, ${temperature}, ${humidity}, #{note})
|
||||
</insert>
|
||||
|
||||
<select id="getSubTables" resultType="String">
|
||||
select tbname
|
||||
from test.weather
|
||||
</select>
|
||||
|
||||
<select id="count" resultType="int">
|
||||
select count(*)
|
||||
from test.weather
|
||||
</select>
|
||||
|
||||
<resultMap id="avgResultSet" type="com.taosdata.example.springbootdemo.domain.Weather">
|
||||
<id column="ts" jdbcType="TIMESTAMP" property="ts"/>
|
||||
<result column="avg(temperature)" jdbcType="FLOAT" property="temperature"/>
|
||||
<result column="avg(humidity)" jdbcType="FLOAT" property="humidity"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="avg" resultMap="avgResultSet">
|
||||
select avg(temperature), avg(humidity)
|
||||
from test.weather interval(1m)
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,73 @@
|
|||
package com.taosdata.example.springbootdemo.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
public class Weather {
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS", timezone = "GMT+8")
|
||||
private Timestamp ts;
|
||||
private Float temperature;
|
||||
private Float humidity;
|
||||
private String location;
|
||||
private String note;
|
||||
private int groupId;
|
||||
|
||||
public Weather() {
|
||||
}
|
||||
|
||||
public Weather(Timestamp ts, float temperature, float humidity) {
|
||||
this.ts = ts;
|
||||
this.temperature = temperature;
|
||||
this.humidity = humidity;
|
||||
}
|
||||
|
||||
public Timestamp getTs() {
|
||||
return ts;
|
||||
}
|
||||
|
||||
public void setTs(Timestamp ts) {
|
||||
this.ts = ts;
|
||||
}
|
||||
|
||||
public Float getTemperature() {
|
||||
return temperature;
|
||||
}
|
||||
|
||||
public void setTemperature(Float temperature) {
|
||||
this.temperature = temperature;
|
||||
}
|
||||
|
||||
public Float getHumidity() {
|
||||
return humidity;
|
||||
}
|
||||
|
||||
public void setHumidity(Float humidity) {
|
||||
this.humidity = humidity;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public int getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public void setGroupId(int groupId) {
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
public String getNote() {
|
||||
return note;
|
||||
}
|
||||
|
||||
public void setNote(String note) {
|
||||
this.note = note;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package com.taosdata.example.springbootdemo.service;
|
||||
|
||||
import com.taosdata.example.springbootdemo.dao.WeatherMapper;
|
||||
import com.taosdata.example.springbootdemo.domain.Weather;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
@Service
|
||||
public class WeatherService {
|
||||
|
||||
@Autowired
|
||||
private WeatherMapper weatherMapper;
|
||||
private Random random = new Random(System.currentTimeMillis());
|
||||
private String[] locations = {"北京", "上海", "广州", "深圳", "天津"};
|
||||
|
||||
public int init() {
|
||||
weatherMapper.dropDB();
|
||||
weatherMapper.createDB();
|
||||
weatherMapper.createSuperTable();
|
||||
long ts = System.currentTimeMillis();
|
||||
long thirtySec = 1000 * 30;
|
||||
int count = 0;
|
||||
for (int i = 0; i < 20; i++) {
|
||||
Weather weather = new Weather(new Timestamp(ts + (thirtySec * i)), 30 * random.nextFloat(), random.nextInt(100));
|
||||
weather.setLocation(locations[random.nextInt(locations.length)]);
|
||||
weather.setGroupId(i % locations.length);
|
||||
weather.setNote("note-" + i);
|
||||
weatherMapper.createTable(weather);
|
||||
count += weatherMapper.insert(weather);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public List<Weather> query(Long limit, Long offset) {
|
||||
return weatherMapper.select(limit, offset);
|
||||
}
|
||||
|
||||
public int save(float temperature, float humidity) {
|
||||
Weather weather = new Weather();
|
||||
weather.setTemperature(temperature);
|
||||
weather.setHumidity(humidity);
|
||||
|
||||
return weatherMapper.insert(weather);
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return weatherMapper.count();
|
||||
}
|
||||
|
||||
public List<String> getSubTables() {
|
||||
return weatherMapper.getSubTables();
|
||||
}
|
||||
|
||||
public List<Weather> avg() {
|
||||
return weatherMapper.avg();
|
||||
}
|
||||
|
||||
public Weather lastOne() {
|
||||
Map<String, Object> result = weatherMapper.lastOne();
|
||||
|
||||
long ts = (long) result.get("ts");
|
||||
float temperature = (float) result.get("temperature");
|
||||
float humidity = (float) result.get("humidity");
|
||||
String note = (String) result.get("note");
|
||||
int groupId = (int) result.get("groupid");
|
||||
String location = (String) result.get("location");
|
||||
|
||||
Weather weather = new Weather(new Timestamp(ts), temperature, humidity);
|
||||
weather.setNote(note);
|
||||
weather.setGroupId(groupId);
|
||||
weather.setLocation(location);
|
||||
return weather;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.taosdata.example.springbootdemo.util;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Map;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class TaosAspect {
|
||||
|
||||
@Around("execution(java.util.Map<String,Object> com.taosdata.example.springbootdemo.dao.*.*(..))")
|
||||
public Object handleType(ProceedingJoinPoint joinPoint) {
|
||||
Map<String, Object> result = null;
|
||||
try {
|
||||
result = (Map<String, Object>) joinPoint.proceed();
|
||||
for (String key : result.keySet()) {
|
||||
Object obj = result.get(key);
|
||||
if (obj instanceof byte[]) {
|
||||
obj = new String((byte[]) obj);
|
||||
result.put(key, obj);
|
||||
}
|
||||
if (obj instanceof Timestamp) {
|
||||
obj = ((Timestamp) obj).getTime();
|
||||
result.put(key, obj);
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
# datasource config - JDBC-JNI
|
||||
#spring.datasource.driver-class-name=com.taosdata.jdbc.TSDBDriver
|
||||
#spring.datasource.url=jdbc:TAOS://localhost:6030/?timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8
|
||||
#spring.datasource.username=root
|
||||
#spring.datasource.password=taosdata
|
||||
# datasource config - JDBC-RESTful
|
||||
spring.datasource.driver-class-name=com.taosdata.jdbc.rs.RestfulDriver
|
||||
spring.datasource.url=jdbc:TAOS-RS://localhsot:6041/test?timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=taosdata
|
||||
spring.datasource.druid.initial-size=5
|
||||
spring.datasource.druid.min-idle=5
|
||||
spring.datasource.druid.max-active=5
|
||||
spring.datasource.druid.max-wait=30000
|
||||
spring.datasource.druid.validation-query=select server_status();
|
||||
spring.aop.auto=true
|
||||
spring.aop.proxy-target-class=true
|
||||
#mybatis
|
||||
mybatis.mapper-locations=classpath:mapper/*.xml
|
||||
logging.level.com.taosdata.jdbc.springbootdemo.dao=debug
|
|
@ -0,0 +1,33 @@
|
|||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright 2007-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.nio.channels.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class MavenWrapperDownloader {
|
||||
|
||||
private static final String WRAPPER_VERSION = "0.5.6";
|
||||
/**
|
||||
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
|
||||
*/
|
||||
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
|
||||
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
|
||||
|
||||
/**
|
||||
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
|
||||
* use instead of the default one.
|
||||
*/
|
||||
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
|
||||
".mvn/wrapper/maven-wrapper.properties";
|
||||
|
||||
/**
|
||||
* Path where the maven-wrapper.jar will be saved to.
|
||||
*/
|
||||
private static final String MAVEN_WRAPPER_JAR_PATH =
|
||||
".mvn/wrapper/maven-wrapper.jar";
|
||||
|
||||
/**
|
||||
* Name of the property which should be used to override the default download url for the wrapper.
|
||||
*/
|
||||
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
|
||||
|
||||
public static void main(String args[]) {
|
||||
System.out.println("- Downloader started");
|
||||
File baseDirectory = new File(args[0]);
|
||||
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
|
||||
|
||||
// If the maven-wrapper.properties exists, read it and check if it contains a custom
|
||||
// wrapperUrl parameter.
|
||||
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
|
||||
String url = DEFAULT_DOWNLOAD_URL;
|
||||
if (mavenWrapperPropertyFile.exists()) {
|
||||
FileInputStream mavenWrapperPropertyFileInputStream = null;
|
||||
try {
|
||||
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
|
||||
Properties mavenWrapperProperties = new Properties();
|
||||
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
|
||||
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
|
||||
} catch (IOException e) {
|
||||
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
|
||||
} finally {
|
||||
try {
|
||||
if (mavenWrapperPropertyFileInputStream != null) {
|
||||
mavenWrapperPropertyFileInputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignore ...
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("- Downloading from: " + url);
|
||||
|
||||
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
|
||||
if (!outputFile.getParentFile().exists()) {
|
||||
if (!outputFile.getParentFile().mkdirs()) {
|
||||
System.out.println(
|
||||
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
|
||||
}
|
||||
}
|
||||
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
|
||||
try {
|
||||
downloadFileFromURL(url, outputFile);
|
||||
System.out.println("Done");
|
||||
System.exit(0);
|
||||
} catch (Throwable e) {
|
||||
System.out.println("- Error downloading");
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
|
||||
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
|
||||
String username = System.getenv("MVNW_USERNAME");
|
||||
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
|
||||
Authenticator.setDefault(new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(username, password);
|
||||
}
|
||||
});
|
||||
}
|
||||
URL website = new URL(urlString);
|
||||
ReadableByteChannel rbc;
|
||||
rbc = Channels.newChannel(website.openStream());
|
||||
FileOutputStream fos = new FileOutputStream(destination);
|
||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
||||
fos.close();
|
||||
rbc.close();
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
|||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
|
||||
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
|
|
@ -0,0 +1,322 @@
|
|||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ]; then
|
||||
|
||||
if [ -f /etc/mavenrc ]; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ]; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false
|
||||
darwin=false
|
||||
mingw=false
|
||||
case "$(uname)" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true ;;
|
||||
Darwin*)
|
||||
darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
export JAVA_HOME="$(/usr/libexec/java_home)"
|
||||
else
|
||||
export JAVA_HOME="/Library/Java/Home"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -r /etc/gentoo-release ]; then
|
||||
JAVA_HOME=$(java-config --jre-home)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ]; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ]; do
|
||||
ls=$(ls -ld "$PRG")
|
||||
link=$(expr "$ls" : '.*-> \(.*\)$')
|
||||
if expr "$link" : '/.*' >/dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="$(dirname "$PRG")/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=$(pwd)
|
||||
|
||||
M2_HOME=$(dirname "$PRG")/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=$(cd "$M2_HOME" && pwd)
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=$(cygpath --unix "$M2_HOME")
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="$( (
|
||||
cd "$M2_HOME"
|
||||
pwd
|
||||
))"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="$( (
|
||||
cd "$JAVA_HOME"
|
||||
pwd
|
||||
))"
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="$(which javac)"
|
||||
if [ -n "$javaExecutable" ] && ! [ "$(expr \"$javaExecutable\" : '\([^ ]*\)')" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=$(which readlink)
|
||||
if [ ! $(expr "$readLink" : '\([^ ]*\)') = "no" ]; then
|
||||
if $darwin; then
|
||||
javaHome="$(dirname \"$javaExecutable\")"
|
||||
javaExecutable="$(cd \"$javaHome\" && pwd -P)/javac"
|
||||
else
|
||||
javaExecutable="$(readlink -f \"$javaExecutable\")"
|
||||
fi
|
||||
javaHome="$(dirname \"$javaExecutable\")"
|
||||
javaHome=$(expr "$javaHome" : '\(.*\)/bin')
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ]; then
|
||||
if [ -n "$JAVA_HOME" ]; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="$(which java)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ]; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ]; do
|
||||
if [ -d "$wdir"/.mvn ]; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=$(
|
||||
cd "$wdir/.."
|
||||
pwd
|
||||
)
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' <"$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=$(find_maven_basedir "$(pwd)")
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||
fi
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||
fi
|
||||
if [ -n "$MVNW_REPOURL" ]; then
|
||||
jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
else
|
||||
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
fi
|
||||
while IFS="=" read key value; do
|
||||
case "$key" in wrapperUrl)
|
||||
jarUrl="$value"
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done <"$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Downloading from: $jarUrl"
|
||||
fi
|
||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
if $cygwin; then
|
||||
wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
|
||||
fi
|
||||
|
||||
if command -v wget >/dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found wget ... using wget"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
wget "$jarUrl" -O "$wrapperJarPath"
|
||||
else
|
||||
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
|
||||
fi
|
||||
elif command -v curl >/dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found curl ... using curl"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
curl -o "$wrapperJarPath" "$jarUrl" -f
|
||||
else
|
||||
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
|
||||
fi
|
||||
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Falling back to using Java to download"
|
||||
fi
|
||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
# For Cygwin, switch paths to Windows format before running javac
|
||||
if $cygwin; then
|
||||
javaClass=$(cygpath --path --windows "$javaClass")
|
||||
fi
|
||||
if [ -e "$javaClass" ]; then
|
||||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
# Compiling the Java class
|
||||
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||
fi
|
||||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
# Running the downloader
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Running MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo $MAVEN_PROJECTBASEDIR
|
||||
fi
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=$(cygpath --path --windows "$M2_HOME")
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
|
@ -0,0 +1,182 @@
|
|||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
|
||||
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Found %WRAPPER_JAR%
|
||||
)
|
||||
) else (
|
||||
if not "%MVNW_REPOURL%" == "" (
|
||||
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
)
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %DOWNLOAD_URL%
|
||||
)
|
||||
|
||||
powershell -Command "&{"^
|
||||
"$webclient = new-object System.Net.WebClient;"^
|
||||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||
"}"^
|
||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
|
||||
"}"
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
@REM Provide a "standardized" way to retrieve the CLI args that will
|
||||
@REM work with both Windows and non-Windows executions.
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||
|
||||
exit /B %ERROR_CODE%
|
|
@ -0,0 +1,168 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.taosdata</groupId>
|
||||
<artifactId>taosdemo</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<name>taosdemo</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>Demo project for TDengine</description>
|
||||
|
||||
<properties>
|
||||
<spring.version>5.3.2</spring.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-expression</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- HikariCP -->
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>3.4.5</version>
|
||||
</dependency>
|
||||
<!-- taos jdbc -->
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>2.0.20</version>
|
||||
<!-- <scope>system</scope>-->
|
||||
<!-- <systemPath>${project.basedir}/src/main/resources/lib/taos-jdbcdriver-2.0.15-dist.jar</systemPath>-->
|
||||
</dependency>
|
||||
<!-- fastjson -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.75</version>
|
||||
</dependency>
|
||||
<!-- mysql: just for test -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.16</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- log4j -->
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.14.1</version>
|
||||
</dependency>
|
||||
<!-- junit -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.16</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*.properties</include>
|
||||
<include>**/*.xml</include>
|
||||
<include>**/*.jar</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
<includes>
|
||||
<include>**/*.properties</include>
|
||||
<include>**/*.xml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<!-- 指定JdbcChecker为mainClass -->
|
||||
<mainClass>com.taosdata.taosdemo.TaosDemoApplication</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,13 @@
|
|||
```
|
||||
cd tests/examples/JDBC/taosdemo
|
||||
mvn clean package -Dmaven.test.skip=true
|
||||
# 先建表,再插入的
|
||||
java -jar target/taosdemo-2.0-jar-with-dependencies.jar -host [hostname] -database [database] -doCreateTable true -superTableSQL "create table weather(ts timestamp, f1 int) tags(t1 nchar(4))" -numOfTables 1000 -numOfRowsPerTable 100000000 -numOfThreadsForInsert 10 -numOfTablesPerSQL 10 -numOfValuesPerSQL 100
|
||||
# 不建表,直接插入的
|
||||
java -jar target/taosdemo-2.0-jar-with-dependencies.jar -host [hostname] -database [database] -doCreateTable false -superTableSQL "create table weather(ts timestamp, f1 int) tags(t1 nchar(4))" -numOfTables 1000 -numOfRowsPerTable 100000000 -numOfThreadsForInsert 10 -numOfTablesPerSQL 10 -numOfValuesPerSQL 100
|
||||
```
|
||||
|
||||
需求:
|
||||
1. 可以读lowa的配置文件
|
||||
2. 支持JDBC-JNI和JDBC-restful
|
||||
3. 读取配置文件,持续执行查询
|
|
@ -0,0 +1,128 @@
|
|||
package com.taosdata.taosdemo;
|
||||
|
||||
import com.taosdata.taosdemo.components.DataSourceFactory;
|
||||
import com.taosdata.taosdemo.components.JdbcTaosdemoConfig;
|
||||
import com.taosdata.taosdemo.domain.SuperTableMeta;
|
||||
import com.taosdata.taosdemo.service.DatabaseService;
|
||||
import com.taosdata.taosdemo.service.SqlExecuteTask;
|
||||
import com.taosdata.taosdemo.service.SubTableService;
|
||||
import com.taosdata.taosdemo.service.SuperTableService;
|
||||
import com.taosdata.taosdemo.service.data.SuperTableMetaGenerator;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class TaosDemoApplication {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(TaosDemoApplication.class);
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
// 读配置参数
|
||||
JdbcTaosdemoConfig config = new JdbcTaosdemoConfig(args);
|
||||
boolean isHelp = Arrays.asList(args).contains("--help");
|
||||
if (isHelp || config.host == null || config.host.isEmpty()) {
|
||||
JdbcTaosdemoConfig.printHelp();
|
||||
System.exit(0);
|
||||
}
|
||||
// 初始化
|
||||
final DataSource dataSource = DataSourceFactory.getInstance(config.host, config.port, config.user, config.password);
|
||||
if (config.executeSql != null && !config.executeSql.isEmpty() && !config.executeSql.replaceAll("\\s", "").isEmpty()) {
|
||||
Thread task = new Thread(new SqlExecuteTask(dataSource, config.executeSql));
|
||||
task.start();
|
||||
try {
|
||||
task.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final DatabaseService databaseService = new DatabaseService(dataSource);
|
||||
final SuperTableService superTableService = new SuperTableService(dataSource);
|
||||
final SubTableService subTableService = new SubTableService(dataSource);
|
||||
|
||||
// 创建数据库
|
||||
long start = System.currentTimeMillis();
|
||||
Map<String, String> databaseParam = new HashMap<>();
|
||||
databaseParam.put("database", config.database);
|
||||
databaseParam.put("keep", Integer.toString(config.keep));
|
||||
databaseParam.put("days", Integer.toString(config.days));
|
||||
databaseParam.put("replica", Integer.toString(config.replica));
|
||||
//TODO: other database parameters
|
||||
databaseService.createDatabase(databaseParam);
|
||||
databaseService.useDatabase(config.database);
|
||||
long end = System.currentTimeMillis();
|
||||
logger.info(">>> create database time cost : " + (end - start) + " ms.");
|
||||
/**********************************************************************************/
|
||||
// 构造超级表的meta
|
||||
SuperTableMeta superTableMeta;
|
||||
// create super table
|
||||
if (config.superTableSQL != null) {
|
||||
// use a sql to create super table
|
||||
superTableMeta = SuperTableMetaGenerator.generate(config.superTableSQL);
|
||||
if (config.database != null && !config.database.isEmpty())
|
||||
superTableMeta.setDatabase(config.database);
|
||||
} else if (config.numOfFields == 0) {
|
||||
String sql = "create table " + config.database + "." + config.superTable + " (ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int)";
|
||||
superTableMeta = SuperTableMetaGenerator.generate(sql);
|
||||
} else {
|
||||
// create super table with specified field size and tag size
|
||||
superTableMeta = SuperTableMetaGenerator.generate(config.database, config.superTable, config.numOfFields, config.prefixOfFields, config.numOfTags, config.prefixOfTags);
|
||||
}
|
||||
/**********************************************************************************/
|
||||
// 建表
|
||||
start = System.currentTimeMillis();
|
||||
if (config.doCreateTable) {
|
||||
superTableService.drop(superTableMeta.getDatabase(), superTableMeta.getName());
|
||||
superTableService.create(superTableMeta);
|
||||
if (!config.autoCreateTable) {
|
||||
// 批量建子表
|
||||
subTableService.createSubTable(superTableMeta, config.numOfTables, config.prefixOfTable, config.numOfThreadsForCreate);
|
||||
}
|
||||
}
|
||||
end = System.currentTimeMillis();
|
||||
logger.info(">>> create table time cost : " + (end - start) + " ms.");
|
||||
/**********************************************************************************/
|
||||
// 插入
|
||||
long tableSize = config.numOfTables;
|
||||
int threadSize = config.numOfThreadsForInsert;
|
||||
long startTime = getProperStartTime(config.startTime, config.keep);
|
||||
|
||||
if (tableSize < threadSize)
|
||||
threadSize = (int) tableSize;
|
||||
long gap = (long) Math.ceil((0.0d + tableSize) / threadSize);
|
||||
|
||||
start = System.currentTimeMillis();
|
||||
// multi threads to insert
|
||||
int affectedRows = subTableService.insertMultiThreads(superTableMeta, threadSize, tableSize, startTime, gap, config);
|
||||
end = System.currentTimeMillis();
|
||||
logger.info("insert " + affectedRows + " rows, time cost: " + (end - start) + " ms");
|
||||
/**********************************************************************************/
|
||||
// 查询
|
||||
|
||||
|
||||
/**********************************************************************************/
|
||||
// 删除表
|
||||
if (config.dropTable) {
|
||||
superTableService.drop(config.database, config.superTable);
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private static long getProperStartTime(long startTime, int keep) {
|
||||
Instant now = Instant.now();
|
||||
long earliest = now.minus(Duration.ofDays(keep - 1)).toEpochMilli();
|
||||
if (startTime == 0 || startTime < earliest) {
|
||||
startTime = earliest;
|
||||
}
|
||||
return startTime;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package com.taosdata.taosdemo.components;
|
||||
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
@Component
|
||||
public class DataSourceFactory {
|
||||
|
||||
private static DataSource instance;
|
||||
|
||||
public static DataSource getInstance(String host, int port, String user, String password) throws IOException {
|
||||
if (instance == null) {
|
||||
synchronized (DataSourceFactory.class) {
|
||||
if (instance == null) {
|
||||
InputStream is = DataSourceFactory.class.getClassLoader().getResourceAsStream("application.properties");
|
||||
Properties properties = new Properties();
|
||||
properties.load(is);
|
||||
|
||||
HikariConfig config = new HikariConfig();
|
||||
if (properties.containsKey("jdbc.driver")) {
|
||||
// String driverName = properties.getProperty("jdbc.driver");
|
||||
// System.out.println(">>> load driver : " + driverName);
|
||||
// try {
|
||||
// Class.forName(driverName);
|
||||
// } catch (ClassNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
config.setDriverClassName(properties.getProperty("jdbc.driver"));
|
||||
} else {
|
||||
config.setDriverClassName("com.taosdata.jdbc.TSDBDriver");
|
||||
}
|
||||
if ("com.taosdata.jdbc.rs.RestfulDriver".equalsIgnoreCase(properties.getProperty("jdbc.driver")))
|
||||
config.setJdbcUrl("jdbc:TAOS-RS://" + host + ":6041/?charset=UTF-8&locale=en_US.UTF-8&timezone=UTC-8");
|
||||
else
|
||||
config.setJdbcUrl("jdbc:TAOS://" + host + ":" + port + "/?charset=UTF-8&locale=en_US.UTF-8&timezone=UTC-8");
|
||||
config.setUsername(user);
|
||||
config.setPassword(password);
|
||||
// maximum-pool-size
|
||||
if (properties.containsKey("hikari.maximum-pool-size"))
|
||||
config.setMaximumPoolSize(Integer.parseInt(properties.getProperty("hikari.maximum-pool-size")));
|
||||
else
|
||||
config.setMaximumPoolSize(500);
|
||||
// minimum-idle
|
||||
if (properties.containsKey("hikari.minimum-idle"))
|
||||
config.setMinimumIdle(Integer.parseInt(properties.getProperty("hikari.minimum-idle")));
|
||||
else
|
||||
config.setMinimumIdle(100);
|
||||
config.setMaxLifetime(0);
|
||||
instance = new HikariDataSource(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
package com.taosdata.taosdemo.components;
|
||||
|
||||
import com.taosdata.taosdemo.utils.TimeStampUtil;
|
||||
|
||||
public final class JdbcTaosdemoConfig {
|
||||
// instance
|
||||
public String host; //host
|
||||
public int port = 6030; //port
|
||||
public String user = "root"; //user
|
||||
public String password = "taosdata"; //password
|
||||
// database
|
||||
public String database = "jdbcdb"; //database
|
||||
public int keep = 3650; //keep
|
||||
public int days = 30; //days
|
||||
public int replica = 1; //replica
|
||||
public int blocks = 16;
|
||||
public int cache = 8;
|
||||
public String precision = "ms";
|
||||
|
||||
//super table
|
||||
public boolean doCreateTable = true;
|
||||
public String superTable = "weather"; //super table name
|
||||
public String prefixOfFields = "col";
|
||||
public int numOfFields;
|
||||
public String prefixOfTags = "tag";
|
||||
public int numOfTags;
|
||||
public String superTableSQL;
|
||||
//sub table
|
||||
public String prefixOfTable = "t";
|
||||
// insert task
|
||||
public boolean autoCreateTable;
|
||||
public long numOfTables = 10;
|
||||
public long numOfRowsPerTable = 10;
|
||||
public int numOfTablesPerSQL = 1;
|
||||
public int numOfValuesPerSQL = 1;
|
||||
public int numOfThreadsForCreate = 1;
|
||||
public int numOfThreadsForInsert = 1;
|
||||
public long startTime;
|
||||
public long timeGap = 1;
|
||||
public int frequency;
|
||||
public int order;
|
||||
public int rate = 10;
|
||||
public long range = 1000l;
|
||||
// select task
|
||||
public String executeSql;
|
||||
// drop task
|
||||
public boolean dropTable = false;
|
||||
|
||||
public static void printHelp() {
|
||||
System.out.println("Usage: java -jar jdbc-taosdemo-2.0.jar [OPTION...]");
|
||||
// instance
|
||||
System.out.println("-host The host to connect to TDengine which you must specify");
|
||||
System.out.println("-port The TCP/IP port number to use for the connection. Default is 6030");
|
||||
System.out.println("-user The TDengine user name to use when connecting to the server. Default is 'root'");
|
||||
System.out.println("-password The password to use when connecting to the server.Default is 'taosdata'");
|
||||
// database
|
||||
System.out.println("-database Destination database. Default is 'jdbcdb'");
|
||||
System.out.println("-keep database keep parameter. Default is 3650");
|
||||
System.out.println("-days database days parameter. Default is 30");
|
||||
System.out.println("-replica database replica parameter. Default 1, min: 1, max: 3");
|
||||
System.out.println("-blocks database blocks parameter. Default is 16");
|
||||
System.out.println("-cache database cache parameter. Default is 8");
|
||||
System.out.println("-precision database precision parameter. Default is ms");
|
||||
|
||||
// super table
|
||||
System.out.println("-doCreateTable do create super table and sub table, true or false, Default true");
|
||||
System.out.println("-superTable super table name. Default 'weather'");
|
||||
System.out.println("-prefixOfFields The prefix of field in super table. Default is 'col'");
|
||||
System.out.println("-numOfFields The number of field in super table. Default is (ts timestamp, temperature float, humidity int).");
|
||||
System.out.println("-prefixOfTags The prefix of tag in super table. Default is 'tag'");
|
||||
System.out.println("-numOfTags The number of tag in super table. Default is (location nchar(64), groupId int).");
|
||||
System.out.println("-superTableSQL specify a sql statement for the super table.\n" +
|
||||
" Default is 'create table weather(ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int). \n" +
|
||||
" if you use this parameter, the numOfFields and numOfTags will be invalid'");
|
||||
// sub table
|
||||
System.out.println("-prefixOfTable The prefix of sub tables. Default is 't'");
|
||||
System.out.println("-numOfTables The number of tables. Default is 1");
|
||||
System.out.println("-numOfThreadsForCreate The number of thread during create sub table. Default is 1");
|
||||
// insert task
|
||||
System.out.println("-autoCreateTable Use auto Create sub tables SQL. Default is false");
|
||||
System.out.println("-numOfRowsPerTable The number of records per table. Default is 1");
|
||||
System.out.println("-numOfThreadsForInsert The number of threads during insert row. Default is 1");
|
||||
System.out.println("-numOfTablesPerSQL The number of table per SQL. Default is 1");
|
||||
System.out.println("-numOfValuesPerSQL The number of value per SQL. Default is 1");
|
||||
System.out.println("-startTime start time for insert task, The format is \"yyyy-MM-dd HH:mm:ss.SSS\".");
|
||||
System.out.println("-timeGap the number of time gap. Default is 1000 ms");
|
||||
System.out.println("-frequency the number of records per second inserted into one table. default is 0, do not control frequency");
|
||||
System.out.println("-order Insert mode--0: In order, 1: Out of order. Default is in order");
|
||||
System.out.println("-rate The proportion of data out of order. effective only if order is 1. min 0, max 100, default is 10");
|
||||
System.out.println("-range The range of data out of order. effective only if order is 1. default is 1000 ms");
|
||||
// query task
|
||||
System.out.println("-executeSql execute a specific sql.");
|
||||
// drop task
|
||||
System.out.println("-dropTable Drop data before quit. Default is false");
|
||||
System.out.println("--help Give this help list");
|
||||
}
|
||||
|
||||
/**
|
||||
* parse args from command line
|
||||
*
|
||||
* @param args command line args
|
||||
* @return JdbcTaosdemoConfig
|
||||
*/
|
||||
public JdbcTaosdemoConfig(String[] args) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
// instance
|
||||
if ("-host".equals(args[i]) && i < args.length - 1) {
|
||||
host = args[++i];
|
||||
}
|
||||
if ("-port".equals(args[i]) && i < args.length - 1) {
|
||||
port = Integer.parseInt(args[++i]);
|
||||
}
|
||||
if ("-user".equals(args[i]) && i < args.length - 1) {
|
||||
user = args[++i];
|
||||
}
|
||||
if ("-password".equals(args[i]) && i < args.length - 1) {
|
||||
password = args[++i];
|
||||
}
|
||||
// database
|
||||
if ("-database".equals(args[i]) && i < args.length - 1) {
|
||||
database = args[++i];
|
||||
}
|
||||
if ("-keep".equals(args[i]) && i < args.length - 1) {
|
||||
keep = Integer.parseInt(args[++i]);
|
||||
}
|
||||
if ("-days".equals(args[i]) && i < args.length - 1) {
|
||||
days = Integer.parseInt(args[++i]);
|
||||
}
|
||||
if ("-replica".equals(args[i]) && i < args.length - 1) {
|
||||
replica = Integer.parseInt(args[++i]);
|
||||
}
|
||||
if ("-blocks".equals(args[i]) && i < args.length - 1) {
|
||||
blocks = Integer.parseInt(args[++i]);
|
||||
}
|
||||
if ("-cache".equals(args[i]) && i < args.length - 1) {
|
||||
cache = Integer.parseInt(args[++i]);
|
||||
}
|
||||
if ("-precision".equals(args[i]) && i < args.length - 1) {
|
||||
precision = args[++i];
|
||||
}
|
||||
// super table
|
||||
if ("-doCreateTable".equals(args[i]) && i < args.length - 1) {
|
||||
doCreateTable = Boolean.parseBoolean(args[++i]);
|
||||
}
|
||||
if ("-superTable".equals(args[i]) && i < args.length - 1) {
|
||||
superTable = args[++i];
|
||||
}
|
||||
if ("-prefixOfFields".equals(args[i]) && i < args.length - 1) {
|
||||
prefixOfFields = args[++i];
|
||||
}
|
||||
if ("-numOfFields".equals(args[i]) && i < args.length - 1) {
|
||||
numOfFields = Integer.parseInt(args[++i]);
|
||||
}
|
||||
if ("-prefixOfTags".equals(args[i]) && i < args.length - 1) {
|
||||
prefixOfTags = args[++i];
|
||||
}
|
||||
if ("-numOfTags".equals(args[i]) && i < args.length - 1) {
|
||||
numOfTags = Integer.parseInt(args[++i]);
|
||||
}
|
||||
if ("-superTableSQL".equals(args[i]) && i < args.length - 1) {
|
||||
superTableSQL = args[++i];
|
||||
}
|
||||
// sub table
|
||||
if ("-prefixOfTable".equals(args[i]) && i < args.length - 1) {
|
||||
prefixOfTable = args[++i];
|
||||
}
|
||||
if ("-numOfTables".equals(args[i]) && i < args.length - 1) {
|
||||
numOfTables = Long.parseLong(args[++i]);
|
||||
}
|
||||
if ("-autoCreateTable".equals(args[i]) && i < args.length - 1) {
|
||||
autoCreateTable = Boolean.parseBoolean(args[++i]);
|
||||
}
|
||||
if ("-numOfThreadsForCreate".equals(args[i]) && i < args.length - 1) {
|
||||
numOfThreadsForCreate = Integer.parseInt(args[++i]);
|
||||
}
|
||||
// insert task
|
||||
if ("-numOfRowsPerTable".equals(args[i]) && i < args.length - 1) {
|
||||
numOfRowsPerTable = Long.parseLong(args[++i]);
|
||||
}
|
||||
if ("-numOfThreadsForInsert".equals(args[i]) && i < args.length - 1) {
|
||||
numOfThreadsForInsert = Integer.parseInt(args[++i]);
|
||||
}
|
||||
if ("-numOfTablesPerSQL".equals(args[i]) && i < args.length - 1) {
|
||||
numOfTablesPerSQL = Integer.parseInt(args[++i]);
|
||||
}
|
||||
if ("-numOfValuesPerSQL".equals(args[i]) && i < args.length - 1) {
|
||||
numOfValuesPerSQL = Integer.parseInt(args[++i]);
|
||||
}
|
||||
if ("-startTime".equals(args[i]) && i < args.length - 1) {
|
||||
startTime = TimeStampUtil.datetimeToLong(args[++i]);
|
||||
}
|
||||
if ("-timeGap".equals(args[i]) && i < args.length - 1) {
|
||||
timeGap = Long.parseLong(args[++i]);
|
||||
}
|
||||
if ("-frequency".equals(args[i]) && i < args.length - 1) {
|
||||
frequency = Integer.parseInt(args[++i]);
|
||||
}
|
||||
if ("-order".equals(args[i]) && i < args.length - 1) {
|
||||
order = Integer.parseInt(args[++i]);
|
||||
}
|
||||
if ("-rate".equals(args[i]) && i < args.length - 1) {
|
||||
rate = Integer.parseInt(args[++i]);
|
||||
if (rate < 0 || rate > 100)
|
||||
throw new IllegalArgumentException("rate must between 0 and 100");
|
||||
}
|
||||
if ("-range".equals(args[i]) && i < args.length - 1) {
|
||||
range = Integer.parseInt(args[++i]);
|
||||
}
|
||||
// select task
|
||||
if ("-executeSql".equals(args[i]) && i < args.length - 1) {
|
||||
executeSql = args[++i];
|
||||
}
|
||||
|
||||
// drop task
|
||||
if ("-dropTable".equals(args[i]) && i < args.length - 1) {
|
||||
dropTable = Boolean.parseBoolean(args[++i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.taosdata.taosdemo.components;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
public class JsonConfig {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
JsonConfig config = new JsonConfig();
|
||||
String str = config.read("insert.json");
|
||||
JSONObject jsonObject = JSONObject.parseObject(str);
|
||||
System.out.println(jsonObject);
|
||||
|
||||
}
|
||||
|
||||
private String read(String fileName) {
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(JsonConfig.class.getClassLoader().getResourceAsStream(fileName))
|
||||
);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.taosdata.taosdemo.dao;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface DatabaseMapper {
|
||||
|
||||
// create database if not exists XXX
|
||||
void createDatabase(String dbname);
|
||||
|
||||
// drop database if exists XXX
|
||||
void dropDatabase(String dbname);
|
||||
|
||||
// create database if not exists XXX keep XX days XX replica XX
|
||||
void createDatabaseWithParameters(Map<String, String> map);
|
||||
|
||||
// use XXX
|
||||
void useDatabase(String dbname);
|
||||
|
||||
//TODO: alter database
|
||||
|
||||
//TODO: show database
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.taosdata.taosdemo.dao;
|
||||
|
||||
import com.taosdata.taosdemo.utils.SqlSpeller;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Map;
|
||||
|
||||
public class DatabaseMapperImpl implements DatabaseMapper {
|
||||
private static final Logger logger = LogManager.getLogger(DatabaseMapperImpl.class);
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
public DatabaseMapperImpl(DataSource dataSource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void createDatabase(String dbname) {
|
||||
String sql = "create database if not exists " + dbname;
|
||||
jdbcTemplate.execute(sql);
|
||||
logger.debug("SQL >>> " + sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropDatabase(String dbname) {
|
||||
String sql = "drop database if exists " + dbname;
|
||||
jdbcTemplate.update(sql);
|
||||
logger.debug("SQL >>> " + sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createDatabaseWithParameters(Map<String, String> map) {
|
||||
String sql = SqlSpeller.createDatabase(map);
|
||||
jdbcTemplate.execute(sql);
|
||||
logger.debug("SQL >>> " + sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void useDatabase(String dbname) {
|
||||
String sql = "use " + dbname;
|
||||
jdbcTemplate.execute(sql);
|
||||
logger.debug("SQL >>> " + sql);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.taosdata.taosdemo.dao;
|
||||
|
||||
import com.taosdata.taosdemo.domain.SubTableMeta;
|
||||
import com.taosdata.taosdemo.domain.SubTableValue;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface SubTableMapper {
|
||||
|
||||
// 创建:子表
|
||||
void createUsingSuperTable(SubTableMeta subTableMeta);
|
||||
|
||||
// 插入:一张子表多个values
|
||||
int insertOneTableMultiValues(SubTableValue subTableValue);
|
||||
|
||||
// 插入:一张子表多个values, 自动建表
|
||||
int insertOneTableMultiValuesUsingSuperTable(SubTableValue subTableValue);
|
||||
|
||||
// 插入:多张表多个values
|
||||
int insertMultiTableMultiValues(List<SubTableValue> tables);
|
||||
|
||||
// 插入:多张表多个values,自动建表
|
||||
int insertMultiTableMultiValuesUsingSuperTable(List<SubTableValue> tables);
|
||||
|
||||
//<!-- TODO:修改子表标签值 alter table ${tablename} set tag tagName=newTagValue-->
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package com.taosdata.taosdemo.dao;
|
||||
|
||||
import com.taosdata.taosdemo.domain.SubTableMeta;
|
||||
import com.taosdata.taosdemo.domain.SubTableValue;
|
||||
import com.taosdata.taosdemo.utils.SqlSpeller;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.List;
|
||||
|
||||
public class SubTableMapperImpl implements SubTableMapper {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(SubTableMapperImpl.class);
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
public SubTableMapperImpl(DataSource dataSource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createUsingSuperTable(SubTableMeta subTableMeta) {
|
||||
String sql = SqlSpeller.createTableUsingSuperTable(subTableMeta);
|
||||
logger.debug("SQL >>> " + sql);
|
||||
jdbcTemplate.execute(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertOneTableMultiValues(SubTableValue subTableValue) {
|
||||
String sql = SqlSpeller.insertOneTableMultiValues(subTableValue);
|
||||
logger.debug("SQL >>> " + sql);
|
||||
|
||||
int affectRows = 0;
|
||||
try {
|
||||
affectRows = jdbcTemplate.update(sql);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return affectRows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertOneTableMultiValuesUsingSuperTable(SubTableValue subTableValue) {
|
||||
String sql = SqlSpeller.insertOneTableMultiValuesUsingSuperTable(subTableValue);
|
||||
logger.debug("SQL >>> " + sql);
|
||||
|
||||
int affectRows = 0;
|
||||
try {
|
||||
affectRows = jdbcTemplate.update(sql);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return affectRows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertMultiTableMultiValues(List<SubTableValue> tables) {
|
||||
String sql = SqlSpeller.insertMultiSubTableMultiValues(tables);
|
||||
logger.debug("SQL >>> " + sql);
|
||||
int affectRows = 0;
|
||||
try {
|
||||
affectRows = jdbcTemplate.update(sql);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return affectRows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertMultiTableMultiValuesUsingSuperTable(List<SubTableValue> tables) {
|
||||
String sql = SqlSpeller.insertMultiTableMultiValuesUsingSuperTable(tables);
|
||||
logger.debug("SQL >>> " + sql);
|
||||
int affectRows = 0;
|
||||
try {
|
||||
affectRows = jdbcTemplate.update(sql);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return affectRows;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.taosdata.taosdemo.dao;
|
||||
|
||||
import com.taosdata.taosdemo.domain.SuperTableMeta;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface SuperTableMapper {
|
||||
|
||||
// 创建超级表 create table if not exists xxx.xxx (f1 type1, f2 type2, ... ) tags( t1 type1, t2 type2 ...)
|
||||
void createSuperTable(SuperTableMeta tableMetadata);
|
||||
|
||||
// 删除超级表 drop table if exists xxx;
|
||||
void dropSuperTable(String database, String name);
|
||||
|
||||
//<!-- TODO:查询所有超级表信息 show stables -->
|
||||
|
||||
//<!-- TODO:查询表结构 describe stable -->
|
||||
|
||||
//<!-- TODO:增加列 alter table ${tablename} add column fieldName dataType -->
|
||||
|
||||
//<!-- TODO:删除列 alter table ${tablename} drop column fieldName -->
|
||||
|
||||
//<!-- TODO:添加标签 alter table ${tablename} add tag new_tagName tag_type -->
|
||||
|
||||
//<!-- TODO:删除标签 alter table ${tablename} drop tag_name -->
|
||||
|
||||
//<!-- TODO:修改标签名 alter table ${tablename} change tag old_tagName new_tagName -->
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.taosdata.taosdemo.dao;
|
||||
|
||||
import com.taosdata.taosdemo.domain.SuperTableMeta;
|
||||
import com.taosdata.taosdemo.utils.SqlSpeller;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
public class SuperTableMapperImpl implements SuperTableMapper {
|
||||
private static final Logger logger = LogManager.getLogger(SuperTableMapperImpl.class);
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
public SuperTableMapperImpl(DataSource dataSource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createSuperTable(SuperTableMeta tableMetadata) {
|
||||
String sql = SqlSpeller.createSuperTable(tableMetadata);
|
||||
logger.debug("SQL >>> " + sql);
|
||||
jdbcTemplate.execute(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropSuperTable(String database, String name) {
|
||||
String sql = "drop table if exists " + database + "." + name;
|
||||
logger.debug("SQL >>> " + sql);
|
||||
jdbcTemplate.execute(sql);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.taosdata.taosdemo.dao;
|
||||
|
||||
import com.taosdata.taosdemo.domain.TableMeta;
|
||||
import com.taosdata.taosdemo.domain.TableValue;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface TableMapper {
|
||||
|
||||
// 创建:普通表
|
||||
void create(TableMeta tableMeta);
|
||||
|
||||
// 插入:一张表多个value
|
||||
int insertOneTableMultiValues(TableValue values);
|
||||
|
||||
// 插入: 一张表多个value,指定的列
|
||||
int insertOneTableMultiValuesWithColumns(TableValue values);
|
||||
|
||||
// 插入:多个表多个value
|
||||
int insertMultiTableMultiValues(List<TableValue> tables);
|
||||
|
||||
// 插入:多个表多个value, 指定的列
|
||||
int insertMultiTableMultiValuesWithColumns(List<TableValue> tables);
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.taosdata.taosdemo.dao;
|
||||
|
||||
import com.taosdata.taosdemo.domain.TableMeta;
|
||||
import com.taosdata.taosdemo.domain.TableValue;
|
||||
import com.taosdata.taosdemo.utils.SqlSpeller;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TableMapperImpl implements TableMapper {
|
||||
private static final Logger logger = LogManager.getLogger(TableMapperImpl.class);
|
||||
private JdbcTemplate template;
|
||||
|
||||
@Override
|
||||
public void create(TableMeta tableMeta) {
|
||||
String sql = SqlSpeller.createTable(tableMeta);
|
||||
logger.debug("SQL >>> " + sql);
|
||||
template.execute(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertOneTableMultiValues(TableValue values) {
|
||||
String sql = SqlSpeller.insertOneTableMultiValues(values);
|
||||
logger.debug("SQL >>> " + sql);
|
||||
return template.update(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertOneTableMultiValuesWithColumns(TableValue values) {
|
||||
String sql = SqlSpeller.insertOneTableMultiValuesWithColumns(values);
|
||||
logger.debug("SQL >>> " + sql);
|
||||
return template.update(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertMultiTableMultiValues(List<TableValue> tables) {
|
||||
String sql = SqlSpeller.insertMultiTableMultiValues(tables);
|
||||
logger.debug("SQL >>> " + sql);
|
||||
return template.update(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertMultiTableMultiValuesWithColumns(List<TableValue> tables) {
|
||||
String sql = SqlSpeller.insertMultiTableMultiValuesWithColumns(tables);
|
||||
logger.debug("SQL >>> " + sql);
|
||||
return template.update(sql);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.taosdata.taosdemo.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FieldMeta {
|
||||
private String name;
|
||||
private String type;
|
||||
|
||||
public FieldMeta() {
|
||||
}
|
||||
|
||||
public FieldMeta(String name, String type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.taosdata.taosdemo.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FieldValue<T> {
|
||||
private String name;
|
||||
private T value;
|
||||
|
||||
public FieldValue() {
|
||||
}
|
||||
|
||||
public FieldValue(String name, T value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.taosdata.taosdemo.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class RowValue {
|
||||
private List<FieldValue> fields;
|
||||
|
||||
public RowValue(List<FieldValue> fields) {
|
||||
this.fields = fields;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.taosdata.taosdemo.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class SubTableMeta {
|
||||
|
||||
private String database;
|
||||
private String supertable;
|
||||
private String name;
|
||||
private List<TagValue> tags;
|
||||
private List<FieldMeta> fields;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.taosdata.taosdemo.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class SubTableValue {
|
||||
|
||||
private String database;
|
||||
private String supertable;
|
||||
private String name;
|
||||
private List<TagValue> tags;
|
||||
private List<RowValue> values;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.taosdata.taosdemo.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class SuperTableMeta {
|
||||
|
||||
private String database;
|
||||
private String name;
|
||||
private List<FieldMeta> fields;
|
||||
private List<TagMeta> tags;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.taosdata.taosdemo.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class TableMeta {
|
||||
|
||||
private String database;
|
||||
private String name;
|
||||
private List<FieldMeta> fields;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.taosdata.taosdemo.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class TableValue {
|
||||
|
||||
private String database;
|
||||
private String name;
|
||||
private List<FieldMeta> columns;
|
||||
private List<RowValue> values;
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.taosdata.taosdemo.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TagMeta {
|
||||
private String name;
|
||||
private String type;
|
||||
|
||||
public TagMeta() {
|
||||
|
||||
}
|
||||
|
||||
public TagMeta(String name, String type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.taosdata.taosdemo.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TagValue<T> {
|
||||
private String name;
|
||||
private T value;
|
||||
|
||||
public TagValue() {
|
||||
}
|
||||
|
||||
public TagValue(String name, T value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.taosdata.taosdemo.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class AbstractService {
|
||||
|
||||
protected int getAffectRows(List<Future<Integer>> futureList) {
|
||||
int count = 0;
|
||||
for (Future<Integer> future : futureList) {
|
||||
try {
|
||||
count += future.get();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
protected int getAffectRows(Future<Integer> future) {
|
||||
int count = 0;
|
||||
try {
|
||||
count += future.get();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.taosdata.taosdemo.service;
|
||||
|
||||
import com.taosdata.taosdemo.dao.DatabaseMapper;
|
||||
import com.taosdata.taosdemo.dao.DatabaseMapperImpl;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Map;
|
||||
|
||||
public class DatabaseService {
|
||||
|
||||
private final DatabaseMapper databaseMapper;
|
||||
|
||||
public DatabaseService(DataSource dataSource) {
|
||||
this.databaseMapper = new DatabaseMapperImpl(dataSource);
|
||||
}
|
||||
|
||||
// 建库,指定 name
|
||||
public void createDatabase(String database) {
|
||||
databaseMapper.createDatabase(database);
|
||||
}
|
||||
|
||||
// 建库,指定参数 keep,days,replica等
|
||||
public void createDatabase(Map<String, String> map) {
|
||||
if (map.isEmpty())
|
||||
return;
|
||||
if (map.containsKey("database") && map.size() == 1) {
|
||||
createDatabase(map.get("database"));
|
||||
return;
|
||||
}
|
||||
databaseMapper.createDatabaseWithParameters(map);
|
||||
}
|
||||
|
||||
// drop database
|
||||
public void dropDatabase(String dbname) {
|
||||
databaseMapper.dropDatabase(dbname);
|
||||
}
|
||||
|
||||
// use database
|
||||
public void useDatabase(String dbname) {
|
||||
databaseMapper.useDatabase(dbname);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package com.taosdata.taosdemo.service;
|
||||
|
||||
import com.taosdata.jdbc.utils.SqlSyntaxValidator;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class QueryService {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
public QueryService(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
/* only select or show SQL Statement is valid for executeQuery */
|
||||
public Boolean[] areValidQueries(String[] sqls) {
|
||||
Boolean[] ret = new Boolean[sqls.length];
|
||||
for (int i = 0; i < sqls.length; i++) {
|
||||
ret[i] = true;
|
||||
if (!SqlSyntaxValidator.isValidForExecuteQuery(sqls[i])) {
|
||||
ret[i] = false;
|
||||
continue;
|
||||
}
|
||||
try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) {
|
||||
stmt.executeQuery(sqls[i]);
|
||||
} catch (SQLException e) {
|
||||
ret[i] = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public String[] generateSuperTableQueries(String dbName) {
|
||||
List<String> sqls = new ArrayList<>();
|
||||
try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) {
|
||||
stmt.execute("use " + dbName);
|
||||
ResultSet rs = stmt.executeQuery("show stables");
|
||||
while (rs.next()) {
|
||||
String name = rs.getString("name");
|
||||
sqls.add("select count(*) from " + dbName + "." + name);
|
||||
sqls.add("select first(*) from " + dbName + "." + name);
|
||||
sqls.add("select last(*) from " + dbName + "." + name);
|
||||
sqls.add("select last_row(*) from " + dbName + "." + name);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
String[] sqlArr = new String[sqls.size()];
|
||||
return sqls.toArray(sqlArr);
|
||||
}
|
||||
|
||||
public void querySuperTable(String[] sqls, int interval, int threadCount, long queryTimes) {
|
||||
List<Thread> threads = IntStream.range(0, threadCount).mapToObj(i -> new Thread(() -> {
|
||||
// do query
|
||||
try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) {
|
||||
long count = queryTimes;
|
||||
if (count == 0)
|
||||
count = Long.MAX_VALUE;
|
||||
while (count > 0) {
|
||||
for (String sql : sqls) {
|
||||
long start = System.currentTimeMillis();
|
||||
ResultSet rs = stmt.executeQuery(sql);
|
||||
printResultSet(rs);
|
||||
long end = System.currentTimeMillis();
|
||||
long timecost = end - start;
|
||||
if (interval - timecost > 0) {
|
||||
TimeUnit.MILLISECONDS.sleep(interval - timecost);
|
||||
}
|
||||
}
|
||||
count--;
|
||||
}
|
||||
|
||||
} catch (SQLException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
})).collect(Collectors.toList());
|
||||
threads.stream().forEach(Thread::start);
|
||||
for (Thread thread : threads) {
|
||||
try {
|
||||
thread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void printResultSet(ResultSet rs) throws SQLException {
|
||||
ResultSetMetaData meta = rs.getMetaData();
|
||||
while (rs.next()) {
|
||||
for (int i = 1; i <= meta.getColumnCount(); i++) {
|
||||
System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue