How to test to see if mySql Database is working? - c#

I am new to MySQL database, I am using Visual Studio C# to connect to my database. I have got a following select method. How can I run it to check if it is working?
EDITED The open and close connection methods
//Open connection to database
private bool OpenConnection()
{
try
{
// connection.open();
return true;
}
catch (MySqlException ex)
{
//When handling errors, your application's response based
//on the error number.
//The two most common error numbers when connecting are as follows:
//0: Cannot connect to server.
//1045: Invalid user name and/or password.
switch (ex.Number)
{
case 0:
MessageBox.Show("Cannot connect to server.");
break;
case 1045:
MessageBox.Show("Invalid username/password, please try again");
break;
}
return false;
}
}
//Close connection
private bool CloseConnection()
{
try
{
connection.Close();
return true;
}
catch (MySqlException ex)
{
MessageBox.Show(ex.Message);
return false;
}
}
Select method which is in the same class as the close and open connection as shown above
public List<string>[] Select()
{
string query = "SELECT * FROM Questions";
//Create a list to store the result
List<string>[] list = new List<string>[3];
list[0] = new List<string>();
list[1] = new List<string>();
list[2] = new List<string>();
list[3] = new List<string>();
list[4] = new List<string>();
list[5] = new List<string>();
list[6] = new List<string>();
list[7] = new List<string>();
//Open connection
if (this.OpenConnection() == true)
{
//Create Command
MySqlCommand cmd = new MySqlCommand(query, connection);
//Create a data reader and Execute the command
MySqlDataReader dataReader = cmd.ExecuteReader();
//Read the data and store them in the list
while (dataReader.Read())
{
list[0].Add(dataReader["id"] + "");
list[1].Add(dataReader["difficulty"] + "");
list[2].Add(dataReader["qustions"] + "");
list[3].Add(dataReader["c_answer"] + "");
list[4].Add(dataReader["choiceA"] + "");
list[5].Add(dataReader["choiceB"] + "");
list[6].Add(dataReader["choiceC"] + "");
list[7].Add(dataReader["choiceD"] + "");
}
//close Data Reader
dataReader.Close();
//close Connection
this.CloseConnection();
//return list to be displayed
return list;
}
else
{
return list;
}
}
This method is in a separate class which has got all the database connection settings. Now that I want to call this method from my main class to test it to see if it's working, how can I do this?

You should create an object instance of that DB class and then call the Select() method.
So, supposing that this DB class is named QuestionsDB you should write something like this:
QuestionDB questionDAL = new QuestionDB();
List<string>[] questions = questionDAL.Select();
However, before this, please correct this line
List<string>[] list = new List<string>[8]; // you need 8 lists for your db query
You could check if you have any record testing if the first list in your array list has more than zero elements.
if(questions[0].Count > 0)
... // you have read records.
However, said that, I will change your code adding a specific class for questions and using a list(of Question) instead of an array of list
So, for example, create a class like this
public class Question
{
public string ID;
public string Difficulty;
public string Question;
public string RightAnswer;
public string AnswerA;
public string AnswerB;
public string AnswerC;
public string AnswerD;
}
and change your select to return a List(of Question)
List<Question> list = new List<Question>;
......
while (dataReader.Read())
{
Question qst = new Question();
qst.ID = dataReader["id"] + "";
qst.Difficulty = dataReader["difficulty"] + "";
qst.Question = dataReader["qustions"] + "";
qst.RightAnswer = dataReader["c_answer"] + "";
qst.AnswerA = dataReader["choiceA"] + "";
qst.AnswerB = dataReader["choiceB"] + "";
qst.AnswerC = dataReader["choiceC"] + "";
qst.AnswerD = dataReader["choiceD"] + "";
list.Add(qst);
}
return list;

You can test whether the method works by writing a unit test for it. A good unit testing frame work is Nunit. Before you call this you must create and open a connection to the DB:
//Open connection
if (this.OpenConnection() == true)
{
as the other person said, you will want to fix the lists up.

Related

Invoice number displayed blank

I am creating a simple inventory system using c#.
When I am generating the invoice number, the form is loaded but it doesn't show anything.
It is an auto-incremented invoice number; order is completed incrementally by 1.
For example, starting at E-0000001, after order we expect E-0000002. I don't understand why it is blank.
No error displayed. I tried to debug the code but I couldn't find what's wrong.
public void invoiceno()
{
try
{
string c;
sql = "SELECT MAX(invoid) FROM sales";
cmd = new SqlCommand(sql, con);
var maxInvId = cmd.ExecuteScalar() as string;
if (maxInvId == null)
{
label4.Text = "E-000001";
}
else
{
int intVal = int.Parse(maxInvId.Substring(2, 6));
intVal++;
label4.Text = String.Format("E-{0:000000}", intVal);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.Write(ex.StackTrace);
}
}
Let's extract a method - NextInvoiceId - we
Open connection
Execute query
Obtain next invoice number
Code:
private int NextInvoiceNumber() {
//TODO: put the right connection string here
using(var conn = new SqlConnection(ConnectionStringHere)) {
conn.Open();
string sql =
#"SELECT MAX(invoid)
FROM sales";
using (var cmd = new SqlCommand(sql, conn)) {
var raw = cmd.ExecuteScalar() as string;
return raw == null
? 1 // no invoces, we start from 1
: int.Parse(raw.Trim('e', 'E', '-')) + 1;
}
}
}
Then we can easily call it:
public void invoiceno() {
label4.Text = $"E-{NextInvoiceNumber():d6}";
}
Edit: You should not swallow exceptions:
try
{
...
}
// Don't do this!
catch (Exception ex) // All the exceptions will be caught and...
{
// printed on the Console...
// Which is invisible to you, since you develop Win Forms (WPF) application
Console.WriteLine(ex.ToString());
Console.Write(ex.StackTrace);
}
let system die and inform you that something got wrong

Parallel.Foreach with OledbDataReader to call web api causes duplicated rows

I have a DB table with 7 columns and 10rows. Each row is provided an input parameter to a web api call, and the response returned by the api, is inserted into a table. My problem is, the Parallel.Foreach is not producing the same result as the regular ForEach.
Specifically, if 1st row has address as "123 Jump Street Arizona Us", I get a response from web api with the standardized address as "123 Jump Street Arizona USA", like that I have 10 different rows with 10 different input address. However, the output response I get from Parallel.Foreach is for the same address repeated 5 times. And the next time i run it, it is a different result altogether
Could someone please point out why this is happening and the potential solution?
Here is my code:
public void Main()
{
// TODO: Add your code here
string query = "SELECT ADDR_LINE_ONE,ADDR_LINE_TWO,ADDR_LINE_THREE,COUNTRY,PROVINCE,CITY_NAME,POSTAL_CODE FROM Addresstestpoc";
try
{
using (OleDbConnection connection = new OleDbConnection(conn))
{
OleDbCommand command = new OleDbCommand(query, connection);
connection.Open();
OleDbDataReader reader = command.ExecuteReader();
int i = reader.FieldCount;
bool b = reader.HasRows;
Parallel.ForEach(GetFromReader(reader), record =>
{
//AddrOne = record[0].ToString();
string AddrOne = record.GetString(0);
string AddrTwo = record.GetString(1);
string AddrThree = record.GetString(2);
string Country = record.GetString(3);
string Province = record.GetString(4);
string City = record.GetString(5);
string PostalCode = record.GetString(6);
string Sender = "G";
//sqlk = (string)Dts.Variables["User::sqlconn"].Value;
standardizeAddressReturn result;
string data = string.Empty;
string queri;
MDMStandardizeAddressService web = new MDMStandardizeAddressService();
try
{
result = web.standardizeAddress(AddrOne, AddrTwo, AddrThree, City, Province, PostalCode, Country, Sender);
data = SerializeToXml(result);
queri = "insert into [CPM].[dbo].[AddressResponsetest_new] values ('" + data + "')";
//MessageBox.Show(data);
insertintosql(queri);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
});
}
}
catch (Exception ex)
{
string msg = ex.Message;
}
}
IEnumerable<IDataRecord> GetFromReader(IDataReader reader)
{
while (reader.Read()) yield return reader;
}
I think you need another approach. Command and DataReader are not thread safe. Even if DataReader was thread safe it is a forward only cursor so it is not going to be faster.
I recommend a producer consumer pattern (.e.g BlockingCollection). In the consumer is where you can parallel process the
MDMStandardizeAddressService web = new MDMStandardizeAddressService();
try
{
You could probably use tasks, await, asynch for producer consumer.
An easier approach might be to create a class for properties and put that in a List and then just Read that List. This will happen if a fraction of a second.
You can then parallel process the List.
Stub code:
public class WebMailer
{
public void process()
{
List<Addr> Addrs = new List<Addr>();
SqlCommand command = new SqlCommand();
using (var reader = command.ExecuteReader())
{
using (SqlDataReader r = command.ExecuteReader())
{
Addrs.Add(new Addr(r.GetString(0), r.GetString(1)));
}
}
foreach(Addr addr in Addrs) // can use parallel here
{ }
}
}
s

C# Programming Return ArrayList

I am trying to return an error message for a method in my code, but I am unable to find the correct return object, I have searched on the internet but have no been successful in finding an answer.
The following is a code snippet:
public ArrayList getBeneficiaryID(string UserID)
{
try
{
//long Beneficiary_ID = 0;
//string BeneficiaryID = "";
ArrayList BeneficiaryArray = new ArrayList();
// Open connection to the database
string strConn = System.Configuration.ConfigurationManager.ConnectionStrings["Databasebcfintec_alice"].ConnectionString;
aConn = new SqlConnection(strConn);
aConn.Open();
// Set up a command with the given query and associate
// this with the current connection.
string sql = "Select BeneficiaryID from Beneficiary where user_id = '" + UserID + "'";
cmd = new SqlCommand(sql);
cmd.Connection = aConn;
// Execute the query
odtr = cmd.ExecuteReader();
while (odtr.Read())
{
BeneficiaryArray.Add(odtr["BeneficiaryID"]);
//User_ID = (long)(odtr["user_id"]);
//UserID = User_ID.ToString();
}
odtr.Close();
return BeneficiaryArray;
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.ToString());
//return ex.ToString();
return;
}
}
Error Message:
"An object of a type convertible to arraylist is required"
Another method I tried was using the following code:
return ex.ToString();
but it provided the following error message:
"Cannot implicitly convert type 'string' to
'System.Collections.ArrayList'
You can just put return null; or return new ArrayList();
since it looks like you don't care with what you're gonna get with the catch. You already have a console log.
The problem is that you have to return an object. You can't do
return;
because you're not returning anything. You also can't return a string because it can't be cast to an ArrayList.
You can, however, return null, which it sounds like is what you want.
In the catch section you should have to throw the exception.
public ArrayList MethodName(string UserID)
{
try
{
//write your code
}
catch (Exception )
{
//log the exception
throw ;
}
}

SQLite connection strategies

I have a database that may be on the network drive.
There are two things that I want to achieve:
When the first user connects to it in read-only mode (he doesn't
have a read-write access to the location, or the database is
read-only), other users must use the read-only connection also (even
if they have RW access).
When the first user connects to it in RW mode, others can not
connect to the database at all.
I'm using SQLite, and the concurrency should not be the problem, as the database should never be used by more than 10 people at the same time.
UPDATE: This is a sample that I'm trying to make work, so I could implement it in the program itself. Almost everything can be changed.
UPDATE: Now when I finally understood what #CL. was telling me, I made it work and this is the updated code.
using System.Diagnostics;
using System.Linq;
using System.IO;
using DbSample.Domain;
using DbSample.Infrastructure;
using NHibernate.Linq;
using NHibernate.Util;
namespace DbSample.Console
{
class Program
{
static void Main(string[] args)
{
IDatabaseContext databaseContext = null;
databaseContext = new SqliteDatabaseContext(args[1]);
var connection = LockDB(args[1]);
if (connection == null) return;
var sessionFactory = databaseContext.CreateSessionFactory();
if (sessionFactory != null)
{
int insertCount = 0;
while (true)
{
try
{
using (var session = sessionFactory.OpenSession(connection))
{
string result;
session.FlushMode = NHibernate.FlushMode.Never;
var command = session.Connection.CreateCommand();
command.CommandText = "PRAGMA locking_mode=EXCLUSIVE";
command.ExecuteNonQuery();
using (var transaction = session.BeginTransaction(ReadCommited))
{
bool update = false;
bool delete = false;
bool read = false;
bool readall = false;
int op = 0;
System.Console.Write("\nMenu of the day:\n1: update\n2: delete\n3: read\n4: read all\n0: EXIT\n\nYour choice: ");
op = System.Convert.ToInt32(System.Console.ReadLine());
if (op == 1)
update = true;
else if (op == 2)
delete = true;
else if (op == 3)
read = true;
else if (op == 4)
readall = true;
else if (op == 0)
break;
else System.Console.WriteLine("Are you retarded? Can't you read?");
if (delete)
{
System.Console.Write("Enter the ID of the object to delete: ");
var objectToRemove = session.Get<MyObject>(System.Convert.ToInt32(System.Console.ReadLine()));
if (!(objectToRemove == null))
{
session.Delete(objectToRemove);
System.Console.WriteLine("Deleted {0}, ID: {1}", objectToRemove.MyName, objectToRemove.Id);
deleteCount++;
}
else
System.Console.WriteLine("\nObject not present in the database!\n");
}
else if (update)
{
System.Console.Write("How many objects to add/update? ");
int number = System.Convert.ToInt32(System.Console.ReadLine());
number += insertCount;
for (; insertCount < number; insertCount++)
{
var myObject = session.Get<MyObject>(insertCount + 1);
if (myObject == null)
{
myObject = new MyObject
{
MtName = "Object" + insertCount,
IdLegacy = 0,
};
session.Save(myObject);
System.Console.WriteLine("Added {0}, ID: {1}", myObject.MyName, myObject.Id);
}
else
{
session.Update(myObject);
System.Console.WriteLine("Updated {0}, ID: {1}", myObject.MyName, myObject.Id);
}
}
}
else if (read)
{
System.Console.Write("Enter the ID of the object to read: ");
var objectToRead = session.Get<MyObject>(System.Convert.ToInt32(System.Console.ReadLine()));
if (!(objectToRead == null))
System.Console.WriteLine("Got {0}, ID: {1}", objectToRead.MyName, objectToRead.Id);
else
System.Console.WriteLine("\nObject not present in the database!\n");
}
else if (readall)
{
System.Console.Write("How many objects to read? ");
int number = System.Convert.ToInt32(System.Console.ReadLine());
for (int i = 0; i < number; i++)
{
var objectToRead = session.Get<MyObject>(i + 1);
if (!(objectToRead == null))
System.Console.WriteLine("Got {0}, ID: {1}", objectToRead.MyName, objectToRead.Id);
else
System.Console.WriteLine("\nObject not present in the database! ID: {0}\n", i + 1);
}
}
update = false;
delete = false;
read = false;
readall = false;
transaction.Commit();
}
}
}
catch (System.Exception e)
{
throw e;
}
}
sessionFactory.Close();
}
}
private static SQLiteConnection LockDbNew(string database)
{
var fi = new FileInfo(database);
if (!fi.Exists)
return null;
var builder = new SQLiteConnectionStringBuilder { DefaultTimeout = 1, DataSource = fi.FullName, Version = 3 };
var connectionStr = builder.ToString();
var connection = new SQLiteConnection(connectionStr) { DefaultTimeout = 1 };
var cmd = new SQLiteCommand(connection);
connection.Open();
// try to get an exclusive lock on the database
try
{
cmd.CommandText = "PRAGMA locking_mode = EXCLUSIVE; BEGIN EXCLUSIVE; COMMIT;";
cmd.ExecuteNonQuery();
}
// if we can't get the exclusive lock, it could mean 3 things
// 1: someone else has locked the database
// 2: we don't have a write acces to the database location
// 3: database itself is a read-only file
// So, we try to connect as read-only
catch (Exception)
{
// we try to set the SHARED lock
try
{
// first we clear the locks
cmd.CommandText = "PRAGMA locking_mode = NORMAL";
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT COUNT(*) FROM MyObject";
cmd.ExecuteNonQuery();
// then set the SHARED lock on the database
cmd.CommandText = "PRAGMA locking_mode = EXCLUSIVE";
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT COUNT(*) FROM MyObject";
cmd.ExecuteNonQuery();
readOnly = true;
}
catch (Exception)
{
// if we can't set EXCLUSIVE nor SHARED lock, someone else has opened the DB in read-write mode and we can't connect at all
connection.Close();
return null;
}
}
return connection;
}
}
}
Set PRAGMA locking_mode=EXCLUSIVE to prevent SQLite from releasing its locks after a transaction ends.
I don't know if it can be done within db but in application;
You can set a global variable (not sure if it's a web or desktop app) to check if anyone connected and he has a write access or not.
After that you can check the other client's state.

Array class not rendering into datagrid

The following application is not rendering the information that I am getting back from a web service into the datagrid. I know I am being able to connect to the webservice because I am getting the count for the class array. I am being able to get a Response.Write but when I try to pull all the information from the array class I haven't been able to see the elements nor to render the whole class into the data grid. What might be my issue? I am stuck with this one.
void LoadABCPhoneInfo()
{
PhoneTypeInfo[] PhoneInfo = GetPhoneInfo();
DataSet quoteDataSet = XmlString2DataSet(PhoneInfo.ToString());
//Here is NOT doing the databinding.
grdABC.DataSource = quoteDataSet;
grdABC.DataBind();
grdABC.Visible = true;
}
private PhoneTypeInfo[] GetPhoneInfo()
{
//string strGetPhoneInfo = String.Empty;
PhoneTypeInfo[] strGetPhoneInfo; //
try
{
OwnerAndReservation ownerAndReservationWS = new OwnerAndReservation();
strGetPhoneInfo = ownerAndReservationWS.GetPhoneTypes();
//GetPhoneTypesAsync()
//Here I can get the count for the array
Response.Write("GetPhoneInfo Length "+ strGetPhoneInfo);
}
catch (Exception ex)
{
//raise the error
string errorMessage = String.Format("Error while trying to connect to the Web Service. {0}", ex.Message);
throw new Exception(errorMessage);
}
//return the quote information
return strGetPhoneInfo;
}
private DataSet XmlString2DataSet(string xmlString)
{
//create a new DataSet that will hold our values
DataSet quoteDataSet = null;
//check if the xmlString is not blank
if (String.IsNullOrEmpty(xmlString))
{
//stop the processing
return quoteDataSet;
}
try
{
//create a StringReader object to read our xml string
using (StringReader stringReader = new StringReader(xmlString))
{
//initialize our DataSet
quoteDataSet = new DataSet();
//load the StringReader to our DataSet
quoteDataSet.ReadXml(stringReader);
}
}
catch
{
//return null
quoteDataSet = null;
}
//return the DataSet containing the stock information
return quoteDataSet;
}

Categories