"Unresolved reference" error in SqlDelight - database

I have simple query in kotlin multiplatform project with SqlDelight database:
getLast: SELECT * FROM history ORDER BY id DESC LIMIT ?;
But when I try to build the app, I get such error ".....DatabaseImpl.kt: (207, 72): Unresolved reference: value_".
DatabaseImpl.kt is generated class and I can't modify it.
This is the code from this class with compilation error:
public override fun getLast(`value`: Long): Query<History> = getLast(value_) { id, time, spo2,
pulse_rate, status ->
History(
id,
time,
spo2,
pulse_rate,
status
) }
Why does it generate "value" as function parameter, but then use "value_" with underscore? It causes an error.

Try to use the named parameter:
getLast:
SELECT * FROM history
ORDER BY id DESC LIMIT :rowNumbers;

Related

When using Exposed's method "createMissingTablesAndColumns", I get a NoSuchElementException

I'm using 0.22.1 Exposed libs (core/dao/jdbc) and when I use "SchemaUtils.createMissingTablesAndColumns", my tables are created but I get an Exception.
If I relaunch the server with a new column, I get the same Exception and the update isn't performed
See the stacktrace :
Exception in thread "main" java.util.NoSuchElementException: Collection contains no element matching the predicate.
at org.jetbrains.exposed.sql.statements.jdbc.JdbcDatabaseMetadataImpl$tableConstraints$$inlined$associateWith$lambda$1.invoke(JdbcDatabaseMetadataImpl.kt:170)
at org.jetbrains.exposed.sql.statements.jdbc.JdbcDatabaseMetadataImpl$tableConstraints$$inlined$associateWith$lambda$1.invoke(JdbcDatabaseMetadataImpl.kt:13)
at org.jetbrains.exposed.sql.statements.jdbc.JdbcDatabaseMetadataImplKt.iterate(JdbcDatabaseMetadataImpl.kt:164)
at org.jetbrains.exposed.sql.statements.jdbc.JdbcDatabaseMetadataImpl.tableConstraints(JdbcDatabaseMetadataImpl.kt:123)
at org.jetbrains.exposed.sql.vendors.VendorDialect$fillConstraintCacheForTables$1.invoke(Default.kt:639)
at org.jetbrains.exposed.sql.vendors.VendorDialect$fillConstraintCacheForTables$1.invoke(Default.kt:560)
at org.jetbrains.exposed.sql.statements.jdbc.JdbcConnectionImpl.metadata(JdbcConnectionImpl.kt:47)
at org.jetbrains.exposed.sql.Database.metadata$exposed_core(Database.kt:31)
at org.jetbrains.exposed.sql.vendors.VendorDialect.fillConstraintCacheForTables(Default.kt:639)
at org.jetbrains.exposed.sql.vendors.VendorDialect.columnConstraints(Default.kt:617)
at org.jetbrains.exposed.sql.SchemaUtils.addMissingColumnsStatements(SchemaUtils.kt:145)
at org.jetbrains.exposed.sql.SchemaUtils.createMissingTablesAndColumns(SchemaUtils.kt:241)
at org.jetbrains.exposed.sql.SchemaUtils.createMissingTablesAndColumns$default(SchemaUtils.kt:229)
at repository.database.DatabaseRepository$createTableAndColumn$1.invoke(DatabaseRepository.kt:36)
at repository.database.DatabaseRepository$createTableAndColumn$1.invoke(DatabaseRepository.kt:17)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt$inTopLevelTransaction$1.invoke(ThreadLocalTransactionManager.kt:156)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt$inTopLevelTransaction$2.invoke(ThreadLocalTransactionManager.kt:197)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.keepAndRestoreTransactionRefAfterRun(ThreadLocalTransactionManager.kt:205)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.inTopLevelTransaction(ThreadLocalTransactionManager.kt:196)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt$transaction$1.invoke(ThreadLocalTransactionManager.kt:134)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.keepAndRestoreTransactionRefAfterRun(ThreadLocalTransactionManager.kt:205)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.transaction(ThreadLocalTransactionManager.kt:106)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.transaction(ThreadLocalTransactionManager.kt:104)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.transaction$default(ThreadLocalTransactionManager.kt:103)
at repository.database.DatabaseRepository.createTableAndColumn(DatabaseRepository.kt:35)
at repository.database.DatabaseRepository.createAndUpdateDB(DatabaseRepository.kt:31)
at domain.database.PrepareDatabaseUseCase.performNow(PrepareDatabaseUseCase.kt:18)
at controller.MainController.<init>(MainController.kt:18)
at controller.MainControllerKt.main(MainController.kt:10)
My tables are simple (just for test) :
import org.jetbrains.exposed.dao.id.IntIdTable
object UserTable: IntIdTable()
and
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.IntIdTable
import org.jetbrains.exposed.sql.Column
object SpaceTable: IntIdTable() {
val userIdColumn: Column<EntityID<Int>> = reference("userId", UserTable.id)
}
When I try the method "SchemaUtils.create", everything is ok but, of course, when I relaunch the server with some news columns, columns aren't created
Have you an idea to how fix this ? What I doing wrong ?
Thank you

Eiffel: a way to get target and project name #runtime

Is there a way to get the project name and target at execution time or is it not stored into executable?
Project and target names are not stored in an executable.
As a workaround Setting the executable name into project settings -> target -> Output name and getting it from following function made me able to do something similar
application_file_name: STRING
local
l_path: PATH
once
Result := {EXECUTION_ENVIRONMENT}.arguments.argument (0).out
create l_path.make_from_string (Result)
check
attached l_path.entry as l_fname_path
then
Result := l_fname_path.utf_8_name
end
ensure
instance_free: Class
end

Simplejdbccall Stored Procedure withNamedBinding true

I want to execute stored procedure with dynamic parameters with SimpleJdbcCall. In total I have 6 optional parameters in SQL server SP, out of them I must be able to pass any or none. My SP executes fine as expected in MS Studio. But not by SimpleJdbcCall. I tried in many ways and one of them I tried is withNamedBinding. But it gives Input Syntax error near "=" as below.
this.simpleJdbcCall = new SimpleJdbcCall(jdbcTemplateObject)
.withNamedBinding()
.withSchemaName("dbo")
.withProcedureName("EmployeeDetails")
.useInParameterNames(
paramNameArray)
.returningResultSet("detailReportData", BeanPropertyRowMapper.newInstance(Employee.class));
Map<String,Object> out = this.simpleJdbcCall.execute(sqlSource);
Log:
2019-01-31 18:14:49 DEBUG SimpleJdbcCall:405 - The following
parameters are used for call {call dbo.EmployeeDetails(empCode => ?,
empName => ?, empLoc => ?)} with {empCode=0, empName='hgkghdkgf',
empLoc='kjhjk'} 2019-01-31 18:14:49 DEBUG DispatcherServlet:993 -
Could not complete request
org.springframework.jdbc.UncategorizedSQLException:
CallableStatementCallback; uncategorized SQLException for SQL [{call
dbo.EmployeeDetails(empCode => ?, empName => ?, empLoc => ?)}]; SQL
state [S0001]; error code [102]; Incorrect syntax near '='.; nested
exception is com.microsoft.sqlserver.jdbc.SQLServerException:
Incorrect syntax near '='.
I had faced similar type of problem and found few solutions in this stack overflow question. But in my case I was using MS-SQL server and it was giving me this same syntax error. While searching for solutions I came across this example of Spring (See Section 11.5.6. Declaring parameters to use for a SimpleJdbcCall).
Just in case if the link becomes unavailable, here is what it says
We can opt to declare one, some or all of the parameters explicitly. The parameter metadata is still being used. By calling the method withoutProcedureColumnMetaDataAccess we can specify that we would like to bypass any processing of the metadata lookups for potential parameters and only use the declared ones. Another situation that can arise is that one or more in parameters have default values and we would like to leave them out of the call. To do that we will just call the useInParameterNames to specify the list of in parameter names to include.
And here is the sample code
public class JdbcActorDao implements ActorDao {
private SimpleJdbcCall procReadActor;
public void setDataSource(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.setResultsMapCaseInsensitive(true);
this.procReadActor =
new SimpleJdbcCall(jdbcTemplate)
.withProcedureName("read_actor")
.withoutProcedureColumnMetaDataAccess()
.useInParameterNames("in_id")
.declareParameters(
new SqlParameter("in_id", Types.NUMERIC),
new SqlOutParameter("out_first_name", Types.VARCHAR),
new SqlOutParameter("out_last_name", Types.VARCHAR),
new SqlOutParameter("out_birth_date", Types.DATE)
);
}
// ... additional methods
}
I am not sure why but the withNamedBinding() method seems to not work properly with ms-sql server and creates the syntax error.
So in the above solution the work around is to
not to use the .withNamedBinding() method.
use the .withoutProcedureColumnMetaDataAccess() method.
while passing your parameter array to the .useInParameterNames() method, make sure you pass it in the sequence it is declared in the proc (as we are not using name binding). My out parameter was declared few parameters before the last one and so it was giving me error while converting var to int as my out param was int.
So now your solution should look something like this :
this.simpleJdbcCall = new SimpleJdbcCall(jdbcTemplateObject)
.withSchemaName("dbo")
.withProcedureName("EmployeeDetails")
.withoutProcedureColumnMetaDataAccess()
.useInParameterNames(paramNameArray)
.returningResultSet("detailReportData", BeanPropertyRowMapper.newInstance(Employee.class));
Map<String,Object> out = this.simpleJdbcCall.execute(sqlSource);
Give it a try and see if this works for you.

Can Stream Analytics filter items of array property?

Hi I wonder if it is possible to select certain items from the array property of a JSON input of Stream Analytics and return them as an array property of a JSON output.
My example to make it more clear - I send a list of OSGI bundles running on a device with name, version and state of the bundle. (I leave out rest of the content.) Sample message:
{"bundles":[{"name":"org.eclipse.osgi","version":"3.5.1.R35x_v20090827","state":32},{"name":"slf4j.log4j12","version":"1.6.1","state":4}]}
Via Stream Analytics I want to create one JSON output (event hub) for active bundle (state == 32) and put the rest in the different output. Content of those event hubs will be processed later. But in the processing I also need the original Device ID so I fetch it from the IoTHub message properties.
So my query looks like this:
WITH Step1 AS
(
SELECT
IoTHub.ConnectionDeviceId AS deviceId,
bundles as bundles
FROM
iotHubMessages
)
SELECT
messages.deviceId AS deviceId,
bundle.ArrayValue.name AS name,
bundle.ArrayValue.version AS version
INTO
active
FROM
Step1 as messages
CROSS APPLY GetArrayElements(messages.bundles) AS bundle
WHERE
bundle.ArrayValue.state = 32
SELECT
messages.deviceId AS deviceId,
bundle.ArrayValue.name AS name,
bundle.ArrayValue.version AS version
INTO
other
FROM
Step1 as messages
CROSS APPLY GetArrayElements(messages.bundles) AS bundle
WHERE
bundle.ArrayValue.state != 32
This way there is a row for every item of the original array containing deviceId, name and version properties in the active output. So the deviceId property is copied several times, which means additional data in a message. I'd prefer a JSON with one deviceId property and one array property bundles, similar to the original JSON input.
Like active:
{"deviceid":"javadevice","bundles":[{"name":"org.eclipse.osgi","version":"3.5.1.R35x_v20090827"}]}
And other:
{"deviceid":"javadevice","bundles":[{"name":"slf4j.log4j12","version":"1.6.1"}]}
Is there any way to achieve this? - To filter items of array and return it back as an array in the same format as is in the input. (In my code I change number of properties, but that is not necessary.)
Thanks for any ideas!
I think you can achieve this using the Collect() aggregate function.
The only issue I see is that the deviceId property will be outputted in the bundle array as well.
WITH Step1 AS
(
SELECT
IoTHub.ConnectionDeviceId AS deviceId,
bundles as bundles
FROM
iotHubMessages
),
Step2 AS
(
SELECT
messages.deviceId AS deviceId,
bundle.ArrayValue.name AS name,
bundle.ArrayValue.version AS version
bundle.ArrayValue.state AS state
FROM
Step1 as messages
CROSS APPLY GetArrayElements(messages.bundles) AS bundle
)
SELECT deviceId, Collect() AS bundles
FROM Step2
GROUP BY deviceId, state, System.Timestamp
WHERE state = 32

why does gql query result cause exception when calling get()

I am attempting to retrieve an entry from my datastore with this:
query = UserData.gql("WHERE mDeviceId = :1", id)
Utils.log("my Object:" + str(query))
entry = query.get()
It just so happens that the variable 'id' doesn't even exist (typo), so I know how to fix this, but I don't understand why the result I get won't let me call get() on it. When I do, I get the error:
Exception: Unsupported type for property : <type 'builtin_function_or_method'>
Normally I just check if entry == None to see if I get no results. Does anyone know why this occurs and if I should be doing my checks for None differently, in case I have such typos in the future?
A variable named id is not defined in your code, so it passes the builtin function id, and QL complains that it's getting a function when it expected a value (integer?).
Check to make sure you're assigning id a value before you use it.
Even better, don't shadow builtins with your own variables-- it'll cause confusing errors like this. :-)

Resources