I would like to make sure that I can connect to the db from Java service from time to time (like ping). This answer suggests to use show version.
My Java service is using the Cassandra thrift client (which is deprecated) and I couldn't find an example how to execute such a query.
I have a client of type org.apache.cassandra.thrift.Cassandra.Client.
Those are the methods I found that are similar:
System.out.println("describe_schema_versions: " + nativeClient.describe_schema_versions());
System.out.println("describe_version: " + nativeClient.describe_version());
System.out.println("describe_snitch: " + nativeClient.describe_snitch());
System.out.println("describe_cluster_name: " + nativeClient.describe_cluster_name());
System.out.println("describe_keyspaces: " + nativeClient.describe_keyspaces());
System.out.println("describe_partitioner: " + nativeClient.describe_partitioner());
System.out.println("describe_token_map: " + nativeClient.describe_token_map());
How can I execute query to get Cassandra server version like this?
cqlsh> show version;
[cqlsh 3.1.8 | Cassandra 1.2.19 | CQL spec 3.0.5 | Thrift protocol 19.36.2]
Or is there an alternative query preferred as "ping"?
if you just want make a health check, i think run a simple query is a good choice.
SELECT now() FROM system.local
here is the doc about how thrift client run query.
Cassandra.Client (apache-cassandra API) - Javadoc Extreme
Worth noting, but some folks have had a hard time with system.now() due to the integer format with Thrift. This is largely due to the fact that system.local is a cql3 table, and not a Thrift column family.
To that end, this returns a string, which may be easier to deal with:
aploetz#cqlsh> SELECT release_version FROM system.local;
release_version
-----------------
3.11.6
(1 rows)
Or via the Cassandra CLI:
[default#system] get local['local']['release_version']
You can also pull thrift_version, if you'd rather do that (which is also a string).
Related
the TL;DR is that I am not able to delete a row previously created with an upsert using Java.
Basically I have a table like this:
CREATE TABLE transactions (
key text PRIMARY KEY,
created_at timestamp
);
Then I execute:
String sql = "update transactions set created_at = toTimestamp(now()) where key = 'test' if created_at = null";
session.execute(sql)
As expected the row is created:
cqlsh:thingleme> SELECT * FROM transactions ;
key | created_at
------+---------------------------------
test | 2018-01-30 16:35:16.663000+0000
But (this is what is making me crazy) if I execute:
sql = "delete from transactions where key = 'test'";
ResultSet resultSet = session.execute(sql);
Nothing happens. I mean: no exception is thrown and the row is still there!
Some other weird stuff:
if I replace the upsert with a plain insert, then the delete works
if I directly run the sql code (update and delete) by using cqlsh, it works
If I run this code against an EmbeddedCassandraService, it works (this is very bad, because my integration tests are just green!)
My environment:
cassandra: 3.11.1
datastax java driver: 3.4.0
docker image: cassandra:3.11.1
Any idea/suggestion on how to tackle this problem is really appreciated ;-)
I think the issue you are encountering might be explained by the mixing of lightweight transactions (LWTs) (update transactions set created_at = toTimestamp(now()) where key = 'test' if created_at = null) and non-LWTs (delete from transactions where key = 'test').
Cassandra uses timestamps to determine which mutations (deletes, updates) are the most recently applied. When using LWTs, the timestamp assignment is different then when not using LWTs:
Lightweight transactions will block other lightweight transactions from occurring, but will not stop normal read and write operations from occurring. Lightweight transactions use a timestamping mechanism different than for normal operations and mixing LWTs and normal operations can result in errors. If lightweight transactions are used to write to a row within a partition, only lightweight transactions for both read and write operations should be used.
Source: How do I accomplish lightweight transactions with linearizable consistency?
Further complicating things is that by default the java driver uses client timestamps, meaning the write timestamp is determined by the client rather than the coordinating cassandra node. However, when you use LWTs, the client timestamp is bypassed. In your case, unless you disable client timestamps, your non-LWT queries are using client timestamps, where your LWT queries are using a timestamp assigned by the paxos logic in cassandra. In any case, even if the driver wasn't assigning client timestamps this still might be a problem because the timestamp assignment logic is different on the C* side for LWT and non-LWT as well.
To fix this, you could alter your delete statement to include IF EXISTS, i.e.:
delete from transactions where key = 'test' if exists
Similar issue from the java driver mailing list
Is there any fluent "create trigger" builder? It's weird but I can't find any trigger builder example (also searched in the jOOQ manual but without success).
I would like to transform hard-coded statement:
"CREATE TRIGGER " + TRIGGER_DELETE_TAB + " " +
"BEFORE DELETE ON " + TABLE_TABS + " " +
"BEGIN " +
"DELETE FROM " + TABLE_CHORDNAMES + " " +
"WHERE " + CHORDNAME_TAB + " = " + "OLD."+TAB_ID +"; " +
"END;"
in something like that:
SQLiteDSL.createTrigger(TRIGGER_DELETE_TAB)
.beforeDeleteOn(TABLE_TABS)
.begin()
.deleteFrom(TABLE_CHORDNAMES)
.where(column(CHORDNAME_TAB).eq("OLD."+TAB_ID))
.end()
.getSQL();
jOOQ could contain an API to implement a really trivial trigger like yours seems to be, and chances are, it will in some future version (#6956).
But in order to fully support triggers, jOOQ needs a runtime model abstracting over all sorts of procedural languages first, before going into the details of vendor specific trigger features. There's a feature request "Add procedural language abstraction API", in fact: #6475
This is being worked on for the upcoming version jOOQ 3.11, which will definitely support BEGIN .. END style blocks: #6474.
For jOOQ 3.10 and less, you will need to build your own jOOQ extension API based on the plain SQL templating mechanism documented here:
https://www.jooq.org/doc/latest/manual/sql-building/plain-sql-templating
You don't need too much plumbing to get that functionality working...
I don't think you can do that, but you can use instead ExecuteListeners, which can be considered as triggers and you can do something similar that what you build with your SQL.
You can check out their documentation regarding ExecuteListeners, they also provide a few example, like query statistics listener, logging listener and so forth.
They recommend extending DefaultExecuteListener and start from their with Javadoc, they have quite a variety of methods that you can override. I am pretty sure you will find what you need.
Using Neo4j 2.3.0 Community Edition with Oracle JDK 8 and Windows 7
I am new to Neo4j and just trying how it works with Java. In the Neo4j Browser I created 3 nodes with the following statement:
CREATE (c:Customer {name:'King'})-[:CREATES]->(:Order {status:'created'}),
(c)-[:CREATES]->(:Order {status:'created'})
Executed from the Neo4j Browser, the following query returns in 200 ms:
MATCH (c:Customer)-[:CREATES]->(o:Order)
WHERE c.name = 'King'
RETURN o.status
Executing this in Eclipse takes about 2500 ms, sometimes up to 3000 ms:
String query = "MATCH (c:Customer)-[:CREATES]->(o:Order) "
+ "WHERE c.name = 'King' "
+ "RETURN o.status";
Result result = db.execute(query);
This is incredibly slow! What am I doing wrong?
In addition, I ran the following snippet in Eclipse and it only took about 50 ms:
Node king = db.findNode(NodeType.Customer, "name", "King");
Iterable<Relationship> kingRels = king.getRelationships(RelType.CREATES);
for(Relationship rel : kingRels) {
System.out.println(rel.getEndNode().getProperty("status"));
}
So there are actually two things I am suprised of:
Running a Cypher query in the Neo4j Browser seems to be way slower than doing a comparable thing with the Neo4j Core Java API in Eclipse.
Running a Cypher query "embedded" in Java code is incredibly slow compared to the Neo4j Browser solution as well as compared to the plain Java solution.
I am pretty sure that this cannot be true. So what am I doing wrong?
How do you measure it? if you measure the full runtime, then your time includes, jvm startup, database startup and class-loading and loading of store-files from disk.
Remember in the browser all of that is already running, and warmed up etc.
If you really want to measure your query, run it a number of times to warm up and then measure only the query execution and result loading.
Also consider using indexes or constraints as indicated and parameters, e.g. for your customer.name.
Running Netcool 7.3.1. Looking for simple api to access Object Server Tables. I've already done the run an SQL command from nco_sql, and scraped the output into a C# data table, but wondering if there was some type of api that I could use for either C# or Java to access table data?
If you can use a more up-to-date version of Omnibus, you can use the built-in HTTP / REST API.
http://www-01.ibm.com/support/knowledgecenter/SSSHTQ_8.1.0/com.ibm.netcool_OMNIbus.doc_8.1.0/omnibus/wip/api/concept/omn_api_http_overview.html?lang=en
You may need to use sybase database adapter so far I have used below three ways to query netcool object server:
Free TDS - This is free sybase client.
Jconn3 - this is paid sybase client, but if you are using WebGUI/Impact, this driver comes with TIP.
nco_sql - here you may need to create a file with query and then pass it to nco_sql. This require extra effort to parse column wise information as output will be on console.
I prefer jconn3, simple and similar to jdbc driver, you only need this jar in classpath.
You can write your own java program to connect to Objectserver by simply initiating
//Load Sybase Driver
Class.forName("com.sybase.jdbc3.jdbc.SybDriver");
String url = "jdbc:sybase:Tds:" + host + ":" + port;
con = DriverManager.getConnection(url, user, pass);
Execute Statements
Statement stat = conn.createStatement();
ResultSet result = stat.executeQuery("Select count(*) from alerts.status");;`
I have an application that uses Firebird. The application performs a long list of queries e.g. each time you list your items. I want to take out these queries, and run them in my own Java application (so I can manipulate the list, display it, and so on.)
The problem is... there is a debug option in the application where you can see what kind of queries does your application run. Some of the original queries got # signs. If I run a query with an # in it, I get an error. If I take out that part of the query, everything runs and works "as expected". No errors, like a charm.
Detailed error message:
Error code: -104
Token unknown - line 8, column 32
We use IntelliJ IDEA which automatically applies escape characters when needed.
Such a part from the original query:
SELECT TBL4487."Id" "database.id",
TBL4487."Code" "database.code",
TBL4487."Name" "database.name",
TBL4487."Barcode" "database.barcode",
TBL4488."Name" "Datagroup",
TBL4489."Name" "Mey",
(SELECT FIRST 1 TBL4494."Price" / (CASE
WHEN (TBL4487."GrossPrices" = #Param4495) THEN 1
ELSE (TBL4492."Rate" + 100) / 100
END) "productprice.price"
FROM "ProductPrice" TBL4494
WHERE (TBL4494."Product" = TBL4487."Id") AND (TBL4494."PriceCategory" = #Param4497) AND (TBL4494."ValidFrom" <= #Param4498) AND (TBL4494."Currency" = #Param4499) AND (TBL4494."QuantityUnit" = TBL4487."QuantityUnit")
ORDER BY TBL4494."ValidFrom" DESC) "xyz",
(SELECT FIRST 1 TBL4500."Price" / (CASE
WHEN (TBL4487."GrossPrices" = #Param4501) THEN 1
ELSE (TBL4492."Rate" + 100) / 100
The question is.. how could I run this query? How do I replace the # symbol?
You can't run this query directly with Jaybird. These #ParamXXXX seem to be placeholders in the query for parameters. However Firebird nor Jaybird supports this type of placeholders (they only support ? as placeholder in DSQL).
To execute this with Jaybird, you will need to replace each instance of the #ParamXXXX either with a ? and set the right value for each placeholder in a PreparedStatement, or with the actual value in the query text itself.
The Firebird .NET provider does support #....-style placeholders (it translates them to Firebird-style ? placeholders), so you could try to use C#/.NET instead if you don't want to do replacing yourself.
Full disclosure: I am the developer of Jaybird