Can you manage transaction commit/rollback manually? - mysql

I'd like to do something like this:
["START", "a", "b", "c", "STOP", "START", "d", "e", "STOP"].each do |message|
if message == "START"
Transaction.begin
elsif message == "STOP"
Transaction.commit if Transaction.active?
else
begin
Message.create!(body: message)
rescue
Transaction.rollback
end
end
end
In short, I have a stream of 'messages' and I'd like to transactionalise parts of that stream.
Whenever a "START" appears on the stream, a new transaction is begun. Whenever a "STOP" appears, the transaction is committed.
I'm struggling with the transactions.
I can see that I can do ActiveRecord::Base.transaction do ... end, but that won't work in this case unless I batch everything up, which isn't possible here because of the streams.
I saw that there's a transaction manager buried in ActiveRecord that I could potentially use (https://github.com/rails/rails/blob/0d76ab9c6f01e6390ba8878a296ff9d3ac6b9aa8/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb) but I haven't been able to get my tests passing against it.
I think part of the problem is also RSpec's transactional fixtures interfering, although disabling these didn't seem to solve the problem either.
Any help would be appreciated.
Thanks

you can manage transaction the following way
manager = ActiveRecord::Base.connection.transaction_manager
...
manager.begin_transaction
...
manager.commit_transaction
...
manager.rollback_transaction
or in your case
manager = ActiveRecord::Base.connection.transaction_manager
["START", "a", "b", "c", "STOP", "START", "d", "e", "STOP"].each do |message|
if message == "START"
manager.begin_transaction
elsif message == "STOP"
manager.commit_transaction
else
begin
Message.create!(body: message)
rescue
manager.rollback_transaction
end
end
end

I'd do this:
messages.chunk {|value| value != 'START' && value != 'STOP'}.each do |is_data, bodies|
if is_data
Message.transaction do
bodies.each {|body| Message.create(body: body)}
end
end
end
The first step is to use chunk to group the messages. The output of this is an array of pairs. If the first value of the pair is true, then the second value is the array of bodies, if not the bodies are just true false. With the data thus reorganised it is then trivial to use the existing transaction method.

Related

Python/JSON : I want to go to a specific thing when it can't find it in a json file

I'm actually making my discord bot and I wanted to make a command to know plane informations. I made it but know i want to put plane photos depending on the company.
I tried to do that:
if plane_data["data"][f"{flight_companie}"] == "FedEx" or "Ryanair" or "SWISS" or "Air France" or "SWISS" or "British Airways":
plane_photo = plane_data["data"][flight_companie]
else:
plane_photo = plane_data["data"]["unknown"]
Unknown is equal to a url photo that says there is no plane photos.
When i try with UPS it gives me that out:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: KeyError: 'UPS Airlines'
Please help me out!!
if plane_data["data"][f"{flight_companie}"] == "FedEx" or "Ryanair"...
will always evaluate to True. This is because a string like "Ryanair" is truthy. Meaning it becomes true when converted to a boolean. So your line is equivialent to
if plane_data["data"][f"{flight_companie}"] == "FedEx" or True or True or True ...
or can not be used in this situation. I would use
if plane_data["data"][f"{flight_companie}"] in ["FedEx","Ryanair","SWISS","Air France","SWISS","British Airways"]:
instead.

How to omit empty rows using last_row in Roo Rails

I have a spreadsheet of members designed as below:
My aim is to upload some columns and exclude others. In this case, I wish to upload only the name, age and email and exclude the others. I have been able to achieve this using the slice method as shown below:
def load_imported_members
spreadsheet = open_spreadsheet
spreadsheet.default_sheet = 'Worksheet'
header = spreadsheet.row(1)
(2..spreadsheet.last_row).map do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
member = Member.find_by_id(row["id"]) || Member.new
member.attributes = row.to_hash.slice("id", "name", "age", "email")
member
end
end
The problem is that last_row considers all the rows upto the last one (13), and since there are validations on the form, there are errors due to missing data as a result of the empty rows (which shouldn’t be considered). Is there a way I can upload only specific columns as I have done, yet limit to only the rows that have data?
You might want to chain the map call off of a reject filter like this example
You may just need to change the map line to this (assuming the missing rows all look like those above):
(2..spreadsheet.last_row).reject{|i| spreadsheet.row(i)[0] }.map do |i|
This is assuming the blank rows return as nil and that blank rows will always have all four desired fields blank as shown in the image. The reject call tests to see if spreadsheet.row(i)[0], the id column, is nil, if so the item is rejected from the list output given to map
Thanks for this question. I have learned some things from this question.
I have shortlisted your answer [note: use 'ROO' gem]
def load_imported_members(member)
spreadsheet = open_spreadsheet(member)
spreadsheet.each do |records|
record = #spreadsheet ? Hash[[#header, #spreadsheet.row(records)].transpose] : Hash[records] # transpose for xlsx records and
attributes = {id: record['id'], name: record['name'], email: record['email'], age: record['age']}
member_object = Member.new(attributes)
if member_object.valid?
if Member.find(attributes[:id])
Member.find(attributes[:id]).update(attributes)
else
member_object.save
end
end
end
end
You can parse your uploaded file using Roo gem.
def self.open_spreadsheet(member)
case File.extname(member.file.original_filename)
when ".csv" then
Roo::CSV.new(member.file.expiring_url, csv_options: {headers: true, skip_blanks: true, header_converters: ->(header) { header.strip }, converters: ->(data) { data ? data.strip : nil }})
when ".xlsx", ".xls" then
#spreadsheet = Roo::Spreadsheet.open(member.file.expiring_url)
#header = #spreadsheet.row(1)
(2..#spreadsheet.last_row)
end
end
Here I have used s3 uploaded url i.e expiring_url. Hope This will helpful. I have not tested. sorry, for small errors.
If you have used validations for name, email, and age. This will surely help u..

Jmeter Json Extractor with multiple conditional - failed

I am trying to create a Json Extractor and it`s being a thought activity. I have this json structure:
[
{
"reportType":{
"id":3,
"nomeTipoRelatorio":"etc etc etc",
"descricaoTipoRelatorio":"etc etc etc",
"esExibeSite":"S",
"esExibeEmail":"S",
"esExibeFisico":"N"
},
"account":{
"id":9999999,
"holdersName":"etc etc etc",
"accountNamber":"9999999",
"nickname":null
},
"file":{
"id":2913847,
"typeId":null,
"version":null,
"name":null,
"format":null,
"description":"description",
"typeCode":null,
"size":153196,
"mimeType":null,
"file":null,
"publicationDate":"2018-12-05",
"referenceStartDate":"2018-12-05",
"referenceEndDate":"2018-12-06",
"extension":null,
"fileStatusLog":{
"idArquivo":2913847,
"dhAlteracao":"2018-12-05",
"nmSistema":"SISTEMA X",
"idUsuario":999999,
"reportStatusIndicador":"Z"
}
}
}
]
What I need to do: First of all, I am using the option "Compute concatenation var" and "Match No." as -1. Because the service can bring in the response many of those.
I have to verify, if "reportStatusIndicador" = 'Z' or 'Y', if positive, I have to collect File.Id OR file.FileStatusLog.idArquivo, they are the same, I was trying the first option, in this case the number "2913847", but if come more results, I will collect all File.id`s
With this values in hands, I will continue with a for each for all File.id`s.
My last try, was this combination, after reading a lot and tried many others combinations.
[?(#...file.fileStatusLog.reportStatusIndicador == 'Z' || #...file.fileStatusLog.reportStatusIndicador == 'Y')].file.id
But my debug post processor always appears like this, empty:
filesIds=
Go for $..[?(#.file.fileStatusLog.reportStatusIndicador == 'Z' || #.file.fileStatusLog.reportStatusIndicador == 'Y')].file.id
Demo:
References:
Jayway JsonPath: Inline Predicates
JMeter's JSON Path Extractor Plugin - Advanced Usage Scenarios
I could do it with this pattern:
[?(#.file.fileStatusLog.reportStatusIndicador == 'Z' ||
#.file.fileStatusLog.reportStatusIndicador == 'Y')].file.id
filesIds_ALL=2913755,2913756,2913758,2913759,2913760,2913761,2913762,2913763,2913764,2913765,2913766,2913767,2913768,2913769,2913770

Rails displaying a string as an array

First off, I apologize in advance for any incorrect terms or general misunderstanding of ruby/rails/html that I may display in this question, as I'm still learning the languages and how they work. I've been given a gui to work on and fix bugs for and after upgrading from rails 3.0 to 3.2 I'm seeing artifacts in many places.
Specifically what I'm asking in this post though is a string display issue. The short version of what I have is a message thread displayed with in a web page that looks close to what you'd see in most text message clients on smartphones now days. The page displays a persons name if the system knows who they are (registered with us) and just a mobile number if they are not.
However the issue is that instead of displaying 5554440002, it's displaying as:
["(", "5", "5", "5", ")", " ", "4", "4", "4", "-", "0", "0", "0", "1"]
Looking around the net, and on stack overflow I found this post To be the closest thing to answering my issue. However the suggestion of dropping the = out of <%= ends in the mobile number no longer displaying.
The line of code that generates this output is:
<%= find_associated_account conversation_message['from'] -%>
Edit 1 (definition):
def find_associated_account(input)
if input[0..0] == $operator.domestic_code.to_s
input = input[1..10]
end
if #account.associated_accounts and #account.associated_accounts.count > 0
if !(input.match(/#/)) && !(input.match(/MISSING_MAILBOX/))
input = input[0..9]
end
begin
acc = #account.associated_accounts.find_by_number(input)
if acc
return get_display_name_for_account(acc)
end
end
return format_mdn(input)
end
def format_mdn(input)
domestic_length = $operator.domestic_mask.count('#')
number_cc_stripped = input.sub(/\A[#{$operator.domestic_code}]/, '')
if /^[0-9]{#{domestic_length}}$/.match(number_cc_stripped)
result = []
count = 0
$operator.domestic_mask.each_char do |c|
if c == '#'
result << number_cc_stripped[count,1]
count += 1
else
result << c
end
end
return result.to_s
end
return input
end
Any advice given will be greatly appreciated and any other information needed will be provided.
Fixed this after messing with the return value of format_mdn. I changed the initialization of result to "" instead of [] which I'm guessing changed the type of the variable? In any case the final code for this definition is:
def format_mdn(input)
domestic_length = $operator.domestic_mask.count('#')
number_cc_stripped = input.sub(/\A[#{$operator.domestic_code}]/, '')
if /^[0-9]{#{domestic_length}}$/.match(number_cc_stripped)
result = []
count = 0
$operator.domestic_mask.each_char do |c|
if c == '#'
result << number_cc_stripped[count,1]
count += 1
else
result << c
end
end
return result.join("")
end
result = number_cc_stripped
return result
end

How to get Python to use a list of answers I give it, to decide if it should go on to the next function

I am starting out, so this code may not be as efficient as it could be, but I try. This is a text based game, something happens and the player must decide if he wants to continue or not.
but Everyone is different. so everyone is going to answer with some variation of "yes". How can I get the program to move on if someone types any variation of "yes" the commas give me a syntax error, and i don't know how else to get it to separate the possible answers.
def continueyn():
option1_des1 = raw_input("> ")
if option1_des1 == "yes", "Yes", "forward", "Forward", "Full impulse", "Full Impulse", "yeah", "yup", "Yup", "Yeah":
gravityp1()
elif option1_des1 == "no":
bearing(), userinput()
else:
print "Sorry Captain, I didn't get that. What did you say?"
continueyn()
Using 'or', as pointed out in the comments is incorrect. The correct way to go ahead through this would be either using lists and a loop, or iterating using "in":
Method 1:
option1_des1 = raw_input("> ")
if option1_des1 in {"yes", "Yes", "forward"} :
print "yes"
elif option1_des1 == "no":
print "no"
else:
print "Sorry Captain, I didn't get that. What did you say?"
Method 2:
You can also make a list and then go across values of the list like this-
flag=True
yesList = ['yes', 'Yes', 'forward']
option1_des1 = raw_input("> ")
for element in yesList:
if option1_des1 == element:
print "yes"
flag=False
break;
if option1_des1 == "no" and flag:
print "no"
elif flag:
print "Sorry Captain, I didn't get that. What did you say?"
Even better, you can use regex to match several variations of one type instead of figuring out every permutation. The xample below only covers "yes", but you can make a list of words like in method 2.
import re
pattern = 'yes'
option1_des1 = raw_input("> ")
matchObj = re.search(pattern, option1_des1, re.I)
if matchObj:
print "yes"
elif option1_des1 == "no":
print "no"
else:
print "Sorry Captain, I didn't get that. What did you say?"
Similar to sbhatla's answer you could use a list and use the built in "in" function which returns as a boolean.
yesoptions = ["yes", "Y", "etc"]
if option_des1 in yesoptions:
#runs actions for a yes answer
elif option in:
etcetc
else:
etc..