mssql_io 0.0.2 copy "mssql_io: ^0.0.2" to clipboard
mssql_io: ^0.0.2 copied to clipboard

Flutter plugin for Microsoft SQL Server using FFI and FreeTDS. Cross-platform support.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:mssql_io/mssql_io.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'MSSQL IO Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        useMaterial3: true,
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final _hostController = TextEditingController(text: 'localhost');
  final _portController = TextEditingController(text: '1433');
  final _databaseController = TextEditingController(text: 'TestDB');
  final _usernameController = TextEditingController(text: 'sa');
  final _passwordController = TextEditingController(text: 'Password123');

  final _queryController = TextEditingController(
    text: 'SELECT 1 AS num, \'Hello\' AS message',
  );

  final MssqlConnection _conn = MssqlConnection.getInstance();

  bool _isConnected = false;
  String _output = 'Not connected';
  bool _isLoading = false;

  @override
  void dispose() {
    _hostController.dispose();
    _portController.dispose();
    _databaseController.dispose();
    _usernameController.dispose();
    _passwordController.dispose();
    _queryController.dispose();
    super.dispose();
  }

  Future<void> _connect() async {
    setState(() {
      _isLoading = true;
      _output = 'Connecting...';
    });

    try {
      await _conn.connect(
        host: _hostController.text,
        port: int.parse(_portController.text),
        databaseName: _databaseController.text,
        username: _usernameController.text,
        password: _passwordController.text,
        timeoutInSeconds: 15,
      );

      setState(() {
        _isConnected = true;
        _output = 'Connected successfully to ${_databaseController.text}';
      });
    } catch (e) {
      setState(() {
        _isConnected = false;
        _output = 'Connection failed: $e';
      });
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  Future<void> _disconnect() async {
    try {
      await _conn.disconnect();
      setState(() {
        _isConnected = false;
        _output = 'Disconnected';
      });
    } catch (e) {
      setState(() {
        _output = 'Disconnect failed: $e';
      });
    }
  }

  Future<void> _executeQuery() async {
    if (!_isConnected) {
      setState(() {
        _output = 'Not connected. Please connect first.';
      });
      return;
    }

    setState(() {
      _isLoading = true;
      _output = 'Executing query...';
    });

    try {
      final result = await _conn.getData(_queryController.text);

      final buffer = StringBuffer();
      buffer.writeln('Query executed successfully\n');
      buffer.writeln('Columns: ${result.columns.join(", ")}\n');
      buffer.writeln('Rows returned: ${result.rowCount}\n');

      if (result.isNotEmpty) {
        buffer.writeln('Results:');
        for (int i = 0; i < result.rows.length; i++) {
          buffer.writeln('Row ${i + 1}: ${result.rows[i]}');
        }
      }

      setState(() {
        _output = buffer.toString();
      });
    } catch (e) {
      setState(() {
        _output = 'Query failed: $e';
      });
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  Future<void> _testTransaction() async {
    if (!_isConnected) {
      setState(() {
        _output = 'Not connected. Please connect first.';
      });
      return;
    }

    setState(() {
      _isLoading = true;
      _output = 'Testing transaction...';
    });

    try {
      await _conn.beginTransaction();

      // Create a temporary table
      await _conn.writeData('''
        IF OBJECT_ID('TempTest', 'U') IS NOT NULL 
          DROP TABLE TempTest;
        CREATE TABLE TempTest (Id INT, Value NVARCHAR(50));
      ''');

      // Insert some data
      await _conn.writeData('INSERT INTO TempTest VALUES (1, \'Test1\')');
      await _conn.writeData('INSERT INTO TempTest VALUES (2, \'Test2\')');

      // Query the data
      final result = await _conn.getData('SELECT * FROM TempTest');

      // Rollback to clean up
      await _conn.rollback();

      setState(() {
        _output = 'Transaction test successful\n'
            'Created table, inserted ${result.rowCount} rows, '
            'then rolled back.\n\n'
            'Data during transaction:\n${result.rows}';
      });
    } catch (e) {
      try {
        await _conn.rollback();
      } catch (_) {}
      setState(() {
        _output = 'Transaction test failed: $e';
      });
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  Future<void> _testParameterizedQuery() async {
    if (!_isConnected) {
      setState(() {
        _output = 'Not connected. Please connect first.';
      });
      return;
    }

    setState(() {
      _isLoading = true;
      _output = 'Testing parameterized query...';
    });

    try {
      final result = await _conn.getDataWithParams(
        'SELECT @name AS Name, @age AS Age, @active AS Active',
        [
          SqlParameter(name: 'name', value: 'John Doe'),
          SqlParameter(name: 'age', value: 30),
          SqlParameter(name: 'active', value: true),
        ],
      );

      setState(() {
        _output = 'Parameterized query successful\n\n'
            'Result: ${result.rows.first}';
      });
    } catch (e) {
      setState(() {
        _output = 'Parameterized query failed: $e';
      });
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('MSSQL IO Example'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            // Connection Status
            Card(
              color: _isConnected ? Colors.green[50] : Colors.grey[100],
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Row(
                  children: [
                    Icon(
                      _isConnected ? Icons.check_circle : Icons.cancel,
                      color: _isConnected ? Colors.green : Colors.grey,
                    ),
                    const SizedBox(width: 8),
                    Text(
                      _isConnected ? 'Connected' : 'Disconnected',
                      style: Theme.of(context).textTheme.titleMedium,
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),

            // Connection Fields
            TextField(
              controller: _hostController,
              decoration: const InputDecoration(
                labelText: 'Host',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 8),
            TextField(
              controller: _portController,
              decoration: const InputDecoration(
                labelText: 'Port',
                border: OutlineInputBorder(),
              ),
              keyboardType: TextInputType.number,
            ),
            const SizedBox(height: 8),
            TextField(
              controller: _databaseController,
              decoration: const InputDecoration(
                labelText: 'Database',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 8),
            TextField(
              controller: _usernameController,
              decoration: const InputDecoration(
                labelText: 'Username',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 8),
            TextField(
              controller: _passwordController,
              decoration: const InputDecoration(
                labelText: 'Password',
                border: OutlineInputBorder(),
              ),
              obscureText: true,
            ),
            const SizedBox(height: 16),

            // Connection Buttons
            Row(
              children: [
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: _isLoading || _isConnected ? null : _connect,
                    icon: const Icon(Icons.link),
                    label: const Text('Connect'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: _isLoading || !_isConnected ? null : _disconnect,
                    icon: const Icon(Icons.link_off),
                    label: const Text('Disconnect'),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.red[400],
                      foregroundColor: Colors.white,
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 24),

            // Query Section
            const Text(
              'Execute Query',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            TextField(
              controller: _queryController,
              decoration: const InputDecoration(
                labelText: 'SQL Query',
                border: OutlineInputBorder(),
              ),
              maxLines: 3,
            ),
            const SizedBox(height: 8),
            ElevatedButton.icon(
              onPressed: _isLoading || !_isConnected ? null : _executeQuery,
              icon: const Icon(Icons.play_arrow),
              label: const Text('Execute Query'),
            ),
            const SizedBox(height: 16),

            // Test Buttons
            const Text(
              'Test Operations',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            Wrap(
              spacing: 8,
              runSpacing: 8,
              children: [
                ElevatedButton.icon(
                  onPressed: _isLoading || !_isConnected
                      ? null
                      : _testParameterizedQuery,
                  icon: const Icon(Icons.settings),
                  label: const Text('Parameterized Query'),
                ),
                ElevatedButton.icon(
                  onPressed:
                      _isLoading || !_isConnected ? null : _testTransaction,
                  icon: const Icon(Icons.sync),
                  label: const Text('Transaction'),
                ),
              ],
            ),
            const SizedBox(height: 24),

            // Output Section
            const Text(
              'Output',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            Container(
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: Colors.grey[100],
                borderRadius: BorderRadius.circular(8),
                border: Border.all(color: Colors.grey[300]!),
              ),
              constraints: const BoxConstraints(minHeight: 150),
              child: _isLoading
                  ? const Center(child: CircularProgressIndicator())
                  : SingleChildScrollView(
                      child: Text(
                        _output,
                        style: const TextStyle(
                          fontFamily: 'monospace',
                          fontSize: 12,
                        ),
                      ),
                    ),
            ),
          ],
        ),
      ),
    );
  }
}
4
likes
0
points
27
downloads

Publisher

verified publisherfarhansadikgalib.com

Weekly Downloads

Flutter plugin for Microsoft SQL Server using FFI and FreeTDS. Cross-platform support.

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

ffi, flutter, flutter_web_plugins, http, js

More

Packages that depend on mssql_io

Packages that implement mssql_io