Skip to content

Improved documentation of exported functions #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 17, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,22 @@ command = """CREATE TABLE Employee
JoinDate DATE,
PRIMARY KEY (ID)
);"""
mysql_execute_query(con, command)
mysql_execute(con, command)

# Insert some values
mysql_execute_query(con, "INSERT INTO Employee (Name, Salary, JoinDate) values ("John", 25000.00, '2015-12-12'), ("Sam", 35000.00, '2012-18-17), ("Tom", 50000.00, '2013-12-14');")
mysql_execute(con, "INSERT INTO Employee (Name, Salary, JoinDate) values ("John", 25000.00, '2015-12-12'), ("Sam", 35000.00, '2012-18-17), ("Tom", 50000.00, '2013-12-14');")

# Get SELECT results
command = "SELECT * FROM Employee;"
dframe = mysql_execute_query(con, command)
dframe = mysql_execute(con, command)

# Close connection
mysql_disconnect(con)
```

## Getting the result set

By default, `mysql_execute_query` returns a DataFrame. To obtain each row as a tuple use `mysql_execute_query(con, command; opformat=MYSQL_TUPLES)`. The same can also be done with the `MySQLRowIterator`, example:
By default, `mysql_execute` returns a DataFrame. To obtain each row as a tuple use `mysql_execute(con, command; opformat=MYSQL_TUPLES)`. The same can also be done with the `MySQLRowIterator`, example:

```julia
for row in MySQLRowIterator(con, command)
Expand All @@ -68,11 +68,11 @@ values = [("John", 10000.50, "2015-8-3"),
("Jim", 30000.00, "2015-6-2")]

for val in values
mysql_execute_query(conn, [MYSQL_TYPE_VARCHAR, MYSQL_TYPE_FLOAT, MYSQL_TYPE_DATE], val)
mysql_execute(conn, [MYSQL_TYPE_VARCHAR, MYSQL_TYPE_FLOAT, MYSQL_TYPE_DATE], val)
end

mysql_stmt_prepare(conn, "SELECT * from Employee WHERE ID = ? AND Salary > ?")
dframe = mysql_execute_query(conn, [MYSQL_TYPE_LONG, MYSQL_TYPE_FLOAT], [5, 35000.00])
dframe = mysql_execute(conn, [MYSQL_TYPE_LONG, MYSQL_TYPE_FLOAT], [5, 35000.00])

# To iterate over the result and get each row as a tuple
for row in MySQLRowIterator(conn, [MYSQL_TYPE_LONG, MYSQL_TYPE_FLOAT], [5, 35000.00])
Expand Down Expand Up @@ -100,7 +100,7 @@ The same function `mysql_metadata` can be called for prepared statements with th

# Multi-Query

`mysql_execute_query` handles multi-query. It returns an array of DataFrames and integers.
`mysql_execute` handles multi-query. It returns an array of DataFrames and integers.
The DataFrames correspond to the SELECT queries and the integers respresent the number of
affected rows corresponding to non-SELECT queries in the multi statement.

Expand Down
18 changes: 0 additions & 18 deletions src/api.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ function mysql_real_connect(mysqlptr::Ptr{Void},
client_flag)
end

"""
Used to set options. Must be called after mysql_init and before
mysql_real_connect. Can be called multiple times to set options.
Returns non zero on error.
"""
function mysql_options(mysqlptr::Ptr{Void},
option_type::Cuint,
option::Ptr{Void})
Expand Down Expand Up @@ -119,10 +114,6 @@ function mysql_stmt_close(stmtptr::Ptr{MYSQL_STMT})
stmtptr)
end

"""
Returns the value generated by auto increment column by the previous
insert / update statement.
"""
function mysql_insert_id(mysqlptr::Ptr{Void})
return ccall((:mysql_insert_id, mysql_lib),
Culong,
Expand Down Expand Up @@ -159,9 +150,6 @@ function mysql_stmt_init(mysqlptr::Ptr{Void})
mysqlptr)
end

"""
Creates the prepared statement. There should be only 1 statement
"""
function mysql_stmt_prepare(stmtptr::Ptr{MYSQL_STMT}, sql::AbstractString)
s = utf8(sql)
return ccall((:mysql_stmt_prepare, mysql_lib),
Expand Down Expand Up @@ -234,9 +222,6 @@ function mysql_stmt_bind_result(stmtptr::Ptr{MYSQL_STMT}, bind::Ptr{MYSQL_BIND})
bind)
end

"""
Executes the query and returns the status of the same.
"""
function mysql_query(mysqlptr::Ptr{Void}, sql::AbstractString)
return ccall((:mysql_query, mysql_lib),
Cchar,
Expand All @@ -245,9 +230,6 @@ function mysql_query(mysqlptr::Ptr{Void}, sql::AbstractString)
sql)
end

"""
Stores the result in to an object.
"""
function mysql_store_result(mysqlptr::Ptr{Void})
return ccall((:mysql_store_result, mysql_lib),
MYSQL_RES,
Expand Down
108 changes: 79 additions & 29 deletions src/handy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@
using Compat

"""
Set multiple options specified in the dictionary opts. The keys represent the option type,
for example `MYSQL_OPT_RECONNECT` and the values are the value of the corresponding option.
mysql_options(hndl::MySQLHandle, opts)

Set multiple options specified in the dictionary `opts`. The keys represent the option type,
for example `MYSQL_OPT_RECONNECT` and the values are the value of the corresponding option. See `MYSQL_OPT_*` for a list of options.
"""
function mysql_options(hndl, opts)
for (k, v) in opts
mysql_options(hndl, k, v)
end
nothing
end

"""
A handy function that wraps mysql_init and mysql_real_connect. Also does error
checking on the pointers returned by init and real_connect.
"""
function mysql_connect(host::AbstractString,
user::AbstractString,
passwd::AbstractString,
Expand All @@ -36,17 +35,19 @@ function mysql_connect(host::AbstractString,
end

"""
Wrapper over mysql_real_connect with CLIENT_MULTI_STATEMENTS passed
as client flag options.
mysql_connect(host::AbstractString, user::AbstractString, passwd::AbstractString, db::AbstractString = ""; opts = Dict())

Connect to a MySQL database.
"""
function mysql_connect(host::AbstractString, user::AbstractString,
passwd::AbstractString, db::AbstractString; opts = Dict())
function mysql_connect(host, user, passwd, db=""; opts = Dict())
return mysql_connect(host, user, passwd, db, convert(Cuint, 0),
convert(Ptr{Cchar}, C_NULL), CLIENT_MULTI_STATEMENTS, opts=opts)
end

"""
Wrapper over mysql_close. Must be called to close the connection opened by mysql_connect.
mysql_disconnect(hndl::MySQLHandle)

Close a handle to a MySQL database opened by `mysql_connect`.
"""
function mysql_disconnect(hndl)
hndl.mysqlptr == C_NULL && throw(MySQLInterfaceError("Method called with NULL connection."))
Expand Down Expand Up @@ -84,6 +85,14 @@ for func = (:mysql_field_count, :mysql_error, :mysql_insert_id)
end)
end

"""
mysql_insert_id(hndl::MySQLHandle) -> Int

Returns the value generated by auto increment column by the previous
insert / update statement.
"""
mysql_insert_id

# wrappers to take MySQLHandle as input as well as check for NULL pointer.
for func = (:mysql_query, :mysql_options)
eval(quote
Expand All @@ -96,6 +105,18 @@ for func = (:mysql_query, :mysql_options)
end)
end

"""
mysql_query(hndl::MySQLHandle, sql::AbstractString)

Executes a SQL statement. This function does not return query results or number of affected rows. Please use `mysql_execute` for such purposes.
"""
mysql_query

"""
mysql_store_result(hndl::MySQLHandle) -> MySQLResult

Returns a `MySQLResult` instance for a query executed with `mysql_query`.
"""
function mysql_store_result(hndl::MySQLHandle)
hndl.mysqlptr == C_NULL && throw(MySQLInterfaceError("Method called with NULL connection."))
ptr = mysql_store_result(hndl.mysqlptr)
Expand All @@ -104,22 +125,24 @@ function mysql_store_result(hndl::MySQLHandle)
end

"""
mysql_execute(hndl::MySQLHandle, command::AbstractString; opformat=MYSQL_DATA_FRAME)

A function for executing queries and getting results.

In the case of multi queries returns an array of number of affected
In the case of multi queries this function returns an array of number of affected
rows and DataFrames. The number of affected rows correspond to the
non-SELECT queries and the DataFrames for the SELECT queries in the
multi-query.

In the case of non-multi queries returns either the number of affected
In the case of non-multi queries this function returns either the number of affected
rows for non-SELECT queries or a DataFrame for SELECT queries.

By default, returns SELECT query results as DataFrames.
Set `opformat` to `MYSQL_TUPLES` to get results as tuples.
"""
function mysql_execute_query(con, command; opformat=MYSQL_DATA_FRAME)
con.mysqlptr == C_NULL && throw(MySQLInterfaceError("Method called with null connection."))
mysql_query(con.mysqlptr, command) != 0 && throw(MySQLInternalError(con))
function mysql_execute(hndl, command; opformat=MYSQL_DATA_FRAME)
hndl.mysqlptr == C_NULL && throw(MySQLInterfaceError("Method called with null connection."))
mysql_query(hndl.mysqlptr, command) != 0 && throw(MySQLInternalError(hndl))

data = Any[]

Expand All @@ -132,21 +155,21 @@ function mysql_execute_query(con, command; opformat=MYSQL_DATA_FRAME)
end

while true
result = mysql_store_result(con.mysqlptr)
result = mysql_store_result(hndl.mysqlptr)
if result != C_NULL # if select query
retval = convfunc(MySQLResult(con, result))
retval = convfunc(MySQLResult(hndl, result))
push!(data, retval)
mysql_free_result(result)

elseif mysql_field_count(con.mysqlptr) == 0
push!(data, @compat Int(mysql_affected_rows(con.mysqlptr)))
elseif mysql_field_count(hndl.mysqlptr) == 0
push!(data, @compat Int(mysql_affected_rows(hndl.mysqlptr)))
else
throw(MySQLInterfaceError("Query expected to produce results but did not."))
end

status = mysql_next_result(con.mysqlptr)
status = mysql_next_result(hndl.mysqlptr)
if status > 0
throw(MySQLInternalError(con))
throw(MySQLInternalError(hndl))
elseif status == -1 # if no more results
break
end
Expand All @@ -158,7 +181,12 @@ function mysql_execute_query(con, command; opformat=MYSQL_DATA_FRAME)
return data
end

function mysql_execute_query(hndl::MySQLHandle; opformat=MYSQL_DATA_FRAME)
"""
mysql_execute(hndl::MySQLHandle; opformat=MYSQL_DATA_FRAME)

Execute and get results for prepared statements. A statement must be prepared with `mysql_stmt_prepare` before calling this function.
"""
function mysql_execute(hndl::MySQLHandle; opformat=MYSQL_DATA_FRAME)
mysql_stmt_execute(hndl)
naff = mysql_stmt_affected_rows(hndl)
naff != typemax(typeof(naff)) && return naff # Not a SELECT query
Expand All @@ -171,11 +199,18 @@ function mysql_execute_query(hndl::MySQLHandle; opformat=MYSQL_DATA_FRAME)
end
end

function mysql_execute_query(hndl::MySQLHandle, typs, values;
opformat=MYSQL_DATA_FRAME)
"""
mysql_execute(hndl::MySQLHandle, typs, values; opformat=MYSQL_DATA_FRAME)

Execute and get results for prepared statements. A statement must be prepared with `mysql_stmt_prepare` before calling this function.

Parameters are passed to the query in the `values` array. The corresponding MySQL types must be mentioned in the `typs` array. See `MYSQL_TYPE_*` for a list of MySQL types.
"""
function mysql_execute(hndl::MySQLHandle, typs, values;
opformat=MYSQL_DATA_FRAME)
bindarr = mysql_bind_array(typs, values)
mysql_stmt_bind_param(hndl, bindarr)
return mysql_execute_query(hndl; opformat=opformat)
return mysql_execute(hndl; opformat=opformat)
end

for func = (:mysql_stmt_num_rows, :mysql_stmt_affected_rows,
Expand All @@ -188,6 +223,11 @@ for func = (:mysql_stmt_num_rows, :mysql_stmt_affected_rows,
end)
end

"""
mysql_stmt_prepare(hndl::MySQLHandle, command::AbstractString)

Creates a prepared statement with the `command` SQL string.
"""
function mysql_stmt_prepare(hndl::MySQLHandle, command)
hndl.stmtptr == C_NULL && throw(MySQLInterfaceError("Method called with NULL statement."))
val = mysql_stmt_prepare(hndl.stmtptr, command)
Expand Down Expand Up @@ -264,22 +304,32 @@ function mysql_bind_array(typs, params)
return bindarr
end

function MySQLResult(con, resptr)
res = MySQLResult(con, resptr)
function MySQLResult(hndl, resptr)
res = MySQLResult(hndl, resptr)
finalizer(ret, x -> mysql_free_result(res.resptr))
return res
end

"""
mysql_metadata(hndl::MySQLResult) -> MySQLMetadata

Get result metadata from a `MySQLResult` instance.
"""
function mysql_metadata(result::MySQLResult)
result.resptr == C_NULL && throw(MySQLInterfaceError("Method called with null result set."))
return MySQLMetadata(mysql_metadata(result.resptr))
end

"""
mysql_metadata(hndl::MySQLHandle) -> MySQLMetadata

Get result metadata for a query. The query must be prepared with `mysql_stmt_prepare` before calling this function.
"""
function mysql_metadata(hndl::MySQLHandle)
hndl.stmtptr == C_NULL && throw(MySQLInterfaceError("Method called with null statement pointer."))
return MySQLMetadata(mysql_metadata(hndl.stmtptr))
end

export mysql_options, mysql_connect, mysql_disconnect, mysql_execute_query,
export mysql_options, mysql_connect, mysql_disconnect, mysql_execute,
mysql_insert_id, mysql_store_result, mysql_metadata, mysql_query,
mysql_stmt_prepare
4 changes: 0 additions & 4 deletions src/results.jl
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,6 @@ function mysql_load_string_from_resultptr(result, idx)
return strval
end

"""
Returns an array of MYSQL_FIELD. This array contains metadata information such
as field type and field length etc. (see types.jl)
"""
function mysql_metadata(result::MYSQL_RES)
nfields = mysql_num_fields(result)
rawfields = mysql_fetch_fields(result)
Expand Down
4 changes: 2 additions & 2 deletions test/test_basic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ end

function show_results()
command = """SELECT * FROM Employee;"""
dframe = mysql_execute_query(hndl, command)
dframe = mysql_execute(hndl, command)
println("\n *** Results as Dataframe: \n", dframe)
println("\n *** Expected Result: \n", DataFrameResults)
@test dfisequal(dframe, DataFrameResults)
Expand All @@ -79,7 +79,7 @@ function show_results()
end

println("\n *** Results as tuples: \n")
tupres = mysql_execute_query(hndl, command; opformat=MYSQL_TUPLES)
tupres = mysql_execute(hndl, command; opformat=MYSQL_TUPLES)
println(tupres)
for i in length(tupres)
@test compare_rows(tupres[i], ArrayResults[i])
Expand Down
6 changes: 3 additions & 3 deletions test/test_common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,12 @@ function drop_test_database()
end

function init_test()
mysql_execute_query(hndl, "DROP DATABASE IF EXISTS mysqltest;")
mysql_execute(hndl, "DROP DATABASE IF EXISTS mysqltest;")
# There seems to be a bug in MySQL that prevents you
# from saying "DROP USER IF EXISTS test@127.0.0.1;"
# So here we create a user with a harmless privilege and drop the user.
mysql_execute_query(hndl, "GRANT USAGE ON *.* TO 'test'@'127.0.0.1';")
mysql_execute_query(hndl, "DROP USER 'test'@'127.0.0.1';")
mysql_execute(hndl, "GRANT USAGE ON *.* TO 'test'@'127.0.0.1';")
mysql_execute(hndl, "DROP USER 'test'@'127.0.0.1';")
end

function run_test()
Expand Down
4 changes: 2 additions & 2 deletions test/test_multiquery.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ function run_test()
DROP DATABASE test_db"""

# Run twice: Related to an earlier bug where 2nd run was failing.
mysql_execute_query(hndl, query)
data = mysql_execute_query(hndl, query)
mysql_execute(hndl, query)
data = mysql_execute(hndl, query)

@show data

Expand Down
Loading