We have an automated vending machine (avm with a plain c program) that work on data serialized in some binary files : currently for example the avm need a file for the products (products.bin), one file for listing products that could be not be sell together (no_cohabitation.bin).
Often the file no_cohabitation.bin lists (hardcode) various products according to a specific criterion (but this can vary): for example, if the vending machine is used to dispense medication and we can not sell all products for the heart and those causing the tachycardia => we must indicate for each product the listing or a pointer to a list of all those that cause tachycardia and we need to update this list each time a new dangerous product is added...
Here a fictionnal sample of how the files are working :
products.bin :
Id (Int) => 1
Language char (60) => Avlocardyl (for the heart)
Properties (a key value pair loop)
"Good_ForHeart" TRUE
Id (Int) => 2
Language char (60) => SICATOL-1 (can cause the tachycardia)
Properties (a key value pair loop)
"Good_ForHeart" : FALSE
"DANGEROUS_ForHeart": TRUE
...
Id (Int) => 846
Language char (60) => SICATOL-846 (may cause the tachycardia)
Properties (a key value pair loop)
"Good_ForHeart" : FALSE
"DANGEROUS_ForHeart": TRUE
no_cohabitation.bin:
ProductId (Int) => 1
Incompatibilities length (Int) => 845 ( a loop of all products incompatible with the product 1)
IncomaptibleProductId (Int) => 2
...
IncomaptibleProductId (Int) => 846
I am looking for a way to serialize a query (or query filter expression) in my file no_cohabitation.bin to indicate how to find the products incompatible with the one with Id=1...
Is there any way to do that ? I have heard of linq expression tree in c#, may be there is a similar api for plain c?
Related
I am trying to implement a multiple values filter to my database using flutter's moor package.
moor already has where method that takes an expression and converts it into sql statement. like:
(select(exercisesTable)..where((e) => (e.name.equals(name)))).get();
But I need to filter data due to more one value.
After I searched in the documentation I have found two possible solutions:
Use CutomExpressionClass link:
Expression expression = CustomExpression<bool, BoolType>(" water BETWEEN 4.0 AND 5.0 AND protein BETWEEN 4.0 AND 15.0 AND description LIKE CHESS%");
But I get this error : *
SqliteException: near ";": syntax error, SQL logic error
*
Use Custom select statements link:
I have not tried this because, I believe the problem is in sql itself not moor package.
From the comments of the SingleTableQueryMixin::where method (link):
...
/// If a where condition has already been set before, the resulting filter
/// will be the conjunction of both calls.
...
According to this you can use something like that:
Future<List<TableData>> getTableList({int position, int type}) {
final _select = select(table);
if (position != null) {
_select..where((tbl) => tbl.position.equals(position));
}
if (type != null) {
_select..where((tbl) => tbl.type.equals(type));
}
return _select.get();
}
You can use the boolean algebra feature to have multiple where conditions.
// find all animals that aren't mammals and have 4 legs
select(animals)..where((a) => a.isMammal.not() & a.amountOfLegs.equals(4));
// find all animals that are mammals or have 2 legs
select(animals)..where((a) => a.isMammal | a.amountOfLegs.equals(2));
Let's say we have a FoodTable with the following columns: Name, Calories, Carbs, Protein. I have an entry for Name = Chocolate, Calories = 100, Carbs = "10g", and Protein = "2g".
I'm wondering if there's a way to pass in a column name and a new value to update with. For example, I want a method that's like
def updateFood(food, columnName, value):
table.filter(_.name === food).map(x => x.columnName).update(value)
It seems like dynamic columns are not possible with Slick? I want to avoid writing a SQL query because that could lead to security flaws or bugs in the code. Is there really no way to do this?
I also don't want to have to pass in the entire object to update, since ideally, it should be:
I want to update column X to value Y. I should only need to pass in the id of the object, the column, and the value to update to.
I'm wondering if there's a way to pass in a column name and a new value to update with
This depends a little bit on what you want the "column name" to be. To maintain safety, what I'd suggest is having the "column name" be a function that can select a column in your table.
At a high level that would look like this:
// Won't compile, but we'll fix that in a moment
def updateFood[V](food: Food, column: FoodTable => Rep[V], value: V): DBIO[Int] =
foods.filter(_.name === food.name).map(column).update(value)
...which we'd call like this:
updateFood(choc, _.calories, 99)
Notice how the "column name" is a function from FoodTable to a column of some value V. Then you provide a value for the V and we do a normal update.
The problem is that Slick knows how to map certain types of values (String, Int, etc) into SQL, but not any kind of value. And the code above won't compile because V is unconstrained.
We can sort of fix that my adding a constraint on V, and it mostly will work:
// Will compile, will work for basic types
def updateFood[V : slick.ast.BaseTypedType](food: Food, column: FoodTable => Rep[V], value: V): DBIO[Int] =
foods.filter(_.name === food.name).map(column).update(value)
However, if you have custom column mappings, they won't match the constraint. We need to go another step on and have an implicit shape in scope:
def updateFood[V](food: Food, column: FoodTable => Rep[V], value: V)(implicit shape: Shape[_ <: FlatShapeLevel, Rep[V], V, _]): DBIO[Int] =
foods.filter(_.name === food.name).map(column).update(value)
I think of Shape as an extra level of abstraction in Slick, above Rep[V]. The mechanisms of the "shape levels" and other details are not something I can explain because I don't understand them yet! (There is a talk that goes into the design of Slick called "Polymorphic Record Types in a Lifted Embedding" which you can find at http://slick.lightbend.com/docs/)
A final note: if you really want the column name to be a String or something like that, I'd suggest pattern matching the string (or validate in some way) to a FoodTable => Rep function and use that in your SQL. That's going to be tricky because your value V is going to have to match the type of the column you want to update.
Off the top of my head, that could look something like this:
def tryUpdateFood(food: Food, columnName: String, value: String): DBIO[Int] =
columnName match {
case "calories" => updateFood(food, _.calories, value.toInt)
case "carbs" => updateFood(food, _.carbs, value)
// etc...
case unknown => DBIO.failed(new Exception(s"Don't know how to update $unknown columns"))
}
I can imagine better error handling, safer or smarter parsing of the value, but in outline the above could work.
For hints at other ways to approach dynamic problems, take a look at the talk "Patterns for Slick database applications" (also listed at: http://slick.lightbend.com/docs/), and towards the end of the presentation there's a section on "Dynamic sorting".
I'm performing a semantic similarity using a tool here,
I'm getting the following results, but cannot properly interprete them:
apple#n#1,banana#n#1 0.04809463683080774
apple#n#1,banana#n#2 0.13293629283742603
apple#n#2,banana#n#1 0.0
apple#n#2,banana#n#2 0.0
here is the code:
URL url = new URL ( "file" , null , "dictionary/3.0/dict" );
IDictionary dict = new Dictionary ( url ) ;
dict.open () ;
// look up first sense of the word " dog "
IIndexWord idxWord = dict . getIndexWord ( "dog" , POS.NOUN ) ;
IWordID wordID = idxWord . getWordIDs () . get (0) ; // 1 st meaning
List <IWordID> wordIDs = idxWord.getWordIDs();
JWS ws= new JWS ("dictionary", "3.0");
TreeMap <String,Double> scores1 = ws.getJiangAndConrath().jcn("apple", "banana", "n");
for (String s:scores1.keySet())
System.out.println(s+"\t"+scores1.get(s));
From the NLTK Documentation:
The Jiang Conrath similarity returns a score denoting how similar two
word senses are, based on the Information Content (IC) of the Least
Common Subsumer (most specific ancestor node) and that of the two
input Synsets. The relationship is given by the equation 1 / (IC(s1) +
IC(s2) - 2 * IC(lcs)).
A result of 0 means that the two concepts are not related at all.
A result near 1 would mean a very close relationship.
can you put me code source written in JAVA responsible for the execution of LeacockAndChodorow algorithm because I do have some problems with Url variable?
I need to get maximum page order from database:
int maxOrder = GetSession.Query<Page>().Max(x => x.PageOrder);
The above works if there are rows in the database table, but when table is empty I'm getting:
Value cannot be null.
Parameter name: item
In the way you are doing it is normal to get an exception as the enumerable, that the GetSession.Query<Page>() returns, is empty (because the table is empty as you mentioned).
The exception that you should be getting is: Sequence contains no elements.
The exception you mention in your question is because the item variable (which is irrelevant with the NHiberanate query you list above) is null (line 54 assigns the item property to null).
A safer way to get the max from a property in a table would be the following:
var max = GetSession.CreateCriteria<Page>()
.SetProjection(Projections.Max("PageOrder"))
.UniqueResult();
or using QueryOver with NHibenrate 3.0:
var max = GetSession.QueryOver<Page>()
.Select(
Projections
.ProjectionList()
.Add(Projections.Max<Page>(x => x.PageOrder)))
.List<int>().First();
If the table is empty you will get max = 0
Session.Query<Page>().Max(x => (int?)x.PageOrder)
Note the cast (I'm assuming PageOrder is an int)
If you are having problems with the QueryOver example by tolism7 (InvalidCastException), here's how I got it working:
var max = session.QueryOver<Page>()
.Select(Projections.Max<Page>(x => x.PageOrder))
.SingleOrDefault<object>();
return max == null ? 0 : Convert.ToInt32(max);
So the main program is in C#. Inserting new records into a VFP database table. It was taking too long to generate the next ID for the record via
select max(id)+1 from table
, so I put that code into a compile dll in VFP and am calling that COM object through C#.
The COM object returns the new ID in about 250ms. I then just do an update through OLEDB. The problem I am having is that after the COM object returns the newly inserted ID, I cannot immediately find it from C# via the OLEDB
select id form table where id = *newlyReturnedID*
returns 0 rows back. If I wait an unknown time period the query will return 1 row. I can only assume it returns 0 rows immediately because it has yet to add the newly minted ID into the index and therefore the select cannot find it.
Has anyone else ever run into something similar? If so, how did you handle it?
DD
Warning: your code is flawed in a multi-user environment. Two people could run the query at the same time and get the same ID. One of them will fail on the INSERT if the column has a primary or candidate key, which is a best practice for key fields.
My recommendation is to either have the ID be a auto-incrementing integer field (I'm not a fan of them), or even better, create a table of keys. Each record in the table is for a table that gets keys assigned. I use the a structure similar to this:
Structure for: countergenerator.dbf
Database Name: conferencereg.dbc
Long table name: countergenerator
Number of records: 0
Last updated: 11/08/2008
Memo file block size: 64
Code Page: 1252
Table Type: Visual FoxPro Table
Field Name Type Size Nulls Next Step Default
----------------------------------------------------------------------------------------------------------------
1 ccountergenerator_pk Character 36 N guid(36)
2 ckey Character (Binary) 50 Y
3 ivalue Integer 4 Y
4 mnote Memo 4 Y "Automatically created"
5 cuserid Character 30 Y
6 tupdated DateTime 8 Y DATETIME()
Index Tags:
1. Tag Name: PRIMARY
- Type: primary
- Key Expression: ccountergenerator_pk
- Filter: (nothing)
- Order: ascending
- Collate Sequence: machine
2. Tag Name: CKEY
- Type: regular
- Key Expression: lower(ckey)
- Filter: (nothing)
- Order: ascending
- Collate Sequence: machine
Now the code for the stored procedure in the DBC (or in another program) is this:
FUNCTION NextCounter(tcAlias)
LOCAL lcAlias, ;
lnNextValue, ;
lnOldReprocess, ;
lnOldArea
lnOldArea = SELECT()
IF PARAMETERS() < 1
lcAlias = ALIAS()
IF CURSORGETPROP("SOURCETYPE") = DB_SRCLOCALVIEW
*-- Attempt to get base table
lcAlias = LOWER(CURSORGETPROP("TABLES"))
lcAlias = SUBSTR(lcAlias, AT("!", lcAlias) + 1)
ENDIF
ELSE
lcAlias = LOWER(tcAlias)
ENDIF
lnOrderNumber = 0
lnOldReprocess = SET('REPROCESS')
*-- Lock until user presses Esc
SET REPROCESS TO AUTOMATIC
IF !USED("countergenerator")
USE EventManagement!countergenerator IN 0 SHARED ALIAS countergenerator
ENDIF
SELECT countergenerator
IF SEEK(LOWER(lcAlias), "countergenerator", "ckey")
IF RLOCK()
lnNextValue = countergenerator.iValue
REPLACE countergenerator.iValue WITH countergenerator.iValue + 1
UNLOCK
ENDIF
ELSE
* Create the new record with the starting value.
APPEND BLANK IN countergenerator
SCATTER MEMVAR MEMO
m.cKey = LOWER(lcAlias)
m.iValue = 1
m.mNote = "Automatically created by stored procedure."
m.tUpdated = DATETIME()
GATHER MEMVAR MEMO
IF RLOCK()
lnNextValue = countergenerator.iValue
REPLACE countergenerator.iValue WITH countergenerator.iValue + 1
UNLOCK
ENDIF
ENDIF
SELECT (lnOldArea)
SET REPROCESS TO lnOldReprocess
RETURN lnNextValue
ENDFUNC
The RLOCK() ensures there is no contention for the records and is fast enough to not have bottleneck the process. This is way safer than the approach you are currently taking.
Rick Schummer
VFP MVP
VFP needs to FLUSH its workareas.