parsql_macros/lib.rs
1//! # parsql-macros
2//!
3//! Procedural macros for the parsql crate.
4//! This crate provides derive macros for SQL query generation and parameter handling.
5//!
6//! ## Features
7//!
8//! - Automatic SQL query generation
9//! - Secure parameter handling
10//! - Support for multiple database systems (PostgreSQL, SQLite)
11//! - Type-safe database operations
12//!
13//! ## Macros
14//!
15//! - `Updateable`: Generates UPDATE queries
16//! - `Insertable`: Generates INSERT queries
17//! - `Queryable`: Generates SELECT queries
18//! - `Deletable`: Generates DELETE queries
19//! - `SqlParams`: Generates parameter handling code
20//! - `UpdateParams`: Generates parameter handling code for UPDATE operations
21//! - `FromRow`: Generates code for converting database rows to Rust structs
22
23use std::env;
24
25use proc_macro::TokenStream;
26use syn::{parse_macro_input, DeriveInput};
27
28mod deletable;
29mod from_row;
30mod insertable;
31mod numbering_test;
32mod query_builder;
33mod queryable;
34mod sql_params;
35mod update_params;
36mod updateable;
37mod utils;
38
39#[path = "tests/param_numbering_tests.rs"]
40mod param_numbering_tests;
41#[path = "tests/sql_param_counter_tests.rs"]
42mod sql_param_counter_tests;
43
44mod implementations;
45
46pub(crate) use query_builder::*;
47pub(crate) use utils::*;
48/// Derive macro for generating UPDATE queries.
49///
50/// # Attributes
51/// - `table`: The name of the table to update
52/// - `where_clause`: The WHERE clause for the UPDATE statement
53/// - `update`: The columns to update
54#[proc_macro_derive(Updateable, attributes(table, where_clause, update))]
55pub fn derive_updateable(input: TokenStream) -> TokenStream {
56 // Let's add special checks for secure parameter usage
57 updateable::derive_updateable_impl(input)
58}
59
60/// Derive macro for generating INSERT queries.
61///
62/// # Attributes
63/// - `table`: The name of the table to insert into
64/// - `returning`: The column to return after insert (optional)
65#[proc_macro_derive(Insertable, attributes(table, returning, sql_type))]
66pub fn derive_insertable(input: TokenStream) -> TokenStream {
67 insertable::derive_insertable_impl(input)
68}
69
70/// Derive macro for generating SELECT queries.
71///
72/// # Attributes
73/// - `table`: The name of the table to select from
74/// - `where_clause`: The WHERE clause for the SELECT statement
75/// - `select`: The columns to select (optional)
76/// - `join`: JOIN clauses (optional)
77/// - `group_by`: GROUP BY clause (optional)
78/// - `order_by`: ORDER BY clause (optional)
79/// - `having`: HAVING clause (optional)
80/// - `limit`: LIMIT clause (optional)
81/// - `offset`: OFFSET clause (optional)
82/// - `distinct`: Make query return distinct results (optional)
83/// - `result_type`: The type to return as query result (optional, defaults to self)
84#[proc_macro_derive(
85 Queryable,
86 attributes(
87 table,
88 where_clause,
89 select,
90 join,
91 group_by,
92 order_by,
93 having,
94 limit,
95 offset,
96 distinct,
97 result_type
98 )
99)]
100pub fn derive_queryable(input: TokenStream) -> TokenStream {
101 queryable::derive_queryable_impl(input)
102}
103
104/// Derive macro for generating DELETE queries.
105///
106/// # Attributes
107/// - `table`: The name of the table to delete from
108/// - `where_clause`: The WHERE clause for the DELETE statement
109#[proc_macro_derive(Deletable, attributes(table, where_clause))]
110pub fn derive_deletable(input: TokenStream) -> TokenStream {
111 deletable::derive_deletable_impl(input)
112}
113
114/// Derive macro for generating SQL parameter handling code.
115///
116/// # Attributes
117/// - `where_clause`: The WHERE clause containing parameter placeholders
118#[proc_macro_derive(SqlParams, attributes(where_clause))]
119pub fn derive_sql_params(input: TokenStream) -> TokenStream {
120 sql_params::derive_sql_params_impl(input)
121}
122
123/// Derive macro for generating UPDATE parameter handling code.
124///
125/// # Attributes
126/// - `update`: The columns to update
127/// - `where_clause`: The WHERE clause containing parameter placeholders
128#[proc_macro_derive(UpdateParams, attributes(update, where_clause))]
129pub fn derive_update_params(input: TokenStream) -> TokenStream {
130 update_params::derive_update_params_impl(input)
131}
132
133/// Derive macro for converting database rows to Rust structs.
134///
135/// This macro automatically detects the enabled database feature and generates
136/// the appropriate implementation for converting database rows to Rust structs.
137///
138/// # Features
139/// - `postgres`: Generate code for PostgreSQL
140/// - `tokio-postgres`: Generate code for Tokio PostgreSQL
141/// - `deadpool-postgres`: Generate code for Deadpool PostgreSQL
142/// - `sqlite`: Generate code for SQLite
143///
144/// # Usage
145/// ```rust
146/// #[derive(FromRow)]
147/// struct User {
148/// id: i32,
149/// name: String,
150/// email: String,
151/// }
152/// ```
153#[proc_macro_derive(FromRow)]
154pub fn derive_from_row(input: TokenStream) -> TokenStream {
155 from_row::expand_from_row(input)
156}
157
158// Geriye dönük uyumluluk için özel veritabanı makroları
159#[cfg(feature = "sqlite")]
160#[proc_macro_derive(FromRowSqlite)]
161pub fn derive_from_row_sqlite(input: TokenStream) -> TokenStream {
162 crate::implementations::sqlite::generate_from_row(&parse_macro_input!(input as DeriveInput))
163 .into()
164}
165
166#[cfg(any(
167 feature = "postgres",
168 feature = "tokio-postgres",
169 feature = "deadpool-postgres"
170))]
171#[proc_macro_derive(FromRowPostgres)]
172pub fn derive_from_row_postgres(input: TokenStream) -> TokenStream {
173 crate::implementations::postgres::generate_from_row(&parse_macro_input!(input as DeriveInput))
174 .into()
175}
176
177// SqlParamCounter ve number_where_clause_params fonksiyonlarını sadece test için dışa aktarıyoruz
178#[cfg(test)]
179pub(crate) use utils::{number_where_clause_params, SqlParamCounter};
180
181/// Log mesajlarını yazdırmak için yardımcı fonksiyon
182pub(crate) fn log_message(message: &str) {
183 if let Ok(trace) = env::var("PARSQL_TRACE") {
184 if trace == "1" {
185 println!("{}", message);
186 }
187 }
188}