feat: Add Continuous Delivery system with auto-commit and file watcher
Automatically commit and push changes to GitHub with zero manual intervention. Features: - File watcher mode: Auto-detects changes in real-time - Timer mode: Commits at regular intervals (default 5 minutes) - Smart exclusions: Ignores temp files, sessions, cache, db files - Retry logic: Auto-retries failed pushes - Change summaries: Detailed commit messages with file lists Components: - auto-deploy.ps1: Core CD engine with file watcher - start-cd.ps1: Easy-to-use wrapper with commands - .cd-config.json: Configuration file - CONTINUOUS_DELIVERY_GUIDE.md: Complete documentation Usage: .\start-cd.ps1 watch # Start file watcher (recommended) .\start-cd.ps1 start # Timer mode (every 5 min) .\start-cd.ps1 once # One-time commit Also removed db_data/ from git tracking (now in .gitignore). Database runtime files should never be committed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
18
.cd-config.json
Normal file
18
.cd-config.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"intervalSeconds": 300,
|
||||||
|
"branch": "dev",
|
||||||
|
"commitPrefix": "auto:",
|
||||||
|
"excludePatterns": [
|
||||||
|
"f_data/data_sessions/*",
|
||||||
|
"f_data/data_cache/_c_tpl/*",
|
||||||
|
".setup_complete",
|
||||||
|
"*.log",
|
||||||
|
"db_data/*",
|
||||||
|
"node_modules/*",
|
||||||
|
"vendor/*",
|
||||||
|
".git/*",
|
||||||
|
".vscode/*"
|
||||||
|
],
|
||||||
|
"enableNotifications": true,
|
||||||
|
"autoStart": false
|
||||||
|
}
|
||||||
17
.gitignore
vendored
17
.gitignore
vendored
@@ -1,6 +1,23 @@
|
|||||||
# Exclude temporary session files
|
# Exclude temporary session files
|
||||||
f_data/data_sessions/sess_*
|
f_data/data_sessions/sess_*
|
||||||
|
|
||||||
# Exclude cache files
|
# Exclude cache files
|
||||||
f_data/data_cache/_c_tpl/*
|
f_data/data_cache/_c_tpl/*
|
||||||
|
|
||||||
# Keep setup complete marker out of repo
|
# Keep setup complete marker out of repo
|
||||||
.setup_complete
|
.setup_complete
|
||||||
|
|
||||||
|
# Database runtime files (never commit these!)
|
||||||
|
db_data/
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
*.log.*
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
node_modules/
|
||||||
|
vendor/
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
|||||||
428
CONTINUOUS_DELIVERY_GUIDE.md
Normal file
428
CONTINUOUS_DELIVERY_GUIDE.md
Normal file
@@ -0,0 +1,428 @@
|
|||||||
|
# EasyStream Continuous Delivery Guide
|
||||||
|
|
||||||
|
Automatically commit and push your changes to GitHub with zero manual intervention.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **File Watcher Mode**: Detects file changes in real-time and auto-commits after 30 seconds of inactivity
|
||||||
|
- **Timer Mode**: Commits and pushes at regular intervals (default: 5 minutes)
|
||||||
|
- **Smart Exclusions**: Automatically excludes temporary files, sessions, cache, and database files
|
||||||
|
- **Retry Logic**: Automatically retries failed pushes with exponential backoff
|
||||||
|
- **Change Summaries**: Generates detailed commit messages with file change lists
|
||||||
|
- **Zero Configuration**: Works out of the box with sensible defaults
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Option 1: File Watcher Mode (Recommended)
|
||||||
|
|
||||||
|
This mode monitors your files and automatically commits changes 30 seconds after you stop editing:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\start-cd.ps1 watch
|
||||||
|
```
|
||||||
|
|
||||||
|
You'll see:
|
||||||
|
```
|
||||||
|
========================================
|
||||||
|
EasyStream File Watcher Started
|
||||||
|
========================================
|
||||||
|
Watching: E:\repos\easystream-main
|
||||||
|
Branch: dev
|
||||||
|
Debounce: 30 seconds after last change
|
||||||
|
========================================
|
||||||
|
|
||||||
|
✓ File watcher active. Monitoring for changes...
|
||||||
|
```
|
||||||
|
|
||||||
|
When you save a file:
|
||||||
|
```
|
||||||
|
[14:23:45] Changed: setup.php
|
||||||
|
[14:23:47] Changed: f_core/config.href.php
|
||||||
|
[14:23:50] Changed: docker-compose.yml
|
||||||
|
|
||||||
|
Debounce period elapsed. Processing 3 changes...
|
||||||
|
ℹ Found 3 changed files
|
||||||
|
✓ Committed changes
|
||||||
|
✓ Successfully pushed to GitHub
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 2: Timer Mode
|
||||||
|
|
||||||
|
Commits and pushes at regular intervals (every 5 minutes by default):
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\start-cd.ps1 start
|
||||||
|
```
|
||||||
|
|
||||||
|
Change the interval to 1 minute:
|
||||||
|
```powershell
|
||||||
|
.\start-cd.ps1 start -Interval 60
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 3: One-Time Commit
|
||||||
|
|
||||||
|
Manually trigger a single commit and push:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\start-cd.ps1 once
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Edit [.cd-config.json](.cd-config.json) to customize behavior:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"intervalSeconds": 300,
|
||||||
|
"branch": "dev",
|
||||||
|
"commitPrefix": "auto:",
|
||||||
|
"excludePatterns": [
|
||||||
|
"f_data/data_sessions/*",
|
||||||
|
"f_data/data_cache/_c_tpl/*",
|
||||||
|
".setup_complete",
|
||||||
|
"*.log",
|
||||||
|
"db_data/*",
|
||||||
|
"node_modules/*",
|
||||||
|
"vendor/*"
|
||||||
|
],
|
||||||
|
"enableNotifications": true,
|
||||||
|
"autoStart": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration Options
|
||||||
|
|
||||||
|
| Option | Description | Default |
|
||||||
|
|--------|-------------|---------|
|
||||||
|
| `intervalSeconds` | Time between auto-commits (timer mode) | 300 (5 min) |
|
||||||
|
| `branch` | Git branch to push to | "dev" |
|
||||||
|
| `commitPrefix` | Prefix for auto-generated commit messages | "auto:" |
|
||||||
|
| `excludePatterns` | File patterns to ignore | See above |
|
||||||
|
| `enableNotifications` | Show Windows notifications (future) | true |
|
||||||
|
| `autoStart` | Start CD on system boot (future) | false |
|
||||||
|
|
||||||
|
## Commands Reference
|
||||||
|
|
||||||
|
### start-cd.ps1 Commands
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Start file watcher mode
|
||||||
|
.\start-cd.ps1 watch
|
||||||
|
|
||||||
|
# Start timer mode (default interval: 5 minutes)
|
||||||
|
.\start-cd.ps1 start
|
||||||
|
|
||||||
|
# Start timer mode with custom interval (60 seconds)
|
||||||
|
.\start-cd.ps1 start -Interval 60
|
||||||
|
|
||||||
|
# Run one-time commit and push
|
||||||
|
.\start-cd.ps1 once
|
||||||
|
|
||||||
|
# Check git status
|
||||||
|
.\start-cd.ps1 status
|
||||||
|
|
||||||
|
# Stop all running CD processes
|
||||||
|
.\start-cd.ps1 stop
|
||||||
|
|
||||||
|
# Show help
|
||||||
|
.\start-cd.ps1 help
|
||||||
|
```
|
||||||
|
|
||||||
|
### auto-deploy.ps1 Advanced Usage
|
||||||
|
|
||||||
|
Direct script usage for advanced scenarios:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# File watcher mode with verbose output
|
||||||
|
.\auto-deploy.ps1 -WatchMode -Verbose
|
||||||
|
|
||||||
|
# Timer mode with custom interval and branch
|
||||||
|
.\auto-deploy.ps1 -IntervalSeconds 120 -Branch main -Verbose
|
||||||
|
|
||||||
|
# Custom commit prefix
|
||||||
|
.\auto-deploy.ps1 -CommitPrefix "wip:" -IntervalSeconds 60
|
||||||
|
```
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
### File Watcher Mode
|
||||||
|
|
||||||
|
1. **Monitors**: Watches all files in the repository using .NET FileSystemWatcher
|
||||||
|
2. **Debounces**: Waits 30 seconds after the last file change to avoid committing partial edits
|
||||||
|
3. **Excludes**: Filters out temporary files based on `.gitignore` and config patterns
|
||||||
|
4. **Commits**: Stages all changes and creates a commit with file change summary
|
||||||
|
5. **Pushes**: Uploads to GitHub with retry logic
|
||||||
|
6. **Repeats**: Continues monitoring for the next change
|
||||||
|
|
||||||
|
### Timer Mode
|
||||||
|
|
||||||
|
1. **Checks**: Scans for changes at regular intervals
|
||||||
|
2. **Stages**: Adds all modified, new, and deleted files
|
||||||
|
3. **Commits**: Creates a timestamped commit with change summary
|
||||||
|
4. **Pushes**: Uploads to GitHub if there are new commits
|
||||||
|
5. **Waits**: Sleeps for the configured interval before next check
|
||||||
|
|
||||||
|
## Commit Message Format
|
||||||
|
|
||||||
|
Auto-generated commits include:
|
||||||
|
|
||||||
|
```
|
||||||
|
auto: Update at 2025-10-26 14:30:00
|
||||||
|
|
||||||
|
Changed files:
|
||||||
|
- setup.php
|
||||||
|
- docker-compose.yml
|
||||||
|
- f_core/config.href.php
|
||||||
|
- ... and 5 more files
|
||||||
|
|
||||||
|
🤖 Generated with Claude Code Continuous Delivery
|
||||||
|
|
||||||
|
Co-Authored-By: Claude <noreply@anthropic.com>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Excluded Files
|
||||||
|
|
||||||
|
The following files are automatically excluded from commits:
|
||||||
|
|
||||||
|
- Session files: `f_data/data_sessions/sess_*`
|
||||||
|
- Cache files: `f_data/data_cache/_c_tpl/*`
|
||||||
|
- Setup marker: `.setup_complete`
|
||||||
|
- Database files: `db_data/*`
|
||||||
|
- Log files: `*.log`
|
||||||
|
- Dependencies: `node_modules/*`, `vendor/*`
|
||||||
|
- IDE files: `.vscode/*`, `.idea/*`
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### CD not detecting changes
|
||||||
|
|
||||||
|
**Problem**: Files changed but no commit triggered
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```powershell
|
||||||
|
# Check if files are excluded
|
||||||
|
git status
|
||||||
|
|
||||||
|
# Verify .gitignore doesn't over-exclude
|
||||||
|
cat .gitignore
|
||||||
|
|
||||||
|
# Check CD config
|
||||||
|
cat .cd-config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Push failed: Authentication required
|
||||||
|
|
||||||
|
**Problem**: Git asks for credentials
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```powershell
|
||||||
|
# Set up Git credential helper (Windows)
|
||||||
|
git config --global credential.helper manager
|
||||||
|
|
||||||
|
# Or use SSH keys
|
||||||
|
git remote set-url origin git@github.com:SamiAhmed7777/easystream-main.git
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multiple CD processes running
|
||||||
|
|
||||||
|
**Problem**: CD commits too frequently
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```powershell
|
||||||
|
# Stop all CD processes
|
||||||
|
.\start-cd.ps1 stop
|
||||||
|
|
||||||
|
# Restart with single instance
|
||||||
|
.\start-cd.ps1 watch
|
||||||
|
```
|
||||||
|
|
||||||
|
### Large files rejected by GitHub
|
||||||
|
|
||||||
|
**Problem**: `db_data/*` files are too large
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
These files are already excluded in `.gitignore`. If they're already tracked:
|
||||||
|
```powershell
|
||||||
|
# Remove from git but keep locally
|
||||||
|
git rm --cached -r db_data/
|
||||||
|
git commit -m "Remove database files from tracking"
|
||||||
|
git push
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running as Background Service
|
||||||
|
|
||||||
|
### Option 1: Windows Task Scheduler
|
||||||
|
|
||||||
|
1. Open Task Scheduler
|
||||||
|
2. Create Basic Task
|
||||||
|
3. Trigger: At system startup
|
||||||
|
4. Action: Start a program
|
||||||
|
- Program: `powershell.exe`
|
||||||
|
- Arguments: `-WindowStyle Hidden -File "E:\repos\easystream-main\start-cd.ps1" watch`
|
||||||
|
|
||||||
|
### Option 2: PowerShell Background Job
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Start in background
|
||||||
|
Start-Job -ScriptBlock {
|
||||||
|
Set-Location "E:\repos\easystream-main"
|
||||||
|
.\start-cd.ps1 watch
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
Get-Job
|
||||||
|
|
||||||
|
# View output
|
||||||
|
Receive-Job -Id 1 -Keep
|
||||||
|
|
||||||
|
# Stop
|
||||||
|
Stop-Job -Id 1
|
||||||
|
Remove-Job -Id 1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 3: Screen/Tmux (Windows Terminal)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Open new Windows Terminal tab
|
||||||
|
wt -w 0 nt -d E:\repos\easystream-main powershell -NoExit -Command ".\start-cd.ps1 watch"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
### What Gets Committed
|
||||||
|
|
||||||
|
- Application code (PHP, JavaScript, CSS)
|
||||||
|
- Configuration files (docker-compose.yml, .env templates)
|
||||||
|
- Documentation (Markdown files)
|
||||||
|
- SQL schema files
|
||||||
|
|
||||||
|
### What's Excluded
|
||||||
|
|
||||||
|
- Session data (user sessions)
|
||||||
|
- Cache (compiled templates)
|
||||||
|
- Database runtime files (actual data)
|
||||||
|
- Secrets (`.env` files are tracked but should only contain templates)
|
||||||
|
|
||||||
|
### Best Practices
|
||||||
|
|
||||||
|
1. **Review `.gitignore`**: Ensure sensitive files are excluded
|
||||||
|
2. **Use environment variables**: Never commit actual passwords or API keys
|
||||||
|
3. **Separate repos for secrets**: Use a private repo for production `.env` files
|
||||||
|
4. **Monitor commits**: Occasionally review auto-commits for unwanted files
|
||||||
|
|
||||||
|
## Performance Tips
|
||||||
|
|
||||||
|
### For Large Repositories
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"intervalSeconds": 600,
|
||||||
|
"excludePatterns": [
|
||||||
|
"f_data/*",
|
||||||
|
"uploads/*",
|
||||||
|
"*.mp4",
|
||||||
|
"*.mkv"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### For Active Development
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"intervalSeconds": 180,
|
||||||
|
"commitPrefix": "wip:"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integration with IDE
|
||||||
|
|
||||||
|
### VS Code
|
||||||
|
|
||||||
|
Add to `.vscode/tasks.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "Start Continuous Delivery",
|
||||||
|
"type": "shell",
|
||||||
|
"command": ".\\start-cd.ps1 watch",
|
||||||
|
"presentation": {
|
||||||
|
"reveal": "always",
|
||||||
|
"panel": "dedicated"
|
||||||
|
},
|
||||||
|
"problemMatcher": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Run with: `Ctrl+Shift+P` → `Tasks: Run Task` → `Start Continuous Delivery`
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
**Q: Will this commit every keystroke?**
|
||||||
|
A: No. File watcher mode waits 30 seconds after the last change before committing.
|
||||||
|
|
||||||
|
**Q: Can I customize commit messages?**
|
||||||
|
A: Yes, edit the commit message generation in [auto-deploy.ps1:176-188](auto-deploy.ps1#L176-L188)
|
||||||
|
|
||||||
|
**Q: Does this work with pull requests?**
|
||||||
|
A: Yes, but you may want to squash auto-commits before merging. Consider using a feature branch.
|
||||||
|
|
||||||
|
**Q: Can I run this on Linux/Mac?**
|
||||||
|
A: The scripts are PowerShell-specific. For Linux/Mac, use Git hooks or tools like `watchman` + bash scripts.
|
||||||
|
|
||||||
|
**Q: Will this conflict with manual commits?**
|
||||||
|
A: No. The CD system checks for changes and only commits if there are uncommitted files.
|
||||||
|
|
||||||
|
**Q: How do I temporarily pause CD?**
|
||||||
|
A: Press `Ctrl+C` in the CD terminal, or run `.\start-cd.ps1 stop`
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Development Workflow
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Morning: Start CD
|
||||||
|
.\start-cd.ps1 watch
|
||||||
|
|
||||||
|
# Work normally - changes auto-commit as you save
|
||||||
|
|
||||||
|
# End of day: Review commits
|
||||||
|
git log --oneline --since="8 hours ago"
|
||||||
|
|
||||||
|
# Squash if needed before PR
|
||||||
|
git rebase -i HEAD~20
|
||||||
|
```
|
||||||
|
|
||||||
|
### Emergency Hotfix
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Stop CD
|
||||||
|
.\start-cd.ps1 stop
|
||||||
|
|
||||||
|
# Make critical fix
|
||||||
|
# ... edit files ...
|
||||||
|
|
||||||
|
# Manual commit with detailed message
|
||||||
|
git add .
|
||||||
|
git commit -m "fix: Critical security patch for XSS vulnerability"
|
||||||
|
git push
|
||||||
|
|
||||||
|
# Resume CD
|
||||||
|
.\start-cd.ps1 watch
|
||||||
|
```
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
For issues or questions:
|
||||||
|
- GitHub Issues: https://github.com/SamiAhmed7777/easystream-main/issues
|
||||||
|
- Check logs in terminal output
|
||||||
|
- Use `-Verbose` flag for detailed diagnostics
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Next Steps**: [Start using CD now!](#quick-start)
|
||||||
362
auto-deploy.ps1
Normal file
362
auto-deploy.ps1
Normal file
@@ -0,0 +1,362 @@
|
|||||||
|
# Continuous Delivery Script for EasyStream
|
||||||
|
# Automatically commits and pushes changes to GitHub
|
||||||
|
|
||||||
|
param(
|
||||||
|
[int]$IntervalSeconds = 300, # Default: 5 minutes
|
||||||
|
[string]$Branch = "dev",
|
||||||
|
[string]$CommitPrefix = "auto:",
|
||||||
|
[switch]$WatchMode,
|
||||||
|
[switch]$Verbose
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Continue"
|
||||||
|
$RepoPath = $PSScriptRoot
|
||||||
|
|
||||||
|
# Color output functions
|
||||||
|
function Write-Success { param($msg) Write-Host "✓ $msg" -ForegroundColor Green }
|
||||||
|
function Write-Info { param($msg) Write-Host "ℹ $msg" -ForegroundColor Cyan }
|
||||||
|
function Write-Warning { param($msg) Write-Host "⚠ $msg" -ForegroundColor Yellow }
|
||||||
|
function Write-Error { param($msg) Write-Host "✗ $msg" -ForegroundColor Red }
|
||||||
|
|
||||||
|
# Load configuration
|
||||||
|
$configPath = Join-Path $RepoPath ".cd-config.json"
|
||||||
|
if (Test-Path $configPath) {
|
||||||
|
$config = Get-Content $configPath | ConvertFrom-Json
|
||||||
|
if ($config.intervalSeconds) { $IntervalSeconds = $config.intervalSeconds }
|
||||||
|
if ($config.branch) { $Branch = $config.branch }
|
||||||
|
if ($config.commitPrefix) { $CommitPrefix = $config.commitPrefix }
|
||||||
|
if ($config.excludePatterns) { $excludePatterns = $config.excludePatterns }
|
||||||
|
} else {
|
||||||
|
$excludePatterns = @(
|
||||||
|
"f_data/data_sessions/*",
|
||||||
|
"f_data/data_cache/_c_tpl/*",
|
||||||
|
".setup_complete",
|
||||||
|
"*.log",
|
||||||
|
"db_data/*",
|
||||||
|
"node_modules/*",
|
||||||
|
"vendor/*"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test-GitRepo {
|
||||||
|
Push-Location $RepoPath
|
||||||
|
try {
|
||||||
|
$null = git rev-parse --git-dir 2>&1
|
||||||
|
return $?
|
||||||
|
} finally {
|
||||||
|
Pop-Location
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-GitStatus {
|
||||||
|
Push-Location $RepoPath
|
||||||
|
try {
|
||||||
|
$status = git status --porcelain 2>&1
|
||||||
|
return $status
|
||||||
|
} finally {
|
||||||
|
Pop-Location
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-ChangeSummary {
|
||||||
|
Push-Location $RepoPath
|
||||||
|
try {
|
||||||
|
$modified = @(git diff --name-only).Count
|
||||||
|
$staged = @(git diff --cached --name-only).Count
|
||||||
|
$untracked = @(git ls-files --others --exclude-standard).Count
|
||||||
|
|
||||||
|
return @{
|
||||||
|
Modified = $modified
|
||||||
|
Staged = $staged
|
||||||
|
Untracked = $untracked
|
||||||
|
Total = $modified + $staged + $untracked
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Pop-Location
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Update-GitIgnore {
|
||||||
|
$gitignorePath = Join-Path $RepoPath ".gitignore"
|
||||||
|
|
||||||
|
$ignoreContent = @"
|
||||||
|
# Temporary session files
|
||||||
|
f_data/data_sessions/sess_*
|
||||||
|
# Cache files
|
||||||
|
f_data/data_cache/_c_tpl/*
|
||||||
|
# Setup marker
|
||||||
|
.setup_complete
|
||||||
|
# Database runtime files
|
||||||
|
db_data/*
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
# Dependencies
|
||||||
|
node_modules/
|
||||||
|
vendor/
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
"@
|
||||||
|
|
||||||
|
if (-not (Test-Path $gitignorePath)) {
|
||||||
|
$ignoreContent | Out-File -FilePath $gitignorePath -Encoding UTF8
|
||||||
|
Write-Success "Created .gitignore"
|
||||||
|
} else {
|
||||||
|
# Append if patterns are missing
|
||||||
|
$existing = Get-Content $gitignorePath -Raw
|
||||||
|
if ($existing -notmatch "f_data/data_sessions/sess_\*") {
|
||||||
|
"`n# Auto-generated exclusions`n$ignoreContent" | Add-Content -Path $gitignorePath
|
||||||
|
Write-Success "Updated .gitignore"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Invoke-AutoCommit {
|
||||||
|
param([string]$message)
|
||||||
|
|
||||||
|
Push-Location $RepoPath
|
||||||
|
try {
|
||||||
|
Write-Info "Checking for changes..."
|
||||||
|
|
||||||
|
$changes = Get-ChangeSummary
|
||||||
|
|
||||||
|
if ($changes.Total -eq 0) {
|
||||||
|
if ($Verbose) { Write-Info "No changes detected" }
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Info "Found $($changes.Total) changed files (Modified: $($changes.Modified), Staged: $($changes.Staged), Untracked: $($changes.Untracked))"
|
||||||
|
|
||||||
|
# Stage all changes
|
||||||
|
Write-Info "Staging changes..."
|
||||||
|
git add -A 2>&1 | Out-Null
|
||||||
|
|
||||||
|
# Generate commit message if not provided
|
||||||
|
if (-not $message) {
|
||||||
|
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||||
|
$message = "${CommitPrefix} Update at $timestamp"
|
||||||
|
|
||||||
|
# Add file change summary
|
||||||
|
$fileList = @(git diff --cached --name-only | Select-Object -First 5)
|
||||||
|
if ($fileList.Count -gt 0) {
|
||||||
|
$message += "`n`nChanged files:"
|
||||||
|
foreach ($file in $fileList) {
|
||||||
|
$message += "`n- $file"
|
||||||
|
}
|
||||||
|
if ($changes.Total -gt 5) {
|
||||||
|
$message += "`n- ... and $($changes.Total - 5) more files"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$message += "`n`n🤖 Generated with Claude Code Continuous Delivery`n`nCo-Authored-By: Claude <noreply@anthropic.com>"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create commit
|
||||||
|
Write-Info "Creating commit..."
|
||||||
|
$commitResult = git commit -m $message 2>&1
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -eq 0) {
|
||||||
|
Write-Success "Committed changes"
|
||||||
|
return $true
|
||||||
|
} else {
|
||||||
|
Write-Warning "Commit failed or nothing to commit"
|
||||||
|
if ($Verbose) { Write-Host $commitResult }
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Pop-Location
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Invoke-AutoPush {
|
||||||
|
Push-Location $RepoPath
|
||||||
|
try {
|
||||||
|
Write-Info "Pushing to origin/$Branch..."
|
||||||
|
|
||||||
|
# Check if we're ahead of remote
|
||||||
|
$ahead = git rev-list --count "origin/$Branch..$Branch" 2>&1
|
||||||
|
|
||||||
|
if ($ahead -match "^\d+$" -and [int]$ahead -gt 0) {
|
||||||
|
Write-Info "Local is $ahead commit(s) ahead of remote"
|
||||||
|
|
||||||
|
# Push with retry logic
|
||||||
|
$maxRetries = 3
|
||||||
|
$retryCount = 0
|
||||||
|
|
||||||
|
while ($retryCount -lt $maxRetries) {
|
||||||
|
$pushResult = git push origin $Branch 2>&1
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -eq 0) {
|
||||||
|
Write-Success "Successfully pushed to GitHub"
|
||||||
|
return $true
|
||||||
|
} else {
|
||||||
|
$retryCount++
|
||||||
|
Write-Warning "Push attempt $retryCount failed"
|
||||||
|
if ($Verbose) { Write-Host $pushResult }
|
||||||
|
|
||||||
|
if ($retryCount -lt $maxRetries) {
|
||||||
|
Write-Info "Retrying in 5 seconds..."
|
||||||
|
Start-Sleep -Seconds 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Error "Failed to push after $maxRetries attempts"
|
||||||
|
return $false
|
||||||
|
} else {
|
||||||
|
if ($Verbose) { Write-Info "Already up to date with remote" }
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Pop-Location
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Start-ContinuousDelivery {
|
||||||
|
Write-Info "========================================="
|
||||||
|
Write-Info "EasyStream Continuous Delivery Started"
|
||||||
|
Write-Info "========================================="
|
||||||
|
Write-Info "Repository: $RepoPath"
|
||||||
|
Write-Info "Branch: $Branch"
|
||||||
|
Write-Info "Interval: $IntervalSeconds seconds"
|
||||||
|
Write-Info "========================================="
|
||||||
|
Write-Info ""
|
||||||
|
|
||||||
|
# Verify git repository
|
||||||
|
if (-not (Test-GitRepo)) {
|
||||||
|
Write-Error "Not a git repository: $RepoPath"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update .gitignore
|
||||||
|
Update-GitIgnore
|
||||||
|
|
||||||
|
$iteration = 0
|
||||||
|
|
||||||
|
while ($true) {
|
||||||
|
$iteration++
|
||||||
|
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||||
|
|
||||||
|
Write-Host "`n[$timestamp] Check #$iteration" -ForegroundColor Magenta
|
||||||
|
|
||||||
|
try {
|
||||||
|
# Commit changes
|
||||||
|
$committed = Invoke-AutoCommit
|
||||||
|
|
||||||
|
# Push if there was a commit
|
||||||
|
if ($committed) {
|
||||||
|
Start-Sleep -Seconds 2
|
||||||
|
Invoke-AutoPush
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wait for next interval
|
||||||
|
Write-Info "Next check in $IntervalSeconds seconds... (Press Ctrl+C to stop)"
|
||||||
|
Start-Sleep -Seconds $IntervalSeconds
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
Write-Error "Error during CD cycle: $_"
|
||||||
|
Write-Info "Continuing in 30 seconds..."
|
||||||
|
Start-Sleep -Seconds 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Start-FileWatcher {
|
||||||
|
Write-Info "========================================="
|
||||||
|
Write-Info "EasyStream File Watcher Started"
|
||||||
|
Write-Info "========================================="
|
||||||
|
Write-Info "Watching: $RepoPath"
|
||||||
|
Write-Info "Branch: $Branch"
|
||||||
|
Write-Info "Debounce: 30 seconds after last change"
|
||||||
|
Write-Info "========================================="
|
||||||
|
Write-Info ""
|
||||||
|
|
||||||
|
# Verify git repository
|
||||||
|
if (-not (Test-GitRepo)) {
|
||||||
|
Write-Error "Not a git repository: $RepoPath"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update .gitignore
|
||||||
|
Update-GitIgnore
|
||||||
|
|
||||||
|
# Create file system watcher
|
||||||
|
$watcher = New-Object System.IO.FileSystemWatcher
|
||||||
|
$watcher.Path = $RepoPath
|
||||||
|
$watcher.IncludeSubdirectories = $true
|
||||||
|
$watcher.EnableRaisingEvents = $true
|
||||||
|
|
||||||
|
# Exclude patterns
|
||||||
|
$watcher.Filter = "*.*"
|
||||||
|
$watcher.NotifyFilter = [System.IO.NotifyFilters]::FileName -bor
|
||||||
|
[System.IO.NotifyFilters]::DirectoryName -bor
|
||||||
|
[System.IO.NotifyFilters]::LastWrite
|
||||||
|
|
||||||
|
$global:lastChangeTime = Get-Date
|
||||||
|
$global:changedFiles = @{}
|
||||||
|
|
||||||
|
$onChange = {
|
||||||
|
param($sender, $e)
|
||||||
|
|
||||||
|
# Skip excluded patterns
|
||||||
|
$relativePath = $e.FullPath.Replace($RepoPath, "").TrimStart('\', '/')
|
||||||
|
$exclude = $false
|
||||||
|
foreach ($pattern in $excludePatterns) {
|
||||||
|
if ($relativePath -like $pattern) {
|
||||||
|
$exclude = $true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $exclude) {
|
||||||
|
$global:lastChangeTime = Get-Date
|
||||||
|
$global:changedFiles[$e.FullPath] = $e.ChangeType
|
||||||
|
Write-Host "[$(Get-Date -Format 'HH:mm:ss')] " -NoNewline -ForegroundColor Gray
|
||||||
|
Write-Host "$($e.ChangeType): " -NoNewline -ForegroundColor Yellow
|
||||||
|
Write-Host $relativePath -ForegroundColor White
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Register events
|
||||||
|
Register-ObjectEvent -InputObject $watcher -EventName Changed -Action $onChange | Out-Null
|
||||||
|
Register-ObjectEvent -InputObject $watcher -EventName Created -Action $onChange | Out-Null
|
||||||
|
Register-ObjectEvent -InputObject $watcher -EventName Deleted -Action $onChange | Out-Null
|
||||||
|
Register-ObjectEvent -InputObject $watcher -EventName Renamed -Action $onChange | Out-Null
|
||||||
|
|
||||||
|
Write-Success "File watcher active. Monitoring for changes..."
|
||||||
|
Write-Info "Changes will auto-commit 30 seconds after last modification"
|
||||||
|
Write-Info ""
|
||||||
|
|
||||||
|
try {
|
||||||
|
while ($true) {
|
||||||
|
Start-Sleep -Seconds 5
|
||||||
|
|
||||||
|
# Check if enough time has passed since last change
|
||||||
|
$timeSinceLastChange = (Get-Date) - $global:lastChangeTime
|
||||||
|
|
||||||
|
if ($global:changedFiles.Count -gt 0 -and $timeSinceLastChange.TotalSeconds -ge 30) {
|
||||||
|
Write-Info "`nDebounce period elapsed. Processing $($global:changedFiles.Count) changes..."
|
||||||
|
|
||||||
|
$committed = Invoke-AutoCommit
|
||||||
|
if ($committed) {
|
||||||
|
Start-Sleep -Seconds 2
|
||||||
|
Invoke-AutoPush
|
||||||
|
}
|
||||||
|
|
||||||
|
# Reset
|
||||||
|
$global:changedFiles = @{}
|
||||||
|
Write-Info "`nContinuing to watch for changes...`n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
$watcher.Dispose()
|
||||||
|
Get-EventSubscriber | Unregister-Event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
if ($WatchMode) {
|
||||||
|
Start-FileWatcher
|
||||||
|
} else {
|
||||||
|
Start-ContinuousDelivery
|
||||||
|
}
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
[mariadb-client]
|
|
||||||
port=3306
|
|
||||||
socket=/run/mysqld/mysqld.sock
|
|
||||||
user=healthcheck
|
|
||||||
password=/dG+QV8:N6Kzmww>pXRbf(<8))b`L_wn
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
BIN
db_data/ibdata1
BIN
db_data/ibdata1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,2 +0,0 @@
|
|||||||
default-character-set=utf8mb4
|
|
||||||
default-collation=utf8mb4_general_ci
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,16 +0,0 @@
|
|||||||
TYPE=VIEW
|
|
||||||
query=select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.plugin\') in (\'mysql_native_password\',\'mysql_old_password\'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.authentication_string\'),\'\'),\'\') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 1,\'Y\',\'N\') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 2,\'Y\',\'N\') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 4,\'Y\',\'N\') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 8,\'Y\',\'N\') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 16,\'Y\',\'N\') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 32,\'Y\',\'N\') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 64,\'Y\',\'N\') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 128,\'Y\',\'N\') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 256,\'Y\',\'N\') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 512,\'Y\',\'N\') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 1024,\'Y\',\'N\') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 2048,\'Y\',\'N\') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 4096,\'Y\',\'N\') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 8192,\'Y\',\'N\') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 16384,\'Y\',\'N\') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 32768,\'Y\',\'N\') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 65536,\'Y\',\'N\') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 131072,\'Y\',\'N\') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 262144,\'Y\',\'N\') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 524288,\'Y\',\'N\') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 1048576,\'Y\',\'N\') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 2097152,\'Y\',\'N\') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 4194304,\'Y\',\'N\') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 8388608,\'Y\',\'N\') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 16777216,\'Y\',\'N\') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 33554432,\'Y\',\'N\') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 67108864,\'Y\',\'N\') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 134217728,\'Y\',\'N\') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 268435456,\'Y\',\'N\') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 536870912,\'Y\',\'N\') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.ssl_type\'),0) + 1,\'\',\'ANY\',\'X509\',\'SPECIFIED\') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.ssl_cipher\'),\'\') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.x509_issuer\'),\'\') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.x509_subject\'),\'\') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.max_questions\'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.max_updates\'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.max_connections\'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.max_user_connections\'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.plugin\'),\'\') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.authentication_string\'),\'\') AS `authentication_string`,if(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.password_last_changed\'),1) = 0,\'Y\',\'N\') AS `password_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.is_role\'),0) + 1,\'N\',\'Y\') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.default_role\'),\'\') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.max_statement_time\'),0.0) as decimal(12,6)) AS `max_statement_time` from `mysql`.`global_priv`
|
|
||||||
md5=9e8063501afc8396f55d7c723632d5d8
|
|
||||||
updatable=1
|
|
||||||
algorithm=0
|
|
||||||
definer_user=mariadb.sys
|
|
||||||
definer_host=localhost
|
|
||||||
suid=1
|
|
||||||
with_check_option=0
|
|
||||||
timestamp=0001760433290176447
|
|
||||||
create-version=2
|
|
||||||
source=SELECT\n Host,\n User,\n IF(JSON_VALUE(Priv, \'$.plugin\') IN (\'mysql_native_password\', \'mysql_old_password\'), IFNULL(JSON_VALUE(Priv, \'$.authentication_string\'), \'\'), \'\') AS Password,\n IF(JSON_VALUE(Priv, \'$.access\') & 1, \'Y\', \'N\') AS Select_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 2, \'Y\', \'N\') AS Insert_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 4, \'Y\', \'N\') AS Update_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 8, \'Y\', \'N\') AS Delete_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 16, \'Y\', \'N\') AS Create_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 32, \'Y\', \'N\') AS Drop_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 64, \'Y\', \'N\') AS Reload_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 128, \'Y\', \'N\') AS Shutdown_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 256, \'Y\', \'N\') AS Process_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 512, \'Y\', \'N\') AS File_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 1024, \'Y\', \'N\') AS Grant_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 2048, \'Y\', \'N\') AS References_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 4096, \'Y\', \'N\') AS Index_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 8192, \'Y\', \'N\') AS Alter_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 16384, \'Y\', \'N\') AS Show_db_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 32768, \'Y\', \'N\') AS Super_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 65536, \'Y\', \'N\') AS Create_tmp_table_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 131072, \'Y\', \'N\') AS Lock_tables_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 262144, \'Y\', \'N\') AS Execute_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 524288, \'Y\', \'N\') AS Repl_slave_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 1048576, \'Y\', \'N\') AS Repl_client_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 2097152, \'Y\', \'N\') AS Create_view_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 4194304, \'Y\', \'N\') AS Show_view_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 8388608, \'Y\', \'N\') AS Create_routine_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 16777216, \'Y\', \'N\') AS Alter_routine_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 33554432, \'Y\', \'N\') AS Create_user_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 67108864, \'Y\', \'N\') AS Event_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 134217728, \'Y\', \'N\') AS Trigger_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 268435456, \'Y\', \'N\') AS Create_tablespace_priv,\n IF(JSON_VALUE(Priv, \'$.access\') & 536870912, \'Y\', \'N\') AS Delete_history_priv,\n ELT(IFNULL(JSON_VALUE(Priv, \'$.ssl_type\'), 0) + 1, \'\', \'ANY\',\'X509\', \'SPECIFIED\') AS ssl_type,\n IFNULL(JSON_VALUE(Priv, \'$.ssl_cipher\'), \'\') AS ssl_cipher,\n IFNULL(JSON_VALUE(Priv, \'$.x509_issuer\'), \'\') AS x509_issuer,\n IFNULL(JSON_VALUE(Priv, \'$.x509_subject\'), \'\') AS x509_subject,\n CAST(IFNULL(JSON_VALUE(Priv, \'$.max_questions\'), 0) AS UNSIGNED) AS max_questions,\n CAST(IFNULL(JSON_VALUE(Priv, \'$.max_updates\'), 0) AS UNSIGNED) AS max_updates,\n CAST(IFNULL(JSON_VALUE(Priv, \'$.max_connections\'), 0) AS UNSIGNED) AS max_connections,\n CAST(IFNULL(JSON_VALUE(Priv, \'$.max_user_connections\'), 0) AS SIGNED) AS max_user_connections,\n IFNULL(JSON_VALUE(Priv, \'$.plugin\'), \'\') AS plugin,\n IFNULL(JSON_VALUE(Priv, \'$.authentication_string\'), \'\') AS authentication_string,\n IF(IFNULL(JSON_VALUE(Priv, \'$.password_last_changed\'), 1) = 0, \'Y\', \'N\') AS password_expired,\n ELT(IFNULL(JSON_VALUE(Priv, \'$.is_role\'), 0) + 1, \'N\', \'Y\') AS is_role,\n IFNULL(JSON_VALUE(Priv, \'$.default_role\'), \'\') AS default_role,\n CAST(IFNULL(JSON_VALUE(Priv, \'$.max_statement_time\'), 0.0) AS DECIMAL(12,6)) AS max_statement_time\n FROM global_priv;
|
|
||||||
client_cs_name=utf8mb4
|
|
||||||
connection_cl_name=utf8mb4_general_ci
|
|
||||||
view_body_utf8=select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.plugin\') in (\'mysql_native_password\',\'mysql_old_password\'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.authentication_string\'),\'\'),\'\') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 1,\'Y\',\'N\') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 2,\'Y\',\'N\') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 4,\'Y\',\'N\') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 8,\'Y\',\'N\') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 16,\'Y\',\'N\') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 32,\'Y\',\'N\') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 64,\'Y\',\'N\') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 128,\'Y\',\'N\') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 256,\'Y\',\'N\') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 512,\'Y\',\'N\') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 1024,\'Y\',\'N\') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 2048,\'Y\',\'N\') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 4096,\'Y\',\'N\') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 8192,\'Y\',\'N\') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 16384,\'Y\',\'N\') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 32768,\'Y\',\'N\') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 65536,\'Y\',\'N\') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 131072,\'Y\',\'N\') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 262144,\'Y\',\'N\') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 524288,\'Y\',\'N\') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 1048576,\'Y\',\'N\') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 2097152,\'Y\',\'N\') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 4194304,\'Y\',\'N\') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 8388608,\'Y\',\'N\') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 16777216,\'Y\',\'N\') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 33554432,\'Y\',\'N\') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 67108864,\'Y\',\'N\') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 134217728,\'Y\',\'N\') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 268435456,\'Y\',\'N\') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,\'$.access\') & 536870912,\'Y\',\'N\') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.ssl_type\'),0) + 1,\'\',\'ANY\',\'X509\',\'SPECIFIED\') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.ssl_cipher\'),\'\') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.x509_issuer\'),\'\') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.x509_subject\'),\'\') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.max_questions\'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.max_updates\'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.max_connections\'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.max_user_connections\'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.plugin\'),\'\') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.authentication_string\'),\'\') AS `authentication_string`,if(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.password_last_changed\'),1) = 0,\'Y\',\'N\') AS `password_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.is_role\'),0) + 1,\'N\',\'Y\') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.default_role\'),\'\') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,\'$.max_statement_time\'),0.0) as decimal(12,6)) AS `max_statement_time` from `mysql`.`global_priv`
|
|
||||||
mariadb-version=100623
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user