> ## Documentation Index
> Fetch the complete documentation index at: https://docs.powersync.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Reading Data

> Query data from your local SQLite database using SQL with the PowerSync SDK.

On the client-side, you can read data directly from the local SQLite database using standard SQL queries.

## Basic Queries

Read data using SQL queries:

<CodeGroup>
  ```typescript TypeScript theme={null}
  // Get all todos
  const todos = await db.getAll('SELECT * FROM todos');

  // Get a single todo
  const todo = await db.get('SELECT * FROM todos WHERE id = ?', [todoId]);

  // Watch for changes (reactive query)
  const stream = db.watch('SELECT * FROM todos WHERE list_id = ?', [listId]);
  for await (const todos of stream) {
    // Update UI when data changes
    console.log(todos);
  }
  ```

  ```kotlin Kotlin theme={null}
  // Get all todos
  val todos = database.getAll("SELECT * FROM todos") { cursor ->
    Todo.fromCursor(cursor)
  }

  // Get a single todo
  val todo = database.get("SELECT * FROM todos WHERE id = ?", listOf(todoId)) { cursor ->
    Todo.fromCursor(cursor)
  }

  // Watch for changes
  database.watch("SELECT * FROM todos WHERE list_id = ?", listOf(listId))
    .collect { todos ->
      // Update UI when data changes
    }
  ```

  ```swift Swift theme={null}
  // Get all todos
  let todos = try await db.getAll(
    sql: "SELECT * FROM todos",
    mapper: { cursor in
      TodoContent(
        description: try cursor.getString(name: "description")!,
        completed: try cursor.getBooleanOptional(name: "completed")
      )
    }
  )

  // Watch for changes
  for try await todos in db.watch(
    sql: "SELECT * FROM todos WHERE list_id = ?",
    parameters: [listId]
  ) {
    // Update UI when data changes
  }
  ```

  ```dart Dart/Flutter theme={null}
  // Get all todos
  final todos = await db.getAll('SELECT * FROM todos');

  // Get a single todo
  final todo = await db.get('SELECT * FROM todos WHERE id = ?', [todoId]);

  // Watch for changes
  db.watch('SELECT * FROM todos WHERE list_id = ?', [listId])
    .listen((todos) {
      // Update UI when data changes
    });
  ```

  ```csharp .NET theme={null}
  // Define a result type with properties matching the schema columns (some columns omitted here for brevity)
  // public class TodoResult { public string id; public string description; public int completed; ... }

  // Get all todos
  var todos = await db.GetAll<TodoResult>("SELECT * FROM todos");

  // Get a single todo
  var todo = await db.Get<TodoResult>("SELECT * FROM todos WHERE id = ?", [todoId]);

  // You can also query without specifying a type to get dynamic results:
  dynamic asset = await db.Get("SELECT id, description, make FROM assets");
  Console.WriteLine($"Asset ID: {asset.id}");
  ```
</CodeGroup>

## Live Queries / Watch Queries

For reactive UI updates that automatically refresh when data changes, use watch queries. These queries execute whenever dependent tables are modified.

See [Live Queries / Watch Queries](/client-sdks/watch-queries) for more details.

## ORM Support

PowerSync integrates with popular ORM libraries, which provide type safety and additional tooling. Using an ORM is often preferable to writing raw SQL queries, especially for common operations.

See [ORM Support](/client-sdks/orms/overview) to learn which ORMs PowerSync supports and how to get started.

## Advanced Topics

* [Usage Examples](/client-sdks/usage-examples) - Code examples for common use cases
* [Full-Text Search](/client-sdks/full-text-search) - Full-text search using the [SQLite FTS5 extension](https://www.sqlite.org/fts5.html)
* [Query JSON in SQLite](/client-sdks/advanced/query-json-in-sqlite) - Learn how to work with JSON data in SQLite
* [Infinite Scrolling](/client-sdks/infinite-scrolling) - Efficiently load large datasets
* [High Performance Diffs](/client-sdks/high-performance-diffs) - Efficiently get row changes for large datasets
