8000 Merge pull request #1 from mauricio/master · olksdr/postgresql-async@9bd2427 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9bd2427

Browse files
committed
Merge pull request #1 from mauricio/master
update from the upstream
2 parents 6148f68 + 7e3937e commit 9bd2427

File tree

57 files changed

+1238
-252
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1238
-252
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
databases/*
12
out/*
23
generate_bundles.rb
34
.cache

.travis.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
language: scala
22
scala:
33
- 2.10.4
4-
- 2.11.0
4+
- 2.11.7
55
jdk:
66
- oraclejdk7
7-
- openjdk7
7+
- oraclejdk8
88
services:
99
- postgresql
1010
- mysql
11+
cache:
12+
directories:
13+
- vendor/bundle
14+
- $HOME/.m2
15+
- $HOME/.ivy2
16+
- $HOME/.sbt
1117
before_script:
1218
- ./script/prepare_build.sh
1319

CHANGELOG.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
**Table of Contents**
44

55
- [Changelog](#changelog)
6+
- [0.2.17 - in progresss](#0217---in-progresss)
7+
- [0.2.16 - 2015-01-04](#0216---2015-01-04)
8+
- [0.2.15 - 2014-09-12](#0215---2014-09-12)
69
- [0.2.14 - 2014-08-30](#0214---2014-08-30)
710
- [0.2.13 - 2014-04-07](#0213---2014-04-07)
811
- [0.2.12 - 2014-01-11](#0212---2014-01-11)
@@ -22,7 +25,25 @@
2225

2326
# Changelog
2427

25-
## 0.2.15 - still in progress
28+
## 0.2.18 - 2015-08-08
29+
30+
* Timeouts implemented queries for MySQL and PostgreSQL - @lifey - #147
31+
32+
## 0.2.17 - 2015-07-13
33+
34+
* Fixed pool leak issue - @haski
35+
* Fixed date time formatting issue - #142
36+
37+
## 0.2.16 - 2015-01-04
38+
39+
* Add support to byte arrays for PostgreSQL 8 and older - @SattaiLanfear - #21;
40+
* Make sure connections are returned to the pool before the result is returned to the user - @haski - #119;
41+
* Support to `SEND_LONG_DATA` to MySQL - @mst-appear - #115;
42+
* Support for `ByteBuffer` and `ByteBuf` for binary data - @mst-appear - #113 #112;
43+
* Fixed encoding backslashes in PostgreSQL arrays - @dylex - #110;
44+
* Included `escape` encoding method for bytes in PostgreSQL - @SattaiLanfear - #107;
45+
46+
## 0.2.15 - 2014-09-12
2647

2748
* Fixes issue where PostgreSQL decoders fail to produce a NULL value if the null is wrapped by a `Some` instance - #99;
2849
* Fixes issue where the 253 case of length encoded fields on MySQL produce a wrong value;

Procfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
postgresql: postgres -D /Users/mauricio/databases/postgresql
1+
postgresql: postgres -D databases/postgresql
22
mysql: mysqld --log-warnings --console

README.markdown

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
- [Prepared statements](#prepared-statements)
1818
- [Transactions](#transactions)
1919
- [Example usage (for PostgreSQL, but it looks almost the same on MySQL)](#example-usage-for-postgresql-but-it-looks-almost-the-same-on-mysql)
20+
- [LISTEN/NOTIFY support (PostgreSQL only)](#listennotify-support-postgresql-only)
2021
- [Contributing](#contributing)
2122
- [Licence](#licence)
2223

@@ -45,13 +46,15 @@ You can view the project's [CHANGELOG here](CHANGELOG.md).
4546
driver allowing you to write less SQL and make use of a nice high level database access API;
4647
* [mod-mysql-postgresql](https://github.com/vert-x/mod-mysql-postgresql) - [vert.x](http://vertx.io/) module that integrates
4748
the driver into a vert.x application;
49+
* [dbmapper](https://github.com/njeuk/dbmapper) - enables SQL queries with automatic mapping from the database table to the Scala
50+
class and a mechanism to create a Table Date Gateway model with very little boiler plate code;
4851

4952
## Include them as dependencies
5053

5154
And if you're in a hurry, you can include them in your build like this, if you're using PostgreSQL:
5255

5356
```scala
54-
"com.github.mauricio" %% "postgresql-async" % "0.2.14"
57 F41A +
"com.github.mauricio" %% "postgresql-async" % "0.2.18"
5558
```
5659

5760
Or Maven:
@@ -60,14 +63,14 @@ Or Maven:
6063
<dependency>
6164
<groupId>com.github.mauricio</groupId>
6265
<artifactId>postgresql-async_2.11</artifactId>
63-
<version>0.2.14</version>
66+
<version>0.2.18</version>
6467
</dependency>
6568
```
6669

6770
And if you're into MySQL:
6871

6972
```scala
70-
"com.github.mauricio" %% "mysql-async" % "0.2.14"
73+
"com.github.mauricio" %% "mysql-async" % "0.2.18"
7174
```
7275

7376
Or Maven:
@@ -76,7 +79,7 @@ Or Maven:
7679
<dependency>
7780
<groupId>com.github.mauricio</groupId>
7881
<artifactId>mysql-async_2.11</artifactId>
79-
<version>0.2.14</version>
82+
<version>0.2.18</version>
8083
</dependency>
8184
```
8285

@@ -267,6 +270,21 @@ disconnect and the connection is closed.
267270
You can also use the `ConnectionPool` provided by the driver to simplify working with database connections in your app.
268271
Check the blog post above for more details and the project's ScalaDocs.
269272

273+
## LISTEN/NOTIFY support (PostgreSQL only)
274+
275+
LISTEN/NOTIFY is a PostgreSQL-specific feature for database-wide publish-subscribe scenarios. You can listen to database
276+
notifications as such:
277+
278+
```scala
279+
val connection: Connection = ...
280+
281+
connection.sendQuery("LISTEN my_channel")
282+
connection.registerNotifyListener {
283+
message =>
284+
println(s"channel: ${message.channel}, payload: ${message.payload}")
285+
}
286+
```
287+
270288
## Contributing
271289

272290
Contributing to the project is simple, fork it on Github, hack on what you're insterested in seeing done or at the

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# postgresql-async
2+
3+
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mauricio/postgresql-async?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

db-async-common/src/main/scala/com/github/mauricio/async/db/Configuration.scala

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@
1717
package com.github.mauricio.async.db
1818

1919
import java.nio.charset.Charset
20-
import scala.Predef._
21-
import scala.{None, Option, Int}
20+
21+
import io.netty.buffer.{ByteBufAllocator, PooledByteBufAllocator}
2222
import io.netty.util.CharsetUtil
23-
import io.netty.buffer.AbstractByteBufAllocator
24-
import io.netty.buffer.PooledByteBufAllocator
23+
2524
import scala.concurrent.duration._
2625

2726
object Configuration {
@@ -44,6 +43,11 @@ object Configuration {
4443
* OOM or eternal loop attacks the client could have, defaults to 16 MB. You can set this
4544
* to any value you would like but again, make sure you know what you are doing if you do
4645
* change it.
46+
* @param allocator the netty buffer allocator to be used
47+
* @param connectTimeout the timeout for connecting to servers
48+
* @param testTimeout the timeout for connection tests performed by pools
49+
* @param queryTimeout the optional query timeout
50+
*
4751
*/
4852

4953
case class Configuration(username: String,
@@ -53,7 +57,7 @@ case class Configuration(username: String,
5357
database: Option[String] = None,
5458
charset: Charset = Configuration.DefaultCharset,
5559
maximumMessageSize: Int = 16777216,
56-
allocator: AbstractByteBufAllocator = PooledByteBufAllocator.DEFAULT,
60+
allocator: ByteBufAllocator = PooledByteBufAllocator.DEFAULT,
5761
connectTimeout: Duration = 5.seconds,
58-
testTimeout: Duration = 5.seconds
59-
)
62+
testTimeout: Duration = 5.seconds,
63+
queryTimeout: Option[Duration] = None)

db-async-common/src/main/scala/com/github/mauricio/async/db/column/TimeEncoderDecoder.scala

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,16 @@ class TimeEncoderDecoder extends ColumnEncoderDecoder {
3333
.appendOptional(optional)
3434
.toFormatter
3535

36+
final private val printer = new DateTimeFormatterBuilder()
37+
.appendPattern("HH:mm:ss.SSSSSS")
38+
.toFormatter
39+
3640
def formatter = format
3741

38-
override def decode(value: String): LocalTime = {
42+
override def decode(value: String): LocalTime =
3943
format.parseLocalTime(value)
40-
}
4144

42-
override def encode(value: Any): String = {
43-
this.format.print(value.asInstanceOf[LocalTime])
44-
}
45+
override def encode(value: Any): String =
46+
this.printer.print(value.asInstanceOf[LocalTime])
4547

4648
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2013 Maurício Linhares
3+
*
4+
* Maurício Linhares licenses this file to you under the Apache License,
5+
* version 2.0 (the "License"); you may not use this file except in compliance
6+
* with the License. You may obtain a copy of the License at:
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations
14+
* under the License.
15+
*/
16+
17+
package com.github.mauricio.async.db.column
18+
19+
import java.util.UUID
20+
21+
object UUIDEncoderDecoder extends ColumnEncoderDecoder {
22+
23+
override def decode(value: String): UUID = UUID.fromString(value)
24+
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.github.mauricio.async.db.exceptions
2+
3+
import com.github.mauricio.async.db.Connection
4+
5+
class ConnectionTimeoutedException( val connection : Connection )
6+
extends DatabaseException( "The connection %s has a timeouted query and is being closed".format(connection) )

db-async-common/src/main/scala/com/github/mauricio/async/db/general/ArrayRowData.scala

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,10 @@
1717
package com.github.mauricio.async.db.general
1818

1919
import com.github.mauricio.async.db.RowData
20-
import scala.collection.mutable
2120

22-
class ArrayRowData( columnCount : Int, row : Int, val mapping : Map[String, Int] )
23-
extends RowData
21+
class ArrayRowData(row : Int, val mapping : Map[String, Int], val columns : Array[Any]) extends RowData
2422
{
2523

26-
private val columns = new Array[Any](columnCount)
27-
2824
/**
2925
*
3026
* Returns a column value by it's position in the originating query.
@@ -51,16 +47,5 @@ class ArrayRowData( columnCount : Int, row : Int, val mapping : Map[String, Int]
5147
*/
5248
def rowNumber: Int = row
5349

54-
/**
55-
*
56-
* Sets a value to a column in this collection.
57-
*
58-
* @param i
59-
* @param x
60-
*/
61-
62-
def update(i: Int, x: Any) = columns(i) = x
63-
6450
def length: Int = columns.length
65-
6651
}

db-async-common/src/main/scala/com/github/mauricio/async/db/general/MutableResultSet.scala

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,18 @@ class MutableResultSet[T <: ColumnData](
3131
private val columnMapping: Map[String, Int] = this.columnTypes.indices.map(
3232
index =>
3333
( this.columnTypes(index).name, index ) ).toMap
34-
34+
3535

3636
val columnNames : IndexedSeq[String] = this.columnTypes.map(c => c.name)
3737

38+
val types : IndexedSeq[Int] = this.columnTypes.map(c => c.dataType)
39+
3840
override def length: Int = this.rows.length
3941

4042
override def apply(idx: Int): RowData = this.rows(idx)
4143
42-
def addRow( row : Seq[Any] ) {
43-
val realRow = new ArrayRowData( columnTypes.size, this.rows.size, this.columnMapping )
44-
var x = 0
45-
while ( x < row.size ) {
46-
realRow(x) = row(x)
47-
x += 1
48-
}
49-
this.rows += realRow
44+
def addRow(row : Array[Any] ) {
45+
this.rows += new ArrayRowData(this.rows.size, this.columnMapping, row)
5046
}
5147

52-
}
48+
}

db-async-common/src/main/scala/com/github/mauricio/async/db/pool/AsyncObjectPool.scala

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
package com.github.mauricio.async.db.pool
1818

19-
import scala.concurrent.Future
19+
import scala.concurrent.{ExecutionContext, Future, Promise}
2020

2121
/**
2222
*
@@ -70,11 +70,26 @@ trait AsyncObjectPool[T] {
7070
* @return f wrapped with take and giveBack
7171
*/
7272

73-
def use[A](f : T => Future[A])(implicit executionContext : scala.concurrent.ExecutionContext) : Future[A] =
73+
def use[A](f: (T) => Future[A])(implicit executionContext: ExecutionContext): Future[A] =
7474
take.flatMap { item =>
75-
f(item).andThen { case _ =>
76-
giveBack(item)
75+
val p = Promise[A]()
76+
try {
77+
f(item).onComplete { r =>
78+
giveBack(item).onComplete { _ =>
79+
p.complete(r)
80+
}
81+
}
82+
} catch {
83+
// calling f might throw exception.
84+
// in that case the item will be removed from the pool if identified as invalid by the factory.
85+
// the error returned to the user is the original error thrown by f.
86+
case error: Throwable =>
87+
giveBack(item).onComplete { _ =>
88+
p.failure(error)
89+
}
7790
}
91+
92+
p.future
7893
}
7994

8095
}

0 commit comments

Comments
 (0)
0