TDengine connectors
-TDengine provides many connectors for development, including C/C++, JAVA, Python, RESTful, Go, etc.
+TDengine provides many connectors for development, including C/C++, JAVA, Python, RESTful, Go, Node.JS, etc.
C/C++ API
C/C++ APIs are similar to the MySQL APIs. Applications should include TDengine head file taos.h to use C/C++ APIs by adding the following line in code:
#include <taos.h>
-Make sure TDengine library libtaos.so is installed and use -ltaos option to link the library when compile. The return values of all APIs are -1 or NULL for failure.
+Make sure TDengine library libtaos.so is installed and use -ltaos option to link the library when compiling. The return values of all APIs are -1 or NULL for failure.
C/C++ sync API
Sync APIs are those APIs waiting for responses from the server after sending a request. TDengine has the following sync APIs:
-
@@ -35,21 +35,21 @@
The 12 APIs are the most important APIs frequently used. Users can check taos.h file for more API information.
Note: The connection to a TDengine server is not multi-thread safe. So a connection can only be used by one thread.
C/C++ async API
-In addition to sync APIs, TDengine also provides async APIs, which are more efficient. Async APIs are returned right away without waiting for the response from ther server, so the application can continute with other tasks without blocking. So async APIs are more efficient, especially in a poor network.
+In addition to sync APIs, TDengine also provides async APIs, which are more efficient. Async APIs are returned right away without waiting for a response from the server, allowing the application to continute with other tasks without blocking. So async APIs are more efficient, especially useful when in a poor network.
All async APIs require callback functions. The callback functions have the format:
void fp(void *param, TAOS_RES * res, TYPE param3)
The first two parameters of the callback function are the same for all async APIs. The third parameter is different for different APIs. Generally, the first parameter is the handle provided to the API for action. The second parameter is a result handle.
-void taos_query_a(TAOS *taos, char *sqlstr, void (*fp)(void *param, TAOS_RES *, int code), void *param);
The async query interface. taos is the handle returned by taos_connect interface. sqlstr is the SQL command to run. fp is the callback function. param is the parameter required by the callback function. The third parameter of the callback function code is 0 (for success) or -1 (for failure). Applications mainly handle with the second parameter, the returned result set.
+void taos_fetch_rows_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, int numOfRows), void *param);
The async API to fetch a batch of rows, which should only be used with a taos_query_a call. The parameter res is the result handle returned by taos_query_a. fp is the callback function. param is a user-defined structure to pass to fp. The parameter numOfRows is the number of result rows in the current fetch cycle. In the callback function, applications should call taos_fetch_row to get records from the result handle. After getting a batch of results, applications should continue to call taos_fetch_rows_a API to handle the next batch, until the numOfRows is 0 (for no more data to fetch) or -1 (for failure).
-
+void taos_fetch_row_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, TAOS_ROW), void *param);
void taos_fetch_row_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), void *param);
The async API to fetch a result row. res is the result handle. fp is the callback function. param is a user-defined structure to pass to fp. The third parameter of the callback function is a single result row, which is different from that of taos_fetch_rows_a API. With this API, it is not necessary to call taos_fetch_row to retrieve each result row, which is handier than taos_fetch_rows_a but less efficient.
The async query interface. taos is the handle returned by taos_connect interface. sqlstr is the SQL command to run. fp is the callback function. param is the parameter required by the callback function. The third parameter of the callback function code is 0 (for success) or a negative number (for failure, call taos_errstr to get the error as a string). Applications mainly handle with the second parameter, the returned result set.
Applications may apply operations on multiple tables. However, it is important to make sure the operations on the same table are serialized. That means after sending an insert request in a table to the server, no operations on the table are allowed before a request is received.
C/C++ continuous query interface
-TDengine provides APIs for continuous query driven by time, which run query periodically in the background. There are only two APIs:
+TDengine provides APIs for continuous query driven by time, which run queries periodically in the background. There are only two APIs:
TAOS_STREAM *taos_open_stream(TAOS *taos, char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), int64_t stime, void *param, void (*callback)(void *));
The API is used to create a continuous query.
@@ -80,8 +80,8 @@ The API used to get the description of each column.
- data: the returned data array. If no data is returned, only an affected_rows field is listed
- rows: the number of rows returned
Java Connector
JDBC Interface
TDengine provides a JDBC driver taos-jdbcdriver-x.x.x.jar
for Enterprise Java developers. TDengine's JDBC Driver is implemented as a subset of the standard JDBC 3.0 Specification and supports the most common Java development frameworks. The driver is currently not published to the online dependency repositories such as Maven Center Repository, and users should manually add the .jar
file to their local dependency repository.
Please note the JDBC driver itself relies on a native library written in C. On a Linux OS, the driver relies on a libtaos.so
native library, where .so stands for "Shared Object". After the successful installation of the TDengine on Linux, libtaos.so
should be automatically copied to /usr/local/lib/taos
and added to the system's default searching path. On a Windows OS, the driver relies on a taos.dll
native library, where .dll stands for "Dynamic Link Library". After the successful installation of TDengine client on Windows, the taos-jdbcdriver.jar
file can be found in C:/TDengine/driver/JDBC
; the taos.dll
file can be found in C:/TDengine/driver/C
and should have been automatically copied to the system's searching path C:/Windows/System32
.
Developers can refer to the Oracle's official JDBC API documentation for detailed usage on classes and methods. There do exist differences of connection configurations and supported methods in the driver implementation between TDengine and traditional relational databases.
+Please note the JDBC driver itself relies on a native library written in C. On a Linux OS, the driver relies on a libtaos.so
native library, where .so stands for "Shared Object". After the successful installation of TDengine on Linux, libtaos.so
should be automatically copied to /usr/local/lib/taos
and added to the system's default search path. On a Windows OS, the driver relies on a taos.dll
native library, where .dll stands for "Dynamic Link Library". After the successful installation of the TDengine client on Windows, the taos-jdbcdriver.jar
file can be found in C:/TDengine/driver/JDBC
; the taos.dll
file can be found in C:/TDengine/driver/C
and should have been automatically copied to the system's searching path C:/Windows/System32
.
Developers can refer to the Oracle's official JDBC API documentation for detailed usage on classes and methods. However, there are some differences of connection configurations and supported methods in the driver implementation between TDengine and traditional relational databases.
For database connections, TDengine's JDBC driver has the following configurable parameters in the JDBC URL. The standard format of a TDengine JDBC URL is:
jdbc:TSDB://{host_ip}:{port}/{database_name}?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]
where {}
marks the required parameters and []
marks the optional. The usage of each parameter is pretty straightforward:
Example
+Example
Use curl command to query all the data in table t1 of database demo:
curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.t1' 192.168.0.1:6020/rest/sql
@@ -216,7 +216,7 @@ public Connection getConn() throws Exception{
To get started, just type in the following to install the connector through npm.
npm install td-connector
It is highly suggested you use npm. If you don't have it installed, you can also just copy the nodejs folder from src/connector/nodejs/ into your node project folder.
-To interact with TDengine, we make use of the [node-gyp[(https://github.com/nodejs/node-gyp)] library. To install, you will need to install the following depending on platform (the following instructions are quoted from node-gyp)
+To interact with TDengine, we make use of the node-gyp library. To install, you will need to install the following depending on platform (the following instructions are quoted from node-gyp)
On Unix
python
(v2.7
recommended,v3.x.x
is not supported)
@@ -249,143 +249,36 @@ public Connection getConn() throws Exception{
If the above steps didn't work for you, please visit Microsoft's Node.js Guidelines for Windows for additional tips.
To target native ARM64 Node.js on Windows 10 on ARM, add the components "Visual C++ compilers and libraries for ARM64" and "Visual C++ ATL for ARM64".
-Usage
-To use the connector, first request the td-connector
package. Running the function taos.connect
with the connection options passed in as an object will return a TDengine connection object. A cursor needs to be intialized in order to interact with TDengine from node.
Usage
+The following is a short summary of the basic usage of the connector, the full api and documentation can be found here
+Connection
+To use the connector, first require the library td-connector
. Running the function taos.connect
with the connection options passed in as an object will return a TDengine connection object. The required connection option is host
, other options if not set, will be the default values as shown below.
A cursor also needs to be initialized in order to interact with TDengine from Node.js.
const taos = require('td-connector');
var conn = taos.connect({host:"127.0.0.1", user:"root", password:"taosdata", config:"/etc/taos",port:0})
-var c1 = conn.cursor(); // Initializing a new cursor
-We can now start executing queries through the cursor.execute
function.
c1.execute('show databases;')
-We can get the results of the queries by doing the following
-var data = c1.fetchall();
-console.log(c1.fieldNames); // Returns the names of the columns/fields
-console.log(data); // Logs all the data from the query as an array of arrays, each of which represents a row and data[row_number] is sorted in order of the fields
-Example
-The following is an example use of the connector showing how to make a table with weather data, insert random data, and then retrieve it.
-// Get the td-connector package
-const taos = require('td-connector');
-
-/* We will connect to TDengine by passing an object comprised of connection options to taos.connect and store the
- * connection to the variable conn
- */
-/*
- * Connection Options
- * host: the host to connect to
- * user: the use to login as
- * password: the password for the above user to login
- * config: the location of the taos.cfg file, by default it is in /etc/taos
- * port: the port we connect through
- */
-var conn = taos.connect({host:"127.0.0.1", user:"root", password:"taosdata", config:"/etc/taos",port:0});
-
-// Initialize our TDengineCursor, which we use to interact with TDengine
-var c1 = conn.cursor();
-
-// c1.execute(query) will execute the query
-// Let's create a database named db
-try {
- c1.execute('create database db;');
-}
-catch(err) {
- conn.close();
- throw err;
-}
-
-// Now we will use database db
-try {
- c1.execute('use db;');
-}
-catch (err) {
- conn.close();
- throw err;
-}
-
-// Let's create a table called weather
-// which stores some weather data like humidity, AQI (air quality index), temperature, and some notes as text
-try {
- c1.execute('create table if not exists weather (ts timestamp, humidity smallint, aqi int, temperature float, notes binary(30));');
-}
-catch (err) {
- conn.close();
- throw err;
-}
-
-// Let's get the description of the table weather
-try {
- c1.execute('describe db.weather');
-}
-catch (err) {
- conn.close();
- throw err;
-}
-
-// To get results, we run the function c1.fetchall()
-// It only returns the query results as an array of result rows, but also stores the latest results in c1.data
-try {
- var tableDesc = c1.fetchall(); // The description variable here is equal to c1.data;
- console.log(tableDesc);
-}
-catch (err) {
- conn.close();
- throw err;
-}
-
-// Let's try to insert some random generated data to test with
-
-let stime = new Date();
-let interval = 1000;
-
-// Timestamps must be in the form of "YYYY-MM-DD HH:MM:SS.MMM" if they are in milliseconds
-// "YYYY-MM-DD HH:MM:SS.MMMMMM" if they are in microseconds
-// Thus, we create the following function to convert a javascript Date object to the correct formatting
-function convertDateToTS(date) {
- let tsArr = date.toISOString().split("T")
- return "\"" + tsArr[0] + " " + tsArr[1].substring(0, tsArr[1].length-1) + "\"";
-}
-
-try {
- for (let i = 0; i < 10000; i++) {
- stime.setMilliseconds(stime.getMilliseconds() + interval);
- let insertData = [convertDateToTS(stime),
- parseInt(Math.random()*100),
- parseInt(Math.random()*300),
- parseFloat(Math.random()*10 + 30),
- "\"random note!\""];
- c1.execute('insert into db.weather values(' + insertData.join(',') + ' );');
- }
-}
-catch (err) {
- conn.close();
- throw err;
-}
-
-// Now let's look at our newly inserted data
-var retrievedData;
-try {
- c1.execute('select * from db.weather;')
- retrievedData = c1.fetchall();
-
- // c1.fieldNames stores the names of each column retrieved
- console.log(c1.fieldNames);
- console.log(retrievedData);
- // timestamps retrieved are always JS Date Objects
- // Numbers are numbers, big ints are big ints, and strings are strings
-}
-catch (err) {
- conn.close();
- throw err;
-}
-
-// Let's try running some basic functions
-try {
- c1.execute('select count(*), avg(temperature), max(temperature), min(temperature), stddev(temperature) from db.weather;')
- c1.fetchall();
- console.log(c1.fieldNames);
- console.log(c1.data);
-}
-catch(err) {
- conn.close();
- throw err;
-}
-
-conn.close();
Back