NSIS read value from listbox and write it to registry - listbox

I’ve been struggling for a while with NSIS, I need a listbox filled with 300 values like
Value Label
Then take selected value and write it to registry. So far I was able to create the listbox but hadn’t luck getting selected value. Any idea or example. Thanks

!include nsDialogs.nsh
Var ListboxValue
Function .onInit
StrCpy $ListboxValue "xyz" ; Default value used in silent installers
FunctionEnd
Page Custom MyPageCreate MyPageLeave
Page InstFiles
!define LISTITEMSEP ": "
Function MyPageCreate
nsDialogs::Create 1018
Pop $0
${NSD_CreateListBox} 0 0 100% 50% ""
Pop $1
${NSD_LB_AppendString} $1 "Foo${LISTITEMSEP}Bar"
${NSD_LB_AppendString} $1 "Hello${LISTITEMSEP}World"
${NSD_LB_SetSelectionIndex} $1 0 ; Select the first item by default
nsDialogs::Show
FunctionEnd
Function MyPageLeave
${NSD_LB_GetSelection} $1 $2
; Extract the part after the separator
StrLen $3 "${LISTITEMSEP}"
StrCpy $4 0
loop:
StrCpy $5 $2 $3 $4
${If} $5 != "${LISTITEMSEP}"
IntOp $4 $4 + 1
StrCmp $5 "" 0 loop
${EndIf}
IntOp $4 $4 + $3
StrCpy $ListboxValue $2 "" $4
${If} $ListboxValue == ""
MessageBox MB_ICONSTOP "Please select something!"
Abort
${EndIf}
FunctionEnd
Section
MessageBox MB_OK "Write $ListboxValue to the registry here"
SectionEnd
You can also use ${NSD_LB_SetItemData} and ${NSD_LB_GetItemData} if you need to assign a numeric value to each item.

Related

Mode.scope.first instead of Model.scope[0] - why we have so different execution time?

I have two simular codes:
1 code:
User.chats.first // execution time 17 SEC!
2 code
User.chats[0] // execution time is 2 ms
SQL log - 1 code:
**(17018.8ms)** SELECT "chats".* FROM "chats" WHERE "chats"."user_id" = $1 AND
("chats"."blocked" = 'f' OR "chats"."blocked" IS NULL) ORDER BY "chats"."id" ASC LIMIT $2
SQL log - 2 code:
**(2.2ms)** SELECT "chats".* FROM "chats" WHERE "chats"."user_id" = $1 AND
("chats"."blocked" = 'f' OR "chats"."blocked" IS NULL) ORDER BY "chats"."id" ASC
What is diffirent beetwen first method and [0]?
Why execution speed so different 17 sec and 2 ms?

where.not with where in rails/activerecord excluding all records?

I have a model (pairings) that has a length and date attribute (among others). I am trying to query all pairings that do NOT touch a specific date or date range while matching other properties of the pairing. The code for all other queries working fine, but my where.not is excluding all records. This is because (I think) of the way I am building the relation/query.
I need something that excludes selected date range AND matches the length. This needs to be stacked on other scoped queries.
Any ideas on how to accomplish this?
Thanks in advance!
Controller code:
rel = rel.other scoped queries
#all_trip_len.each do |len|
rel = rel.date_selector(#date_sel_1, #date_start_1, #date_end_1, len)
end
rel = rel.more scoped queries
Model Scope:
def self.date_selector(sel, start_d, end_d, length)
# Need to get all possible start dates that could touch avoid days for each length of trip
rel = self
start = Date.parse(start_d) - (length.to_i - 1)
rel = rel.where.not(date: start.to_s..Date.parse(end_d).to_s).where(length: length)
return rel
end
I am getting a query that is:
SELECT "pairings".*
FROM "pairings"
WHERE "pairings"."bid_month_id" = $1
AND NOT ("pairings"."date" BETWEEN $2 AND $3)
AND "pairings"."length" = $4
AND NOT ("pairings"."date" BETWEEN $5 AND $6)
AND "pairings"."length" = $7 [["bid_month_id", 8], ["date", "2020-04-08"], ["date", "2020-04-08"], ["length", 1], ["date", "2020-04-07"], ["date", "2020-04-08"], ["length", 2]
And I need something more like:
SELECT "pairings".*
FROM "pairings"
WHERE "pairings"."bid_month_id" = $1
AND NOT (("pairings"."date" BETWEEN $2 AND $3)
AND "pairings"."length" = $4)
AND NOT (("pairings"."date" BETWEEN $5 AND $6)
AND "pairings"."length" = $7) [["bid_month_id", 8], ["date", "2020-04-08"], ["date", "2020-04-08"], ["length", 1], ["date", "2020-04-07"], ["date", "2020-04-08"], ["length", 2]
Edit:
With the help of MurifoX I got a little farther. The query is built almost correctly but I need OR in between the pairing.date grouping.
What I have now:
SELECT "pairings".*
FROM "pairings"
WHERE "pairings"."bid_month_id" = $3
AND (((date <= '2020-04-06' AND date >= '2020-04-07') AND length = 1))
AND (((date <= '2020-04-05' AND date >= '2020-04-07') AND length = 2))
What I need:
SELECT "pairings".*
FROM "pairings"
WHERE "pairings"."bid_month_id" = $3
AND (((date <= '2020-04-06' AND date >= '2020-04-07') AND length = 1)
OR ((date <= '2020-04-05' AND date >= '2020-04-07') AND length = 2))
I have tried using the rails 5 or (rel.or(Pairing.date_selector(xxx)) but that does not work because it turns all the where AND into OR and I just need the OR between the pairing/date groupings. Also need the parens around the date groupings.
The construction of semi-complex queries with ActiveRecord methods can be tricky sometimes, so in this particular cases i always tell people to do it by hand:
rel = self
start = Date.parse(start_d) - (length.to_i - 1)
rel = rel.where("((date <= ? AND date >= ?) AND length = ?)", start.to_s, Date.parse(end_d).to_s, length)
return rel
I ended up having to build this as a string to get it to do exactly what I want. the or relation in rails 5 created a statement that OR'd ALL of my previous scope clauses with the new one (all AND -> OR) and I needed all my previous scoped queries to stand and just the new dates to be OR'd.
def exclude_dates(rel, date_start_1, date_end_1, all_trip_len)
dates_query = String.new
count = 0
all_trip_len.each do |len|
start_d = Date.parse(date_start_1) - (len.to_i - 1)
end_d = Date.parse(date_end_1)
count += 1
dates_query += " OR " if count > 1
dates_query += "((date < '#{start_d.to_s}' OR date > '#{end_d.to_s}') AND length = '#{len}')"
end
rel = rel.where(dates_query)
end
This created the query I needed. Wish there was a more 'rails' way to do it...
SELECT COUNT(*) FROM "pairings" WHERE "pairings"."bid_month_id" = $1 AND (((date < '2020-04-02' OR date > '2020-04-02') AND length = '1') OR ((date < '2020-04-01' OR date > '2020-04-02') AND length = '2') OR ((date < '2020-03-31' OR date > '2020-04-02') AND length = '3') OR ((date < '2020-03-30' OR date > '2020-04-02') AND length = '4')) AND (((date < '2020-04-14' OR date > '2020-04-17') AND length = '1') OR ((date < '2020-04-13' OR date > '2020-04-17') AND length = '2') OR ((date < '2020-04-12' OR date > '2020-04-17') AND length = '3') OR ((date < '2020-04-11' OR date > '2020-04-17') AND length = '4')) [["bid_month_id", 8]]
Thanks to #MurifoX for getting me going in the right direction with the dates stuff!

How to use ReadFile from kernel32 with NSIS

I'm trying to open a file and read the content inside a buffer using NSIS Installer.
Unfortunatly, everything works except KERNEL32::ReadFile. I read that a lot of people have some problem with this API, and i can't find a solution.
Here is my code :
StrCpy $2 $2\TOS.TXT
System::Call 'Kernel32::CreateFile(t, i, i, i, i, i, i) i (r2, 0x80000000, 0, 0, 4, 0x80, 0) .r3'
System::Call 'kernel32::GetFileSize(pr3, p0)i.r7' ; Call API to read 32-bit file size
System::Call "kernel32::VirtualAlloc(i0, ir7, i0x3000, i0x40) .r1"
System::Call "KERNEL32::ReadFile(pr3,pr1,ir7,*i,p0)i.r3"
The file is well opened and the buffer is well created with the correct size.
Any help is appreciated,
Thank,
Chris.
Your VirtualAlloc call is missing the output type before .r1.
There is no need to use the System plug-in just to read from a simple file.
!macro MakeTestFile
FileOpen $0 "$temp\nsis_test.txt" w
FileWrite $0 "Hello$\nWorld!"
FileClose $0
!macroend
StrCpy $9 "$temp\nsis_test.txt"
!insertmacro MakeTestFile
FileOpen $0 "$9" r
FileRead $0 $1 ; Line 1
FileRead $0 $2 ; Line 2
FileClose $0
MessageBox MB_OK $1$2
!insertmacro MakeTestFile
FileOpen $0 "$9" r
FileSeek $0 1 SET
FileReadByte $0 $1
FileClose $0
IntFmt $1 "0x%.2X" $1
MessageBox MB_OK "Byte #2 is $1"
!insertmacro MakeTestFile
System::Call 'KERNEL32::CreateFile(t, i, i, p, i, i, p) p (r9, 0x80000000, 0, 0, 4, 0x80, 0) .r3'
System::Call 'KERNEL32::GetFileSize(pr3, p0)i.r7'
System::Call "KERNEL32::VirtualAlloc(p0, pr7, i0x3000, i0x40)p.r1"
System::Call "KERNEL32::ReadFile(pr3,pr1,ir7,*i,p0)i.r3"
System::Call "USER32::MessageBoxA(p$hwndparent,pr1,t 'System::Call',i0)"
System::Call "KERNEL32::VirtualFree(pr1,p0,i0x8000)"
The System plug-in also has System::Alloc/StrAlloc/Free so there is no need to call VirtualAlloc directly if you need memory.

Weird behavior of CAST with 0 in rails

Sorry for long query but its what im working with.
I got this query in rails
#posts = Cama::PostType.first.posts.joins(:custom_field_values).where("(status = ?) AND (cama_custom_fields_relationships.custom_field_slug = ? AND
CAST(cama_custom_fields_relationships.value AS INTEGER) >= ? AND
CAST(cama_custom_fields_relationships.value AS INTEGER) <= ? ) OR
(cama_custom_fields_relationships.custom_field_slug = ? AND
CAST(cama_custom_fields_relationships.value AS INTEGER) >= ? AND
CAST(cama_custom_fields_relationships.value AS INTEGER) <= ? ) AND
(LOWER(title) LIKE ? OR LOWER(content_filtered) LIKE ?)","published", "filtry-
powierzchnia", params['size-start'].to_i, params['size-end'].to_i,"filtry-
cena", params['price-start'].to_i, params['price-end'].to_i
,"%#{params[:q]}%",
"%#{params[:q]}%").group("cama_posts.id").having("COUNT(cama_custom_fields_rel
ationships.objectid) >= 2")
that make this sql
CamaleonCms::Post Load (0.9ms) SELECT "cama_posts".* FROM "cama_posts"
INNER JOIN "cama_custom_fields_relationships" ON
"cama_custom_fields_relationships"."objectid" = "cama_posts"."id" AND
"cama_custom_fields_relationships"."object_class" = $1 WHERE
"cama_posts"."post_class" = $2 AND "cama_posts"."taxonomy_id" = $3 AND
((status = 'published') AND
(cama_custom_fields_relationships.custom_field_slug = 'filtry-powierzchnia'
AND CAST(cama_custom_fields_relationships.value AS INTEGER) >= 1 AND
CAST(cama_custom_fields_relationships.value AS INTEGER) <= 10000 ) OR
(cama_custom_fields_relationships.custom_field_slug = 'filtry-cena' AND
CAST(cama_custom_fields_relationships.value AS INTEGER) >= 0 AND
CAST(cama_custom_fields_relationships.value AS INTEGER) <= 10000000 ) AND
(LOWER(title) LIKE '%%' OR LOWER(content_filtered) LIKE '%%')) GROUP BY
cama_posts.id HAVING (COUNT(cama_custom_fields_relationships.objectid) >= 2)
ORDER BY "cama_posts"."post_order" ASC, "cama_posts"."created_at" DESC LIMIT
$4 OFFSET $5 [["object_class", "Post"], ["post_class", "Post"],
["taxonomy_id", 2], ["LIMIT", 6], ["OFFSET", 0]]
As you can see Im using CAST, I can't change column just to integer, because its CMS. I created custom_field that suppoust to be integer but table in db is still text so im forced to do it that way.
Now everything is ok if my
..CAST(cama_custom_fields_relationships.value AS INTEGER) >= 1..
but when this value will be 0
so when my query will look like
CamaleonCms::Post Load (0.9ms) SELECT "cama_posts".* FROM "cama_posts"
INNER JOIN "cama_custom_fields_relationships" ON
"cama_custom_fields_relationships"."objectid" = "cama_posts"."id" AND
"cama_custom_fields_relationships"."object_class" = $1 WHERE
"cama_posts"."post_class" = $2 AND "cama_posts"."taxonomy_id" = $3 AND
((status = 'published') AND
(cama_custom_fields_relationships.custom_field_slug = 'filtry-powierzchnia'
AND ****CAST(cama_custom_fields_relationships.value AS INTEGER) >= 0**** AND
CAST(cama_custom_fields_relationships.value AS INTEGER) <= 10000 ) OR
(cama_custom_fields_relationships.custom_field_slug = 'filtry-cena' AND
CAST(cama_custom_fields_relationships.value AS INTEGER) >= 0 AND
CAST(cama_custom_fields_relationships.value AS INTEGER) <= 10000000 ) AND
(LOWER(title) LIKE '%%' OR LOWER(content_filtered) LIKE '%%')) GROUP BY
cama_posts.id HAVING (COUNT(cama_custom_fields_relationships.objectid) >= 2)
ORDER BY "cama_posts"."post_order" ASC, "cama_posts"."created_at" DESC LIMIT
$4 OFFSET $5 [["object_class", "Post"], ["post_class", "Post"],
["taxonomy_id", 2], ["LIMIT", 6], ["OFFSET", 0]]
Im getting error:
ActionView::Template::Error (PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: "/media/1/asd.jpg"
: SELECT "cama_posts".* FROM "cama_posts" INNER JOIN "cama_custom_fields_relationships" ON "cama_custom_fields_relationships"."objectid" = "cama_posts"."id" AND "cama_custom_fields_relationships"."object_class" = $1 WHERE "cama_posts"."post_class" = $2 AND "cama_posts"."taxonomy_id" = $3 AND ((status = 'published') AND (cama_custom_fields_relationships.custom_field_slug = 'filtry-powierzchnia' AND CAST(cama_custom_fields_relationships.value AS INTEGER) >= 0 AND CAST(cama_custom_fields_relationships.value AS INTEGER) <= 10000 ) OR (cama_custom_fields_relationships.custom_field_slug = 'filtry-cena' AND CAST(cama_custom_fields_relationships.value AS INTEGER) >= 0 AND CAST(cama_custom_fields_relationships.value AS INTEGER) <= 10000000 ) AND (LOWER(title) LIKE '%%' OR LOWER(content_filtered) LIKE '%%')) GROUP BY cama_posts.id HAVING (COUNT(cama_custom_fields_relationships.objectid) >= 2) ORDER BY "cama_posts"."post_order" ASC, "cama_posts"."created_at" DESC LIMIT $4 OFFSET $5):
and #posts return it on the query lvl so its not error that occurs somewhere else.
I tried CASTing to numeric, same problem. It only happens when its starting condition, when there is another condition before it, it accepts 0 like in my example, the second condition after this one works with >= 0

Ruby ActiveRecord group and average "syntax error at or near "AS""

params = {device_id: "u100", device_point: "1", point_no: "1", max_date: "2016-12-01 12:00", min_date: "2016-12-01 11:40"}
I am working in a ruby/rails environment with a PG database.
I am trying to add to my device controller to use ActiveRecord to get 10 minute averages from a some dummy sensor data.
I can group by minute fine with;
.group("date_trunc('minute', device_time)").average('point_data_val')
e.g
device_data = DeviceDatum.select('device_time, point_data_val').filter(params.slice(:device_id, :device_point, :point_no, :iot_version, :iot_time, :device_time, :point_data_type, :point_data_val, :point_bat_val,:min_val, :max_val, :min_date, :max_date)).limit(1008).group("date_trunc('minute', device_time)").average('point_data_val')
(240.3ms) SELECT AVG("device_data"."point_data_val") AS average_point_data_val, date_trunc('minute', device_time) AS date_trunc_minute_device_time FROM "device_data" WHERE "device_data"."device_id" = $1 AND "device_data"."device_point" = $2 AND "device_data"."point_no" = $3 AND (device_time >= '2016-12-01 11:40') AND (device_time <= '2016-12-01 12:00') GROUP BY date_trunc('minute', device_time) LIMIT 1008 [["device_id", "u100"], ["device_point", 1], ["point_no", 1]]
=> {2016-12-01 11:41:00 +0900=>#<BigDecimal:7f91599cfbc0,'-0.4816E1',18(27)>, 2016-12-01 11:51:00 +0900=>#<BigDecimal:7f91599cf8f0,'-0.4868E1',18(27)>}
I found this method to do it
But when I try and use AS in the group method
DeviceDatum.select('device_time, point_data_val')
.filter(params.slice(:device_id, :device_point, :point_no, :iot_version, :iot_time, :device_time,
:point_data_type, :point_data_val, :point_bat_val,:min_val, :max_val, :min_date,
:max_date)).limit(1008)
.group("date_trunc('hour', device_time) AS hour_stump,
(extract(minute FROM device_time)::int / 10)
AS min10_slot,count(*)").average('point_data_val')
I am getting this error.
ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: syntax error at or near "AS"
LINE 1: ... 12:00') GROUP BY date_trunc('hour', device_time) AS hour_st... : SELECT AVG("device_data"."point_data_val") AS average_point_data_val, date_trunc('hour', device_time) AS hour_stump,(extract(minute FROM device_time)::int / 10) AS min10_slot,count(*) AS date_trunc_hour_device_time_as_hour_stump_extract_minute_from_d FROM "device_data" WHERE "device_data"."device_id" = $1 AND "device_data"."device_point" = $2 AND "device_data"."point_no" = $3 AND (device_time >= '2016-12-01 11:40') AND (device_time <= '2016-12-01 12:00') GROUP BY date_trunc('hour', device_time) AS hour_stump,(extract(minute FROM device_time)::int / 10) AS min10_slot,count(*) LIMIT 1008
from ...../bundle/ruby/2.1.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/postgresql_adapter.rb:637:in `prepare'
ActiveRecord seems to be using the options from the group method in sql it generates for average as well.
SELECT
AVG("device_data"."point_data_val") AS average_point_data_val,
date_trunc('hour', device_time) AS hour_stump,
(
extract(minute
FROM
device_time)::int / 10
)
AS min10_slot,
count(*) AS date_trunc_hour_device_time_as_hour_stump_extract_minute_from_d
FROM
"device_data"
WHERE
"device_data"."device_id" = $1
AND "device_data"."device_point" = $2
AND "device_data"."point_no" = $3
AND
(
device_time >= '2016-12-01 11:40'
)
AND
(
device_time <= '2016-12-01 12:00'
)
GROUP BY
date_trunc('hour', device_time) AS hour_stump,
(
extract(minute
FROM
device_time)::int / 10
)
AS min10_slot,
count(*) LIMIT 1008
What am I missing here?
I think that your group clause should look like this:
group("hour_stump, min10_slot,
date_trunc_hour_device_time_as_hour_stump_extract_minute_from_d")
if you use aliases in select clause. As #Fallenhero and #Iceman said, aliases in group by are not allowed.
If aliases are substituted in select automatically, I think the only way is to use functions as is
group("date_trunc('hour', device_time),
(extract(minute FROM device_time)::int / 10), count(*)")
.

Resources