Granite ORM + fiber + mysql = Unexpected EOF (Exception)? - crystal-lang

Is working with Fibers in Granite possible? I didn't have a reason to believe otherwise, until I attempted to write some code for it. I am attempting to learn to work with Fibers, so perhaps incorrect fiber implementation could also be a cause. The following code results in an exception. Any hints to resolve this?
lines = File.read_lines INVENTORY_FILE
channel = Channel(Int32).new(199)
lines[0..200].each do |line|
row_number += 1
proc = ->(line : NamedTuple(item_number: String) do
spawn do
sku = Sku.find_by :item_number, item_number
channel.send(1)
end
end
proc.call({ line: line })
end
199.times do |i|
channel.receive
end
The above results in the following repeated exception starting from the very first fiber's attempt to access the DB. I've ensured that MySQL is in a working state and that the code works when fibers are not in use:
Unexpected EOF (Exception)
from lib/mysql/src/mysql/read_packet.cr:38:18 in 'read_byte!'
from lib/mysql/src/mysql/read_packet.cr:63:5 in 'read_int'
from lib/mysql/src/mysql/packets.cr:13:7 in 'read'
from lib/mysql/src/mysql/connection.cr:63:14 in 'read_packet'
from lib/mysql/src/mysql/connection.cr:22:19 in 'initialize'
from lib/mysql/src/mysql/connection.cr:4:3 in 'new'
from lib/mysql/src/mysql/driver.cr:3:5 in 'build_connection'
from lib/db/src/db/pool.cr:255:3 in 'build_resource'
from lib/db/src/db/pool.cr:34:22 in 'checkout'
from lib/db/src/db/pool.cr:65:7 in 'checkout_some'
from lib/db/src/db/database.cr:99:7 in 'checkout_some'
from lib/db/src/db/pool_prepared_statement.cr:35:24 in 'build_statement'
from lib/db/src/db/pool_prepared_statement.cr:53:22 in 'initialize'
from lib/db/src/db/pool_prepared_statement.cr:11:5 in 'new'
from lib/db/src/db/database.cr:89:7 in 'build_prepared_statement'
from lib/db/src/db/database.cr:7:15 in 'fetch_or_build_prepared_statement'
from lib/db/src/db/session_methods.cr:23:9 in 'build'
from lib/db/src/db/query_methods.cr:38:7 in 'query'
from lib/granite/src/granite/querying.cr:53:12 in 'find_by'
from /usr/share/crystal/src/kernel.cr:0:3 in '~procProc(Nil)'
from /usr/share/crystal/src/fiber.cr:255:3 in 'run'
from /usr/share/crystal/src/concurrent.cr:0:3 in '~proc2Proc(Fiber, (IO::FileDescriptor | Nil))'
from ???

Related

"org.jdbi.v3.core.statement.UnableToCreateStatementException: Undefined attribute for token '<endif>'

Method in Dao Interface
#RegisterRowMapper(MapMapper.class)
#SqlQuery(
"SELECT Table1.tenantId,Table1.sacTenantId, sacLogId,currentStep,status from Table1 inner join Table2 on Table1.tenantId = Table2.tenantId where <if(tenantId)>Table1.tenantId = :tenantId and<endif> Table2.status = 'FAILED'")
List<Map<String, Object>> getTenantFailedJobDetails(#Define("tenantId") #Bind("tenantId") String tenantId);
Error trace:
"level":"ERROR","categories":[],"msg":"Servlet.service() for servlet
[dispatcherServlet] in context with path [] threw exception [Request
processing failed; nested exception is
org.jdbi.v3.core.statement.UnableToCreateStatementException: Error
rendering SQL template: 'SELECT Table1.tenantId,Table1.sacTenantId,
sacLogId,currentStep,status from Table1 inner join Table2 on
Table1.tenantId = Table2.tenantId where <if(tenantId)>Table1.tenantId
= :tenantId and Table2.status = 'FAILED'' [statement:"null", arguments:{positional:{0:DUMMY-TENANT}, named:{tenantId:DUMMY-TENANT},
finder:[]}]] with root
cause","stacktrace":["org.jdbi.v3.core.statement.UnableToCreateStatementException:
Undefined attribute for token '' [statement:"null",
arguments:{positional:{0:DUMMY-TENANT}, named:{tenantId:DUMMY-TENANT},
finder:[]}]"
What could be wrong with the if condition?
To make if condition in jdbi query work I added annotation #UseStringTemplateEngine of package org.jdbi.v3.stringtemplate4 to the Dao method
If tenandId is not null then where clause will be
Table1.tenantId = :tenantId and Table2.status = 'FAILED'
else where clause will be just
Table2.status = 'FAILED'
One more information to add, for the else part annotation #AllowUnusedBindings package org.jdbi.v3.sqlobject.customizer is required
The syntax you posted is stringtemplate4, so you need to use the stringtemplate 4 engine (which you select with the annotation that you posted). Otherwise you end up with the default engine which does support only very simply substitutions (and not st4 syntax).

Scala - Looping through an array and applying regex

I have an array of log messages. An example of a message in the array below -
Example below -
Output(RequiredSystemOutput(2017-05-21 13:43:59,085 [scala-execution-context-global-43] ERROR Database - Error executing database store for URI (uri:becbfx08-c491-44e3-bd01-d12c0305bcbf,offset:12054350) for transition to state FileArchived : Could not acquire connection-1 - Connection is not available, request timed out after 15000ms.,2020-01-21 13:43:59.086 GMT)) }}
So imagine the above but repeated.
I would like to loop through the array of individual log messages so that rather than printing out the whole message for each one, it only prints out the uri and offset, like so -
uri:becbfx08-c491-44e3-bd01-d12c0305bcbf,offset:12054350
I have the regex which is val regex = "\\(([^()]+)\\)" but I am struggling to apply this in Scala, especially in an array.
I am not sure that the regex which you mentioned in your code will help because you have provided just one example. I can provide with a more selective for the given example.
val string = "Output(RequiredSystemOutput(2017-05-21 13:43:59,085 [scala-execution-context-global-43] ERROR Database - Error executing database store for URI (uri:becbfx08-c491-44e3-bd01-d12c0305bcbf,offset:12054350) for transition to state FileArchived : Could not acquire connection-1 - Connection is not available, request timed out after 15000ms.,2020-01-21 13:43:59.086 GMT)) }}"
val regex = "\\((uri\\:[0-9a-zA-Z\\-]+,offset\\:[0-9]+)\\)".r
val matchOption = regex.findFirstMatchIn(string)
val extractedStringOption = matchOption.map(_.group(1))
// extractedStringOption: Option[String] = Some(uri:becbfx08-c491-44e3-bd01-d12c0305bcbf,offset:12054350)
You could loop the array, and if there is only a single match use findFirstMatchIn.
The pattern you use is very broad, and you might make it a bit more specific by for example starting the match inside the capturing group with uri:
Regex demo | Scala demo
For example
val array = Array (
"Output(RequiredSystemOutput(2017-05-21 13:43:59,085 [scala-execution-context-global-43] ERROR Database - Error executing database store for URI (uri:becbfx08-c491-44e3-bd01-d12c0305bcbf,offset:12054350) for transition to state FileArchived : Could not acquire connection-1 - Connection is not available, request timed out after 15000ms.,2020-01-21 13:43:59.086 GMT)) }}",
"Output(RequiredSystemOutput(2017-05-21 13:43:59,085 [scala-execution-context-global-43] ERROR Database - Error executing database store for URI (uri:becbfx08-c491-44e3-bd01-d12c0305bcbf,offset:12054350) for transition to state FileArchived : Could not acquire connection-1 - Connection is not available, request timed out after 15000ms.,2020-01-21 13:43:59.086 GMT)) }}"
)
val pattern = """\((uri:[^()]+)\)""".r
val res: Array[String] = for {
s <- array
m <- pattern.findAllMatchIn(s)
} yield m.group(1)
res.foreach(println)
Output
uri:becbfx08-c491-44e3-bd01-d12c0305bcbf,offset:12054350
uri:becbfx08-c491-44e3-bd01-d12c0305bcbf,offset:12054350
To get a more specific match, you could use a character class and repeat the preceding hyphen:
\((uri:[a-z0-9]+(?:-[a-z0-9]+)+,offset:[0-9]+)\)
Regex demo

Unparsable MOF Query When Trying to Register Event

Update 2
I accepted an answer and asked a different question elsewhere, where I am still trying to get to the bottom of this.
I don't think that one-lining this query is the answer, as I am still not getting the required results (and multi-lining queries is allowed in .mof, as shown in the URLs in comments to the answer ...
Update
I rewrote the query as a one-liner as suggested, but still got the same error! As it was still talking about lines 11-19 I knew there must be another issue. After saving a new file with the change, I reran mofcomp and it appears to have loaded, but the event which I have subscribed to simply does not work.
I really feel that there is not enough documentation on this topic and it is hard to work out how I am meant to debug this - any help on this would be much appreciated, even if this means using a different more appropriate method.
I have the following .mof file, which I would like to use to register an event on my system :
#pragma namespace("\\\\.\\root\\subscription")
instance of __EventFilter as $EventFilter
{
Name = "Event Filter Instance Name";
Query = "Select * from __InstanceCreationEvent within 1 "
"where targetInstance isa \"Cim_DirectoryContainsFile\" "
"and targetInstance.GroupComponent = \"Win32_Directory.Name=\"c:\\\\test\"\"";
QueryLanguage = "WQL";
EventNamespace = "Root\\Cimv2";
};
instance of ActiveScriptEventConsumer as $Consumer
{
Name = "TestConsumer";
ScriptingEngine = "VBScript";
ScriptText =
"Set objFSO = CreateObject(\"Scripting.FileSystemObject\")\n"
"Set objFile = objFSO.OpenTextFile(\"c:\\test\\Log.txt\", 8, True)\n"
"objFile.WriteLine Time & \" \" & \" File Created\"\n"
"objFile.Close\n";
// Specify any other relevant properties.
};
instance of __FilterToConsumerBinding
{
Filter = $EventFilter;
Consumer = $Consumer;
};
But whenever I run the command mfcomp myfile.mof I am getting this error:
Parsing MOF file: myfile.mof
MOF file has been successfully parsed
Storing data in the repository...
An error occurred while processing item 1 defined on lines 11 - 19 in file myfile.mof:
Error Number: 0x80041058, Facility: WMI
Description: Unparsable query.
Compiler returned error 0x80041058
This error appears to be caused by incorrect syntax in the query, but I don't understand where I have gone wrong with this - is anyone able to advise?
There are no string concatenation or line continuation characters being used in building "Query". To keep it simple, you could put the entire query on one line.

Pgocaml customizing sql queries

I am trying to write a query that simply drops a table.
let drop_table dbh table_name =
let query = String.concat " " ["drop table"; table_name] in
PGSQL(dbh) query
I am receiving the following error from the query
File "save.ml", line 37, characters 10-11:
Parse error: STRING _ expected after ")" (in [expr])
File "save.ml", line 1:
Error: Preprocessor error
Why am I getting this error? It appears that this function is valid Ocaml syntax.
Thanks guys!
You cannot construct query when using PG'OCaml's syntax extension. You must provide a literal string. This is the tradeoff for getting PG'Ocaml's compile time query validation. If query could be any OCaml expression, PG'OCaml wouldn't know how to validate it at compile time.
Personally, I've stopped using the syntax extension completely. My feeling is it doesn't scale to large projects. Instead I call prepare and execute directly. For example, this function will create a new database connection (assuming the connection parameters are previously defined), run the given query, and close the connection:
let exec query =
let db = PGOCaml.connect ~host ~user ~database ~port ~password ()
PGOCaml.prepare db ~query ();
let ans = PGOCaml.execute db ~params:[] () in
PGOCaml.close db;
ans
Of course, this isn't a robust implementation and shouldn't be used in production code. It doesn't handle errors and isn't asynchronous.

Null Reference Excepion when saving data on subsonic 3

I am testing subsonic 3, i can query my database but when i am inserting a record i have an exception. Here is my code:
Client lClient = new Client();
lClient.Name = "Peter";
lClient.FullName = "Richards";
lCliente.Save();
And i have a null reference exception on this generated code:
var newKey=_repo.Add(this,provider);
Any help is appreciated.
I am using ActiveRecords
I had a similar problem, with code not unlike the following:
var pending = myTable.SingleOrDefault(x => x.Id == 1);
if (pending == null)
pending = new myTable();
pending.Id = 1;
pending.MyDate = DateTime.Now;
pending.MyString = someString;
pending.Save();
This worked the first time I ran it, on an empty table, but not the second time when updating. I got a nullreference exception somewhere inside the subsonic repository. The solution was to add a primary key, as Rob suggested.
Just thought I'd mention it (thanks Rob).
Where does the null reference exception actually happen? Is _repo null?
Try and double check that you don’t have any columns in the “Client” table which are not nullable and you don’t set any value.
Also make sure you PK is handled correctly (check you have the [Property.IsForeignKey=true;] attribute)
Do you have NullReferenceException Checked in (file menu) Debug -> Exceptions (press Find and type NullReferenceException, press OK)?
I downloaded the SubSonic code and used it as reference for my project, the exception is thrown in SubSonic.Core\Repository\SubSonicRepository.cs:209 because prop is not checked for null at line 208, and any exceptions are swallowed as evidenced by line 213.
What happens is visual studio breaks on all the exceptions checked in the mentioned dialog. So in one way, this is the expected behaviour from the code.
What actually causes prop to become null, in my case, the table field name is lower-case, but the property is actually cased properly.
From Immediate:
tbl.PrimaryKey.Name
"playerinformationid"
item.GetType().GetProperties()
{System.Reflection.PropertyInfo[11]}
[0]: {System.Collections.Generic.IList`1[SubSonic.Schema.IColumn] Columns}
// *snip*
[5]: {Int32 PlayerInformationid}
// *snip*
item.GetType().GetProperty("PlayerInformationid")
{Int32 PlayerInformationid} // Works!
item.GetType().GetProperty(tbl.PrimaryKey.Name)
null
I hacked this together to "just make it work" (Warning: newbie at 3.5 stuff)
-var prop = item.GetType().GetProperty(tbl.PrimaryKey.Name);
+var lowerCasedPrimaryKeyName = tbl.PrimaryKey.Name.ToLowerInvariant();
+var prop = item.GetType().GetProperties().First<System.Reflection.PropertyInfo>(x => x.Name.ToLowerInvariant() == lowerCasedPrimaryKeyName);
Does your table have a PrimaryKey? It doesn't sound like it does. If not - this is your problem.