true
if connection with remote host is established, false
otherwise
+ */
+ public abstract boolean isConnected();
+
+ /**
+ * Executes a synchronous query against the remote q service.
+ *
+ * @param query
+ * Query to be executed
+ * @param parameters
+ * Additional parameters
+ * @return deserialized response from the remote q service
+ * @throws QException
+ * @throws IOException
+ */
+ public abstract Object sync( String query, Object... parameters ) throws QException, IOException;
+
+ /**
+ * Executes an asynchronous query against the remote q service.
+ *
+ * @param query
+ * Query to be executed
+ * @param parameters
+ * Additional parameters
+ * @throws QException
+ * @throws IOException
+ */
+ public abstract void async( String query, Object... parameters ) throws QException, IOException;
+
+ /**
+ * Reads next message from the remote q service.
+ *
+ * @param dataOnly
+ * if true
returns only data part of the message, if false
retuns data and
+ * message meta-information encapsulated in QMessage
+ * @param raw
+ * indicates whether message should be parsed to Java object or returned as an array of bytes
+ * @return deserialized response from the remote q service
+ * @throws IOException
+ * @throws QException
+ */
+ public abstract Object receive( boolean dataOnly, boolean raw ) throws IOException, QException;
+
+ /**
+ * Reads next message from the remote q service.
+ *
+ * @return deserialized response from the remote q service
+ * @throws IOException
+ * @throws QException
+ */
+ public abstract Object receive() throws IOException, QException;
+
+ /**
+ * Executes a query against the remote q service. Result of the query has to be retrieved by calling a receive
+ * method.
+ *
+ * @param msgType
+ * Indicates whether message should be synchronous or asynchronous
+ * @param query
+ * Query to be executed
+ * @param parameters
+ * Additional parameters
+ * @return size of the sent message
+ * @throws QException
+ * @throws IOException
+ */
+ public abstract int query( final MessageType msgType, final String query, final Object... parameters ) throws QException, IOException;
+
+ /**
+ * Returns the host of a remote q service.
+ *
+ * @return host of remote a q service
+ */
+ public abstract String getHost();
+
+ /**
+ * Returns the port of a remote q service.
+ *
+ * @return post of remote a q service
+ */
+ public abstract int getPort();
+
+ /**
+ * Returns username for remote authorization.
+ *
+ * @return username for remote authorization
+ */
+ public abstract String getUsername();
+
+ /**
+ * Returns password for remote authorization.
+ *
+ * @return password for remote authorization
+ */
+ public abstract String getPassword();
+
+ /**
+ * Returns encoding used for serialization/deserialization of string objects.
+ *
+ * @return encoding used for serialization/deserialization of string objects
+ */
+ public abstract String getEncoding();
+
+ /**
+ * Retrives version of the IPC protocol for an established connection.
+ *
+ * @return protocol version
+ */
+ public abstract int getProtocolVersion();
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/exxeleron/qjava/QConnectionException.java b/src/main/java/com/exxeleron/qjava/QConnectionException.java
new file mode 100644
index 0000000..ec7aa33
--- /dev/null
+++ b/src/main/java/com/exxeleron/qjava/QConnectionException.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2011-2014 Exxeleron GmbH
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.exxeleron.qjava;
+
+/**
+ * Exception representing q connection error.
+ */
+public class QConnectionException extends QException {
+
+ private static final long serialVersionUID = -6996779408402779829L;
+
+ /**
+ * Constructs an {@link QConnectionException} with the specified detailed message and cause.
+ *
+ * @param message
+ * the detail message
+ * @param cause
+ * the cause
+ */
+ public QConnectionException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs an {@link QConnectionException} with the specified detailed message.
+ *
+ * @param message
+ * the detail message
+ */
+ public QConnectionException(final String message) {
+ super(message);
+ }
+
+}
diff --git a/src/main/java/com/exxeleron/qjava/QDate.java b/src/main/java/com/exxeleron/qjava/QDate.java
new file mode 100644
index 0000000..a93467a
--- /dev/null
+++ b/src/main/java/com/exxeleron/qjava/QDate.java
@@ -0,0 +1,138 @@
+/**
+ * Copyright (c) 2011-2014 Exxeleron GmbH
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.exxeleron.qjava;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Represents q date type.
+ */
+public final class QDate implements DateTime {
+ private static final String NULL_STR = "0Nd";
+
+ private static final DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd");
+
+ private Date datetime;
+ private final Integer value;
+
+ /**
+ * Creates new {@link QDate} instance using specified q date value.
+ *
+ * @param value
+ * a count of days since 2000.01.01
+ */
+ public QDate(final Integer value) {
+ this.value = value;
+ }
+
+ /**
+ * Creates new {@link QDate} instance using specified {@link Date}.
+ *
+ * @param datetime
+ * {@link Date} to be set
+ */
+ public QDate(final Date datetime) {
+ this.datetime = datetime;
+ value = datetime == null ? Integer.MIN_VALUE : (int) (Utils.tzOffsetFromQ(datetime.getTime()) / Utils.DAY_MILLIS - 10957);
+ }
+
+ /**
+ * Returns a count of days since 2000.01.01
+ *
+ * @return raw q value
+ */
+ public Integer getValue() {
+ return value;
+ }
+
+ /**
+ * Converts {@link QDate} object to {@link Date} instance.
+ *
+ * @return {@link Date} representing q value.
+ */
+ public Date toDateTime() {
+ if ( datetime == null && value != Integer.MIN_VALUE ) {
+ datetime = new Date(Utils.tzOffsetToQ(Utils.QEPOCH_MILLIS + Utils.DAY_MILLIS * value));
+ }
+ return datetime;
+ }
+
+ /**
+ * Returns a String that represents the current {@link QDate}.
+ *
+ * @return a String representation of the {@link QDate}
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ final Date dt = toDateTime();
+ return dt == null ? NULL_STR : getDateformat().format(dt);
+ }
+
+ /**
+ * Indicates whether some other object is "equal to" this {@link QDate} . {@link QDate} objects are considered equal
+ * if the underlying q raw value is the same for both instances.
+ *
+ * @return true
if this object is the same as the obj argument, false
otherwise.
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( final Object obj ) {
+ if ( this == obj ) {
+ return true;
+ }
+
+ if ( !(obj instanceof QDate) ) {
+ return false;
+ }
+
+ return value.equals(((QDate) obj).getValue());
+ }
+
+ /**
+ * Returns a hash code value for this {@link QDate}.
+ *
+ * @return a hash code value for this object
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ /**
+ * Returns a {@link QDate} represented by a given string.
+ *
+ * @param date
+ * as {@link String}
+ * @return a {@link QDate} instance representing date.
+ * @throws IllegalArgumentException
+ * when date cannot be parsed
+ */
+ public static QDate fromString( final String date ) {
+ try {
+ return date == null || date.length() == 0 || date.equals(NULL_STR) ? new QDate(Integer.MIN_VALUE) : new QDate(getDateformat().parse(date));
+ } catch ( final Exception e ) {
+ throw new IllegalArgumentException("Cannot parse QDate from: " + date, e);
+ }
+ }
+
+ private static synchronized DateFormat getDateformat() {
+ return dateFormat;
+ }
+}
diff --git a/src/main/java/com/exxeleron/qjava/QDateTime.java b/src/main/java/com/exxeleron/qjava/QDateTime.java
new file mode 100644
index 0000000..3a1a413
--- /dev/null
+++ b/src/main/java/com/exxeleron/qjava/QDateTime.java
@@ -0,0 +1,143 @@
+/**
+ * Copyright (c) 2011-2014 Exxeleron GmbH
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.exxeleron.qjava;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Represents q datetime type.
+ */
+public final class QDateTime implements DateTime {
+
+ private static final String NULL_STR = "0Nz";
+
+ private static final DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd'T'HH:mm:ss.SSS");
+
+ private Date datetime;
+ private Double value;
+
+ /**
+ * Creates new {@link QDateTime} instance using specified q date value.
+ *
+ * @param value
+ * a fractional day count from midnight 2000.01.01
+ */
+ public QDateTime(final Double value) {
+ this.value = value;
+ }
+
+ /**
+ * Creates new {@link QDateTime} instance using specified {@link Date}.
+ *
+ * @param datetime
+ * {@link Date} to be set
+ */
+ public QDateTime(final Date datetime) {
+ this.datetime = datetime;
+ if ( datetime != null ) {
+ value = (double) (Utils.tzOffsetFromQ(datetime.getTime()) - Utils.QEPOCH_MILLIS) / Utils.DAY_MILLIS;
+ } else {
+ value = Double.NaN;
+ }
+ }
+
+ /**
+ * Returns a fractional day count from midnight 2000.01.01.
+ *
+ * @return raw q value
+ */
+ public Double getValue() {
+ return value;
+ }
+
+ /**
+ * Converts {@link QDateTime} object to {@link Date} instance.
+ *
+ * @return {@link Date} representing q value.
+ */
+ public Date toDateTime() {
+ if ( datetime == null && !Double.isNaN(value) ) {
+ datetime = new Date(Utils.tzOffsetToQ(Utils.QEPOCH_MILLIS + (long) (value * Utils.DAY_MILLIS)));
+ }
+ return datetime;
+ }
+
+ /**
+ * Returns a String that represents the current {@link QDateTime}.
+ *
+ * @return a String representation of the {@link QDateTime}
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ final Date dt = toDateTime();
+ return dt == null ? NULL_STR : getDateformat().format(dt);
+ }
+
+ /**
+ * Indicates whether some other object is "equal to" this date. {@link QDateTime} objects are considered equal if
+ * the underlying q raw value is the same for both instances.
+ *
+ * @return true
if this object is the same as the obj argument, false
otherwise.
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( final Object obj ) {
+ if ( this == obj ) {
+ return true;
+ }
+
+ if ( !(obj instanceof QDateTime) ) {
+ return false;
+ }
+
+ return value.equals(((QDateTime) obj).getValue());
+ }
+
+ /**
+ * Returns a hash code value for this {@link QDateTime}.
+ *
+ * @return a hash code value for this object
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ /**
+ * Returns a {@link QDateTime} represented by a given string.
+ *
+ * @param date
+ * as {@link String}
+ * @return a {@link QDateTime} instance representing date.
+ * @throws IllegalArgumentException
+ * when date cannot be parsed
+ */
+ public static QDateTime fromString( final String date ) {
+ try {
+ return date == null || date.length() == 0 || date.equals(NULL_STR) ? new QDateTime(Double.NaN) : new QDateTime(getDateformat().parse(date));
+ } catch ( final Exception e ) {
+ throw new IllegalArgumentException("Cannot parse QDateTime from: " + date, e);
+ }
+ }
+
+ private static synchronized DateFormat getDateformat() {
+ return dateFormat;
+ }
+}
diff --git a/src/main/java/com/exxeleron/qjava/QDictionary.java b/src/main/java/com/exxeleron/qjava/QDictionary.java
new file mode 100644
index 0000000..4b12270
--- /dev/null
+++ b/src/main/java/com/exxeleron/qjava/QDictionary.java
@@ -0,0 +1,177 @@
+/**
+ * Copyright (c) 2011-2014 Exxeleron GmbH
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.exxeleron.qjava;
+
+import java.lang.reflect.Array;
+import java.util.Iterator;
+
+/**
+ * Represents a q dictionary type.
+ */
+public final class QDictionary implements Iterable+ * Returns an iterator over a key/value pairs stored in the dictionary. + *
+ * + *
+ * Note that the iterator returned by this method will throw an {@link UnsupportedOperationException} in response to
+ * its remove
method.
+ *
true
if this object is the same as the obj argument, false
otherwise.
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( final Object obj ) {
+ if ( this == obj ) {
+ return true;
+ }
+
+ if ( !(obj instanceof QDictionary) ) {
+ return false;
+ }
+
+ final QDictionary d = (QDictionary) obj;
+ return Utils.deepArraysEquals(keys, d.keys) && Utils.deepArraysEquals(values, d.values);
+ }
+
+ /**
+ * Returns a hash code value for this {@link QDictionary}.
+ *
+ * @return a hash code value for this object
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return 31 * Utils.arrayHashCode(keys) + Utils.arrayHashCode(values);
+ }
+}
diff --git a/src/main/java/com/exxeleron/qjava/QErrorMessage.java b/src/main/java/com/exxeleron/qjava/QErrorMessage.java
new file mode 100644
index 0000000..f822269
--- /dev/null
+++ b/src/main/java/com/exxeleron/qjava/QErrorMessage.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2011-2014 Exxeleron GmbH
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.exxeleron.qjava;
+
+/**
+ * Encapsulates an error encountered during receiving data from kdb+.
+ *
+ * @author dev123
+ */
+public final class QErrorMessage {
+
+ private final Throwable cause;
+
+ /**
+ * Creates new {@link QErrorMessage} object with specified cause.
+ *
+ * @param cause
+ */
+ public QErrorMessage(final Throwable cause) {
+ this.cause = cause;
+ }
+
+ /**
+ * Retrieves the source exception.
+ *
+ * @return the exception
+ */
+ public Throwable getCause() {
+ return cause;
+ }
+
+}
diff --git a/src/main/java/com/exxeleron/qjava/QException.java b/src/main/java/com/exxeleron/qjava/QException.java
new file mode 100644
index 0000000..92adcc2
--- /dev/null
+++ b/src/main/java/com/exxeleron/qjava/QException.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2011-2014 Exxeleron GmbH
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.exxeleron.qjava;
+
+/**
+ * Exception representing q error.
+ */
+public class QException extends Exception {
+
+ private static final long serialVersionUID = -3871929200321654473L;
+
+ /**
+ * Constructs a {@link QException} with the specified detailed message and cause.
+ *
+ * @param message
+ * the detail message
+ * @param cause
+ * the cause
+ */
+ public QException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a {@link QException} with the specified detailed message.
+ *
+ * @param message
+ * the detail message
+ */
+ public QException(final String message) {
+ super(message);
+ }
+
+}
diff --git a/src/main/java/com/exxeleron/qjava/QKeyedTable.java b/src/main/java/com/exxeleron/qjava/QKeyedTable.java
new file mode 100644
index 0000000..ab3ec39
--- /dev/null
+++ b/src/main/java/com/exxeleron/qjava/QKeyedTable.java
@@ -0,0 +1,171 @@
+/**
+ * Copyright (c) 2011-2014 Exxeleron GmbH
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.exxeleron.qjava;
+
+import java.util.Iterator;
+
+/**
+ * Represents a q keyed table type.
+ */
+public class QKeyedTable implements Iterable+ * Returns an iterator over a key/value pairs stored in the keyed table. + *
+ * + *
+ * Note that the iterator returned by this method will throw an {@link UnsupportedOperationException} in response to
+ * its remove
method.
+ *
true
if this object is the same as the obj argument, false
otherwise.
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( final Object obj ) {
+ if ( this == obj ) {
+ return true;
+ }
+
+ if ( !(obj instanceof QKeyedTable) ) {
+ return false;
+ }
+
+ final QKeyedTable kt = (QKeyedTable) obj;
+ return keys.equals(kt.getKeys()) && values.equals(kt.getValues());
+ }
+
+ /**
+ * Returns a hash code value for this {@link QKeyedTable}.
+ *
+ * @return a hash code value for this object
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return 31 * keys.hashCode() + values.hashCode();
+ }
+
+}
diff --git a/src/main/java/com/exxeleron/qjava/QLambda.java b/src/main/java/com/exxeleron/qjava/QLambda.java
new file mode 100644
index 0000000..a057099
--- /dev/null
+++ b/src/main/java/com/exxeleron/qjava/QLambda.java
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2011-2014 Exxeleron GmbH
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.exxeleron.qjava;
+
+/**
+ * Represents a q lambda expression.
+ */
+public final class QLambda {
+ private final String expression;
+ private final Object[] parameters;
+
+ /**
+ * Gets body of a q lambda expression.
+ *
+ * @return body of a q lambda expression
+ */
+ public String getExpression() {
+ return expression;
+ }
+
+ /**
+ * Gets parameters of a q lambda expression.
+ *
+ * @return array containing lambda expression parameters
+ */
+ public Object[] getParameters() {
+ return parameters;
+ }
+
+ /**
+ * Creates new {@link QLambda} instance with given body and parameters.
+ *
+ * @param expression
+ * body of a q lambda expression
+ * @param parameters
+ * array containing lambda expression parameters
+ */
+ public QLambda(final String expression, final Object[] parameters) {
+ if ( expression == null || expression.length() == 0 ) {
+ throw new IllegalArgumentException("Lambda expression cannot be null or empty");
+ }
+
+ this.expression = expression;
+ this.parameters = parameters;
+ }
+
+ /**
+ * Creates new {@link QLambda} instance with given body and no parameters.
+ *
+ * @param expression
+ * body of a q lambda expression
+ */
+ public QLambda(final String expression) {
+ this(expression, null);
+ }
+
+ /**
+ * Returns a String that represents the current {@link QLambda}.
+ *
+ * @return a String representation of the {@link QLambda}
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "QLambda: " + expression + (parameters == null ? "" : Utils.arrayToString(parameters));
+ }
+
+ /**
+ * Indicates whether some other object is "equal to" this lambda expression. {@link QLambda} objects are considered
+ * equal if the expression and parameters list are equal for both instances.
+ *
+ * @return true
if this object is the same as the obj argument, false
otherwise.
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( final Object obj ) {
+ if ( this == obj ) {
+ return true;
+ }
+
+ if ( !(obj instanceof QLambda) ) {
+ return false;
+ }
+
+ final QLambda l = (QLambda) obj;
+ return expression.equals(l.expression) && Utils.deepArraysEquals(parameters, l.parameters);
+ }
+
+ /**
+ * Returns a hash code value for this {@link QLambda}.
+ *
+ * @return a hash code value for this object
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return expression.hashCode();
+ }
+
+}
diff --git a/src/main/java/com/exxeleron/qjava/QMessage.java b/src/main/java/com/exxeleron/qjava/QMessage.java
new file mode 100644
index 0000000..b4628b6
--- /dev/null
+++ b/src/main/java/com/exxeleron/qjava/QMessage.java
@@ -0,0 +1,128 @@
+/**
+ * Copyright (c) 2011-2014 Exxeleron GmbH
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.exxeleron.qjava;
+
+import java.nio.ByteOrder;
+
+/**
+ * Encapsulates the q message.
+ *
+ * @author dev123
+ */
+public final class QMessage {
+
+ private final ByteOrder endianess;
+ private final boolean compressed;
+ private final boolean raw;
+ private final QConnection.MessageType messageType;
+ private final int messageSize;
+ private final int dataSize;
+
+ private final Object data;
+
+ /**
+ * Creates new {@link QMessage} object.
+ *
+ * @param data
+ * data payload
+ * @param messageType
+ * type of the q message
+ * @param endianess
+ * endianess of the data
+ * @param compressed
+ * true
if message was compressed, false
otherwise
+ * @param raw
+ * true
if raw message was retrieved, false
if message was parsed
+ * @param messageSize
+ * size of the message
+ * @param dataSize
+ * size of the data payload section
+ */
+ public QMessage(final Object data, final QConnection.MessageType messageType, final ByteOrder endianess, final boolean compressed, final boolean raw,
+ final int messageSize, final int dataSize) {
+ this.data = data;
+ this.messageType = messageType;
+ this.endianess = endianess;
+ this.compressed = compressed;
+ this.raw = raw;
+ this.messageSize = messageSize;
+ this.dataSize = dataSize;
+ }
+
+ /**
+ * Retrieves the data payload associated with the message.
+ *
+ * @return the data
+ */
+ public Object getData() {
+ return data;
+ }
+
+ /**
+ * Indicates endianess of the message.
+ *
+ * @return endianess of the message
+ */
+ public ByteOrder getEndianess() {
+ return endianess;
+ }
+
+ /**
+ * Indicates whether message was compressed.
+ *
+ * @return true
if message was compressed, false
otherwise
+ */
+ public boolean isCompressed() {
+ return compressed;
+ }
+
+ /**
+ * Indicates whether message has been parsed.
+ *
+ * @return true
if message is returned as a raw byte data, false
otherwise
+ */
+ public boolean isRaw() {
+ return raw;
+ }
+
+ /**
+ * Gets type of the message.
+ *
+ * @return type of the message
+ */
+ public QConnection.MessageType getMessageType() {
+ return messageType;
+ }
+
+ /**
+ * Gets a total size of the message.
+ *
+ * @return total size of the message
+ */
+ public int getMessageSize() {
+ return messageSize;
+ }
+
+ /**
+ * Gets a size of data section in the message.
+ *
+ * @return size of data section in the message
+ */
+ public int getDataSize() {
+ return dataSize;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/exxeleron/qjava/QMessagesListener.java b/src/main/java/com/exxeleron/qjava/QMessagesListener.java
new file mode 100644
index 0000000..6034cad
--- /dev/null
+++ b/src/main/java/com/exxeleron/qjava/QMessagesListener.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2011-2014 Exxeleron GmbH
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.exxeleron.qjava;
+
+import java.util.EventListener;
+
+/**
+ * Listener class for kdb+ subscription
+ */
+public interface QMessagesListener extends EventListener {
+
+ /**
+ * Invoked when a new message has been received from a kdb+ server.
+ *
+ * @param message
+ * a {@link QMessage} containing received data
+ */
+ public void messageReceived( QMessage message );
+
+ /**
+ * Invoked when an error has been encountered.
+ *
+ * @param message
+ * a {@link QErrorMessage} encapsulating error
+ */
+ public void errorReceived( QErrorMessage message );
+}
diff --git a/src/main/java/com/exxeleron/qjava/QMinute.java b/src/main/java/com/exxeleron/qjava/QMinute.java
new file mode 100644
index 0000000..cadd3f2
--- /dev/null
+++ b/src/main/java/com/exxeleron/qjava/QMinute.java
@@ -0,0 +1,148 @@
+/**
+ * Copyright (c) 2011-2014 Exxeleron GmbH
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.exxeleron.qjava;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * Represents q minute type.
+ */
+public final class QMinute implements DateTime {
+
+ private static final String NULL_STR = "0Nu";
+
+ private static final DateFormat dateFormat = new SimpleDateFormat("HH:mm");
+
+ private Date datetime;
+ private Integer value;
+
+ /**
+ * Creates new {@link QMinute} instance using specified q date value.
+ *
+ * @param value
+ * a count of minutes from midnight
+ */
+ public QMinute(final Integer value) {
+ this.value = value;
+ }
+
+ /**
+ * Creates new {@link QMinute} instance using specified {@link Date}.
+ *
+ * @param datetime
+ * {@link Date} to be set
+ */
+ public QMinute(final Date datetime) {
+ this.datetime = datetime;
+ if ( datetime != null ) {
+ final Calendar c = Calendar.getInstance();
+ c.setTime(datetime);
+ value = c.get(Calendar.MINUTE) + 60 * c.get(Calendar.HOUR_OF_DAY);
+ } else {
+ value = Integer.MIN_VALUE;
+ }
+ }
+
+ /**
+ * Returns a count of minutes from midnight.
+ *
+ * @return raw q value
+ */
+ public Integer getValue() {
+ return value;
+ }
+
+ /**
+ * Converts {@link QMinute} object to {@link Date} instance.
+ *
+ * @return {@link Date} representing q value.
+ */
+ public Date toDateTime() {
+ if ( datetime == null && value != Integer.MIN_VALUE ) {
+ final Calendar c = Calendar.getInstance();
+ c.set(2000, 0, 1, value / 60, value % 60);
+ datetime = c.getTime();
+ }
+ return datetime;
+ }
+
+ /**
+ * Returns a String that represents the current {@link QMinute}.
+ *
+ * @return a String representation of the {@link QMinute}
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ final Date dt = toDateTime();
+ return dt == null ? NULL_STR : getDateformat().format(dt);
+ }
+
+ /**
+ * Indicates whether some other object is "equal to" this date. {@link QMinute} objects are considered equal if the
+ * underlying q raw value is the same for both instances.
+ *
+ * @return true
if this object is the same as the obj argument, false
otherwise.
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( final Object obj ) {
+ if ( this == obj ) {
+ return true;
+ }
+
+ if ( !(obj instanceof QMinute) ) {
+ return false;
+ }
+
+ return value.equals(((QMinute) obj).getValue());
+ }
+
+ /**
+ * Returns a hash code value for this {@link QMinute}.
+ *
+ * @return a hash code value for this object
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ /**
+ * Returns a {@link QMinute} represented by a given string.
+ *
+ * @param date
+ * as {@link String}
+ * @return a {@link QMinute} instance representing date.
+ * @throws IllegalArgumentException
+ * when date cannot be parsed
+ */
+ public static QMinute fromString( final String date ) {
+ try {
+ return date == null || date.length() == 0 || date.equals(NULL_STR) ? new QMinute(Integer.MIN_VALUE) : new QMinute(getDateformat().parse(date));
+ } catch ( final Exception e ) {
+ throw new IllegalArgumentException("Cannot parse QMinute from: " + date, e);
+ }
+ }
+
+ private static synchronized DateFormat getDateformat() {
+ return dateFormat;
+ }
+}
diff --git a/src/main/java/com/exxeleron/qjava/QMonth.java b/src/main/java/com/exxeleron/qjava/QMonth.java
new file mode 100644
index 0000000..9b2de2a
--- /dev/null
+++ b/src/main/java/com/exxeleron/qjava/QMonth.java
@@ -0,0 +1,148 @@
+/**
+ * Copyright (c) 2011-2014 Exxeleron GmbH
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.exxeleron.qjava;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * Represents q month type.
+ */
+public final class QMonth implements DateTime {
+
+ private static final String NULL_STR = "0Nm";
+
+ private static final DateFormat dateFormat = new SimpleDateFormat("yyyy.MM'm'");
+
+ private Date datetime;
+ private Integer value;
+
+ /**
+ * Creates new {@link QMonth} instance using specified q date value.
+ *
+ * @param value
+ * a count of months since 2000.01.01
+ */
+ public QMonth(final Integer value) {
+ this.value = value;
+ }
+
+ /**
+ * Creates new {@link QMonth} instance using specified {@link Date}.
+ *
+ * @param datetime
+ * {@link Date} to be set
+ */
+ public QMonth(final Date datetime) {
+ this.datetime = datetime;
+ if ( datetime != null ) {
+ final Calendar c = Calendar.getInstance();
+ c.setTime(datetime);
+ value = 12 * (c.get(Calendar.YEAR) - 2000) + c.get(Calendar.MONTH);
+ } else {
+ value = Integer.MIN_VALUE;
+ }
+ }
+
+ /**
+ * Returns a count of months since 2000.01.01.
+ *
+ * @return raw q value
+ */
+ public Integer getValue() {
+ return value;
+ }
+
+ /**
+ * Converts {@link QMonth} object to {@link Date} instance.
+ *
+ * @return {@link Date} representing q value.
+ */
+ public Date toDateTime() {
+ if ( datetime == null && value != Integer.MIN_VALUE ) {
+ final Calendar c = Calendar.getInstance();
+ c.set(2000 + value / 12, value % 12 + 1, 0, 0, 0);
+ datetime = c.getTime();
+ }
+ return datetime;
+ }
+
+ /**
+ * Returns a String that represents the current {@link QMonth}.
+ *
+ * @return a String representation of the {@link QMonth}
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ final Date dt = toDateTime();
+ return dt == null ? NULL_STR : getDateformat().format(dt);
+ }
+
+ /**
+ * Indicates whether some other object is "equal to" this date. {@link QMonth} objects are considered equal if the
+ * underlying q raw value is the same for both instances.
+ *
+ * @return true
if this object is the same as the obj argument, false
otherwise.
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( final Object obj ) {
+ if ( this == obj ) {
+ return true;
+ }
+
+ if ( !(obj instanceof QMonth) ) {
+ return false;
+ }
+
+ return value.equals(((QMonth) obj).getValue());
+ }
+
+ /**
+ * Returns a hash code value for this {@link QMonth}.
+ *
+ * @return a hash code value for this object
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ /**
+ * Returns a {@link QMonth} represented by a given string.
+ *
+ * @param date
+ * as {@link String}
+ * @return a {@link QMonth} instance representing date.
+ * @throws IllegalArgumentException
+ * when date cannot be parsed
+ */
+ public static QMonth fromString( final String date ) {
+ try {
+ return date == null || date.length() == 0 || date.equals(NULL_STR) ? new QMonth(Integer.MIN_VALUE) : new QMonth(getDateformat().parse(date));
+ } catch ( final Exception e ) {
+ throw new IllegalArgumentException("Cannot parse QMonth from: " + date, e);
+ }
+ }
+
+ private static synchronized DateFormat getDateformat() {
+ return dateFormat;
+ }
+}
diff --git a/src/main/java/com/exxeleron/qjava/QReader.java b/src/main/java/com/exxeleron/qjava/QReader.java
new file mode 100644
index 0000000..e8c2d4e
--- /dev/null
+++ b/src/main/java/com/exxeleron/qjava/QReader.java
@@ -0,0 +1,514 @@
+/**
+ * Copyright (c) 2011-2014 Exxeleron GmbH
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.exxeleron.qjava;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.UUID;
+
+/**
+ * Provides deserialization from q IPC protocol.true
if this object is the same as the obj argument, false
otherwise.
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( final Object obj ) {
+ if ( this == obj ) {
+ return true;
+ }
+
+ if ( !(obj instanceof QSecond) ) {
+ return false;
+ }
+
+ return value.equals(((QSecond) obj).getValue());
+ }
+
+ /**
+ * Returns a hash code value for this {@link QSecond}.
+ *
+ * @return a hash code value for this object
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ /**
+ * Returns a {@link QSecond} represented by a given string.
+ *
+ * @param date
+ * as {@link String}
+ * @return a {@link QSecond} instance representing date.
+ * @throws IllegalArgumentException
+ * when date cannot be parsed
+ */
+ public static QSecond fromString( final String date ) {
+ try {
+ return date == null || date.length() == 0 || date.equals(NULL_STR) ? new QSecond(Integer.MIN_VALUE) : new QSecond(getDateformat().parse(date));
+ } catch ( final Exception e ) {
+ throw new IllegalArgumentException("Cannot parse QSecond from: " + date, e);
+ }
+ }
+
+ private static synchronized DateFormat getDateformat() {
+ return dateFormat;
+ }
+}
diff --git a/src/main/java/com/exxeleron/qjava/QTable.java b/src/main/java/com/exxeleron/qjava/QTable.java
new file mode 100644
index 0000000..2bcc5d1
--- /dev/null
+++ b/src/main/java/com/exxeleron/qjava/QTable.java
@@ -0,0 +1,311 @@
+/**
+ * Copyright (c) 2011-2014 Exxeleron GmbH
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.exxeleron.qjava;
+
+import java.lang.reflect.Array;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+/**
+ * Represents a q table type.
+ */
+public final class QTable implements Iterabletrue
if this object is the same as the obj argument, false
otherwise.
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( final Object obj ) {
+ if ( this == obj ) {
+ return true;
+ }
+
+ if ( !(obj instanceof QTable) ) {
+ return false;
+ }
+
+ final QTable t = (QTable) obj;
+ return Utils.deepArraysEquals(columns, t.columns) && Utils.deepArraysEquals(data, t.data);
+ }
+
+ /**
+ * Returns a hash code value for this {@link QTable}.
+ *
+ * @return a hash code value for this object
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return 31 * Utils.arrayHashCode(columns) + Utils.arrayHashCode(data);
+ }
+
+ /**
+ * + * Returns an iterator over rows stored in the table. + *
+ * + *
+ * Note that the iterator returned by this method will throw an {@link UnsupportedOperationException} in response to
+ * its remove
method.
+ *