mirror of
https://github.com/Permissionless-Software-Foundation/psf-memo-db.git
synced 2026-09-21 16:52:02 -07:00
Adding block height to all db models
This commit is contained in:
@@ -25,6 +25,7 @@ Default port: **5021**
|
||||
All indexer data is exposed under `/level/*` with CRUD routes per entity (`post`, `like`, `name`, `profile`, `status`, etc.) plus:
|
||||
|
||||
- `GET /profile/recent` — paginated list of profiles, sorted by block height (newest first)
|
||||
- `GET /posts/recent` — paginated list of posts, sorted by block height (newest first)
|
||||
- `POST /level/backup` — zip database snapshot
|
||||
- `POST /level/restore` — restore from snapshot (exits process)
|
||||
- `GET /health` — health check
|
||||
@@ -39,7 +40,16 @@ curl -sS "http://localhost:5021/profile/recent"
|
||||
curl -sS "http://localhost:5021/profile/recent?limit=50&offset=50"
|
||||
```
|
||||
|
||||
Query parameters: `limit` (default `100`, max `100`), `offset` (default `0`). Block height comes from the profile tx’s `ptx` record.
|
||||
Query parameters: `limit` (default `100`, max `100`), `offset` (default `0`). Block height is read from the stored profile document (`blockHeight` field, set at indexing time).
|
||||
|
||||
### List recent posts
|
||||
|
||||
```bash
|
||||
curl -sS "http://localhost:5021/posts/recent"
|
||||
curl -sS "http://localhost:5021/posts/recent?limit=50&offset=50"
|
||||
```
|
||||
|
||||
Same query parameters as `/profile/recent`.
|
||||
|
||||
## Tests
|
||||
|
||||
|
||||
@@ -20,12 +20,10 @@ class Adapters {
|
||||
this.level = level
|
||||
this.dbBackup = new DbBackup(level)
|
||||
this.profileQuery = new ProfileQuery({
|
||||
profilesDb: level.profilesDb,
|
||||
ptxsDb: level.ptxsDb
|
||||
profilesDb: level.profilesDb
|
||||
})
|
||||
this.postQuery = new PostQuery({
|
||||
postsDb: level.postsDb,
|
||||
ptxsDb: level.ptxsDb
|
||||
postsDb: level.postsDb
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1,43 +1,27 @@
|
||||
/*
|
||||
Adapter for scanning posts and resolving block height from ptx records.
|
||||
Adapter for scanning posts with stored block height.
|
||||
*/
|
||||
|
||||
class PostQuery {
|
||||
constructor (localConfig = {}) {
|
||||
const { postsDb, ptxsDb } = localConfig
|
||||
const { postsDb } = localConfig
|
||||
if (!postsDb) {
|
||||
throw new Error('postsDb required when instantiating PostQuery adapter.')
|
||||
}
|
||||
if (!ptxsDb) {
|
||||
throw new Error('ptxsDb required when instantiating PostQuery adapter.')
|
||||
}
|
||||
this.postsDb = postsDb
|
||||
this.ptxsDb = ptxsDb
|
||||
this.scanPostsWithBlockHeight = this.scanPostsWithBlockHeight.bind(this)
|
||||
}
|
||||
|
||||
async getBlockHeightForTxid (txid) {
|
||||
if (!txid) return 0
|
||||
try {
|
||||
const ptx = await this.ptxsDb.get(txid)
|
||||
const height = ptx && ptx.blockHeight
|
||||
return typeof height === 'number' ? height : parseInt(height, 10) || 0
|
||||
} catch (err) {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
async scanPostsWithBlockHeight () {
|
||||
const posts = []
|
||||
|
||||
for await (const [txid, post] of this.postsDb.iterator()) {
|
||||
const blockHeight = await this.getBlockHeightForTxid(txid)
|
||||
posts.push({
|
||||
txid,
|
||||
addr: post.addr,
|
||||
text: post.text,
|
||||
seen: post.seen,
|
||||
blockHeight
|
||||
blockHeight: post.blockHeight ?? 0
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,43 +1,27 @@
|
||||
/*
|
||||
Adapter for scanning profiles and resolving block height from ptx records.
|
||||
Adapter for scanning profiles with stored block height.
|
||||
*/
|
||||
|
||||
class ProfileQuery {
|
||||
constructor (localConfig = {}) {
|
||||
const { profilesDb, ptxsDb } = localConfig
|
||||
const { profilesDb } = localConfig
|
||||
if (!profilesDb) {
|
||||
throw new Error('profilesDb required when instantiating ProfileQuery adapter.')
|
||||
}
|
||||
if (!ptxsDb) {
|
||||
throw new Error('ptxsDb required when instantiating ProfileQuery adapter.')
|
||||
}
|
||||
this.profilesDb = profilesDb
|
||||
this.ptxsDb = ptxsDb
|
||||
this.scanProfilesWithBlockHeight = this.scanProfilesWithBlockHeight.bind(this)
|
||||
}
|
||||
|
||||
async getBlockHeightForTxid (txid) {
|
||||
if (!txid) return 0
|
||||
try {
|
||||
const ptx = await this.ptxsDb.get(txid)
|
||||
const height = ptx && ptx.blockHeight
|
||||
return typeof height === 'number' ? height : parseInt(height, 10) || 0
|
||||
} catch (err) {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
async scanProfilesWithBlockHeight () {
|
||||
const profiles = []
|
||||
|
||||
for await (const [addr, profile] of this.profilesDb.iterator()) {
|
||||
const blockHeight = await this.getBlockHeightForTxid(profile.txid)
|
||||
profiles.push({
|
||||
addr,
|
||||
text: profile.text,
|
||||
txid: profile.txid,
|
||||
seen: profile.seen,
|
||||
blockHeight
|
||||
blockHeight: profile.blockHeight ?? 0
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -6,29 +6,23 @@ describe('#PostQuery', () => {
|
||||
let uut
|
||||
let sandbox
|
||||
let postsDb
|
||||
let ptxsDb
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox = sinon.createSandbox()
|
||||
postsDb = {
|
||||
iterator: sandbox.stub()
|
||||
}
|
||||
ptxsDb = {
|
||||
get: sandbox.stub()
|
||||
}
|
||||
uut = new PostQuery({ postsDb, ptxsDb })
|
||||
uut = new PostQuery({ postsDb })
|
||||
})
|
||||
|
||||
afterEach(() => sandbox.restore())
|
||||
|
||||
it('should scan posts and attach block height from ptx', async () => {
|
||||
it('should scan posts and read block height from stored document', async () => {
|
||||
async function * mockIterator () {
|
||||
yield ['tx1', { addr: 'addr1', text: 'hello', seen: 1000 }]
|
||||
yield ['tx2', { addr: 'addr2', text: 'world', seen: 2000 }]
|
||||
yield ['tx1', { addr: 'addr1', text: 'hello', seen: 1000, blockHeight: 600100 }]
|
||||
yield ['tx2', { addr: 'addr2', text: 'world', seen: 2000, blockHeight: 600200 }]
|
||||
}
|
||||
postsDb.iterator.returns(mockIterator())
|
||||
ptxsDb.get.withArgs('tx1').resolves({ blockHeight: 600100 })
|
||||
ptxsDb.get.withArgs('tx2').resolves({ blockHeight: 600200 })
|
||||
|
||||
const result = await uut.scanPostsWithBlockHeight()
|
||||
|
||||
@@ -39,12 +33,11 @@ describe('#PostQuery', () => {
|
||||
assert.equal(result[1].blockHeight, 600200)
|
||||
})
|
||||
|
||||
it('should use block height 0 when ptx is missing', async () => {
|
||||
it('should use block height 0 when field is missing', async () => {
|
||||
async function * mockIterator () {
|
||||
yield ['tx-missing', { addr: 'addr1', text: 'hi', seen: 1000 }]
|
||||
}
|
||||
postsDb.iterator.returns(mockIterator())
|
||||
ptxsDb.get.rejects(new Error('not found'))
|
||||
|
||||
const result = await uut.scanPostsWithBlockHeight()
|
||||
|
||||
|
||||
@@ -6,29 +6,23 @@ describe('#ProfileQuery', () => {
|
||||
let uut
|
||||
let sandbox
|
||||
let profilesDb
|
||||
let ptxsDb
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox = sinon.createSandbox()
|
||||
profilesDb = {
|
||||
iterator: sandbox.stub()
|
||||
}
|
||||
ptxsDb = {
|
||||
get: sandbox.stub()
|
||||
}
|
||||
uut = new ProfileQuery({ profilesDb, ptxsDb })
|
||||
uut = new ProfileQuery({ profilesDb })
|
||||
})
|
||||
|
||||
afterEach(() => sandbox.restore())
|
||||
|
||||
it('should scan profiles and attach block height from ptx', async () => {
|
||||
it('should scan profiles and read block height from stored document', async () => {
|
||||
async function * mockIterator () {
|
||||
yield ['addr1', { text: 'hi', txid: 'tx1', seen: 1000 }]
|
||||
yield ['addr2', { text: 'bye', txid: 'tx2', seen: 2000 }]
|
||||
yield ['addr1', { text: 'hi', txid: 'tx1', seen: 1000, blockHeight: 600100 }]
|
||||
yield ['addr2', { text: 'bye', txid: 'tx2', seen: 2000, blockHeight: 600200 }]
|
||||
}
|
||||
profilesDb.iterator.returns(mockIterator())
|
||||
ptxsDb.get.withArgs('tx1').resolves({ blockHeight: 600100 })
|
||||
ptxsDb.get.withArgs('tx2').resolves({ blockHeight: 600200 })
|
||||
|
||||
const result = await uut.scanProfilesWithBlockHeight()
|
||||
|
||||
@@ -37,12 +31,11 @@ describe('#ProfileQuery', () => {
|
||||
assert.equal(result[1].blockHeight, 600200)
|
||||
})
|
||||
|
||||
it('should use block height 0 when ptx is missing', async () => {
|
||||
it('should use block height 0 when field is missing', async () => {
|
||||
async function * mockIterator () {
|
||||
yield ['addr1', { text: 'hi', txid: 'tx-missing', seen: 1000 }]
|
||||
yield ['addr1', { text: 'hi', txid: 'tx1', seen: 1000 }]
|
||||
}
|
||||
profilesDb.iterator.returns(mockIterator())
|
||||
ptxsDb.get.rejects(new Error('not found'))
|
||||
|
||||
const result = await uut.scanProfilesWithBlockHeight()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user