dartonic 0.0.9 copy "dartonic: ^0.0.9" to clipboard
dartonic: ^0.0.9 copied to clipboard

A database query builder inspired by Drizzle. It allows you to connect to various databases (SQLite, PostgreSQL, MySQL) and perform database operations using a fluent API.

example/README.md

// final users = await db
// .select({'name': 'users.fullname', 'age': 'users.birthday'})
// .from('users');

// final usersTable = sqliteTable('users', {
// 'id': integer().primaryKey(autoIncrement: true),
// 'name': text(columnName: 'fullname'),
// 'age': integer(columnName: 'birthday'),
// 'created_at': timestamp().notNull().defaultNow(),
// 'updated_at': timestamp().notNull().defaultNow(),
// });

// final ordersTable = sqliteTable('orders', {
// 'id': integer().primaryKey(autoIncrement: true),
// 'user_id': integer(columnName: 'user_id').references(() => 'users.id'),
// 'total': integer(),
// });

// final inserted =
// await db.insert('users').values({
// 'name': "Test User",
// 'age': 99,
// }).returning();
// print("Inserido: $inserted");

// final id = inserted.first['id'];

// final deleted = await db
// .delete('users')
// .where(eq("users.id", id))
// .returning(deletedId: 'users.id');
// print("Deletado: $deleted");

// final insertedUser =
// await db.insert('users').values({'name': "Dan", 'age': 28}).returning();
// print("Insert com RETURNING completo:");
// print(insertedUser);

// // Exemplo de INSERT com RETURNING retornando somente o id inserido.
// final insertedPartial = await db
// .insert('users')
// .values({'name': "Partial Dan", 'age': 30})
// .returning(insertedId: 'users.id');
// print("Insert com RETURNING parcial (somente id):");
// print(insertedPartial);

// // Exemplo de UPDATE com RETURNING retornando todos os campos atualizados.
// final updatedUser =
// await db
// .update('users')
// .set({'name': "Daniel", 'age': 29})
// .where(eq("users.id", 1))
// .returning();
// print("Update com RETURNING completo:");
// print(updatedUser);

// // Exemplo de UPDATE com RETURNING retornando somente o id atualizado.
// final updatedPartial = await db
// .update('users')
// .set({'age': 35})
// .where(eq("users.id", 2))
// .returning(updatedId: 'users.id');
// print("Update com RETURNING parcial (somente id):");
// print(updatedPartial);

// // Exemplo de DELETE com RETURNING retornando todos os campos do registro deletado.
// final deletedUser =
// await db.delete('users').where(eq("users.id", 3)).returning();
// print("Delete com RETURNING completo:");
// print(deletedUser);

// // Exemplo de DELETE com RETURNING retornando somente o id deletado.
// final deletedPartial = await db
// .delete('users')
// .where(eq("users.id", 4))
// .returning(deletedId: 'users.id');
// print("Delete com RETURNING parcial (somente id):");
// print(deletedPartial);

// Inserindo alguns usuários
// await db.insert("users").values({'name': 'Alice', 'age': 30});
// await db.insert("users").values({'name': 'Bob', 'age': 25});
// await db.insert("users").values({'name': 'Charlie', 'age': 35});

// // Inserindo alguns pedidos
// await db.insert("orders").values({'user_id': 1, 'total': 100});
// await db.insert("orders").values({'user_id': 1, 'total': 150});
// await db.insert("orders").values({'user_id': 2, 'total': 200});

// // Exemplos de filtros

// // eq: Seleciona usuários com age igual a 30
// final eqQuery = db.select().from("users").where(eq("users.age", 30));
// print("SQL eq:");
// print(eqQuery.toSql());
// print(await eqQuery);

// // ne: Seleciona usuários com age diferente de 30
// final neQuery = db.select().from("users").where(ne("users.age", 30));
// print("SQL ne:");
// print(neQuery.toSql());
// print(await neQuery);

// // gt: Seleciona usuários com age maior que 25
// final gtQuery = db.select().from("users").where(gt("users.age", 25));
// print("SQL gt:");
// print(gtQuery.toSql());
// print(await gtQuery);

// // gte: Seleciona usuários com age maior ou igual que 30
// final gteQuery = db.select().from("users").where(gte("users.age", 30));
// print("SQL gte:");
// print(gteQuery.toSql());
// print(await gteQuery);

// // lt: Seleciona usuários com age menor que 35
// final ltQuery = db.select().from("users").where(lt("users.age", 35));
// print("SQL lt:");
// print(ltQuery.toSql());
// print(await ltQuery);

// // lte: Seleciona usuários com age menor ou igual que 30
// final lteQuery = db.select().from("users").where(lte("users.age", 30));
// print("SQL lte:");
// print(lteQuery.toSql());
// print(await lteQuery);

// // exists: Seleciona usuários que possuem pedidos
// final subquery = db
// .select()
// .from("orders")
// .where(eq("orders.user_id", "users.id"));
// final existsQuery = db.select().from("users").where(exists(subquery));
// print("SQL exists:");
// print(existsQuery.toSql());
// print(await existsQuery);

// // notExists: Seleciona usuários que não possuem pedidos
// final notExistsQuery = db.select().from("users").where(notExists(subquery));
// print("SQL notExists:");
// print(notExistsQuery.toSql());
// print(await notExistsQuery);

// // isNull: Suponha que exista uma coluna opcional 'nickname'
// final isNullQuery = db.select().from("users").where(isNull("users.name"));
// print("SQL isNull:");
// print(isNullQuery.toSql());
// print(await isNullQuery);

// // isNotNull: Suponha que exista uma coluna opcional 'nickname'
// final isNotNullQuery = db
// .select()
// .from("users")
// .where(isNotNull("users.name"));
// print("SQL isNotNull:");
// print(isNotNullQuery.toSql());
// print(await isNotNullQuery);

// // inArray: Seleciona usuários com age em [25, 35]
// final inArrayQuery = db
// .select()
// .from("users")
// .where(inArray("users.age", [25, 35]));
// print("SQL inArray:");
// print(inArrayQuery.toSql());
// print(await inArrayQuery);

// // notInArray: Seleciona usuários com age que não estejam em [30]
// final notInArrayQuery = db
// .select()
// .from("users")
// .where(notInArray("users.age", [30]));
// print("SQL notInArray:");
// print(notInArrayQuery.toSql());
// print(await notInArrayQuery);

// // between: Seleciona usuários com age entre 26 e 34
// final betweenQuery = db
// .select()
// .from("users")
// .where(between("users.age", 26, 34));
// print("SQL between:");
// print(betweenQuery.toSql());
// print(await betweenQuery);

// // notBetween: Seleciona usuários com age fora do intervalo 26 e 34
// final notBetweenQuery = db
// .select()
// .from("users")
// .where(notBetween("users.age", 26, 34));
// print("SQL notBetween:");
// print(notBetweenQuery.toSql());
// print(await notBetweenQuery);

// // like: Seleciona usuários com nome contendo 'li'
// final likeQuery = db.select().from("users").where(like("users.name", "%li%"));
// print("SQL like:");
// print(likeQuery.toSql());
// print(await likeQuery);

// ilike: (em bancos que suportam ILIKE) similar ao like, Postgres
// final ilikeQuery = db
// .select()
// .from("users")
// .where(ilike("users.name", "%AL%"));
// print("SQL ilike:");
// print(ilikeQuery.toSql());
// print(await ilikeQuery);

// notIlike: Seleciona usuários com nome que não contenham 'bo' not supported in sqlite
// final notIlikeQuery = db
// .select()
// .from("users")
// .where(notIlike("users.name", "%bo%"));
// print("SQL notIlike:");
// print(notIlikeQuery.toSql());
// print(await notIlikeQuery);

// not: Seleciona usuários que NÃO tenham age igual a 30
// final notQuery = db.select().from("users").where(not(eq("users.age", 30)));
// print("SQL not:");
// print(notQuery.toSql());
// print(await notQuery);

// // and: Seleciona usuários com age > 25 e < 35
// final andQuery = db
// .select()
// .from("users")
// .where(and([gt("users.age", 25), lt("users.age", 35)]));
// print("SQL and:");
// print(andQuery.toSql());
// print(await andQuery);

// // or: Seleciona usuários com age < 25 ou age > 35
// final orQuery = db
// .select()
// .from("users")
// .where(or([lt("users.age", 25), gt("users.age", 35)]));
// print("SQL or:");
// print(orQuery.toSql());
// print(await orQuery);

// // JOINs com filtros: Exemplo de INNER JOIN entre users e orders onde total > 100
// final joinQuery = db
// .select()
// .from("users")
// .innerJoin("orders", eq("users.id", "orders.user_id"))
// .where(gt("orders.total", 100));
// print("SQL INNER JOIN com filtro:");
// print(joinQuery.toSql());
// print(await joinQuery);

final usersTable = sqliteTable('users', {
    'id': integer().primaryKey(autoIncrement: true),
    'name': text(),
});

// Definindo a tabela de perfil (relação 1:1 com usuários)
final profileInfo = sqliteTable('profile_info', {
    'id': integer().primaryKey(),
    'user_id': integer(columnName: 'user_id').references(() => 'users.id'),
    'bio': text(),
});

// Definindo a tabela de pets (para exemplificar os diferentes JOINs)
final petsTable = sqliteTable('pets', {
    'id': integer().primaryKey(autoIncrement: true),
    'owner_id': integer(columnName: 'owner_id').references(() => 'users.id'),
    'name': text(),
});

// Definindo a tabela de posts (relação muitos:1 - muitos posts por usuário)
final postsTable = sqliteTable('posts', {
    'id': integer().primaryKey(autoIncrement: true),
    'user_id': integer(columnName: 'user_id').references(() => 'users.id'),
    'content': text(),
});

// // Definindo relacionamentos para a tabela de usuários:
// // Relação one: cada usuário possui um profileInfo
// // Relação many: cada usuário possui vários posts
final usersRelations = relations(usersTable, (builder) => {
    'profileInfo': builder.one(
        'profile_info',
        fields: ['users.id'],
        references: ['profile_info.user_id'],
    ),
    'posts': builder.many(
        'posts',
        fields: ['users.id'],
        references: ['posts.user_id'],
    ),
  },
);

// // Instanciando Dartlize e incluindo apenas as tabelas com definições de coluna
// final dartlize = Dartlize("sqlite://database.db", [
// usersTable,
// profileInfo,
// petsTable,
// postsTable,
// usersRelations, // tabelas de relacionamento são meta-informação e não serão criadas no banco.
// ]);
// final db = await dartlize.sync();

// // Exemplos de INSERT:

// // Inserindo um usuário
// await db.insert("users").values({'name': 'Alice'});
// // Inserindo dados para profile_info (assumindo que o novo usuário tem id = 1)
// await db.insert("profile_info").values({
// 'user_id': 1,
// 'bio': 'Desenvolvedora apaixonada por Dart e Flutter!',
// });
// // Inserindo um pet para o usuário
// await db.insert("pets").values({'owner_id': 1, 'name': 'Bob, o Cachorro'});
// // Inserindo posts para o usuário
// await db.insert("posts").values({
// 'user_id': 1,
// 'content': 'Meu primeiro post!',
// });
// await db.insert("posts").values({
// 'user_id': 1,
// 'content': 'Explorando JOINs com Dartlize.',
// });

// // Exemplos de SELECT com JOINs:

// // Inner Join: usuários e posts (apenas onde houver correspondência)
// final innerJoinQuery = db
// .select()
// .from("users")
// .innerJoin("posts", eq("users.id", "posts.user_id"));
// print("SQL INNER JOIN (users + posts):");
// print(innerJoinQuery.toSql());
// final innerResult = await innerJoinQuery;
// print("Resultado INNER JOIN:");
// print(innerResult);

// // Left Join: usuários com pets (mostra todos os usuários mesmo sem pets)
// final leftJoinQuery = db
// .select()
// .from("users")
// .leftJoin("pets", eq("users.id", "pets.owner_id"));
// print("SQL LEFT JOIN (users + pets):");
// print(leftJoinQuery.toSql());
// final leftResult = await leftJoinQuery;
// print("Resultado LEFT JOIN:");
// print(leftResult);

// // Right Join: Usuários com pets (note: SQLite não suporta RIGHT JOIN nativamente,
// // mas o SQL é gerado conforme solicitado)
// final rightJoinQuery = db
// .select()
// .from("users")
// .rightJoin("pets", eq("users.id", "pets.owner_id"));
// print("SQL RIGHT JOIN (users + pets):");
// print(rightJoinQuery.toSql());
// final rightResult = await rightJoinQuery;
// print("Resultado RIGHT JOIN:");
// print(rightResult);

// // Full Join: Usuários com pets (SQLite não suporta FULL JOIN nativamente,
// // mas vamos gerar a query conforme solicitado para fins de demonstração)
// final fullJoinQuery = db
// .select()
// .from("users")
// .fullJoin("pets", eq("users.id", "pets.owner_id"));
// print("SQL FULL JOIN (users + pets):");
// print(fullJoinQuery.toSql());
// final fullResult = await fullJoinQuery;
// print("Resultado FULL JOIN:");
// print(fullResult);

// final usersTable = sqliteTable('users', {
// 'id': integer().primaryKey(autoIncrement: true),
// 'name': text(),
// });

// // Definição dos relacionamentos para a tabela de usuários.
// // Corrigido: Agora usamos o parâmetro "builder" e chamamos builder.one(...)
// final usersRelations = relations(
// usersTable,
// (builder) => {'profileInfo': builder.one('profile_info')},
// );

// // Definição da tabela de profile_info.
// final profileInfo = sqliteTable('profile_info', {
// 'id': integer().primaryKey(),
// 'userId': integer(columnName: 'user_id').references(() => 'users.id'),
// 'bio': text(),
// });

// // Exemplo de relacionamento para posts.
// final postsRelations = relations(
// 'posts',
// (builder) => {
// 'author': builder.one(
// 'users',
// fields: ['posts.authorId'],
// references: ['users.id'],
// ),
// },
// );

// // Instancia e sincroniza as tabelas usando Dartlize.
// // Note que as relações (do tipo RelationsTable) não serão criadas no banco,
// // garantindo que apenas as tabelas base sejam criadas.
// final dartlize = Dartlize("sqlite://database.db", [
// usersTable,
// profileInfo,
// usersRelations,
// postsRelations,
// ]);
// final db = await dartlize.sync();

// final users = await db.select().from("users");
// print(users);

// Exemplo: Inserção de um usuário.
// await db.insert("users").values({'name': 'Alice'});

// final selectQuery = db.select().from("users").where(eq('name', 'Alice'));
// print(selectQuery);

// final usersTable = sqliteTable("users", {
// 'id': integer().primaryKey(autoIncrement: true),
// 'name': text().notNull(),
// 'age': integer(),
// 'email': text().notNull().unique(),
// });

// final dartlize = Dartlize("sqlite://database.db", [usersTable]);
// final db = await dartlize.sync();

// await db.insert('users').values({
// 'name': 'John Doe',
// 'age': 30,
// 'email': 'john@mail.com',
// });

// var selectQuery = await db.select().from('users');

// await db
// .update('users')
// .set({'age': 31})
// .where(eq('users.email', 'john@mail.com'));

// selectQuery = await db.select().from('users');
// print(selectQuery);

// await db.insert('users').values({
// 'name': 'Evanderson',
// 'age': 32,
// 'email': 'evan@mail.com',
// });

// // Exemplo: Exclusão.
// final deleteQuery = db
// .delete('users')
// // Note: O método set() em delete não gera uma cláusula SET no SQL padrão;
// // ele pode ser utilizado para lógica customizada (ex: soft delete).
// .set({'age': 31})
// .where(eq('users.email', 'john@mail.com'));
// print("SQL gerado (DELETE): ${deleteQuery.toSql()}");
// await deleteQuery.execute();

  // Inserir mais dados de teste
  // final user =
  //     await db.insert('users').values({
  //       'id': Uuid().v4(),
  //       'name': 'Jane Doe',
  //       'email': 'janedoe@mail.com',
  //     }).returning();
  // await db.insert('users').values({
  //   'id': Uuid().v4(),
  //   'name': 'John Doe',
  //   'email': 'johndoe@mail.com',
  // });

  // await db.insert('roles').values({'id': Uuid().v4(), 'name': 'user'});
  // final role =
  //     await db.insert('roles').values({
  //       'id': Uuid().v4(),
  //       'name': 'admin',
  //     }).returning();

  // // Criar mais relacionamentos
  // await db.insert('user_roles').values({
  //   'user_id': user[0]['id'], // Jane Doe
  //   'role_id': role[0]['id'], // role user
  // });

  // await db.insert('user_roles').values({
  //   'user_id': 2, // Jane Doe
  //   'role_id': 1, // role admin
  // });

  // Primeiro vamos garantir que o count está funcionando corretamente
  // Primeiro, confirmamos que temos 2 roles no sistema
  // final userNameLikeJohn = await db
  //     .select()
  //     .from('users')
  //     .where(like('users.name', '%john%'));
  // print('Total de Roles: $totalRoles');
  // final user = await db.select().from('users');
  // print('Select with where like: $userNameLikeJohn');

  // Query para buscar usuários e suas roles
  // final usersWithRoles = await db
  //     .select({
  //       'name': 'users.name',
  //       'total_roles': count(
  //         'user_roles.role_id',
  //         distinct: true,
  //       ), // sql('COUNT(DISTINCT user_roles.role_id)'),
  //     })
  //     .from('users')
  //     .innerJoin('user_roles', eq('users.id', 'user_roles.user_id'))
  //     .groupBy(['users.id', 'users.name']);
  // print('Usuários e suas roles: $usersWithRoles');

  // final usersInnerRole = await db
  //     .select()
  //     .from('users')
  //     .innerJoin('user_roles', eq('users.id', 'user_roles.user_id'));
  // print('Usuários com roles: $usersInnerRole');

  // // Query para buscar apenas usuários que têm TODAS as roles
  // final usersWithAllRoles = await db
  //     .select({
  //       'name': 'users.name',
  //       'total_roles': 'COUNT(DISTINCT user_roles.role_id)',
  //     })
  //     .from('users')
  //     .innerJoin('user_roles', eq('users.id', 'user_roles.user_id'))
  //     .groupBy(['users.id', 'users.name'])
  //     .having(eq('COUNT(DISTINCT user_roles.role_id)', totalRoles[0]['total']));
  // print('Usuários com todas as roles: $usersWithAllRoles');

  // final userUpdate =
  //     await db
  //         .update('users')
  //         .set({'name': 'John Doe Updated'})
  //         .where(eq('id', 1))
  //         .returning();
  // print(userUpdate);

  // final usersCount = await db.select().from('users').count();
  // print('Total de usuários: $usersCount');

  // await db.delete('users').where(eq('users.id', 1));

    // final rolesTableSchema = pgTable('roles', {
  //   'id': uuid().primaryKey(),
  //   'name': text().notNull(),
  //   'created_at': timestamp().defaultNow(),
  // });

  // final userRolesTableSchema = pgTable(
  //   'user_roles',
  //   {
  //     'user_id': uuid().notNull(),
  //     'role_id': uuid().notNull(),
  //     'created_at': timestamp().defaultNow(),
  //   },
  //   foreignKeys: [
  //     ForeignKey(
  //       column: 'user_id',
  //       references: 'users',
  //       referencesColumn: 'id',
  //       onDelete: ReferentialAction.cascade,
  //     ),
  //     ForeignKey(
  //       column: 'role_id',
  //       references: 'roles',
  //       referencesColumn: 'id',
  //       onDelete: ReferentialAction.cascade,
  //     ),
  //   ],
  // );

  // final usersTable = sqliteTable('users', {
  //   'id': integer().primaryKey(autoIncrement: true),
  //   'name': text().notNull(),
  //   'email': text().notNull().unique(),
  // });
12
likes
150
points
61
downloads

Publisher

verified publisherevandersondev.com.br

Weekly Downloads

A database query builder inspired by Drizzle. It allows you to connect to various databases (SQLite, PostgreSQL, MySQL) and perform database operations using a fluent API.

Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

mysql1, postgres, sqlite3

More

Packages that depend on dartonic