Skip to content
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
63 changes: 63 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ $ aio app db --help

# Commands
<!-- commands -->
* [`aio app db getCollectionInfos`](#aio-app-db-getcollectioninfos)
* [`aio app db getCollectionNames`](#aio-app-db-getcollectionnames)
* [`aio app db ping`](#aio-app-db-ping)
* [`aio app db provision`](#aio-app-db-provision)
* [`aio app db stats`](#aio-app-db-stats)
* [`aio app db status`](#aio-app-db-status)
* [`aio app state delete [KEYS]`](#aio-app-state-delete-keys)
* [`aio app state get KEY`](#aio-app-state-get-key)
Expand All @@ -37,6 +40,66 @@ $ aio app db --help
* [`aio app state stats`](#aio-app-state-stats)
* [`aio help [COMMAND]`](#aio-help-command)

## `aio app db getCollectionInfos`

Get details about your App Builder database

```
USAGE
$ aio app db getCollectionInfos [--json]

GLOBAL FLAGS
--json Format output as json.

DESCRIPTION
Get details about your App Builder database

EXAMPLES
$ aio app db getCollectionInfos

$ aio app db getCollectionInfos --json
```

## `aio app db getCollectionNames`

Get collection names from your App Builder database

```
USAGE
$ aio app db getCollectionNames [--json]

GLOBAL FLAGS
--json Format output as json.

DESCRIPTION
Get collection names from your App Builder database

EXAMPLES
$ aio app db getCollectionNames

$ aio app db getCollectionNames --json
```

## `aio app db stats`

Get statistics about your App Builder database

```
USAGE
$ aio app db stats [--json]

GLOBAL FLAGS
--json Format output as json.

DESCRIPTION
Get statistics about your App Builder database

EXAMPLES
$ aio app db stats

$ aio app db stats --json
```

## `aio app state delete [KEYS]`

Delete key-values
Expand Down
88 changes: 88 additions & 0 deletions src/commands/app/db/getCollectionInfos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
Copyright 2025 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/

import { DBBaseCommand } from '../../../DBBaseCommand.js'
import chalk from 'chalk'

export class GetCollectionInfos extends DBBaseCommand {
Comment thread
simrangulati marked this conversation as resolved.
async run () {
try {
this.log(chalk.blue('Fetching collection info...'))

const client = await this.db.connect()
const collectionInfo = await client.listCollections()

this.debugLogger?.info?.(`Retrieved ${collectionInfo.length} collections with full details:`, collectionInfo)

if (this.flags.json) {
return collectionInfo
}
Comment thread
simrangulati marked this conversation as resolved.

this.log(chalk.green('Collection Information:'))
this.log(chalk.dim(` Namespace: ${this.rtNamespace}`))

if (collectionInfo && collectionInfo.length > 0) {
this.log(chalk.dim(` Total Collections: ${collectionInfo.length}`))
this.log('')

collectionInfo.forEach((collection, index) => {
this.log(chalk.cyan(` Collection ${index + 1}:`))
Object.entries(collection).forEach(([key, value]) => {
this.log(chalk.dim(` ${key}: ${this.formatValue(value)}`))
})
if (index < collectionInfo.length - 1) {
this.log('')
}
})
} else {
this.log(chalk.dim(' No collections found'))
}

this.log('')
this.log(chalk.dim(` Retrieved: ${new Date().toLocaleString()}`))

return collectionInfo
} catch (error) {
this.debugLogger?.error?.('Error fetching collection info', error)

this.log(chalk.red('Failed to retrieve collection information'))
this.log(chalk.dim(` Namespace: ${this.rtNamespace}`))
this.log(chalk.dim(` Error: ${error.message}`))

this.error(`Failed to fetch collection information: ${error.message}`)
Comment thread
simrangulati marked this conversation as resolved.
}
}

formatValue (value) {
if (typeof value === 'number') {
// Format large numbers with commas
return value.toLocaleString()
}
if (typeof value === 'object' && value !== null) {
return JSON.stringify(value, null, 2)
}
return String(value)
}
}

GetCollectionInfos.description = 'Get details of your App Builder database collections'

GetCollectionInfos.examples = [
'$ aio app db getCollectionInfos',
'$ aio app db getCollectionInfos --json'
]

GetCollectionInfos.flags = {
...DBBaseCommand.flags
}

GetCollectionInfos.args = {}
60 changes: 60 additions & 0 deletions src/commands/app/db/getCollectionNames.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
Copyright 2025 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/

import { DBBaseCommand } from '../../../DBBaseCommand.js'
import chalk from 'chalk'

export class GetCollectionNames extends DBBaseCommand {
async run () {
try {
this.log(chalk.blue('Fetching collection names...'))

const client = await this.db.connect()
const collectionInfo = await client.listCollections()

this.debugLogger?.info?.(`Retrieved ${collectionInfo.length} collections from database`)

// Extract only the names from the collection info
const collectionNames = collectionInfo.map(collection => collection.name)

if (this.flags.json) {
return collectionNames
}
Comment thread
simrangulati marked this conversation as resolved.

this.log(chalk.green('Collection names:'))
this.log(JSON.stringify(collectionNames, null, 2))

return collectionNames
} catch (error) {
this.debugLogger?.error?.('Error fetching collection names', error)

this.log(chalk.red('Error fetching collection names'))
this.log(chalk.dim(` Namespace: ${this.rtNamespace}`))
this.log(chalk.dim(` Error: ${error.message}`))

this.error(`Failed to fetch collection names: ${error.message}`)
}
}
}

GetCollectionNames.description = 'Get collection names of your App Builder database'

GetCollectionNames.examples = [
'$ aio app db GetCollectionNames',
'$ aio app db GetCollectionNames --json'
]

GetCollectionNames.flags = {
...DBBaseCommand.flags
}

GetCollectionNames.args = {}
8 changes: 2 additions & 6 deletions src/commands/app/db/ping.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import chalk from 'chalk'

export class Ping extends DBBaseCommand {
async run () {
this.debugLogger?.info?.('Starting database ping test')

try {
this.log(chalk.blue('Testing database connectivity...'))

Expand All @@ -25,7 +23,7 @@ export class Ping extends DBBaseCommand {
const endTime = Date.now()
const responseTime = endTime - startTime

this.debugLogger?.info?.('Ping result:', pingResult)
this.debugLogger?.info?.(`Database ping completed in ${responseTime}ms:`, pingResult)

this.log(chalk.green('Database connection successful'))
this.log(chalk.dim(` Namespace: ${this.rtNamespace}`))
Expand All @@ -43,9 +41,7 @@ export class Ping extends DBBaseCommand {
timestamp: new Date().toISOString()
}

if (!this.flags.json) {
this.log(chalk.dim('Database is ready for operations'))
}
this.log(chalk.dim('Database is ready for operations'))

return result
} catch (error) {
Expand Down
2 changes: 0 additions & 2 deletions src/commands/app/db/provision.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ export class Provision extends DBBaseCommand {
async run () {
const { region } = this.flags

this.debugLogger?.info?.('Starting database provisioning process')

try {
// First check if database is already provisioned
this.log(chalk.blue('Checking current provisioning status...'))
Expand Down
33 changes: 33 additions & 0 deletions src/commands/app/db/show/collections.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
Copyright 2025 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/

import { GetCollectionNames } from '../getCollectionNames.js'

export class Collections extends GetCollectionNames {
async run () {
// Delegate to the parent GetCollectionNames implementation
return super.run()
}
}

Collections.description = 'Show collection names of your App Builder database (alias for getCollectionNames)'

Collections.examples = [
'$ aio app db show collections',
'$ aio app db show collections --json'
]

Collections.flags = {
...GetCollectionNames.flags
}

Collections.args = {}
90 changes: 90 additions & 0 deletions src/commands/app/db/stats.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
Copyright 2025 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/

import { DBBaseCommand } from '../../../DBBaseCommand.js'
import chalk from 'chalk'

export class Stats extends DBBaseCommand {
async run () {
try {
this.log(chalk.blue('Fetching database statistics...'))

const client = await this.db.connect()
const stats = await client.dbStats()

this.debugLogger?.info?.('Database statistics retrieved:', stats)

const result = {
...stats,
namespace: this.rtNamespace,
timestamp: new Date().toISOString()
}

if (this.flags.json) {
return result
}
Comment thread
simrangulati marked this conversation as resolved.

this.displayStats(stats)

return result
} catch (error) {
this.debugLogger?.error?.('Stats command error:', error)

this.log(chalk.red('Failed to retrieve database statistics'))
this.log(chalk.dim(` Namespace: ${this.rtNamespace}`))
this.log(chalk.dim(` Error: ${error.message}`))

this.error(`Failed to fetch database statistics: ${error.message}`)
Comment thread
simrangulati marked this conversation as resolved.
}
}

displayStats (stats) {
this.log(chalk.green('Database Statistics:'))
this.log(chalk.dim(` Namespace: ${this.rtNamespace}`))

if (stats && typeof stats === 'object') {
// Format and display stats in a readable way
Object.entries(stats).forEach(([key, value]) => {
this.log(chalk.dim(` ${key}: ${this.formatValue(value)}`))
})
} else {
this.log(chalk.dim(` Raw Stats: ${JSON.stringify(stats, null, 2)}`))
}

this.log('')
this.log(chalk.dim(` Retrieved: ${new Date().toLocaleString()}`))
}

formatValue (value) {
if (typeof value === 'number') {
// Format large numbers with commas
return value.toLocaleString()
}
if (typeof value === 'object' && value !== null) {
return JSON.stringify(value, null, 2)
}
return String(value)
}
}

Stats.description = 'Get statistics of your App Builder database'

Stats.examples = [
'$ aio app db stats',
'$ aio app db stats --json'
]

Stats.flags = {
...DBBaseCommand.flags
}

Stats.args = {}
Loading