index.html 32.1 KB
Newer Older
S
StoneT2000 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
<!DOCTYPE html><html lang='en'><head><title>Documentation | Taos Data</title><meta name='description' content='TDengine is an open-source big data platform for IoT. Along with a 10x faster time-series database, it provides caching, stream computing, message queuing, and other functionalities. It is designed and optimized for Internet of Things, Connected Cars, and Industrial IoT. Read the documentation for TDengine here to get started right away.'><meta name='keywords' content='TDengine, Big Data, Open Source, IoT, Connected Cars, Industrial IoT, time-series database, caching, stream computing, message queuing, IT infrastructure monitoring, application performance monitoring, Internet of Things,TAOS Data, Documentation, programming, coding, syntax, frequently asked questions, questions, faq'><meta name='title' content='Documentation | Taos Data'><meta property='og:site_name' content='Taos Data'/><meta property='og:title' content='Documentation | Taos Data'/><meta property='og:type' content='article'/><meta property='og:url' content='https://www.taosdata.com/en/documentation/connector/index.php'/><meta property='og:description' content='TDengine is an open-source big data platform for IoT. Along with a 10x faster time-series database, it provides caching, stream computing, message queuing, and other functionalities. It is designed and optimized for Internet of Things, Connected Cars, and Industrial IoT. Read the documentation for TDengine here to get started right away.' /><link rel='canonical' href='https://www.taosdata.com/en/documentation/connector/index.php'/><script src='../lib/jquery-3.4.1.min.js' type='application/javascript'></script><link href='../lib/bootstrap.min.css' rel='stylesheet'><link href='../styles/base.min.css' rel='stylesheet'><link rel='stylesheet' href='../lib/docs/taosdataprettify.css'><link rel='stylesheet' href='../lib/docs/docs.css'><script src='../lib/docs/prettify.js'></script><script src='../lib/docs/prettyprint-sql.js'></script></head><body><script>$('#documentation-href').addClass('active')</script><div class='container-fluid'><main class='content-wrapper'><section class='documentation'><a href='../index.html'>Back</a><h1>TDengine connectors</h1>
<p>TDengine provides many connectors for development, including C/C++, JAVA, Python, RESTful, Go, etc.</p>
<a class='anchor' id='C/C++-API'></a><h2>C/C++ API</h2>
<p>C/C++ APIs are similar to the MySQL APIs. Applications should include TDengine head file <em>taos.h</em> to use C/C++ APIs by adding the following line in code:</p>
<pre><code class="C language-C">#include &lt;taos.h&gt;</code></pre>
<p>Make sure TDengine library <em>libtaos.so</em> is installed and use <em>-ltaos</em> option to link the library when compile. The return values of all APIs are <em>-1</em> or <em>NULL</em> for failure.</p>
<a class='anchor' id='C/C++-sync-API'></a><h3>C/C++ sync API</h3>
<p>Sync APIs are those APIs waiting for responses from the server after sending a request. TDengine has the following sync APIs:</p>
<ul>
<li><p><code>TAOS *taos_connect(char *ip, char *user, char *pass, char *db, int port)</code></p>
<p>Open a connection to a TDengine server. The parameters are <em>ip</em> (IP address of the server), <em>user</em> (username to login), <em>pass</em> (password to login), <em>db</em> (database to use after connection) and <em>port</em> (port number to connect). The parameter <em>db</em> can be NULL for no database to use after connection. Otherwise, the database should exist before connection or a connection error is reported. The handle returned by this API should be kept for future use.</p></li>
<li><p><code>void taos_close(TAOS *taos)</code></p>
<p>Close a connection to a TDengine server by the handle returned by <em>taos_connect</em>`</p></li>
<li><p><code>int taos_query(TAOS *taos, char *sqlstr)</code></p>
<p>The API used to run a SQL command. The command can be DQL or DML. The parameter <em>taos</em> is the handle returned by <em>taos_connect</em>. Return value <em>-1</em> means failure.</p></li>
<li><p><code>TAOS_RES *taos_use_result(TAOS *taos)</code></p>
<p>Use the result after running <em>taos_query</em>. The handle returned should be kept for future fetch.</p></li>
<li><p><code>TAOS_ROW taos_fetch_row(TAOS_RES *res)</code></p>
<p>Fetch a row of return results through <em>res</em>, the handle returned by <em>taos_use_result</em>.</p></li>
<li><p><code>int taos_num_fields(TAOS_RES *res)</code></p>
<p>Get the number of fields in the return result.</p></li>
<li><p><code>TAOS_FIELD *taos_fetch_fields(TAOS_RES *res)</code></p>
<p>Fetch the description of each field. The description includes the property of data type, field name, and bytes. The API should be used with <em>taos_num_fields</em> to fetch a row of data.</p></li>
<li><p><code>void taos_free_result(TAOS_RES *res)</code></p>
<p>Free the resources used by a result set. Make sure to call this API after fetching results or memory leak would happen.</p></li>
<li><p><code>void taos_init()</code></p>
<p>Initialize the environment variable used by TDengine client. The API is not necessary since it is called int <em>taos_connect</em> by default.</p></li>
<li><p><code>char *taos_errstr(TAOS *taos)</code></p>
<p>Return the reason of the last API call failure. The return value is a string.</p></li>
<li><p><code>int *taos_errno(TAOS *taos)</code></p>
<p>Return the error code of the last API call failure. The return value is an integer.</p></li>
<li><p><code>int taos_options(TSDB_OPTION option, const void * arg, ...)</code></p>
<p>Set client options. The parameter <em>option</em> supports values of <em>TSDB_OPTION_CONFIGDIR</em> (configuration directory), <em>TSDB_OPTION_SHELL_ACTIVITY_TIMER</em>, <em>TSDB_OPTION_LOCALE</em> (client locale) and <em>TSDB_OPTION_TIMEZONE</em> (client timezone).</p></li>
</ul>
<p>The 12 APIs are the most important APIs frequently used. Users can check <em>taos.h</em> file for more API information.</p>
<p><strong>Note</strong>: The connection to a TDengine server is not multi-thread safe. So a connection can only be used by one thread.</p>
<a class='anchor' id='C/C++-async-API'></a><h3>C/C++ async API</h3>
<p>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.</p>
<p>All async APIs require callback functions. The callback functions have the format:</p>
<pre><code class="C language-C">void fp(void *param, TAOS_RES * res, TYPE param3)</code></pre>
<p>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.</p>
<ul>
<li><p><code>void taos_query_a(TAOS *taos, char *sqlstr, void (*fp)(void *param, TAOS_RES *, int code), void *param);</code></p>
<p>The async query interface. <em>taos</em> is the handle returned by <em>taos_connect</em> interface. <em>sqlstr</em> is the SQL command to run. <em>fp</em> is the callback function. <em>param</em> is the parameter required by the callback function. The third parameter of the callback function <em>code</em> is <em>0</em> (for success) or <em>-1</em> (for failure). Applications mainly handle with the second parameter, the returned result set.</p></li>
<li><p><code>void taos_fetch_rows_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, int numOfRows), void *param);</code></p>
<p>The async API to fetch a batch of rows, which should only be used with a <em>taos_query_a</em> call. The parameter <em>res</em> is the result handle returned by <em>taos_query_a</em>. <em>fp</em> is the callback function. <em>param</em> is a user-defined structure to pass to <em>fp</em>. The parameter <em>numOfRows</em> is the number of result rows in the current fetch cycle. In the callback function, applications should call <em>taos_fetch_row</em> to get records from the result handle. After getting a batch of results, applications should continue to call <em>taos_fetch_rows_a</em> API to handle the next batch, until the <em>numOfRows</em> is <em>0</em> (for no more data to fetch) or <em>-1</em> (for failure).</p></li>
<li><p><code>void taos_fetch_row_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, TAOS_ROW), void *param);</code></p>
<p>The async API to fetch a result row. <em>res</em> is the result handle. <em>fp</em> is the callback function. <em>param</em> is a user-defined structure to pass to <em>fp</em>. The third parameter of the callback function is a single result row, which is different from that of <em>taos_fetch_rows_a</em> API. With this API, it is not necessary to call <em>taos_fetch_row</em> to retrieve each result row, which is handier than <em>taos_fetch_rows_a</em> but less efficient.</p></li>
</ul>
<p>Applications may apply operations on multiple tables. However, <strong>it is important to make sure the operations on the same table are serialized</strong>. 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.</p>
<a class='anchor' id='C/C++-continuous-query-interface'></a><h3>C/C++ continuous query interface</h3>
<p>TDengine provides APIs for continuous query driven by time, which run query periodically in the background. There are only two APIs:</p>
<ul>
<li><p><code>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 *));</code></p>
<p>The API is used to create a continuous query.</p></li>
<li><p><em>taos</em>: the connection handle returned by <em>taos_connect</em>.</p></li>
<li><p><em>sqlstr</em>: the SQL string to run. Only query commands are allowed.</p></li>
<li><p><em>fp</em>: the callback function to run after a query</p></li>
<li><p><em>param</em>: a parameter passed to <em>fp</em></p></li>
<li><p><em>stime</em>: the time of the stream starts in the form of epoch milliseconds. If <em>0</em> is given, the start time is set as the current time.</p></li>
<li><p><em>callback</em>: a callback function to run when the continuous query stops automatically.</p>
<p>The API is expected to return a handle for success. Otherwise, a NULL pointer is returned.</p></li>
<li><p><code>void taos_close_stream (TAOS_STREAM *tstr)</code></p>
<p>Close the continuous query by the handle returned by <em>taos_open_stream</em>. Make sure to call this API when the continuous query is not needed anymore.</p></li>
</ul>
<a class='anchor' id='C/C++-subscription-API'></a><h3>C/C++ subscription API</h3>
<p>For the time being, TDengine supports subscription on one table. It is implemented through periodic pulling from a TDengine server. </p>
<ul>
<li><p><code>TAOS_SUB *taos_subscribe(char *host, char *user, char *pass, char      *db, char *table, long time, int mseconds)</code>
The API is used to start a subscription session by given a handle. The parameters required are <em>host</em> (IP address of a TDenginer server), <em>user</em> (username), <em>pass</em> (password), <em>db</em> (database to use), <em>table</em> (table name to subscribe), <em>time</em> (start time to subscribe, 0 for now), <em>mseconds</em> (pulling period). If failed to open a subscription session, a <em>NULL</em> pointer is returned.</p></li>
<li><p><code>TAOS_ROW taos_consume(TAOS_SUB *tsub)</code>
The API used to get the new data from a TDengine server. It should be put in an infinite loop. The parameter <em>tsub</em> is the handle returned by <em>taos_subscribe</em>. If new data are updated, the API will return a row of the result. Otherwise, the API is blocked until new data arrives. If <em>NULL</em> pointer is returned, it means an error occurs.</p></li>
<li><p><code>void taos_unsubscribe(TAOS_SUB *tsub)</code>
Stop a subscription session by the handle returned by <em>taos_subscribe</em>.</p></li>
<li><p><code>int taos_num_subfields(TAOS_SUB *tsub)</code>
The API used to get the number of fields in a row.</p></li>
<li><p><code>TAOS_FIELD *taos_fetch_subfields(TAOS_RES *res)</code>
The API used to get the description of each column.</p></li>
</ul>
<a class='anchor' id='Java-Connector'></a><h2>Java Connector</h2>
<a class='anchor' id='JDBC-Interface'></a><h3>JDBC Interface</h3>
<p>TDengine provides a JDBC driver <code>taos-jdbcdriver-x.x.x.jar</code> 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 <code>.jar</code> file to their local dependency repository.</p>
<p>Please note the JDBC driver itself relies on a native library written in C. On a Linux OS, the driver relies on a <code>libtaos.so</code> native library, where .so stands for "Shared Object". After the successful installation of the TDengine on Linux, <code>libtaos.so</code> should be automatically copied to <code>/usr/local/lib/taos</code> and added to the system's default searching path. On a Windows OS, the driver relies on a <code>taos.dll</code> native library, where .dll stands for "Dynamic Link Library". After the successful installation of TDengine client on Windows, the <code>taos-jdbcdriver.jar</code> file can be found in <code>C:/TDengine/driver/JDBC</code>; the <code>taos.dll</code> file can be found in <code>C:/TDengine/driver/C</code> and should have been automatically copied to the system's searching path <code>C:/Windows/System32</code>. </p>
<p>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. </p>
<p>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:</p>
<p><code>jdbc:TSDB://{host_ip}:{port}/{database_name}?[user={user}|&amp;password={password}|&amp;charset={charset}|&amp;cfgdir={config_dir}|&amp;locale={locale}|&amp;timezone={timezone}]</code></p>
<p>where <code>{}</code> marks the required parameters and <code>[]</code> marks the optional. The usage of each parameter is pretty straightforward:</p>
<ul>
<li>user - login user name for TDengine; by default, it's <code>root</code></li>
<li>password - login password; by default, it's <code>taosdata</code></li>
<li>charset - the client-side charset; by default, it's the operation system's charset</li>
<li>cfgdir - the directory of TDengine client configuration file; by default it's <code>/etc/taos</code> on Linux and <code>C:\TDengine/cfg</code> on Windows</li>
<li>locale - the language environment of TDengine client; by default, it's the operation system's locale</li>
<li>timezone - the timezone of the TDengine client; by default, it's the operation system's timezone </li>
</ul>
<p>All parameters can be configured at the time when creating a connection using the java.sql.DriverManager class, for example:</p>
<pre><code class="java language-java">import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
import com.taosdata.jdbc.TSDBDriver;

public Connection getConn() throws Exception{
    Class.forName("com.taosdata.jdbc.TSDBDriver");
  String jdbcUrl = "jdbc:TAOS://127.0.0.1:0/db?user=root&amp;password=taosdata";
  Properties connProps = new Properties();
  connProps.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
  connProps.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
  connProps.setProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR, "/etc/taos");
  connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
  connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
  connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIMEZONE, "UTC-8");
  Connection conn = DriverManager.getConnection(jdbcUrl, connProps);
  return conn;
}</code></pre>
<p>Except <code>cfgdir</code>, all the parameters listed above can also be configured in the configuration file. The properties specified when calling DriverManager.getConnection() has the highest priority among all configuration methods. The JDBC URL has the second-highest priority, and the configuration file has the lowest priority. The explicitly configured parameters in a method with higher priorities always overwrite that same parameter configured in methods with lower priorities. For example, if <code>charset</code> is explicitly configured as "UTF-8" in the JDBC URL and "GKB" in the <code>taos.cfg</code> file, then "UTF-8" will be used.</p>
<p>Although the JDBC driver is implemented following the JDBC standard as much as possible, there are major differences between TDengine and traditional databases in terms of data models that lead to the differences in the driver implementation. Here is a list of head-ups for developers who have plenty of experience on traditional databases but little on TDengine:</p>
<ul>
<li>TDengine does NOT support updating or deleting a specific record, which leads to some unsupported methods in the JDBC driver</li>
<li>TDengine currently does not support <code>join</code> or <code>union</code> operations, and thus, is lack of support for associated methods in the JDBC driver</li>
<li>TDengine supports batch insertions which are controlled at the level of SQL statement writing instead of API calls</li>
<li>TDengine doesn't support nested queries and neither does the JDBC driver. Thus for each established connection to TDengine, there should be only one open result set associated with it</li>
</ul>
<p>All the error codes and error messages can be found in <code>TSDBError.java</code> . For a more detailed coding example, please refer to the demo project <code>JDBCDemo</code> in TDengine's code examples. </p>
<a class='anchor' id='Python-Connector'></a><h2>Python Connector</h2>
<a class='anchor' id='Install-TDengine-Python-client'></a><h3>Install TDengine Python client</h3>
<p>Users can find python client packages in our source code directory <em>src/connector/python</em>. There are two directories corresponding two python versions. Please choose the correct package to install. Users can use <em>pip</em> command to install:</p>
<pre><code class="cmd language-cmd">pip install src/connector/python/python2/</code></pre>
<p>or</p>
<pre><code>pip install src/connector/python/python3/</code></pre>
<p>If <em>pip</em> command is not installed on the system, users can choose to install pip or just copy the <em>taos</em> directory in the python client directory to the application directory to use.</p>
<a class='anchor' id='Python-client-interfaces'></a><h3>Python client interfaces</h3>
<p>To use TDengine Python client, import TDengine module at first:</p>
<pre><code class="python language-python">import taos </code></pre>
<p>Users can get module information from Python help interface or refer to our [python code example](). We list the main classes and methods below:</p>
<ul>
<li><p><em>TaosConnection</em> class</p>
<p>Run <code>help(taos.TaosConnection)</code> in python terminal for details.</p></li>
<li><p><em>TaosCursor</em> class</p>
<p>Run <code>help(taos.TaosCursor)</code> in python terminal for details.</p></li>
<li><p>connect method</p>
<p>Open a connection. Run <code>help(taos.connect)</code> in python terminal for details.</p></li>
</ul>
<a class='anchor' id='RESTful-Connector'></a><h2>RESTful Connector</h2>
<p>TDengine also provides RESTful API to satisfy developing on different platforms. Unlike other databases, TDengine RESTful API applies operations to the database through the SQL command in the body of HTTP POST request. What users are required to provide is just a URL.</p>
<p>For the time being, TDengine RESTful API uses a <em>\<TOKEN></em> generated from username and password for identification. Safer identification methods will be provided in the future.</p>
<a class='anchor' id='HTTP-URL-encoding'></a><h3>HTTP URL encoding</h3>
<p>To use TDengine RESTful API, the URL should have the following encoding format:</p>
<pre><code>http://&lt;ip&gt;:&lt;PORT&gt;/rest/sql</code></pre>
<ul>
<li><em>ip</em>: IP address of any node in a TDengine cluster</li>
<li><em>PORT</em>: TDengine HTTP service port. It is 6020 by default.</li>
</ul>
<p>For example, the URL encoding <em>http://192.168.0.1:6020/rest/sql</em> used to send HTTP request to a TDengine server with IP address as 192.168.0.1.</p>
<p>It is required to add a token in an HTTP request header for identification.</p>
<pre><code>Authorization: Basic &lt;TOKEN&gt;</code></pre>
<p>The HTTP request body contains the SQL command to run. If the SQL command contains a table name, it should also provide the database name it belongs to in the form of <code>&lt;db_name&gt;.&lt;tb_name&gt;</code>. Otherwise, an error code is returned.</p>
<p>For example, use <em>curl</em> command to send a HTTP request:</p>
<pre><code>curl -H 'Authorization: Basic &lt;TOKEN&gt;' -d '&lt;SQL&gt;' &lt;ip&gt;:&lt;PORT&gt;/rest/sql</code></pre>
<p>or use</p>
<pre><code>curl -u username:password -d '&lt;SQL&gt;' &lt;ip&gt;:&lt;PORT&gt;/rest/sql</code></pre>
<p>where <code>TOKEN</code> is the encryted string of <code>{username}:{password}</code> using the Base64 algorithm, e.g. <code>root:taosdata</code> will be encoded as <code>cm9vdDp0YW9zZGF0YQ==</code></p>
<a class='anchor' id='HTTP-response'></a><h3>HTTP response</h3>
<p>The HTTP resonse is in JSON format as below:</p>
<pre><code>{
    "status": "succ",
    "head": ["column1","column2", …],
    "data": [
        ["2017-12-12 23:44:25.730", 1],
        ["2017-12-12 22:44:25.728", 4]
    ],
    "rows": 2
} </code></pre>
<p>Specifically,</p>
<ul>
<li><em>status</em>: the result of the operation, success or failure</li>
<li><em>head</em>: description of returned result columns</li>
<li><em>data</em>: the returned data array. If no data is returned, only an <em>affected_rows</em> field is listed</li>
<li><em>rows</em>: the number of rows returned</li>
</ul>
<a class='anchor' id='Example'></a><h3>Example</h3>
<ul>
<li><p>Use <em>curl</em> command to query all the data in table <em>t1</em> of database <em>demo</em>:</p>
<p><code>curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.t1' 192.168.0.1:6020/rest/sql</code></p></li>
</ul>
<p>The return value is like:</p>
<pre><code>{
    "status": "succ",
    "head": ["column1","column2","column3"],
    "data": [
        ["2017-12-12 23:44:25.730", 1, 2.3],
        ["2017-12-12 22:44:25.728", 4, 5.6]
    ],
    "rows": 2
}</code></pre>
<ul>
<li><p>Use HTTP to create a database:</p>
<p><code>curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'create database demo' 192.168.0.1:6020/rest/sql</code></p>
<p>The return value should be:</p></li>
</ul>
<pre><code>{
    "status": "succ",
    "head": ["affected_rows"],
    "data": [[1]],
    "rows": 1,
}</code></pre>
<a class='anchor' id='Go-Connector'></a><h2>Go Connector</h2>
<p>TDengine also provides a Go client package named <em>taosSql</em> for users to access TDengine with Go. The package is in <em>/usr/local/taos/connector/go/src/taosSql</em> by default if you installed TDengine. Users can copy the directory <em>/usr/local/taos/connector/go/src/taosSql</em> to the <em>src</em> directory of your project and import the package in the source code for use.</p>
<pre><code class="Go language-Go">import (
    "database/sql"
    _ "taosSql"
)</code></pre>
<p>The <em>taosSql</em> package is in <em>cgo</em> form, which calls TDengine C/C++ sync interfaces. So a connection is allowed to be used by one thread at the same time. Users can open multiple connections for multi-thread operations.</p>
<p>Please refer the the demo code in the package for more information.</p>
<a class='anchor' id='Node.js-Connector'></a><h2>Node.js Connector</h2>
<p>TDengine also provides a node.js connector package that is installable through <a href="https://www.npmjs.com/">npm</a>. The package is also in our source code at <em>src/connector/nodejs/</em>. The following instructions are also available <a href="https://github.com/taosdata/tdengine/tree/master/src/connector/nodejs">here</a></p>
<p>To get started, just type in the following to install the connector through <a href="https://www.npmjs.com/">npm</a>.</p>
<pre><code class="cmd language-cmd">npm install td-connector</code></pre>
<p>It is highly suggested you use npm. If you don't have it installed, you can also just copy the nodejs folder from <em>src/connector/nodejs/</em> into your node project folder.</p>
<p>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)</p>
<a class='anchor' id='On-Unix'></a><h3>On Unix</h3>
<ul>
<li><code>python</code> (<code>v2.7</code> recommended, <code>v3.x.x</code> is <strong>not</strong> supported)</li>
<li><code>make</code></li>
<li>A proper C/C++ compiler toolchain, like <a href="https://gcc.gnu.org">GCC</a></li>
</ul>
<a class='anchor' id='On-macOS'></a><h3>On macOS</h3>
<ul>
<li><p><code>python</code> (<code>v2.7</code> recommended, <code>v3.x.x</code> is <strong>not</strong> supported) (already installed on macOS)</p></li>
<li><p>Xcode</p></li>
<li><p>You also need to install the </p>
<pre><code>Command Line Tools</code></pre>
<p>via Xcode. You can find this under the menu </p>
<pre><code>Xcode -&gt; Preferences -&gt; Locations</code></pre>
<p>(or by running </p>
<pre><code>xcode-select --install</code></pre>
<p>in your Terminal) </p>
<ul>
<li>This step will install <code>gcc</code> and the related toolchain containing <code>make</code></li></ul></li>
</ul>
<a class='anchor' id='On-Windows'></a><h3>On Windows</h3>
<h4>Option 1</h4>
<p>Install all the required tools and configurations using Microsoft's <a href="https://github.com/felixrieseberg/windows-build-tools">windows-build-tools</a> using <code>npm install --global --production windows-build-tools</code> from an elevated PowerShell or CMD.exe (run as Administrator).</p>
<h4>Option 2</h4>
<p>Install tools and configuration manually:</p>
<ul>
<li>Install Visual C++ Build Environment: <a href="https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools">Visual Studio Build Tools</a> (using "Visual C++ build tools" workload) or <a href="https://visualstudio.microsoft.com/pl/thank-you-downloading-visual-studio/?sku=Community">Visual Studio 2017 Community</a> (using the "Desktop development with C++" workload)</li>
<li>Install <a href="https://www.python.org/downloads/">Python 2.7</a> (<code>v3.x.x</code> is not supported), and run <code>npm config set python python2.7</code> (or see below for further instructions on specifying the proper Python version and path.)</li>
<li>Launch cmd, <code>npm config set msvs_version 2017</code></li>
</ul>
<p>If the above steps didn't work for you, please visit <a href="https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules">Microsoft's Node.js Guidelines for Windows</a> for additional tips.</p>
<p>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".</p>
<a class='anchor' id='Usage'></a><h2>Usage</h2>
<p>To use the connector, first request the <code>td-connector</code> package. Running the function <code>taos.connect</code> 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.</p>
<pre><code class="javascript language-javascript">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</code></pre>
<p>We can now start executing queries through the <code>cursor.execute</code> function.</p>
<pre><code class="javascript language-javascript">c1.execute('show databases;')</code></pre>
<p>We can get the results of the queries by doing the following</p>
<pre><code class="javascript language-javascript">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</code></pre>
<a class='anchor' id='Example'></a><h2>Example</h2>
<p>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.</p>
<pre><code class="javascript language-javascript">// 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 &lt; 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();</code></pre><a href='../index.html'>Back</a></section></main></div><?php include($s.'/footer.php'); ?><script>$('pre').addClass('prettyprint linenums');PR.prettyPrint()</script><script src='lib/docs/liner.js'></script></body></html>