Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the SQL Server plugin to include milliseconds when saving NSTimestamp values #991

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.webobjects.jdbcadaptor;

import com.webobjects.eoaccess.EOAttribute;
import com.webobjects.eoaccess.EOEntity;
import com.webobjects.foundation.NSMutableDictionary;
import com.webobjects.foundation.NSTimestamp;
import com.webobjects.foundation.NSTimestampFormatter;

import java.sql.Timestamp;

/**
* Overrides {@code MicrosoftExpression} in order to add TIMESTAMP values including milliseconds.
*
* @author hprange (most code was copied from {@code EROracleExpression})
*/
public class ERMicrosoftExpression extends MicrosoftPlugIn.MicrosoftExpression {
private static final NSTimestampFormatter _TIMESTAMP_FORMATTER = new NSTimestampFormatter("%Y-%m-%d %H:%M:%S.%F");

public ERMicrosoftExpression(EOEntity entity) {
super(entity);
}

/**
* Overridden in order to add milliseconds to the value. This applies only if value is an instance of
* {@code NSTimestamp} and if valueType from the attribute is {@code 'T'}.
*
* @param attribute the EOAttribute associated with the bind variable dictionary
* @param value the value associated with the bind variable dictionary
* @return the modified bind variable dictionary for {@code attribute} and {@code value}
*/
@Override
public NSMutableDictionary<String, Object> bindVariableDictionaryForAttribute(EOAttribute attribute, Object value) {
NSMutableDictionary<String, Object> result = super.bindVariableDictionaryForAttribute(attribute, value);

if (value instanceof NSTimestamp && isTimestampAttribute(attribute)) {
NSTimestamp nstimestamp = (NSTimestamp) value;
long millis = nstimestamp.getTime();
// AK: since NSTimestamp places fractional millis in the getTime,
// the driver is getting very confused and refuses to update the columns as
// they get translated to 0 as the fractional values.
Timestamp timestamp = new Timestamp(millis);
timestamp.setNanos(timestamp.getNanos() + nstimestamp.getNanos());
result.setObjectForKey(timestamp, "BindVariableValue");
}

return result;
}

/**
* Overridden to add milliseconds to the value. This applies only if value is an instance of {@code NSTimestamp} and
* if valueType from the attribute is {@code T}.
*
* @param value an object to be used in a SQL statement
* @param attribute an EOAttribute to be used in influencing the format
* @return the modified formatted string
*/
@Override
public String formatValueForAttribute(Object value, EOAttribute attribute) {
if (value instanceof NSTimestamp && isTimestampAttribute(attribute)) {
return "'" + _TIMESTAMP_FORMATTER.format(value) + "'";
}

return super.formatValueForAttribute(value, attribute);
}

private boolean isTimestampAttribute(EOAttribute attribute) {
return "T".equals(attribute.valueType());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ public String defaultDriverName() {
return "com.microsoft.sqlserver.jdbc.SQLServerDriver";
}

/**
* Uses the enhanced {@code ERMicrosoftExpression} as the expression class.
*/
@Override
public Class defaultExpressionClass() {
return ERMicrosoftExpression.class;
}

/**
* Generates a batch of new primary keys for the given entity. Overrides the default implementation to provide a
* more efficient mechanism for generating primary keys using database sequences.
Expand Down