Return value and if expression - ado.net

I have the following code to get a row from SQL database. It returns either a record or None. However, it doesn't return because getLogin has the type of unit = () and there is a warning
warning FS0020: This expression should have type 'unit', but has type 'login option'. Use 'ignore' to discard the result of the expression, or 'let' to bind the result to a name.
How to resolve the issue? Is it the best way to handle Ado.Net?
type login = { userName: string; password: string; downloadDir: string}
let getLogin =
let conn = new SqlConnection("Data Source=......;Integrated Security=SSPI;")
try
conn.Open()
let cmd = new SqlCommand("select * FROM Login where website = 'xxx'", conn)
cmd.CommandType <- CommandType.Text
use reader = cmd.ExecuteReader()
if (reader.HasRows) then (
reader.Read() |> ignore
let userName = reader.GetString(5)
let password = reader.GetString(6)
printfn "%s" userName
Some { userName = userName; password = password; downloadDir = "zzz" }
)
else (
printfn "Cannot find login information."
None
)
conn.Close()
with
| :? System.Data.SqlClient.SqlException as sqlEx -> printfn "%A" sqlEx.Message
| _ -> printfn "Unknown Exception"
Update:
I've updated the code by Thomas' suggestion.
let getLogin =
use conn = new SqlConnection("Data Source=mdyptcafgprd101;Initial Catalog=App;Integrated Security=SSPI;")
try
conn.Open()
let cmd = new SqlCommand("select * FROM app.WebCrawler.LoginLbl where website = 'CTSLink'", conn)
cmd.CommandType <- CommandType.Text
use reader = cmd.ExecuteReader()
if (reader.HasRows) then (
reader.Read() |> ignore
let userName = reader.GetString(5)
let password = reader.GetString(6)
Some { userName = userName; password = password; downloadDir = "zzz" }
)
else (
printfn "Cannot find login information."
None
)
with
| :? System.Data.SqlClient.SqlException as sqlEx -> printfn "%A" sqlEx.Message
| _ -> printfn "Unknown Exception"
However, now it gets the following error on line | :? System....
s.fs(31,69): error FS0001: Type mismatch. Expecting a
'a -> login option
but given a
'a -> unit
The type 'login option' does not match the type 'unit'
>

The problem is that your if expression is followed by another line:
if reader.HasRows then
(...)
else
(...)
conn.Close()
... and so the compiler thinks that you are ignoring the result of if and instead returning the result of the last expression, which is conn.Close().
The easiest way to fix this is to use the use construct - it automatically disposes of the conn value when it comes out of scope, and so you do not need the last line and can just use if as the last expression in your code:
use conn = (...)
if reader.HasRows then
(...)
else
(...)
Also, you'll need to return some result in the with ... branch - that handles an exception and you either need to raise another exception or return a valid value - in this case, probably None.

Related

trying to use & and operation in scala

case class takes 3 parameters id, applied by and internal name. Trying to make the result lenght return 3. internal name was a newly added field/parameter so that is why it is returning 0 instead of 3.
I was think to use
result.topics.find(_.topicId == "urn:emmet:1234567").get.appliedBy should be ("human") &
result.topics.find(_.topicId == "urn:emmet:2345678").get.internalName should be ("")
it's giving me syntax error, please advice thanks in advance
it should "dedup topics by id, keeping those applied by human if possible" in {
val doc = Document.empty.copy(
topics = Array(
Topic("urn:emmet:1234567", appliedBy = "machine" , internalName = ""),
Topic("urn:emmet:2345678", appliedBy = "human", internalName = ""),
Topic("urn:emmet:1234567", appliedBy = "human", internalName = ""),
Topic("urn:emmet:2345678", appliedBy = "machine", internalName = ""),
Topic("urn:emmet:3456789", appliedBy = "machine", internalName = ""),
Topic("urn:emmet:3456789", appliedBy = "machine", internalName = "")
)
)
val result = DocumentTransform.dedupSubRecords(doc)
result.topics.length should be (3)
result.topics.find(_.topicId == "urn:emmet:1234567").get.appliedBy should be ("human")
result.topics.find(_.topicId == "urn:emmet:2345678").get.appliedBy should be ("human")
result.topics.find(_.topicId == "urn:emmet:3456789").get.appliedBy should be ("machine")
}
Multiple test statements are already an 'and', because if any one of them fails the whole test fails.
val e1234567 = result.topics.find(_.topicId == "urn:emmet:1234567").get
e1234567.appliedBy shouldEqual "human"
e1234567.internalName shouldEqual ""

scala.js form processing in client / access to form on scala.js client

I want submit a form and want to show the user the process with spinner and reload the new information.
#JSExport
def addToCart(form: html.Form): Unit = {
form.onsubmit = (e: dom.Event) => {
e.preventDefault()
}
val waitSpan = span(
`class` := Waiting.glyphIconWaitClass
)
val waiting = form.getElementsByTagName("button").head.appendChild(waitSpan.render)
dom.window.alert(JSON.stringify( form.elements.namedItem("quantity") ))
Ajax.InputData
Ajax.post(form.action,withCredentials = true).map{q =>
//
}
}
I have no access to form data. Also I cannot execute an ajax call to proof the form and execute it. I have found no way. Someone has an idea?
jQuery helps. I used them now to serialize the form. But now I have no longer the ability of play forms with bindOfRequest()
val jForm = $("#"+form.id)
val serialized = jForm.serialize()
Ajax.post(s"/js/api/form/${UUID.randomUUID().toString}",withCredentials = false,timeout = 12000,data = serialized,headers = Map("X-CSRFToken"->"nocheck","Csrf-Token"->"nocheck"))
I get always:
occurrence%5B%5D=400g&quantity=1&csrfToken=c1606da9a261a7f3284518d4f1fd63eaa8bbb59e-1483472204854-1c5af366c62520883474c160
But now I donĀ“t know what I have to do. Sorry.
def executeAddToCartForm(articleId: UUID) = silhouette.UserAwareAction.async{implicit req =>
val form = complexCartForm.bindFromRequest()
Try(form.get) match {
case Success((i,seq)) => println("article: " + i)
case _ => println(form.errors.mkString + " " + req.body.asText + " " + URLDecoder.decode(req.body.asText.get,"UTF-8"))
}
Future.successful(Ok("danke"))
}
Always get failure :( I will have a look at react.
ADDED
Sometimes I need more sleep!
Ajax.post(
url = form.action,
withCredentials = true,
timeout = 12000,
data = serialized,
headers = Map("Content-Type" -> "application/x-www-form-urlencoded")
)
with this: headers = Map("Content-Type" -> "application/x-www-form-urlencoded") I can use the bindFromRequest() as usually :)
Coffee I need more

Sending email with multiple attachments vb6

Can someone help me.How to send an email with multiples attachments.
I am using cdo and SMTP Send Mail for VB6. Everything works great except I am only able to send one attachment at a time.
here's the code
Public Function SendMail(sTo As String, sSubject As String, sFrom As String, _
sBody As String, sSmtpServer As String, iSmtpPort As Integer, _
sSmtpUser As String, sSmtpPword As String, _
sFilePath As String, bSmtpSSL As Boolean) As String
On Error GoTo SendMail_Error:
Dim lobj_cdomsg As CDO.Message
Set lobj_cdomsg = New CDO.Message
lobj_cdomsg.Configuration.Fields(cdoSMTPServer) = sSmtpServer
lobj_cdomsg.Configuration.Fields(cdoSMTPServerPort) = iSmtpPort
lobj_cdomsg.Configuration.Fields(cdoSMTPUseSSL) = bSmtpSSL
lobj_cdomsg.Configuration.Fields(cdoSMTPAuthenticate) = cdoBasic
lobj_cdomsg.Configuration.Fields(cdoSendUserName) = sSmtpUser
lobj_cdomsg.Configuration.Fields(cdoSendPassword) = sSmtpPword
lobj_cdomsg.Configuration.Fields(cdoSMTPConnectionTimeout) = 30
lobj_cdomsg.Configuration.Fields(cdoSendUsingMethod) = cdoSendUsingPort
lobj_cdomsg.Configuration.Fields.Update
lobj_cdomsg.To = sTo
lobj_cdomsg.From = sFrom
lobj_cdomsg.Subject = sSubject
lobj_cdomsg.TextBody = sBody
If Trim$(sFilePath) <> vbNullString Then
lobj_cdomsg.AddAttachment (sFilePath)
End If
lobj_cdomsg.Send
Set lobj_cdomsg = Nothing
SendMail = "ok"
Exit Function
SendMail_Error:
SendMail = Err.Description
End Function
Private Sub cmdSend_Click()
Dim retVal As String
Dim objControl As Control
For Each objControl In Me.Controls
If TypeOf objControl Is TextBox Then
If Trim$(objControl.Text) = vbNullString And LCase$(objControl.Name) <> "txtAttach" Then
Label2.Caption = "Error: All fields are required!"
Exit Sub
End If
End If
Next
Frame1.Enabled = False
Frame2.Enabled = False
cmdSend.Enabled = False
Label2.Caption = "Sending..."
retVal = SendMail(Trim$(txtTo.Text), _
Trim$(txtSubject.Text), _
Trim$(txtFromName.Text) & "<" & Trim$(txtFromEmail.Text) & ">", _
Trim$(txtMsg.Text), _
Trim$(txtServer.Text), _
CInt(Trim$(txtPort.Text)), _
Trim$(txtUsername.Text), _
Trim$(txtPassword.Text), _
Trim$(txtAttach.Text), _
CBool(chkSSL.Value))
Frame1.Enabled = True
Frame2.Enabled = True
cmdSend.Enabled = True
Label2.Caption = IIf(retVal = "ok", "Message sent!", retVal)
End Sub
Private Sub cmdBrowse_Click()
Dim sFilenames() As String
Dim i As Integer
On Local Error GoTo Err_Cancel
With cmDialog
.FileName = ""
.CancelError = True
.Filter = "All Files (*.*)|*.*|HTML Files (*.htm;*.html;*.shtml)|*.htm;*.html;*.shtml|Images (*.bmp;*.jpg;*.gif)|*.bmp;*.jpg;*.gif"
.FilterIndex = 1
.DialogTitle = "Select File Attachment(s)"
.MaxFileSize = &H7FFF
.Flags = &H4 Or &H800 Or &H40000 Or &H200 Or &H80000
.ShowOpen
' get the selected name(s)
sFilenames = Split(.FileName, vbNullChar)
End With
If UBound(sFilenames) = 0 Then
If txtAttach.Text = "" Then
txtAttach.Text = sFilenames(0)
Else
txtAttach.Text = txtAttach.Text & ";" & sFilenames(0)
End If
ElseIf UBound(sFilenames) > 0 Then
If Right$(sFilenames(0), 1) <> "\" Then sFilenames(0) = sFilenames(0) & "\"
For i = 1 To UBound(sFilenames)
If txtAttach.Text = "" Then
txtAttach.Text = sFilenames(0) & sFilenames(i)
Else
txtAttach.Text = txtAttach.Text & ";" & sFilenames(0) & sFilenames(i)
End If
Next
Else
Exit Sub
End If
Err_Cancel:
End Sub
You are only passing in one file. Try passing in an array of files and loop through the array. Or, since it looks like its semicolon delimiting the list of files selected, try to just split the list...
For Each s As String in sFilePath.Split(";"c)
lobj_cdomsg.AddAttachemt(s)
Next
I have no idea how to run a vb 6 app anymore, but if this helps, please mark it so.

mysqli Fatal error: Call to a member function bind_param() on a non-object

I have a problem with a prepared statement, here is my code:
function query_array($table, $data) {
foreach ($data as $column => $value) {
$columns[] = sprintf("`%s` = '%s'", $column, $this->db->real_escape_string($value));
}
$column_list = join(',', $columns);
// Prepare the statement
$stmt = $this->db->prepare("UPDATE `?` SET ?");
$stmt->bind_param('ss', $table, $column_list);
// Execute the statement
$stmt->execute();
// Save the affected rows
$affected = $stmt->affected_rows;
// Close the statement
$stmt->close();
// ...
}
$this->db returns an object;
$table = 'settings'; (string)
$column_list: (string)
`title` = 'Socialsd',`captcha` = '0',`public` = '',`private` = '',`time` = '1',`perpage` = '10',`message` = '140',`mail` = '1',`inter` = '10000',`size` = '1048576',`format` = 'png,jpg,gif',`sizeMsg` = '1048576',`formatMsg` = 'png,jpg,gif,bmp',`censor` = '',`ad1` = '',`ad2` = ''
The error I'm getting is:
Fatal error: Uncaught exception 'ErrorException' with message 'You
have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near '?' at line
1' in C:\xampp\htdocs\new\includes\classes.php:256 Stack trace: #0
C:\xampp\htdocs\new\sources\admin.php(225):
updateSettings->query_array('settings', Array) #1
C:\xampp\htdocs\new\index.php(42): PageMain() #2 {main} thrown in
C:\xampp\htdocs\new\includes\classes.php on line 256
I can't figure out what causes this, because trying the following works just fine:
$query = sprintf("UPDATE `%s` SET %s", $table, $column_list);
$result = $this->db->query($query);
Any help is appreciated.
Update 1: May I know why this has been down-voted? It would be nice to know.
Update 2: So I've removed the last bind ($column_list) and put in the statement the entire output of $column_list, so basically I was binding only the table name, and now I get another error:
Can't find file: '.\diary\#003f.frm' (errno: 22)
Now I'm really confused.
I have found the answer here: Use one bind_param() with variable number of input vars and also as #Jocelyn linked me, I've found that table names can't be binded. Can be closed.

How to migrate mysqli to pdo

Hi I was wondering how I would migrate a mysqli php file to use PDO. Would anyone be able to take a look at my code and see if I'm on the right track?
This is my original (mysqli) code:
<?php
// connecting to database
$conn = new mysqli('xxxxxx', 'xxxxxx', 'password', 'xxxxxx');
$match_email = 'email';
$match_passhash = 'passhash';
if (isset($_POST['email'])) {
$clean_email = mysqli_real_escape_string($conn, $_POST['email']);
$match_email = $clean_email;
}
if (isset($_POST['passhash'])) {
$clean_passhash = mysqli_real_escape_string($conn, $_POST['passhash']);
$match_passhash = sha1($clean_passhash);
}
$userquery = "SELECT email, passhash, userlevel, confirmed, blocked FROM useraccounts
WHERE email = '$match_email' AND passhash = '$match_passhash'
AND userlevel='user' AND confirmed='true' AND blocked='false';";
$userresult = $conn->query($userquery);
if ($userresult->num_rows == 1) {
$_SESSION['authorisation'] = 'knownuser';
header("Location: userhome.php");
exit;
} else {
$_SESSION['authorisation'] = 'unknownuser';
header("Location: userlogin.php");
exit;
}
?>
And this is my attempt to migrate it to PDO:
<?php
// connecting to database
$dbh = new PDO("mysql:host=xxxxxx; dbname=xxxxxx", "xxxxxx", "password");
$match_email = 'email';
$match_passhash = 'passhash';
if (isset($_POST['email'])) {
$clean_email = mysqli_real_escape_string($conn, $_POST['email']);
$match_email = $clean_email;
}
if (isset($_POST['passhash'])) {
$clean_passhash = mysqli_real_escape_string($conn, $_POST['passhash']);
$match_passhash = sha1($clean_passhash);
}
$userquery = "SELECT email, passhash, userlevel, confirmed, blocked FROM useraccounts
WHERE email = ':match_email' AND passhash = ':match_passhash' AND
userlevel='user' AND confirmed='true' AND blocked='false';";
$stmt = $dbh->prepare($query);
$stmt->bindParam(":match_email", $match_email);
$stmt->bindParam(":match_passhash", $match_passhash);
$stmt->execute();
$userresult = $conn->query($userquery);
if ($userresult->num_rows == 1) {
$_SESSION['authorisation'] = 'knownuser';
header("Location: userhome.php");
exit;
} else {
$_SESSION['authorisation'] = 'unknownuser';
header("Location: userlogin.php");
exit;
}
?>
I'm also not sure how to count the number of rows returned in PDO.
If anyone would be able to help me out that wold be very great.
A million thanks in advance!
When using prepared statements and $stmt->bindValue() or $stmt->bindParam() you do not need to escape values with mysqli_real_escape_string(), PDO will do that for you.
Just remember to set a correct data type for the value. That is the third argument in the bind functions and it is a string by default so your code here is fine. I would only use bindValue() instead of bindParam() as you do not need references.
$stmt->execute() will run your prepared statement as a query. The other $conn->query() does not work with prepared statements. It is for raw queries, like you used to have with MySQLi.
When $stmt->execute() runs your response is saved in the $stmt object. For row count use $stmt->rowCount().