Skip to content

Commit 004c16e

Browse files
committed
update swift-mongodb to get withTemporaryDatabase fix, add test cases for packages.json generation
1 parent 0a4ddb7 commit 004c16e

13 files changed

+257
-89
lines changed

Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ let package:Package = .init(
7373
.package(url: "https://github.com/tayloraswift/swift-grammar", .upToNextMinor(
7474
from: "0.3.2")),
7575
.package(url: "https://github.com/tayloraswift/swift-mongodb", .upToNextMinor(
76-
from: "0.8.0")),
76+
from: "0.8.1")),
7777

7878
.package(url: "https://github.com/swift-server/swift-backtrace", .upToNextMinor(
7979
from: "1.3.4")),

Sources/UnidocDatabase/Packages/PackageDatabase.Editions.Placement.swift

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,38 @@ extension PackageDatabase.Editions
77
{
88
struct Placement
99
{
10-
let cell:Int32
10+
let coordinate:Int32
1111
let sha1:SHA1?
12+
let new:Bool
1213

13-
init(cell:Int32, sha1:SHA1?)
14+
init(coordinate:Int32, sha1:SHA1?, new:Bool)
1415
{
15-
self.cell = cell
16+
self.coordinate = coordinate
1617
self.sha1 = sha1
18+
self.new = new
1719
}
1820
}
1921
}
2022
extension PackageDatabase.Editions.Placement
2123
{
2224
static
23-
var first:Self { .init(cell: 0, sha1: nil) }
25+
var first:Self { .init(coordinate: 0, sha1: nil, new: true) }
2426
}
2527
extension PackageDatabase.Editions.Placement:MongoMasterCodingModel
2628
{
2729
enum CodingKey:String
2830
{
29-
case cell
31+
case coordinate
3032
case sha1
33+
case new
3134
}
3235
}
3336
extension PackageDatabase.Editions.Placement:BSONDocumentDecodable
3437
{
3538
init(bson:BSON.DocumentDecoder<CodingKey, some RandomAccessCollection<UInt8>>) throws
3639
{
37-
self.init(cell: try bson[.cell].decode(), sha1: try bson[.sha1]?.decode())
40+
self.init(coordinate: try bson[.coordinate].decode(),
41+
sha1: try bson[.sha1]?.decode(),
42+
new: try bson[.new].decode())
3843
}
3944
}

Sources/UnidocDatabase/Packages/PackageDatabase.Editions.swift

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,12 @@ extension PackageDatabase.Editions
8888
package:Int32,
8989
with session:Mongo.Session) async throws -> Int32?
9090
{
91-
let allocation:Placement = try await self.register(package: package,
91+
let placement:Placement = try await self.register(package: package,
9292
refname: tag.name,
9393
sha1: tag.hash,
9494
with: session)
9595

96-
return allocation.sha1 == nil ? allocation.cell : nil
96+
return placement.new ? placement.coordinate : nil
9797
}
9898

9999
func register(
@@ -102,31 +102,46 @@ extension PackageDatabase.Editions
102102
sha1:SHA1?,
103103
with session:Mongo.Session) async throws -> Placement
104104
{
105+
// Placement involves autoincrement, which is why this cannot be done in an update.
105106
let placement:Placement = try await self.place(
106107
package: package,
107108
refname: refname,
108109
with: session)
109110

110111
let edition:PackageEdition = .init(id: .init(
111112
package: package,
112-
version: placement.cell),
113+
version: placement.coordinate),
113114
name: refname,
114115
sha1: sha1)
115116

116-
switch placement.sha1
117+
if placement.new
117118
{
118-
case nil:
119119
// This can fail if we race with another process.
120120
try await self.insert(edition, with: session)
121+
}
122+
else if let sha1:SHA1
123+
{
124+
switch placement.sha1
125+
{
126+
case nil:
127+
// If the edition would gain a hash, we should update it.
121128

122-
case sha1:
123-
try await self.update(edition, with: session)
129+
// FIXME: this can race another update, in which case we will store an
130+
// arbitrary choice of hash without marking the edition dirty.
131+
// We should use `placement.sha1` as a hint to skip the update only,
132+
// and set the dirty flag within a custom update statement.
133+
try await self.update(edition, with: session)
124134

125-
case _?:
126-
try await self.update(field: PackageEdition[.lost],
127-
of: edition.id,
128-
to: true,
129-
with: session)
135+
case sha1?:
136+
// Nothing to do.
137+
break
138+
139+
case _?:
140+
try await self.update(field: PackageEdition[.lost],
141+
of: edition.id,
142+
to: true,
143+
with: session)
144+
}
130145
}
131146

132147
return placement
@@ -171,8 +186,9 @@ extension PackageDatabase.Editions
171186
{
172187
$0[.replaceWith] = .init
173188
{
174-
$0[Placement[.cell]] = PackageEdition[.version]
189+
$0[Placement[.coordinate]] = PackageEdition[.version]
175190
$0[Placement[.sha1]] = PackageEdition[.sha1]
191+
$0[Placement[.new]] = false
176192
}
177193
}
178194
}
@@ -193,10 +209,11 @@ extension PackageDatabase.Editions
193209
{
194210
$0[.replaceWith] = .init
195211
{
196-
$0[Placement[.cell]] = .expr
212+
$0[Placement[.coordinate]] = .expr
197213
{
198214
$0[.add] = (PackageEdition[.version], 1)
199215
}
216+
$0[Placement[.new]] = true
200217
}
201218
}
202219
}

Sources/UnidocDatabase/Packages/PackageDatabase.Packages.Placement.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,27 @@ extension PackageDatabase.Packages
66
{
77
struct Placement
88
{
9-
let cell:Int32
9+
let coordinate:Int32
1010
var repo:PackageRepo?
1111
var new:Bool
1212

13-
init(cell:Int32, repo:PackageRepo?, new:Bool)
13+
init(coordinate:Int32, repo:PackageRepo?, new:Bool)
1414
{
15-
self.cell = cell
15+
self.coordinate = coordinate
1616
self.new = new
1717
}
1818
}
1919
}
2020
extension PackageDatabase.Packages.Placement
2121
{
2222
static
23-
var first:Self { .init(cell: 0, repo: nil, new: true) }
23+
var first:Self { .init(coordinate: 0, repo: nil, new: true) }
2424
}
2525
extension PackageDatabase.Packages.Placement:MongoMasterCodingModel
2626
{
2727
enum CodingKey:String
2828
{
29-
case cell
29+
case coordinate
3030
case repo
3131
case new
3232
}
@@ -36,7 +36,7 @@ extension PackageDatabase.Packages.Placement:BSONDocumentDecodable
3636
init(bson:BSON.DocumentDecoder<CodingKey, some RandomAccessCollection<UInt8>>) throws
3737
{
3838
self.init(
39-
cell: try bson[.cell].decode(),
39+
coordinate: try bson[.coordinate].decode(),
4040
repo: try bson[.repo]?.decode(),
4141
new: try bson[.new].decode())
4242
}

Sources/UnidocDatabase/Packages/PackageDatabase.Packages.swift

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,44 +44,36 @@ extension PackageDatabase.Packages:DatabaseCollection
4444
}
4545
extension PackageDatabase.Packages
4646
{
47-
/// Registers the given package identifier in the database, returning its cell.
48-
/// This is really just a glorified string internment system.
47+
/// Registers the given package identifier in the database, returning its package
48+
/// coordinate. This is really just a glorified string internment system.
4949
///
5050
/// This function can be expensive. It only makes one query if the package is already
5151
/// registered, but can take two round trips to intern the identifier otherwise.
52-
public
5352
func register(_ package:PackageIdentifier,
54-
with session:Mongo.Session) async throws -> Int32
55-
{
56-
try await self.register(package, updating: nil, tracking: nil, with: session).cell
57-
}
58-
59-
func register(_ package:PackageIdentifier,
60-
updating meta:PackageDatabase.Meta?,
53+
updating meta:PackageDatabase.Meta,
6154
tracking repo:PackageRepo?,
6255
with session:Mongo.Session) async throws -> Placement
6356
{
57+
// Placement involves autoincrement, which is why this cannot be done in an update.
6458
var placement:Placement = try await self.place(package: package, with: session)
65-
let record:PackageRecord = .init(id: package, cell: placement.cell, repo: repo)
59+
var record:PackageRecord
60+
{
61+
.init(id: package, cell: placement.coordinate, repo: repo)
62+
}
6663

6764
if placement.new
6865
{
6966
// This can fail if we race with another process.
7067
try await self.insert(record, with: session)
71-
68+
// Regenerate the JSON list of all packages.
69+
try await meta.upsert(try await self.scan(with: session), with: session)
7270
}
73-
else if case _? = repo
71+
else if let repo:PackageRepo, repo != placement.repo
7472
{
7573
try await self.update(record, with: session)
7674
placement.repo = repo
7775
}
7876

79-
if let meta:PackageDatabase.Meta, placement.new
80-
{
81-
// Update the list of all packages.
82-
try await meta.upsert(try await self.scan(with: session), with: session)
83-
}
84-
8577
return placement
8678
}
8779

@@ -104,7 +96,7 @@ extension PackageDatabase.Packages
10496
{
10597
$0[.replaceWith] = .init
10698
{
107-
$0[Placement[.cell]] = PackageRecord[.cell]
99+
$0[Placement[.coordinate]] = PackageRecord[.cell]
108100
$0[Placement[.repo]] = PackageRecord[.repo]
109101
$0[Placement[.new]] = false
110102
}
@@ -131,7 +123,7 @@ extension PackageDatabase.Packages
131123
{
132124
$0[.replaceWith] = .init
133125
{
134-
$0[Placement[.cell]] = .expr
126+
$0[Placement[.coordinate]] = .expr
135127
{
136128
$0[.add] = (PackageRecord[.cell], 1)
137129
}
@@ -146,7 +138,7 @@ extension PackageDatabase.Packages
146138
{
147139
$0[.sort] = .init
148140
{
149-
$0[Placement[.cell]] = (+)
141+
$0[Placement[.coordinate]] = (+)
150142
}
151143
}
152144
$0.stage

Sources/UnidocDatabase/Packages/PackageDatabase.swift

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,25 @@ extension PackageDatabase:DatabaseModel
5050
}
5151
extension PackageDatabase
5252
{
53+
@_spi(testable)
54+
public
55+
func track(package:PackageIdentifier,
56+
with session:Mongo.Session) async throws -> Int32
57+
{
58+
try await self.packages.register(package,
59+
updating: self.meta,
60+
tracking: nil,
61+
with: session).coordinate
62+
}
63+
5364
public
5465
func track(repo:GitHubAPI.Repo, with session:Mongo.Session) async throws -> Int32
5566
{
5667
/// Currently, package identifiers are just the name of the repository.
5768
try await self.packages.register(.init(repo.name),
5869
updating: self.meta,
5970
tracking: .github(repo),
60-
with: session).cell
71+
with: session).coordinate
6172
}
6273

6374
public
@@ -66,7 +77,7 @@ extension PackageDatabase
6677
{
6778
let placement:Packages.Placement = try await self.packages.register(
6879
docs.metadata.package,
69-
updating: nil,
80+
updating: self.meta,
7081
tracking: nil,
7182
with: session)
7283

@@ -75,31 +86,31 @@ extension PackageDatabase
7586
if let commit:SymbolGraphMetadata.Commit = docs.metadata.commit
7687
{
7788
let placement:Editions.Placement = try await self.editions.register(
78-
package: placement.cell,
89+
package: placement.coordinate,
7990
refname: commit.refname,
8091
sha1: commit.hash,
8192
with: session)
8293

83-
version = placement.cell
94+
version = placement.coordinate
8495
}
8596
else if case .swift = docs.metadata.package,
8697
let tagname:String = docs.metadata.commit?.refname
8798
{
8899
let placement:Editions.Placement = try await self.editions.register(
89-
package: placement.cell,
100+
package: placement.coordinate,
90101
refname: tagname,
91102
sha1: nil,
92103
with: session)
93104

94-
version = placement.cell
105+
version = placement.coordinate
95106
}
96107
else
97108
{
98109
version = -1
99110
}
100111

101112
let snapshot:Snapshot = .init(
102-
package: placement.cell,
113+
package: placement.coordinate,
103114
version: version,
104115
metadata: docs.metadata,
105116
graph: docs.graph)
Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
import MongoDB
22
import MongoTesting
3+
4+
@_spi(testable)
35
import UnidocDatabase
46

57
struct PackageNumbers:MongoTestBattery
68
{
79
func run(_ tests:TestGroup, pool:Mongo.SessionPool, database:Mongo.Database) async throws
810
{
911
let database:PackageDatabase = await .setup(as: database, in: pool)
10-
let packages:PackageDatabase.Packages = database.packages
11-
1212
let session:Mongo.Session = try await .init(from: pool)
1313

14-
tests.expect(try await packages.register("a", with: session) ==? 0)
15-
tests.expect(try await packages.register("a", with: session) ==? 0)
16-
tests.expect(try await packages.register("b", with: session) ==? 1)
17-
tests.expect(try await packages.register("a", with: session) ==? 0)
18-
tests.expect(try await packages.register("b", with: session) ==? 1)
19-
tests.expect(try await packages.register("c", with: session) ==? 2)
20-
tests.expect(try await packages.register("c", with: session) ==? 2)
21-
tests.expect(try await packages.register("a", with: session) ==? 0)
22-
tests.expect(try await packages.register("b", with: session) ==? 1)
14+
tests.expect(try await database.track(package: "a", with: session) ==? 0)
15+
tests.expect(try await database.track(package: "a", with: session) ==? 0)
16+
tests.expect(try await database.track(package: "b", with: session) ==? 1)
17+
tests.expect(try await database.track(package: "a", with: session) ==? 0)
18+
tests.expect(try await database.track(package: "b", with: session) ==? 1)
19+
tests.expect(try await database.track(package: "c", with: session) ==? 2)
20+
tests.expect(try await database.track(package: "c", with: session) ==? 2)
21+
tests.expect(try await database.track(package: "a", with: session) ==? 0)
22+
tests.expect(try await database.track(package: "b", with: session) ==? 1)
2323
}
2424
}

0 commit comments

Comments
 (0)