Skip to content

Commit 94b41da

Browse files
authored
Session: session-c interface (#17347)
* session c * fix ci * add ut; fix no test run on win * ci fix * ci fix * fixed try-catch memory leak * adjusted error report message * session c example * add code comment for session c example
1 parent b8dad5d commit 94b41da

18 files changed

Lines changed: 3676 additions & 94 deletions

example/client-c-example/README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<!--
2+
3+
Licensed to the Apache Software Foundation (ASF) under one
4+
or more contributor license agreements. See the NOTICE file
5+
distributed with this work for additional information
6+
regarding copyright ownership. The ASF licenses this file
7+
to you under the Apache License, Version 2.0 (the
8+
"License"); you may not use this file except in compliance
9+
with the License. You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing,
14+
software distributed under the License is distributed on an
15+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
KIND, either express or implied. See the License for the
17+
specific language governing permissions and limitations
18+
under the License.
19+
20+
-->
21+
22+
# How to get a complete C client demo project (SessionC)
23+
24+
Pure **C** examples for the IoTDB Session **C API** (`SessionC.h`): **tree model** (`tree_example`) and **table model** (`table_example`). Default connection: `127.0.0.1:6667`, user `root` / password `root` (edit the macros at the top of each `.c` file).
25+
26+
## Get a project
27+
28+
Using Maven to build this example project (requires **Boost**, same as the C++ client; on Windows see [`iotdb-client/client-cpp/README.md`](../../iotdb-client/client-cpp/README.md)):
29+
30+
* `cd` the root path of the whole project
31+
* run
32+
`mvn package -DskipTests -P with-cpp -pl example/client-c-example -am`
33+
(use `mvn clean package ...` when no other process holds files under `iotdb-client/client-cpp/target`; on Windows add Boost paths, e.g.
34+
`-D"boost.include.dir=C:\local\boost_1_87_0" -D"boost.library.dir=C:\local\boost_1_87_0\lib64-msvc-14.2"`)
35+
* `cd example/client-c-example/target`
36+
37+
After a successful build you should have:
38+
39+
* Unpacked C++ client headers and libraries under `client/` and Thrift under `thrift/` (same layout as [client-cpp-example](../client-cpp-example/README.md))
40+
* CMake-generated binaries, for example on Windows MSVC:
41+
`Release/tree_example.exe`, `Release/table_example.exe`
42+
(exact path depends on the CMake generator)
43+
44+
## Run
45+
46+
Start IoTDB first, then:
47+
48+
```text
49+
# Windows (example)
50+
Release\tree_example.exe
51+
Release\table_example.exe
52+
```
53+
54+
On failure, the programs print to `stderr` and you can inspect `ts_get_last_error()`.
55+
56+
## Source layout
57+
58+
```
59+
example/client-c-example/
60+
+-- README.md
61+
+-- pom.xml
62+
+-- src/
63+
| +-- CMakeLists.txt
64+
| +-- tree_example.c
65+
| +-- table_example.c
66+
```
67+
68+
The Maven build copies `src/*.c` and `src/CMakeLists.txt` into `target/` next to the unpacked `client/` and `thrift/` trees, then runs CMake to compile the two executables.

example/client-c-example/pom.xml

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
Licensed to the Apache Software Foundation (ASF) under one
5+
or more contributor license agreements. See the NOTICE file
6+
distributed with this work for additional information
7+
regarding copyright ownership. The ASF licenses this file
8+
to you under the Apache License, Version 2.0 (the
9+
"License"); you may not use this file except in compliance
10+
with the License. You may obtain a copy of the License at
11+
12+
http://www.apache.org/licenses/LICENSE-2.0
13+
14+
Unless required by applicable law or agreed to in writing,
15+
software distributed under the License is distributed on an
16+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
KIND, either express or implied. See the License for the
18+
specific language governing permissions and limitations
19+
under the License.
20+
21+
-->
22+
<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">
23+
<modelVersion>4.0.0</modelVersion>
24+
<parent>
25+
<groupId>org.apache.iotdb</groupId>
26+
<artifactId>iotdb-examples</artifactId>
27+
<version>2.0.7-SNAPSHOT</version>
28+
</parent>
29+
<artifactId>client-c-example</artifactId>
30+
<name>IoTDB: Example: C Client (SessionC)</name>
31+
<dependencies>
32+
<dependency>
33+
<groupId>org.apache.iotdb</groupId>
34+
<artifactId>client-cpp</artifactId>
35+
<version>${project.version}</version>
36+
<type>pom</type>
37+
<scope>provided</scope>
38+
</dependency>
39+
</dependencies>
40+
<build>
41+
<plugins>
42+
<plugin>
43+
<groupId>com.coderplus.maven.plugins</groupId>
44+
<artifactId>copy-rename-maven-plugin</artifactId>
45+
<executions>
46+
<execution>
47+
<id>copy-c-sources-and-cmake</id>
48+
<goals>
49+
<goal>copy</goal>
50+
</goals>
51+
<configuration>
52+
<fileSets>
53+
<fileSet>
54+
<sourceFile>${project.basedir}/src/tree_example.c</sourceFile>
55+
<destinationFile>${project.build.directory}/tree_example.c</destinationFile>
56+
</fileSet>
57+
<fileSet>
58+
<sourceFile>${project.basedir}/src/table_example.c</sourceFile>
59+
<destinationFile>${project.build.directory}/table_example.c</destinationFile>
60+
</fileSet>
61+
<fileSet>
62+
<sourceFile>${project.basedir}/src/CMakeLists.txt</sourceFile>
63+
<destinationFile>${project.build.directory}/CMakeLists.txt</destinationFile>
64+
</fileSet>
65+
</fileSets>
66+
</configuration>
67+
</execution>
68+
</executions>
69+
</plugin>
70+
<plugin>
71+
<groupId>org.apache.maven.plugins</groupId>
72+
<artifactId>maven-dependency-plugin</artifactId>
73+
<executions>
74+
<execution>
75+
<id>unpack-client</id>
76+
<goals>
77+
<goal>unpack</goal>
78+
</goals>
79+
<phase>generate-sources</phase>
80+
<configuration>
81+
<artifactItems>
82+
<artifactItem>
83+
<groupId>org.apache.iotdb</groupId>
84+
<artifactId>client-cpp</artifactId>
85+
<version>${project.version}</version>
86+
<type>zip</type>
87+
<classifier>cpp-${os.classifier}</classifier>
88+
<overWrite>true</overWrite>
89+
</artifactItem>
90+
</artifactItems>
91+
<outputDirectory>${project.build.directory}/client</outputDirectory>
92+
</configuration>
93+
</execution>
94+
<execution>
95+
<id>unpack-thrift</id>
96+
<goals>
97+
<goal>unpack</goal>
98+
</goals>
99+
<phase>generate-sources</phase>
100+
<configuration>
101+
<artifactItems>
102+
<artifactItem>
103+
<groupId>org.apache.iotdb.tools</groupId>
104+
<artifactId>iotdb-tools-thrift</artifactId>
105+
<version>${iotdb-tools-thrift.version}</version>
106+
<classifier>${os.classifier}</classifier>
107+
<type>zip</type>
108+
<overWrite>true</overWrite>
109+
<outputDirectory>${project.build.directory}/thrift</outputDirectory>
110+
</artifactItem>
111+
</artifactItems>
112+
</configuration>
113+
</execution>
114+
</executions>
115+
</plugin>
116+
<plugin>
117+
<groupId>io.github.cmake-maven-plugin</groupId>
118+
<artifactId>cmake-maven-plugin</artifactId>
119+
<executions>
120+
<execution>
121+
<id>cmake-generate</id>
122+
<goals>
123+
<goal>generate</goal>
124+
</goals>
125+
<phase>compile</phase>
126+
<configuration>
127+
<generator>${cmake.generator}</generator>
128+
<sourcePath>${project.build.directory}</sourcePath>
129+
<projectDirectory>${project.build.directory}</projectDirectory>
130+
<options>
131+
<option>-DBOOST_INCLUDEDIR=${boost.include.dir}</option>
132+
</options>
133+
</configuration>
134+
</execution>
135+
<execution>
136+
<id>cmake-compile</id>
137+
<goals>
138+
<goal>compile</goal>
139+
</goals>
140+
<phase>compile</phase>
141+
<configuration>
142+
<config>${cmake.build.type}</config>
143+
<projectDirectory>${project.build.directory}</projectDirectory>
144+
</configuration>
145+
</execution>
146+
</executions>
147+
</plugin>
148+
</plugins>
149+
</build>
150+
</project>
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
/*
21+
* Table model: CREATE DATABASE/TABLE, insert rows via Tablet, SELECT, DROP DATABASE.
22+
* Requires IoTDB table-SQL support. Edit HOST / PORT / credentials below.
23+
*/
24+
25+
#include <stdio.h>
26+
#include <stdlib.h>
27+
#include <string.h>
28+
29+
#include "SessionC.h"
30+
31+
#define HOST "127.0.0.1"
32+
#define PORT 6667
33+
#define USER "root"
34+
#define PASS "root"
35+
36+
#define DB_NAME "cdemo_db"
37+
#define TABLE_NAME "cdemo_t0"
38+
39+
static void fail(const char* ctx, CTableSession* s) {
40+
fprintf(stderr, "[table_example] %s failed: %s\n", ctx, ts_get_last_error());
41+
if (s) {
42+
ts_table_session_close(s);
43+
ts_table_session_destroy(s);
44+
}
45+
exit(1);
46+
}
47+
48+
int main(void) {
49+
/* Last arg: default database name; empty string leaves it unset (we USE "cdemo_db" via SQL below). */
50+
CTableSession* session = ts_table_session_new(HOST, PORT, USER, PASS, "");
51+
if (!session) {
52+
fprintf(stderr, "[table_example] ts_table_session_new returned NULL: %s\n", ts_get_last_error());
53+
return 1;
54+
}
55+
if (ts_table_session_open(session) != TS_OK) {
56+
fail("ts_table_session_open", session);
57+
}
58+
59+
char sql[512];
60+
snprintf(sql, sizeof(sql), "DROP DATABASE IF EXISTS %s", DB_NAME);
61+
(void)ts_table_session_execute_non_query(session, sql);
62+
63+
snprintf(sql, sizeof(sql), "CREATE DATABASE %s", DB_NAME);
64+
if (ts_table_session_execute_non_query(session, sql) != TS_OK) {
65+
fail("CREATE DATABASE", session);
66+
}
67+
68+
snprintf(sql, sizeof(sql), "USE \"%s\"", DB_NAME);
69+
if (ts_table_session_execute_non_query(session, sql) != TS_OK) {
70+
fail("USE DATABASE", session);
71+
}
72+
73+
const char* ddl =
74+
"CREATE TABLE " TABLE_NAME " ("
75+
"tag1 string tag,"
76+
"attr1 string attribute,"
77+
"m1 double field)";
78+
if (ts_table_session_execute_non_query(session, ddl) != TS_OK) {
79+
fail("CREATE TABLE", session);
80+
}
81+
82+
const char* columnNames[] = {"tag1", "attr1", "m1"};
83+
TSDataType_C dataTypes[] = {TS_TYPE_STRING, TS_TYPE_STRING, TS_TYPE_DOUBLE};
84+
TSColumnCategory_C colCategories[] = {TS_COL_TAG, TS_COL_ATTRIBUTE, TS_COL_FIELD};
85+
86+
CTablet* tablet = ts_tablet_new_with_category(TABLE_NAME, 3, columnNames, dataTypes, colCategories, 100);
87+
if (!tablet) {
88+
fail("ts_tablet_new_with_category", session);
89+
}
90+
91+
int i;
92+
for (i = 0; i < 5; i++) {
93+
if (ts_tablet_add_timestamp(tablet, i, (int64_t)i) != TS_OK) {
94+
ts_tablet_destroy(tablet);
95+
fail("ts_tablet_add_timestamp", session);
96+
}
97+
if (ts_tablet_add_value_string(tablet, 0, i, "device_A") != TS_OK) {
98+
ts_tablet_destroy(tablet);
99+
fail("ts_tablet_add_value_string tag", session);
100+
}
101+
if (ts_tablet_add_value_string(tablet, 1, i, "attr_val") != TS_OK) {
102+
ts_tablet_destroy(tablet);
103+
fail("ts_tablet_add_value_string attr", session);
104+
}
105+
if (ts_tablet_add_value_double(tablet, 2, i, (double)i * 1.5) != TS_OK) {
106+
ts_tablet_destroy(tablet);
107+
fail("ts_tablet_add_value_double", session);
108+
}
109+
}
110+
if (ts_tablet_set_row_count(tablet, 5) != TS_OK) {
111+
ts_tablet_destroy(tablet);
112+
fail("ts_tablet_set_row_count", session);
113+
}
114+
115+
if (ts_table_session_insert(session, tablet) != TS_OK) {
116+
ts_tablet_destroy(tablet);
117+
fail("ts_table_session_insert", session);
118+
}
119+
ts_tablet_destroy(tablet);
120+
121+
CSessionDataSet* dataSet = NULL;
122+
if (ts_table_session_execute_query(session, "SELECT * FROM " TABLE_NAME, &dataSet) != TS_OK) {
123+
fail("ts_table_session_execute_query", session);
124+
}
125+
if (!dataSet) {
126+
fprintf(stderr, "[table_example] dataSet is NULL\n");
127+
ts_table_session_close(session);
128+
ts_table_session_destroy(session);
129+
return 1;
130+
}
131+
ts_dataset_set_fetch_size(dataSet, 1024);
132+
133+
int count = 0;
134+
while (ts_dataset_has_next(dataSet)) {
135+
CRowRecord* record = ts_dataset_next(dataSet);
136+
if (!record) {
137+
break;
138+
}
139+
printf("[table_example] row %d: time=%lld\n", count, (long long)ts_row_record_get_timestamp(record));
140+
ts_row_record_destroy(record);
141+
count++;
142+
}
143+
ts_dataset_destroy(dataSet);
144+
printf("[table_example] SELECT returned %d row(s).\n", count);
145+
146+
snprintf(sql, sizeof(sql), "DROP DATABASE IF EXISTS %s", DB_NAME);
147+
(void)ts_table_session_execute_non_query(session, sql);
148+
149+
ts_table_session_close(session);
150+
ts_table_session_destroy(session);
151+
return 0;
152+
}

0 commit comments

Comments
 (0)