Skip to content

Commit

Permalink
Docstrings for everything
Browse files Browse the repository at this point in the history
  • Loading branch information
iamed2 committed Feb 6, 2018
1 parent cd93fc5 commit 159fc66
Show file tree
Hide file tree
Showing 5 changed files with 360 additions and 62 deletions.
120 changes: 117 additions & 3 deletions docs/src/pages/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,121 @@ DocTestSetup = quote
end
```

```@autodocs
Modules = [LibPQ]
Pages = ["LibPQ.jl", "utils.jl", "datastreams.jl"]
## Public

### Connections

```@docs
LibPQ.Connection
execute
prepare
status(::Connection)
Base.close(::Connection)
Base.isopen(::Connection)
reset!(::Connection)
Base.show(::IO, ::Connection)
```

### Results

```@docs
LibPQ.Result
status(::Result)
clear!(::Result)
num_rows(::Result)
num_columns(::Result)
Base.show(::IO, ::Result)
```

### Statements

```@docs
LibPQ.Statement
num_columns(::Statement)
num_params(::Statement)
Base.show(::IO, ::Statement)
```

### DataStreams Integration

```@docs
LibPQ.Statement(::LibPQ.DataStreams.Data.Schema, ::Type{LibPQ.DataStreams.Data.Row}, ::Bool, ::Connection, ::AbstractString)
LibPQ.fetch!
```

## Internals

### Connections

```@docs
LibPQ.handle_new_connection
LibPQ.server_version
LibPQ.encoding
LibPQ.set_encoding!
LibPQ.reset_encoding!
LibPQ.transaction_status
LibPQ.unique_id
LibPQ.error_message(::Connection)
```

### Connection Info

```@docs
LibPQ.ConnectionOption
LibPQ.conninfo
LibPQ.ConninfoDisplay
Base.parse(::Type{LibPQ.ConninfoDisplay}, ::AbstractString)
```

### Results and Statements

```@docs
LibPQ.handle_result
LibPQ.column_name
LibPQ.column_names
LibPQ.column_number
LibPQ.column_oids
LibPQ.column_types
LibPQ.num_params(::Result)
LibPQ.error_message(::Result)
```

### Type Conversions

```@docs
LibPQ.oid
LibPQ.PQChar
LibPQ.PQ_SYSTEM_TYPES
LibPQ.PQTypeMap
Base.getindex(::LibPQ.PQTypeMap, typ)
Base.setindex!(::LibPQ.PQTypeMap, ::Type, typ)
LibPQ._DEFAULT_TYPE_MAP
LibPQ.LIBPQ_TYPE_MAP
LibPQ.PQConversions
Base.getindex(::LibPQ.PQConversions, oid_typ::Tuple{Any, Type})
Base.setindex!(::LibPQ.PQConversions, ::Base.Callable, oid_typ::Tuple{Any, Type})
LibPQ._DEFAULT_CONVERSIONS
LibPQ.LIBPQ_CONVERSIONS
LibPQ._FALLBACK_CONVERSION
```

### Parsing

```@docs
LibPQ.PQValue
LibPQ.data_pointer
LibPQ.num_bytes
Base.unsafe_string(::LibPQ.PQValue)
LibPQ.string_view
LibPQ.bytes_view
Base.parse(::Type{Any}, pqv::LibPQ.PQValue)
```

### Miscellaneous

```@docs
LibPQ.@pqv_str
LibPQ.string_parameters
LibPQ.parameter_pointers
LibPQ.unsafe_string_or_null
```
60 changes: 53 additions & 7 deletions src/LibPQ.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@ module LibPQ

export Connection, Result, Statement
export status, reset!, execute, clear, fetch!, prepare,
server_version, @pqv_str,
encoding, set_encoding!, reset_encoding!,
num_columns, num_rows, num_params,
column_name, column_names, column_number

export PQChar
num_columns, num_rows, num_params

using Compat.Dates
using DocStringExtensions
Expand Down Expand Up @@ -55,7 +50,22 @@ using .libpq_c

include("typemaps.jl")

"""
const LIBPQ_TYPE_MAP::PQTypeMap
The [`PQTypeMap`](@ref) containing LibPQ-level type mappings for LibPQ.jl.
Adding type mappings to this constant will override the default type mappings for all code
using LibPQ.jl.
"""
const LIBPQ_TYPE_MAP = PQTypeMap()

"""
const LIBPQ_CONVERSIONS::PQConversions
The [`PQConversions`](@ref) containing LibPQ-level conversion functions for LibPQ.jl.
Adding conversions to this constant will override the default conversions for all code using
LibPQ.jl.
"""
const LIBPQ_CONVERSIONS = PQConversions()

### CONNECTIONS BEGIN
Expand Down Expand Up @@ -178,6 +188,22 @@ function Connection(str::AbstractString; throw_error::Bool=true, kwargs...)
)
end

"""
Connection(f, args...; kwargs...) -> Connection
A utility method to support `do` syntax.
Constructs the `Connection`, calls `f` on it, then closes it.
"""
function Connection(f::Base.Callable, args...; kwargs...)
jl_conn = Connection(args...; kwargs...)

try
return f(jl_conn)
finally
close(jl_conn)
end
end

"""
server_version(jl_conn::Connection) -> VersionNumber
Expand Down Expand Up @@ -221,6 +247,8 @@ Parse a PostgreSQL version.
## Examples
```jldoctest
julia> using LibPQ: @pqv_str
julia> pqv"10.1" == v"10.0.1"
true
Expand Down Expand Up @@ -953,6 +981,9 @@ struct Statement
"An autogenerated neame for the prepared statement (using [`unique_id`](@ref)"
name::String

"The query string of the prepared statement"
query::String

"A `Result` containing a description of the prepared statement"
description::Result

Expand Down Expand Up @@ -995,7 +1026,22 @@ function prepare(jl_conn::Connection, query::AbstractString)
throw_error=true,
)

Statement(jl_conn, uid, description, num_params(description))
Statement(jl_conn, uid, query, description, num_params(description))
end

"""
show(io::IO, jl_result::Statement)
Show a PostgreSQL prepared statement and its query.
"""
function Base.show(io::IO, stmt::Statement)
print(
io,
"PostgreSQL prepared statement named ",
stmt.name,
" with query ",
stmt.query,
)
end

"""
Expand Down
83 changes: 77 additions & 6 deletions src/parsing.jl
Original file line number Diff line number Diff line change
@@ -1,36 +1,94 @@
# wrapper for value
"A wrapper for one value in a PostgreSQL result."
struct PQValue{OID}
"PostgreSQL result"
jl_result::Result

# 0-indexed
"Row index of the result (0-indexed)"
row::Cint

"Column index of the result (0-indexed)"
col::Cint

function PQValue{OID}(jl_result::Result, row::Integer, col::Integer) where OID
return new{OID}(jl_result, row - 1, col - 1)
end
end

"""
PQValue(jl_result::Result, row::Integer, col::Integer) -> PQValue
PQValue{OID}(jl_result::Result, row::Integer, col::Integer) -> PQValue{OID}
Construct a `PQValue` wrapping one value in a PostgreSQL result.
Row and column positions are provided 1-indexed.
If the `OID` type parameter is not provided, the Oid of the field will be retrieved from
the result.
"""
function PQValue(jl_result::Result, row::Integer, col::Integer)
oid = libpq_c.PQftype(jl_result.result, col - 1)

return PQValue{oid}(jl_result, row, col)
end

# strlen
"""
num_bytes(pqv::PQValue) -> Cint
The length in bytes of the `PQValue`'s corresponding data.
LibPQ.jl currently always uses text format, so this is equivalent to C's `strlen`.
See also: [`data_pointer`](@ref)
"""
num_bytes(pqv::PQValue) = libpq_c.PQgetlength(pqv.jl_result.result, pqv.row, pqv.col)

"""
data_pointer(pqv::PQValue) -> Ptr{UInt8}
Get a raw pointer to the data for one value in a PostgreSQL result.
This data will be freed by libpq when the result is cleared, and should only be used
temporarily.
"""
data_pointer(pqv::PQValue) = libpq_c.PQgetvalue(pqv.jl_result.result, pqv.row, pqv.col)

"""
unsafe_string(pqv::PQValue) -> String
Construct a `String` from a `PQValue` by copying the data.
"""
function Base.unsafe_string(pqv::PQValue)
return unsafe_string(data_pointer(pqv), num_bytes(pqv))
end

"""
string_view(pqv::PQValue) -> String
Wrap a `PQValue`'s underlying data in a `String`.
This function uses [`data_pointer`](@ref) and [`num_bytes`](@ref) and does not copy.
!!! note
The underlying data will be freed by libpq when the result is cleared, and should only
be used temporarily.
See also: [`bytes_view`](@ref)
"""
function string_view(pqv::PQValue)
return String(unsafe_wrap(Vector{UInt8}, data_pointer(pqv), num_bytes(pqv)))
end

# includes null
"""
bytes_view(pqv::PQValue) -> Vector{UInt8}
Wrap a `PQValue`'s underlying data in a vector of bytes.
This function uses [`data_pointer`](@ref) and [`num_bytes`](@ref) and does not copy.
This function differs from [`string_view`](@ref) as it keeps the `\0` byte at the end.
`PQValue` parsing functions should use `bytes_view` when the data returned by PostgreSQL
is not in UTF-8.
!!! note
The underlying data will be freed by libpq when the result is cleared, and should only
be used temporarily.
"""
bytes_view(pqv::PQValue) = unsafe_wrap(Vector{UInt8}, data_pointer(pqv), num_bytes(pqv) + 1)

Base.String(pqv::PQValue) = unsafe_string(pqv)
Expand All @@ -39,7 +97,16 @@ Base.convert(::Type{String}, pqv::PQValue) = String(pqv)
Base.length(pqv::PQValue) = length(string_view(pqv))
Base.endof(pqv::PQValue) = endof(string_view(pqv))

# fallback, because Base is bad with string iteration
# Fallback, because Base requires string iteration state to be indices into the string.
# In an ideal world, PQValue would be an AbstractString and this particular method would
# not be necessary.
"""
parse(::Type{T}, pqv::PQValue) -> T
Parse a value of type `T` from a `PQValue`.
By default, this uses any existing `parse` method for parsing a value of type `T` from a
`String`.
"""
Base.parse(::Type{T}, pqv::PQValue) where {T} = parse(T, string_view(pqv))

# allow parsing as a Symbol anything which works as a String
Expand Down Expand Up @@ -256,7 +323,6 @@ for pq_eltype in ("int2", "int4", "int8", "float4", "float8", "oid", "numeric")
end
end


struct FallbackConversion <: AbstractDict{Tuple{Oid, Type}, Base.Callable}
end

Expand All @@ -270,4 +336,9 @@ end

Base.haskey(cmap::FallbackConversion, oid_typ::Tuple{Integer, Type}) = true

"""
A fallback conversion mapping (like [`PQConversions`](@ref) which holds a single function
for converting PostgreSQL data of a given Oid to a given Julia type, using the [`parse`](@ref)
function.
"""
const _FALLBACK_CONVERSION = FallbackConversion()
Loading

0 comments on commit 159fc66

Please sign in to comment.