or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

database-configuration.mddatabase-initialization.mdindex.mdmysql-container.mdprovider-pattern.mdr2dbc-integration.md

database-initialization.mddocs/

0

# Database Initialization

1

2

Database initialization functionality for running SQL scripts and setup procedures when the MySQL container starts, inherited from JdbcDatabaseContainer.

3

4

## Capabilities

5

6

### Single Script Initialization

7

8

Initialize the database with a single SQL script file.

9

10

```java { .api }

11

/**

12

* Sets a script for initialization that runs after container startup

13

* @param initScriptPath path to the SQL script file (relative to classpath)

14

* @return Container instance for method chaining

15

*/

16

public SELF withInitScript(String initScriptPath);

17

```

18

19

**Usage Examples:**

20

21

```java

22

MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0")

23

.withDatabaseName("testdb")

24

.withInitScript("init/setup.sql");

25

26

mysql.start();

27

```

28

29

Example initialization script (`src/test/resources/init/setup.sql`):

30

31

```sql

32

-- Create tables

33

CREATE TABLE users (

34

id INT AUTO_INCREMENT PRIMARY KEY,

35

username VARCHAR(50) NOT NULL UNIQUE,

36

email VARCHAR(100) NOT NULL,

37

created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

38

);

39

40

CREATE TABLE posts (

41

id INT AUTO_INCREMENT PRIMARY KEY,

42

user_id INT NOT NULL,

43

title VARCHAR(200) NOT NULL,

44

content TEXT,

45

created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

46

FOREIGN KEY (user_id) REFERENCES users(id)

47

);

48

49

-- Insert sample data

50

INSERT INTO users (username, email) VALUES

51

('alice', 'alice@example.com'),

52

('bob', 'bob@example.com');

53

54

INSERT INTO posts (user_id, title, content) VALUES

55

(1, 'First Post', 'This is Alice''s first post'),

56

(2, 'Hello World', 'Bob says hello to the world');

57

```

58

59

### Multiple Scripts Initialization (Array)

60

61

Initialize the database with multiple SQL scripts executed in order.

62

63

```java { .api }

64

/**

65

* Sets an ordered array of scripts for initialization

66

* Scripts are executed in the order provided

67

* @param initScriptPaths paths to the script files

68

* @return Container instance for method chaining

69

*/

70

public SELF withInitScripts(String... initScriptPaths);

71

```

72

73

**Usage Examples:**

74

75

```java

76

MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0")

77

.withDatabaseName("testdb")

78

.withInitScripts(

79

"init/01-schema.sql",

80

"init/02-data.sql",

81

"init/03-indexes.sql"

82

);

83

84

mysql.start();

85

```

86

87

Example script files:

88

89

`src/test/resources/init/01-schema.sql`:

90

```sql

91

-- Create database schema

92

CREATE TABLE categories (

93

id INT AUTO_INCREMENT PRIMARY KEY,

94

name VARCHAR(100) NOT NULL UNIQUE

95

);

96

97

CREATE TABLE products (

98

id INT AUTO_INCREMENT PRIMARY KEY,

99

category_id INT NOT NULL,

100

name VARCHAR(200) NOT NULL,

101

price DECIMAL(10,2) NOT NULL,

102

FOREIGN KEY (category_id) REFERENCES categories(id)

103

);

104

```

105

106

`src/test/resources/init/02-data.sql`:

107

```sql

108

-- Insert master data

109

INSERT INTO categories (name) VALUES

110

('Electronics'),

111

('Books'),

112

('Clothing');

113

114

INSERT INTO products (category_id, name, price) VALUES

115

(1, 'Laptop', 999.99),

116

(1, 'Mouse', 29.99),

117

(2, 'Java Programming Guide', 49.99);

118

```

119

120

`src/test/resources/init/03-indexes.sql`:

121

```sql

122

-- Create performance indexes

123

CREATE INDEX idx_products_category ON products(category_id);

124

CREATE INDEX idx_products_name ON products(name);

125

CREATE INDEX idx_products_price ON products(price);

126

```

127

128

### Multiple Scripts Initialization (Collection)

129

130

Initialize the database with scripts from a collection, maintaining execution order.

131

132

```java { .api }

133

/**

134

* Sets an ordered collection of scripts for initialization

135

* Scripts are executed in the order they appear in the collection

136

* @param initScriptPaths paths to the script files as an Iterable

137

* @return Container instance for method chaining

138

*/

139

public SELF withInitScripts(Iterable<String> initScriptPaths);

140

```

141

142

**Usage Examples:**

143

144

```java

145

import java.util.List;

146

import java.util.Arrays;

147

148

List<String> scriptPaths = Arrays.asList(

149

"init/database-schema.sql",

150

"init/test-data.sql",

151

"init/stored-procedures.sql"

152

);

153

154

MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0")

155

.withDatabaseName("testdb")

156

.withInitScripts(scriptPaths);

157

158

mysql.start();

159

```

160

161

### Script Execution Timing

162

163

Initialization scripts are executed after the container starts and the database is ready, but before the container is considered fully started for test execution.

164

165

**Execution Order:**

166

167

1. Container starts with MySQL server

168

2. Database and user credentials are configured

169

3. Container passes health check (SELECT 1 query succeeds)

170

4. Initialization scripts are executed in specified order

171

5. Container is marked as ready for test execution

172

173

**Script Execution Environment:**

174

175

- Scripts run with the configured database user credentials

176

- The specified database is selected as the current database

177

- Full MySQL SQL syntax is supported

178

- Scripts can create tables, insert data, create stored procedures, etc.

179

- Any SQL errors will cause container startup to fail

180

181

### Advanced Initialization Examples

182

183

**Complex Database Setup:**

184

185

```java

186

MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0")

187

.withDatabaseName("ecommerce_test")

188

.withUsername("app_user")

189

.withPassword("app_password")

190

.withInitScripts(

191

"schema/01-users-table.sql",

192

"schema/02-products-table.sql",

193

"schema/03-orders-table.sql",

194

"data/01-test-users.sql",

195

"data/02-sample-products.sql",

196

"procedures/01-user-procedures.sql",

197

"procedures/02-order-procedures.sql"

198

);

199

200

mysql.start();

201

```

202

203

**Conditional Initialization:**

204

205

```java

206

List<String> scripts = new ArrayList<>();

207

scripts.add("init/base-schema.sql");

208

209

if (includeTestData) {

210

scripts.add("init/test-data.sql");

211

}

212

213

if (includeDemoData) {

214

scripts.add("init/demo-data.sql");

215

}

216

217

MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0")

218

.withDatabaseName("testdb")

219

.withInitScripts(scripts);

220

```

221

222

### Script Content Guidelines

223

224

**Supported SQL Features:**

225

226

- DDL: CREATE TABLE, CREATE INDEX, ALTER TABLE, etc.

227

- DML: INSERT, UPDATE, DELETE statements

228

- Stored procedures and functions

229

- Views and triggers

230

- User-defined variables

231

- Comments (-- and /* */)

232

233

**Best Practices:**

234

235

```sql

236

-- Use IF NOT EXISTS for idempotent scripts

237

CREATE TABLE IF NOT EXISTS users (

238

id INT AUTO_INCREMENT PRIMARY KEY,

239

name VARCHAR(100) NOT NULL

240

);

241

242

-- Handle potential duplicate data

243

INSERT IGNORE INTO categories (name) VALUES ('Electronics');

244

245

-- Use transactions for data consistency

246

START TRANSACTION;

247

INSERT INTO users (name) VALUES ('Test User');

248

INSERT INTO user_profiles (user_id, email) VALUES (LAST_INSERT_ID(), 'test@example.com');

249

COMMIT;

250

251

-- Set character encoding for proper text handling

252

SET NAMES utf8mb4;

253

```

254

255

### Error Handling

256

257

If any initialization script fails, the container startup will fail with a clear error message.

258

259

**Common Script Errors:**

260

261

```java

262

try {

263

MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0")

264

.withInitScript("init/invalid-syntax.sql"); // Contains SQL syntax error

265

266

mysql.start(); // Will throw exception due to script failure

267

} catch (Exception e) {

268

// Handle initialization failure

269

System.err.println("Database initialization failed: " + e.getMessage());

270

// Check container logs for detailed SQL error information

271

}

272

```

273

274

**Script Debugging:**

275

276

- Container logs contain detailed SQL execution output

277

- Use MySQL-specific error codes to diagnose issues

278

- Scripts should be tested independently before container integration

279

- Consider using smaller, focused scripts rather than large monolithic files

280

281

### Integration with Testing Frameworks

282

283

**JUnit 5 Example:**

284

285

```java

286

@Testcontainers

287

class DatabaseIntegrationTest {

288

289

@Container

290

static MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0")

291

.withDatabaseName("test")

292

.withInitScript("test-schema.sql");

293

294

@Test

295

void testDatabaseSetup() {

296

// Database is already initialized with test-schema.sql

297

try (Connection conn = mysql.createConnection("")) {

298

Statement stmt = conn.createStatement();

299

ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM users");

300

rs.next();

301

assertTrue(rs.getInt(1) >= 0); // Table exists and is queryable

302

}

303

}

304

}